From c7c22e3db1c826bcfb2bc66651ec480aae0d4ae0 Mon Sep 17 00:00:00 2001 From: yo mama Date: Sat, 4 Apr 2015 01:00:59 -0700 Subject: first --- node_modules/forever/.npmignore | 6 + node_modules/forever/.travis.yml | 11 + node_modules/forever/CHANGELOG.md | 138 + node_modules/forever/LICENSE | 19 + node_modules/forever/README.md | 141 + node_modules/forever/bin/forever | 3 + node_modules/forever/bin/foreverd | 4 + node_modules/forever/bin/monitor | 83 + node_modules/forever/lib/forever.js | 907 ++ node_modules/forever/lib/forever/cli.js | 564 ++ .../lib/forever/service/adapters/adapter.js | 96 + .../lib/forever/service/adapters/initd/index.js | 9 + .../lib/forever/service/adapters/systemv/foreverd | 82 + .../lib/forever/service/adapters/systemv/index.js | 199 + node_modules/forever/lib/forever/service/cli.js | 102 + node_modules/forever/lib/forever/service/index.js | 22 + .../forever/lib/forever/service/service.js | 268 + node_modules/forever/lib/forever/worker.js | 122 + node_modules/forever/node_modules/.bin/flatiron | 1 + node_modules/forever/node_modules/cliff/.npmignore | 2 + node_modules/forever/node_modules/cliff/LICENSE | 19 + node_modules/forever/node_modules/cliff/README.md | 227 + .../forever/node_modules/cliff/assets/inspect.png | Bin 0 -> 27533 bytes .../node_modules/cliff/assets/put-object-rows.png | Bin 0 -> 54871 bytes .../node_modules/cliff/assets/put-object.png | Bin 0 -> 32635 bytes .../node_modules/cliff/assets/put-rows-colors.png | Bin 0 -> 23408 bytes .../forever/node_modules/cliff/assets/put-rows.png | Bin 0 -> 21809 bytes .../cliff/assets/string-object-rows.png | Bin 0 -> 53234 bytes .../node_modules/cliff/assets/string-rows.png | Bin 0 -> 20775 bytes .../forever/node_modules/cliff/examples/inspect.js | 24 + .../node_modules/cliff/examples/put-object-rows.js | 23 + .../node_modules/cliff/examples/put-object.js | 24 + .../node_modules/cliff/examples/put-rows-colors.js | 12 + .../node_modules/cliff/examples/put-rows.js | 11 + .../cliff/examples/string-object-rows.js | 23 + .../node_modules/cliff/examples/string-rows.js | 11 + .../forever/node_modules/cliff/lib/cliff.js | 280 + .../node_modules/cliff/node_modules/eyes/LICENSE | 20 + .../node_modules/cliff/node_modules/eyes/Makefile | 4 + .../node_modules/cliff/node_modules/eyes/README.md | 73 + .../cliff/node_modules/eyes/lib/eyes.js | 236 + .../cliff/node_modules/eyes/package.json | 44 + .../cliff/node_modules/eyes/test/eyes-test.js | 56 + .../cliff/node_modules/winston/.npmignore | 6 + .../cliff/node_modules/winston/.travis.yml | 12 + .../cliff/node_modules/winston/LICENSE | 19 + .../cliff/node_modules/winston/README.md | 790 ++ .../cliff/node_modules/winston/docs/transports.md | 342 + .../cliff/node_modules/winston/examples/couchdb.js | 18 + .../node_modules/winston/examples/exception.js | 4 + .../node_modules/winston/examples/raw-mode.js | 10 + .../node_modules/winston/examples/webhook-post.js | 17 + .../cliff/node_modules/winston/lib/winston.js | 145 + .../node_modules/winston/lib/winston/common.js | 259 + .../node_modules/winston/lib/winston/config.js | 45 + .../winston/lib/winston/config/cli-config.js | 35 + .../winston/lib/winston/config/npm-config.js | 27 + .../winston/lib/winston/config/syslog-config.js | 31 + .../node_modules/winston/lib/winston/container.js | 101 + .../node_modules/winston/lib/winston/exception.js | 56 + .../node_modules/winston/lib/winston/logger.js | 668 ++ .../node_modules/winston/lib/winston/transports.js | 29 + .../winston/lib/winston/transports/console.js | 88 + .../winston/lib/winston/transports/file.js | 575 ++ .../winston/lib/winston/transports/http.js | 200 + .../winston/lib/winston/transports/transport.js | 120 + .../winston/lib/winston/transports/webhook.js | 136 + .../winston/node_modules/async/.gitmodules | 9 + .../winston/node_modules/async/.npmignore | 4 + .../winston/node_modules/async/LICENSE | 19 + .../winston/node_modules/async/Makefile | 25 + .../winston/node_modules/async/README.md | 1021 +++ .../winston/node_modules/async/index.js | 3 + .../winston/node_modules/async/lib/async.js | 692 ++ .../winston/node_modules/async/package.json | 36 + .../winston/node_modules/cycle/README.md | 45 + .../winston/node_modules/cycle/cycle.js | 164 + .../winston/node_modules/cycle/package.json | 33 + .../winston/node_modules/pkginfo/.npmignore | 2 + .../winston/node_modules/pkginfo/README.md | 85 + .../winston/node_modules/pkginfo/docs/docco.css | 194 + .../winston/node_modules/pkginfo/docs/pkginfo.html | 101 + .../pkginfo/examples/all-properties.js | 19 + .../pkginfo/examples/array-argument.js | 20 + .../pkginfo/examples/multiple-properties.js | 19 + .../pkginfo/examples/object-argument.js | 22 + .../node_modules/pkginfo/examples/package.json | 10 + .../pkginfo/examples/single-property.js | 19 + .../winston/node_modules/pkginfo/lib/pkginfo.js | 132 + .../winston/node_modules/pkginfo/package.json | 39 + .../node_modules/pkginfo/test/pkginfo-test.js | 69 + .../winston/node_modules/request/LICENSE | 55 + .../winston/node_modules/request/README.md | 287 + .../winston/node_modules/request/aws.js | 190 + .../winston/node_modules/request/aws2.js | 128 + .../winston/node_modules/request/forever.js | 103 + .../winston/node_modules/request/main.js | 974 +++ .../winston/node_modules/request/mimetypes.js | 152 + .../winston/node_modules/request/oauth.js | 34 + .../winston/node_modules/request/package.json | 37 + .../node_modules/request/tests/googledoodle.png | Bin 0 -> 38510 bytes .../winston/node_modules/request/tests/run.js | 39 + .../winston/node_modules/request/tests/server.js | 82 + .../winston/node_modules/request/tests/squid.conf | 77 + .../node_modules/request/tests/ssl/ca/ca.cnf | 20 + .../node_modules/request/tests/ssl/ca/ca.crl | 0 .../node_modules/request/tests/ssl/ca/ca.crt | 17 + .../node_modules/request/tests/ssl/ca/ca.csr | 13 + .../node_modules/request/tests/ssl/ca/ca.key | 18 + .../node_modules/request/tests/ssl/ca/ca.srl | 1 + .../node_modules/request/tests/ssl/ca/server.cnf | 19 + .../node_modules/request/tests/ssl/ca/server.crt | 16 + .../node_modules/request/tests/ssl/ca/server.csr | 11 + .../node_modules/request/tests/ssl/ca/server.js | 28 + .../node_modules/request/tests/ssl/ca/server.key | 9 + .../node_modules/request/tests/ssl/npm-ca.crt | 16 + .../node_modules/request/tests/ssl/test.crt | 15 + .../node_modules/request/tests/ssl/test.key | 15 + .../node_modules/request/tests/test-body.js | 80 + .../node_modules/request/tests/test-cookie.js | 29 + .../node_modules/request/tests/test-cookiejar.js | 90 + .../node_modules/request/tests/test-defaults.js | 68 + .../node_modules/request/tests/test-errors.js | 37 + .../node_modules/request/tests/test-headers.js | 52 + .../node_modules/request/tests/test-httpModule.js | 94 + .../request/tests/test-https-strict.js | 97 + .../node_modules/request/tests/test-https.js | 86 + .../node_modules/request/tests/test-oauth.js | 117 + .../node_modules/request/tests/test-params.js | 92 + .../node_modules/request/tests/test-pipes.js | 202 + .../node_modules/request/tests/test-pool.js | 16 + .../node_modules/request/tests/test-proxy.js | 39 + .../winston/node_modules/request/tests/test-qs.js | 28 + .../node_modules/request/tests/test-redirect.js | 154 + .../winston/node_modules/request/tests/test-s3.js | 13 + .../node_modules/request/tests/test-timeout.js | 87 + .../node_modules/request/tests/test-toJSON.js | 14 + .../node_modules/request/tests/test-tunnel.js | 61 + .../winston/node_modules/request/tunnel.js | 229 + .../winston/node_modules/request/uuid.js | 19 + .../node_modules/request/vendor/cookie/index.js | 65 + .../node_modules/request/vendor/cookie/jar.js | 72 + .../winston/node_modules/stack-trace/.npmignore | 1 + .../winston/node_modules/stack-trace/License | 19 + .../winston/node_modules/stack-trace/Makefile | 11 + .../winston/node_modules/stack-trace/Readme.md | 98 + .../node_modules/stack-trace/lib/stack-trace.js | 111 + .../winston/node_modules/stack-trace/package.json | 36 + .../cliff/node_modules/winston/package.json | 54 + .../cliff/node_modules/winston/test/cli-test.js | 40 + .../node_modules/winston/test/container-test.js | 99 + .../winston/test/custom-timestamp-test.js | 62 + .../node_modules/winston/test/exception-test.js | 47 + .../node_modules/winston/test/fixtures/.gitkeep | 0 .../winston/test/fixtures/keys/agent2-cert.pem | 13 + .../winston/test/fixtures/keys/agent2-key.pem | 9 + .../winston/test/fixtures/logs/.gitkeep | 0 .../test/fixtures/scripts/default-exceptions.js | 21 + .../winston/test/fixtures/scripts/exit-on-error.js | 25 + .../test/fixtures/scripts/log-exceptions.js | 25 + .../test/fixtures/scripts/unhandle-exceptions.js | 26 + .../cliff/node_modules/winston/test/helpers.js | 173 + .../winston/test/log-exception-test.js | 60 + .../node_modules/winston/test/log-rewriter-test.js | 98 + .../cliff/node_modules/winston/test/logger-test.js | 200 + .../winston/test/transports/console-test.js | 39 + .../winston/test/transports/file-maxfiles-test.js | 102 + .../winston/test/transports/file-maxsize-test.js | 82 + .../winston/test/transports/file-test.js | 60 + .../winston/test/transports/transport.js | 212 + .../winston/test/transports/webhook-test.js | 125 + .../node_modules/winston/test/winston-test.js | 98 + .../forever/node_modules/cliff/package.json | 51 + .../forever/node_modules/cliff/test/cliff-test.js | 79 + .../forever/node_modules/colors/MIT-LICENSE.txt | 22 + node_modules/forever/node_modules/colors/ReadMe.md | 77 + node_modules/forever/node_modules/colors/colors.js | 269 + .../forever/node_modules/colors/example.html | 74 + .../forever/node_modules/colors/example.js | 65 + .../forever/node_modules/colors/package.json | 27 + node_modules/forever/node_modules/colors/test.js | 65 + .../forever/node_modules/flatiron/.npmignore | 2 + .../forever/node_modules/flatiron/.travis.yml | 12 + node_modules/forever/node_modules/flatiron/LICENSE | 19 + .../forever/node_modules/flatiron/README.md | 482 ++ .../forever/node_modules/flatiron/bin/flatiron | 30 + .../flatiron/examples/cli-sample/index.js | 28 + .../flatiron/examples/cli-sample/print.js | 5 + .../node_modules/flatiron/examples/http-sample.js | 30 + .../flatiron/examples/resourceful-app/app.js | 8 + .../resourceful-app/app/resources/creature.js | 13 + .../flatiron/examples/resourceful-app/package.json | 15 + .../flatiron/examples/socket.io/index.html | 8 + .../flatiron/examples/socket.io/server.js | 38 + .../flatiron/examples/static-app/app.js | 12 + .../examples/static-app/app/assets/style.css | 1 + .../examples/static-app/app/assets/style.js | 1 + .../flatiron/examples/static-app/package.json | 15 + .../forever/node_modules/flatiron/lib/flatiron.js | 75 + .../node_modules/flatiron/lib/flatiron/app.js | 32 + .../flatiron/lib/flatiron/cli/create.js | 97 + .../node_modules/flatiron/lib/flatiron/common.js | 52 + .../flatiron/lib/flatiron/constants.js | 19 + .../flatiron/lib/flatiron/plugins/cli.js | 453 + .../flatiron/lib/flatiron/plugins/http.js | 103 + .../flatiron/lib/flatiron/plugins/resourceful.js | 125 + .../flatiron/lib/flatiron/plugins/static.js | 87 + .../flatiron/node_modules/broadway/.npmignore | 4 + .../flatiron/node_modules/broadway/.travis.yml | 11 + .../flatiron/node_modules/broadway/LICENSE | 19 + .../flatiron/node_modules/broadway/README.md | 124 + .../flatiron/node_modules/broadway/bin/build | 66 + .../node_modules/broadway/examples/browser/app.js | 12 + .../broadway/examples/browser/index.html | 11 + .../examples/browser/plugins/helloworld.js | 23 + .../node_modules/broadway/examples/nodejs/app.js | 17 + .../broadway/examples/nodejs/plugins/helloworld.js | 23 + .../flatiron/node_modules/broadway/lib/broadway.js | 19 + .../node_modules/broadway/lib/broadway/app.js | 225 + .../broadway/lib/broadway/bootstrapper.js | 65 + .../node_modules/broadway/lib/broadway/browser.js | 75 + .../broadway/lib/broadway/common/directories.js | 78 + .../broadway/lib/broadway/common/index.js | 18 + .../broadway/lib/broadway/features/index.js | 48 + .../broadway/lib/broadway/plugins/config.js | 46 + .../broadway/lib/broadway/plugins/directories.js | 49 + .../broadway/lib/broadway/plugins/exceptions.js | 70 + .../broadway/lib/broadway/plugins/inspect.js | 40 + .../broadway/lib/broadway/plugins/log.js | 195 + .../broadway/node_modules/eventemitter2/.npmignore | 13 + .../broadway/node_modules/eventemitter2/README.md | 212 + .../broadway/node_modules/eventemitter2/index.js | 1 + .../eventemitter2/lib/eventemitter2.js | 560 ++ .../node_modules/eventemitter2/package.json | 85 + .../node_modules/eventemitter2/test/common.js | 122 + .../eventemitter2/test/perf/benchmark.js | 53 + .../eventemitter2/test/simple/addListener.js | 179 + .../node_modules/eventemitter2/test/simple/emit.js | 142 + .../eventemitter2/test/simple/reconfigure.js | 55 + .../eventemitter2/test/simple/removeListener.js | 196 + .../eventemitter2/test/simple/setMax.js | 135 + .../node_modules/eventemitter2/test/simple/ttl.js | 115 + .../test/wildcardEvents/addListener.js | 338 + .../eventemitter2/test/wildcardEvents/all.js | 248 + .../test/wildcardEvents/customDelimiter.js | 250 + .../eventemitter2/test/wildcardEvents/k1.js | 56 + .../eventemitter2/test/wildcardEvents/options.js | 72 + .../test/wildcardEvents/removeListener.js | 317 + .../eventemitter2/test/wildcardEvents/ttl.js | 223 + .../broadway/node_modules/winston/.npmignore | 6 + .../broadway/node_modules/winston/.travis.yml | 12 + .../broadway/node_modules/winston/LICENSE | 19 + .../broadway/node_modules/winston/README.md | 790 ++ .../node_modules/winston/docs/transports.md | 342 + .../node_modules/winston/examples/couchdb.js | 18 + .../node_modules/winston/examples/exception.js | 4 + .../node_modules/winston/examples/raw-mode.js | 10 + .../node_modules/winston/examples/webhook-post.js | 17 + .../broadway/node_modules/winston/lib/winston.js | 145 + .../node_modules/winston/lib/winston/common.js | 259 + .../node_modules/winston/lib/winston/config.js | 45 + .../winston/lib/winston/config/cli-config.js | 35 + .../winston/lib/winston/config/npm-config.js | 27 + .../winston/lib/winston/config/syslog-config.js | 31 + .../node_modules/winston/lib/winston/container.js | 101 + .../node_modules/winston/lib/winston/exception.js | 56 + .../node_modules/winston/lib/winston/logger.js | 668 ++ .../node_modules/winston/lib/winston/transports.js | 29 + .../winston/lib/winston/transports/console.js | 88 + .../winston/lib/winston/transports/file.js | 575 ++ .../winston/lib/winston/transports/http.js | 200 + .../winston/lib/winston/transports/transport.js | 120 + .../winston/lib/winston/transports/webhook.js | 136 + .../winston/node_modules/async/.gitmodules | 9 + .../winston/node_modules/async/.npmignore | 4 + .../winston/node_modules/async/LICENSE | 19 + .../winston/node_modules/async/Makefile | 25 + .../winston/node_modules/async/README.md | 1021 +++ .../winston/node_modules/async/index.js | 3 + .../winston/node_modules/async/lib/async.js | 692 ++ .../winston/node_modules/async/package.json | 36 + .../winston/node_modules/cycle/README.md | 45 + .../winston/node_modules/cycle/cycle.js | 164 + .../winston/node_modules/cycle/package.json | 33 + .../node_modules/winston/node_modules/eyes/LICENSE | 20 + .../winston/node_modules/eyes/Makefile | 4 + .../winston/node_modules/eyes/README.md | 73 + .../winston/node_modules/eyes/lib/eyes.js | 236 + .../winston/node_modules/eyes/package.json | 44 + .../winston/node_modules/eyes/test/eyes-test.js | 56 + .../winston/node_modules/pkginfo/.npmignore | 2 + .../winston/node_modules/pkginfo/README.md | 85 + .../winston/node_modules/pkginfo/docs/docco.css | 194 + .../winston/node_modules/pkginfo/docs/pkginfo.html | 101 + .../pkginfo/examples/all-properties.js | 19 + .../pkginfo/examples/array-argument.js | 20 + .../pkginfo/examples/multiple-properties.js | 19 + .../pkginfo/examples/object-argument.js | 22 + .../node_modules/pkginfo/examples/package.json | 10 + .../pkginfo/examples/single-property.js | 19 + .../winston/node_modules/pkginfo/lib/pkginfo.js | 132 + .../winston/node_modules/pkginfo/package.json | 39 + .../node_modules/pkginfo/test/pkginfo-test.js | 69 + .../winston/node_modules/request/LICENSE | 55 + .../winston/node_modules/request/README.md | 287 + .../winston/node_modules/request/aws.js | 190 + .../winston/node_modules/request/aws2.js | 128 + .../winston/node_modules/request/forever.js | 103 + .../winston/node_modules/request/main.js | 974 +++ .../winston/node_modules/request/mimetypes.js | 152 + .../winston/node_modules/request/oauth.js | 34 + .../winston/node_modules/request/package.json | 37 + .../node_modules/request/tests/googledoodle.png | Bin 0 -> 38510 bytes .../winston/node_modules/request/tests/run.js | 39 + .../winston/node_modules/request/tests/server.js | 82 + .../winston/node_modules/request/tests/squid.conf | 77 + .../node_modules/request/tests/ssl/ca/ca.cnf | 20 + .../node_modules/request/tests/ssl/ca/ca.crl | 0 .../node_modules/request/tests/ssl/ca/ca.crt | 17 + .../node_modules/request/tests/ssl/ca/ca.csr | 13 + .../node_modules/request/tests/ssl/ca/ca.key | 18 + .../node_modules/request/tests/ssl/ca/ca.srl | 1 + .../node_modules/request/tests/ssl/ca/server.cnf | 19 + .../node_modules/request/tests/ssl/ca/server.crt | 16 + .../node_modules/request/tests/ssl/ca/server.csr | 11 + .../node_modules/request/tests/ssl/ca/server.js | 28 + .../node_modules/request/tests/ssl/ca/server.key | 9 + .../node_modules/request/tests/ssl/npm-ca.crt | 16 + .../node_modules/request/tests/ssl/test.crt | 15 + .../node_modules/request/tests/ssl/test.key | 15 + .../node_modules/request/tests/test-body.js | 80 + .../node_modules/request/tests/test-cookie.js | 29 + .../node_modules/request/tests/test-cookiejar.js | 90 + .../node_modules/request/tests/test-defaults.js | 68 + .../node_modules/request/tests/test-errors.js | 37 + .../node_modules/request/tests/test-headers.js | 52 + .../node_modules/request/tests/test-httpModule.js | 94 + .../request/tests/test-https-strict.js | 97 + .../node_modules/request/tests/test-https.js | 86 + .../node_modules/request/tests/test-oauth.js | 117 + .../node_modules/request/tests/test-params.js | 92 + .../node_modules/request/tests/test-pipes.js | 202 + .../node_modules/request/tests/test-pool.js | 16 + .../node_modules/request/tests/test-proxy.js | 39 + .../winston/node_modules/request/tests/test-qs.js | 28 + .../node_modules/request/tests/test-redirect.js | 154 + .../winston/node_modules/request/tests/test-s3.js | 13 + .../node_modules/request/tests/test-timeout.js | 87 + .../node_modules/request/tests/test-toJSON.js | 14 + .../node_modules/request/tests/test-tunnel.js | 61 + .../winston/node_modules/request/tunnel.js | 229 + .../winston/node_modules/request/uuid.js | 19 + .../node_modules/request/vendor/cookie/index.js | 65 + .../node_modules/request/vendor/cookie/jar.js | 72 + .../winston/node_modules/stack-trace/.npmignore | 1 + .../winston/node_modules/stack-trace/License | 19 + .../winston/node_modules/stack-trace/Makefile | 11 + .../winston/node_modules/stack-trace/Readme.md | 98 + .../node_modules/stack-trace/lib/stack-trace.js | 111 + .../winston/node_modules/stack-trace/package.json | 36 + .../broadway/node_modules/winston/package.json | 54 + .../broadway/node_modules/winston/test/cli-test.js | 40 + .../node_modules/winston/test/container-test.js | 99 + .../winston/test/custom-timestamp-test.js | 62 + .../node_modules/winston/test/exception-test.js | 47 + .../node_modules/winston/test/fixtures/.gitkeep | 0 .../winston/test/fixtures/keys/agent2-cert.pem | 13 + .../winston/test/fixtures/keys/agent2-key.pem | 9 + .../winston/test/fixtures/logs/.gitkeep | 0 .../test/fixtures/scripts/default-exceptions.js | 21 + .../winston/test/fixtures/scripts/exit-on-error.js | 25 + .../test/fixtures/scripts/log-exceptions.js | 25 + .../test/fixtures/scripts/unhandle-exceptions.js | 26 + .../broadway/node_modules/winston/test/helpers.js | 173 + .../winston/test/log-exception-test.js | 60 + .../node_modules/winston/test/log-rewriter-test.js | 98 + .../node_modules/winston/test/logger-test.js | 200 + .../winston/test/transports/console-test.js | 39 + .../winston/test/transports/file-maxfiles-test.js | 102 + .../winston/test/transports/file-maxsize-test.js | 82 + .../winston/test/transports/file-test.js | 60 + .../winston/test/transports/transport.js | 212 + .../winston/test/transports/webhook-test.js | 125 + .../node_modules/winston/test/winston-test.js | 98 + .../flatiron/node_modules/broadway/package.json | 57 + .../broadway/test/common/directories-test.js | 60 + .../broadway/test/core/app-init-test.js | 100 + .../node_modules/broadway/test/core/app-test.js | 73 + .../broadway/test/core/broadway-test.js | 26 + .../node_modules/broadway/test/fixtures/.gitkeep | 0 .../broadway/test/fixtures/empty-app/.gitkeep | 0 .../broadway/test/fixtures/sample-app.json | 8 + .../broadway/test/fixtures/sample-app/app/index.js | 2 + .../test/fixtures/sample-app/config/topics.json | 5 + .../node_modules/broadway/test/helpers/assert.js | 108 + .../node_modules/broadway/test/helpers/helpers.js | 24 + .../node_modules/broadway/test/helpers/macros.js | 74 + .../broadway/test/plugins/config-test.js | 19 + .../broadway/test/plugins/directories-test.js | 28 + .../node_modules/broadway/test/plugins/log-test.js | 69 + .../flatiron/node_modules/director/.npmignore | 6 + .../flatiron/node_modules/director/.travis.yml | 11 + .../flatiron/node_modules/director/LICENSE | 19 + .../flatiron/node_modules/director/README.md | 822 ++ .../flatiron/node_modules/director/bin/build | 79 + .../node_modules/director/build/director.js | 712 ++ .../node_modules/director/build/director.min.js | 7 + .../flatiron/node_modules/director/build/ender.js | 3 + .../node_modules/director/examples/http.js | 33 + .../node_modules/director/img/director.png | Bin 0 -> 12856 bytes .../node_modules/director/img/hashRoute.png | Bin 0 -> 12485 bytes .../flatiron/node_modules/director/lib/director.js | 6 + .../node_modules/director/lib/director/browser.js | 297 + .../node_modules/director/lib/director/cli.js | 65 + .../director/lib/director/http/index.js | 248 + .../director/lib/director/http/methods.js | 66 + .../director/lib/director/http/responses.js | 93 + .../node_modules/director/lib/director/router.js | 797 ++ .../flatiron/node_modules/director/package.json | 61 + .../director/test/browser/backend/backend.js | 71 + .../director/test/browser/browserify-harness.html | 24 + .../director/test/browser/helpers/api.js | 77 + .../test/browser/html5-routes-harness.html | 23 + .../director/test/browser/html5-routes-test.js | 660 ++ .../director/test/browser/routes-harness.html | 21 + .../director/test/browser/routes-test.js | 694 ++ .../director/test/server/cli/dispatch-test.js | 55 + .../director/test/server/cli/mount-test.js | 30 + .../director/test/server/cli/path-test.js | 39 + .../director/test/server/core/dispatch-test.js | 113 + .../director/test/server/core/insert-test.js | 45 + .../director/test/server/core/mount-test.js | 117 + .../director/test/server/core/on-test.js | 38 + .../director/test/server/core/path-test.js | 49 + .../director/test/server/core/regifystring-test.js | 103 + .../director/test/server/helpers/index.js | 52 + .../director/test/server/helpers/macros.js | 55 + .../director/test/server/http/accept-test.js | 88 + .../director/test/server/http/attach-test.js | 51 + .../director/test/server/http/before-test.js | 38 + .../director/test/server/http/http-test.js | 65 + .../director/test/server/http/methods-test.js | 42 + .../director/test/server/http/responses-test.js | 21 + .../director/test/server/http/stream-test.js | 46 + .../flatiron/node_modules/optimist/.travis.yml | 4 + .../flatiron/node_modules/optimist/LICENSE | 21 + .../flatiron/node_modules/optimist/README.markdown | 487 ++ .../flatiron/node_modules/optimist/example/bool.js | 10 + .../optimist/example/boolean_double.js | 7 + .../optimist/example/boolean_single.js | 7 + .../node_modules/optimist/example/default_hash.js | 8 + .../optimist/example/default_singles.js | 7 + .../node_modules/optimist/example/divide.js | 8 + .../node_modules/optimist/example/line_count.js | 20 + .../optimist/example/line_count_options.js | 29 + .../optimist/example/line_count_wrap.js | 29 + .../node_modules/optimist/example/nonopt.js | 4 + .../node_modules/optimist/example/reflect.js | 2 + .../node_modules/optimist/example/short.js | 3 + .../node_modules/optimist/example/string.js | 11 + .../node_modules/optimist/example/usage-options.js | 19 + .../flatiron/node_modules/optimist/example/xup.js | 10 + .../flatiron/node_modules/optimist/index.js | 475 ++ .../optimist/node_modules/wordwrap/.npmignore | 1 + .../optimist/node_modules/wordwrap/README.markdown | 70 + .../node_modules/wordwrap/example/center.js | 10 + .../optimist/node_modules/wordwrap/example/meat.js | 3 + .../optimist/node_modules/wordwrap/index.js | 76 + .../optimist/node_modules/wordwrap/package.json | 48 + .../optimist/node_modules/wordwrap/test/break.js | 30 + .../node_modules/wordwrap/test/idleness.txt | 63 + .../optimist/node_modules/wordwrap/test/wrap.js | 31 + .../flatiron/node_modules/optimist/package.json | 54 + .../flatiron/node_modules/optimist/test/_.js | 71 + .../flatiron/node_modules/optimist/test/_/argv.js | 2 + .../flatiron/node_modules/optimist/test/_/bin.js | 3 + .../flatiron/node_modules/optimist/test/parse.js | 433 + .../flatiron/node_modules/optimist/test/usage.js | 292 + .../flatiron/node_modules/optimist/x.js | 1 + .../flatiron/node_modules/prompt/.jshintrc | 54 + .../flatiron/node_modules/prompt/.npmignore | 3 + .../flatiron/node_modules/prompt/.travis.yml | 9 + .../flatiron/node_modules/prompt/CHANGELOG.md | 13 + .../flatiron/node_modules/prompt/LICENSE | 19 + .../flatiron/node_modules/prompt/README.md | 293 + .../flatiron/node_modules/prompt/docs/docco.css | 194 + .../flatiron/node_modules/prompt/docs/prompt.html | 296 + .../node_modules/prompt/examples/add-properties.js | 35 + .../prompt/examples/existing-properties.js | 35 + .../node_modules/prompt/examples/history.js | 44 + .../prompt/examples/nested-properties-prompt.js | 37 + .../node_modules/prompt/examples/old-schema.js | 36 + .../prompt/examples/override-validation.js | 52 + .../node_modules/prompt/examples/password.js | 34 + .../prompt/examples/prompt-override.js | 36 + .../prompt/examples/property-prompt.js | 45 + .../node_modules/prompt/examples/simple-prompt.js | 25 + .../prompt/examples/yes-or-no-prompt.js | 32 + .../flatiron/node_modules/prompt/lib/prompt.js | 757 ++ .../prompt/node_modules/read/.npmignore | 2 + .../node_modules/prompt/node_modules/read/LICENCE | 25 + .../prompt/node_modules/read/README.md | 53 + .../prompt/node_modules/read/example/example.js | 13 + .../prompt/node_modules/read/lib/read.js | 113 + .../read/node_modules/mute-stream/LICENSE | 27 + .../read/node_modules/mute-stream/README.md | 68 + .../read/node_modules/mute-stream/mute.js | 140 + .../read/node_modules/mute-stream/package.json | 41 + .../read/node_modules/mute-stream/test/basic.js | 207 + .../prompt/node_modules/read/package.json | 39 + .../node_modules/prompt/node_modules/read/rs.js | 4 + .../prompt/node_modules/read/test/basic.js | 60 + .../prompt/node_modules/read/test/defaults.js | 60 + .../prompt/node_modules/read/test/many.js | 83 + .../prompt/node_modules/revalidator/.npmignore | 2 + .../prompt/node_modules/revalidator/.travis.yml | 11 + .../prompt/node_modules/revalidator/CHANGELOG.md | 25 + .../prompt/node_modules/revalidator/LICENSE | 179 + .../prompt/node_modules/revalidator/README.md | 287 + .../node_modules/revalidator/example/webservice.js | 204 + .../node_modules/revalidator/lib/revalidator.js | 409 + .../prompt/node_modules/revalidator/package.json | 44 + .../revalidator/test/validator-test.js | 399 + .../prompt/node_modules/winston/.npmignore | 6 + .../prompt/node_modules/winston/.travis.yml | 12 + .../prompt/node_modules/winston/LICENSE | 19 + .../prompt/node_modules/winston/README.md | 790 ++ .../prompt/node_modules/winston/docs/transports.md | 342 + .../node_modules/winston/examples/couchdb.js | 18 + .../node_modules/winston/examples/exception.js | 4 + .../node_modules/winston/examples/raw-mode.js | 10 + .../node_modules/winston/examples/webhook-post.js | 17 + .../prompt/node_modules/winston/lib/winston.js | 145 + .../node_modules/winston/lib/winston/common.js | 259 + .../node_modules/winston/lib/winston/config.js | 45 + .../winston/lib/winston/config/cli-config.js | 35 + .../winston/lib/winston/config/npm-config.js | 27 + .../winston/lib/winston/config/syslog-config.js | 31 + .../node_modules/winston/lib/winston/container.js | 101 + .../node_modules/winston/lib/winston/exception.js | 56 + .../node_modules/winston/lib/winston/logger.js | 668 ++ .../node_modules/winston/lib/winston/transports.js | 29 + .../winston/lib/winston/transports/console.js | 88 + .../winston/lib/winston/transports/file.js | 575 ++ .../winston/lib/winston/transports/http.js | 200 + .../winston/lib/winston/transports/transport.js | 120 + .../winston/lib/winston/transports/webhook.js | 136 + .../winston/node_modules/async/.gitmodules | 9 + .../winston/node_modules/async/.npmignore | 4 + .../winston/node_modules/async/LICENSE | 19 + .../winston/node_modules/async/Makefile | 25 + .../winston/node_modules/async/README.md | 1021 +++ .../winston/node_modules/async/index.js | 3 + .../winston/node_modules/async/lib/async.js | 692 ++ .../winston/node_modules/async/package.json | 36 + .../winston/node_modules/cycle/README.md | 45 + .../winston/node_modules/cycle/cycle.js | 164 + .../winston/node_modules/cycle/package.json | 33 + .../node_modules/winston/node_modules/eyes/LICENSE | 20 + .../winston/node_modules/eyes/Makefile | 4 + .../winston/node_modules/eyes/README.md | 73 + .../winston/node_modules/eyes/lib/eyes.js | 236 + .../winston/node_modules/eyes/package.json | 44 + .../winston/node_modules/eyes/test/eyes-test.js | 56 + .../winston/node_modules/pkginfo/.npmignore | 2 + .../winston/node_modules/pkginfo/README.md | 85 + .../winston/node_modules/pkginfo/docs/docco.css | 194 + .../winston/node_modules/pkginfo/docs/pkginfo.html | 101 + .../pkginfo/examples/all-properties.js | 19 + .../pkginfo/examples/array-argument.js | 20 + .../pkginfo/examples/multiple-properties.js | 19 + .../pkginfo/examples/object-argument.js | 22 + .../node_modules/pkginfo/examples/package.json | 10 + .../pkginfo/examples/single-property.js | 19 + .../winston/node_modules/pkginfo/lib/pkginfo.js | 132 + .../winston/node_modules/pkginfo/package.json | 39 + .../node_modules/pkginfo/test/pkginfo-test.js | 69 + .../winston/node_modules/request/LICENSE | 55 + .../winston/node_modules/request/README.md | 287 + .../winston/node_modules/request/aws.js | 190 + .../winston/node_modules/request/aws2.js | 128 + .../winston/node_modules/request/forever.js | 103 + .../winston/node_modules/request/main.js | 974 +++ .../winston/node_modules/request/mimetypes.js | 152 + .../winston/node_modules/request/oauth.js | 34 + .../winston/node_modules/request/package.json | 37 + .../node_modules/request/tests/googledoodle.png | Bin 0 -> 38510 bytes .../winston/node_modules/request/tests/run.js | 39 + .../winston/node_modules/request/tests/server.js | 82 + .../winston/node_modules/request/tests/squid.conf | 77 + .../node_modules/request/tests/ssl/ca/ca.cnf | 20 + .../node_modules/request/tests/ssl/ca/ca.crl | 0 .../node_modules/request/tests/ssl/ca/ca.crt | 17 + .../node_modules/request/tests/ssl/ca/ca.csr | 13 + .../node_modules/request/tests/ssl/ca/ca.key | 18 + .../node_modules/request/tests/ssl/ca/ca.srl | 1 + .../node_modules/request/tests/ssl/ca/server.cnf | 19 + .../node_modules/request/tests/ssl/ca/server.crt | 16 + .../node_modules/request/tests/ssl/ca/server.csr | 11 + .../node_modules/request/tests/ssl/ca/server.js | 28 + .../node_modules/request/tests/ssl/ca/server.key | 9 + .../node_modules/request/tests/ssl/npm-ca.crt | 16 + .../node_modules/request/tests/ssl/test.crt | 15 + .../node_modules/request/tests/ssl/test.key | 15 + .../node_modules/request/tests/test-body.js | 80 + .../node_modules/request/tests/test-cookie.js | 29 + .../node_modules/request/tests/test-cookiejar.js | 90 + .../node_modules/request/tests/test-defaults.js | 68 + .../node_modules/request/tests/test-errors.js | 37 + .../node_modules/request/tests/test-headers.js | 52 + .../node_modules/request/tests/test-httpModule.js | 94 + .../request/tests/test-https-strict.js | 97 + .../node_modules/request/tests/test-https.js | 86 + .../node_modules/request/tests/test-oauth.js | 117 + .../node_modules/request/tests/test-params.js | 92 + .../node_modules/request/tests/test-pipes.js | 202 + .../node_modules/request/tests/test-pool.js | 16 + .../node_modules/request/tests/test-proxy.js | 39 + .../winston/node_modules/request/tests/test-qs.js | 28 + .../node_modules/request/tests/test-redirect.js | 154 + .../winston/node_modules/request/tests/test-s3.js | 13 + .../node_modules/request/tests/test-timeout.js | 87 + .../node_modules/request/tests/test-toJSON.js | 14 + .../node_modules/request/tests/test-tunnel.js | 61 + .../winston/node_modules/request/tunnel.js | 229 + .../winston/node_modules/request/uuid.js | 19 + .../node_modules/request/vendor/cookie/index.js | 65 + .../node_modules/request/vendor/cookie/jar.js | 72 + .../winston/node_modules/stack-trace/.npmignore | 1 + .../winston/node_modules/stack-trace/License | 19 + .../winston/node_modules/stack-trace/Makefile | 11 + .../winston/node_modules/stack-trace/Readme.md | 98 + .../node_modules/stack-trace/lib/stack-trace.js | 111 + .../winston/node_modules/stack-trace/package.json | 36 + .../prompt/node_modules/winston/package.json | 54 + .../prompt/node_modules/winston/test/cli-test.js | 40 + .../node_modules/winston/test/container-test.js | 99 + .../winston/test/custom-timestamp-test.js | 62 + .../node_modules/winston/test/exception-test.js | 47 + .../node_modules/winston/test/fixtures/.gitkeep | 0 .../winston/test/fixtures/keys/agent2-cert.pem | 13 + .../winston/test/fixtures/keys/agent2-key.pem | 9 + .../winston/test/fixtures/logs/.gitkeep | 0 .../test/fixtures/scripts/default-exceptions.js | 21 + .../winston/test/fixtures/scripts/exit-on-error.js | 25 + .../test/fixtures/scripts/log-exceptions.js | 25 + .../test/fixtures/scripts/unhandle-exceptions.js | 26 + .../prompt/node_modules/winston/test/helpers.js | 173 + .../winston/test/log-exception-test.js | 60 + .../node_modules/winston/test/log-rewriter-test.js | 98 + .../node_modules/winston/test/logger-test.js | 200 + .../winston/test/transports/console-test.js | 39 + .../winston/test/transports/file-maxfiles-test.js | 102 + .../winston/test/transports/file-maxsize-test.js | 82 + .../winston/test/transports/file-test.js | 60 + .../winston/test/transports/transport.js | 212 + .../winston/test/transports/webhook-test.js | 125 + .../node_modules/winston/test/winston-test.js | 98 + .../flatiron/node_modules/prompt/package.json | 52 + .../flatiron/node_modules/prompt/test/helpers.js | 156 + .../prompt/test/interactive-prompt-test.js | 49 + .../flatiron/node_modules/prompt/test/macros.js | 82 + .../node_modules/prompt/test/prompt-test.js | 668 ++ .../forever/node_modules/flatiron/package.json | 62 + .../node_modules/flatiron/scaffolds/cli/app.js | 12 + .../flatiron/scaffolds/cli/config/config.json | 2 + .../flatiron/scaffolds/cli/directories.json | 6 + .../node_modules/flatiron/scaffolds/cli/files.json | 5 + .../flatiron/scaffolds/cli/lib/index.js | 0 .../flatiron/scaffolds/cli/package.json | 15 + .../node_modules/flatiron/scaffolds/http/app.js | 13 + .../flatiron/scaffolds/http/config/config.json | 2 + .../flatiron/scaffolds/http/directories.json | 5 + .../flatiron/scaffolds/http/files.json | 4 + .../flatiron/scaffolds/http/package.json | 16 + .../fixtures/sample-app/app/new-york/controller.js | 0 .../test/fixtures/sample-app/app/new-york/index.js | 20 + .../fixtures/sample-app/app/new-york/new-york.js | 0 .../node_modules/flatiron/test/flatiron-test.js | 18 + .../flatiron/test/plugins/resourceful-test.js | 32 + .../flatiron/test/plugins/static-test.js | 56 + .../node_modules/forever-monitor/.npmignore | 19 + .../node_modules/forever-monitor/.travis.yml | 11 + .../forever/node_modules/forever-monitor/LICENSE | 19 + .../forever/node_modules/forever-monitor/README.md | 122 + .../forever-monitor/examples/all-env-vars.js | 1 + .../forever-monitor/examples/always-throw.js | 1 + .../forever-monitor/examples/cli-multiple-start | 4 + .../forever-monitor/examples/count-timer.js | 8 + .../forever-monitor/examples/custom-cwd.js | 1 + .../forever-monitor/examples/env-server.js | 7 + .../forever-monitor/examples/env-vars.js | 4 + .../forever-monitor/examples/error-on-timer.js | 6 + .../forever-monitor/examples/graceful-exit.js | 11 + .../forever-monitor/examples/list-multiple.js | 37 + .../forever-monitor/examples/log-on-interval.js | 3 + .../forever-monitor/examples/multiple-processes.js | 12 + .../forever-monitor/examples/process-send.js | 6 + .../forever-monitor/examples/server.js | 16 + .../forever-monitor/examples/signal-ignore.js | 8 + .../forever-monitor/examples/spawn-and-error.js | 18 + .../forever-monitor/lib/forever-monitor/common.js | 60 + .../forever-monitor/lib/forever-monitor/monitor.js | 442 + .../lib/forever-monitor/plugins/index.js | 10 + .../lib/forever-monitor/plugins/logger.js | 80 + .../lib/forever-monitor/plugins/watch.js | 79 + .../node_modules/forever-monitor/lib/index.js | 34 + .../node_modules/broadway/.npmignore | 4 + .../node_modules/broadway/.travis.yml | 11 + .../forever-monitor/node_modules/broadway/LICENSE | 19 + .../node_modules/broadway/README.md | 124 + .../node_modules/broadway/bin/build | 66 + .../node_modules/broadway/examples/browser/app.js | 12 + .../broadway/examples/browser/index.html | 11 + .../examples/browser/plugins/helloworld.js | 23 + .../node_modules/broadway/examples/nodejs/app.js | 17 + .../broadway/examples/nodejs/plugins/helloworld.js | 23 + .../node_modules/broadway/lib/broadway.js | 19 + .../node_modules/broadway/lib/broadway/app.js | 225 + .../broadway/lib/broadway/bootstrapper.js | 65 + .../node_modules/broadway/lib/broadway/browser.js | 75 + .../broadway/lib/broadway/common/directories.js | 78 + .../broadway/lib/broadway/common/index.js | 18 + .../broadway/lib/broadway/features/index.js | 48 + .../broadway/lib/broadway/plugins/config.js | 46 + .../broadway/lib/broadway/plugins/directories.js | 49 + .../broadway/lib/broadway/plugins/exceptions.js | 70 + .../broadway/lib/broadway/plugins/inspect.js | 40 + .../broadway/lib/broadway/plugins/log.js | 195 + .../broadway/node_modules/eventemitter2/.npmignore | 13 + .../broadway/node_modules/eventemitter2/README.md | 212 + .../broadway/node_modules/eventemitter2/index.js | 1 + .../eventemitter2/lib/eventemitter2.js | 560 ++ .../node_modules/eventemitter2/package.json | 85 + .../node_modules/eventemitter2/test/common.js | 122 + .../eventemitter2/test/perf/benchmark.js | 53 + .../eventemitter2/test/simple/addListener.js | 179 + .../node_modules/eventemitter2/test/simple/emit.js | 142 + .../eventemitter2/test/simple/reconfigure.js | 55 + .../eventemitter2/test/simple/removeListener.js | 196 + .../eventemitter2/test/simple/setMax.js | 135 + .../node_modules/eventemitter2/test/simple/ttl.js | 115 + .../test/wildcardEvents/addListener.js | 338 + .../eventemitter2/test/wildcardEvents/all.js | 248 + .../test/wildcardEvents/customDelimiter.js | 250 + .../eventemitter2/test/wildcardEvents/k1.js | 56 + .../eventemitter2/test/wildcardEvents/options.js | 72 + .../test/wildcardEvents/removeListener.js | 317 + .../eventemitter2/test/wildcardEvents/ttl.js | 223 + .../broadway/node_modules/winston/.npmignore | 6 + .../broadway/node_modules/winston/.travis.yml | 12 + .../broadway/node_modules/winston/LICENSE | 19 + .../broadway/node_modules/winston/README.md | 790 ++ .../node_modules/winston/docs/transports.md | 342 + .../node_modules/winston/examples/couchdb.js | 18 + .../node_modules/winston/examples/exception.js | 4 + .../node_modules/winston/examples/raw-mode.js | 10 + .../node_modules/winston/examples/webhook-post.js | 17 + .../broadway/node_modules/winston/lib/winston.js | 145 + .../node_modules/winston/lib/winston/common.js | 259 + .../node_modules/winston/lib/winston/config.js | 45 + .../winston/lib/winston/config/cli-config.js | 35 + .../winston/lib/winston/config/npm-config.js | 27 + .../winston/lib/winston/config/syslog-config.js | 31 + .../node_modules/winston/lib/winston/container.js | 101 + .../node_modules/winston/lib/winston/exception.js | 56 + .../node_modules/winston/lib/winston/logger.js | 668 ++ .../node_modules/winston/lib/winston/transports.js | 29 + .../winston/lib/winston/transports/console.js | 88 + .../winston/lib/winston/transports/file.js | 575 ++ .../winston/lib/winston/transports/http.js | 200 + .../winston/lib/winston/transports/transport.js | 120 + .../winston/lib/winston/transports/webhook.js | 136 + .../winston/node_modules/async/.gitmodules | 9 + .../winston/node_modules/async/.npmignore | 4 + .../winston/node_modules/async/LICENSE | 19 + .../winston/node_modules/async/Makefile | 25 + .../winston/node_modules/async/README.md | 1021 +++ .../winston/node_modules/async/index.js | 3 + .../winston/node_modules/async/lib/async.js | 692 ++ .../winston/node_modules/async/package.json | 36 + .../winston/node_modules/cycle/README.md | 45 + .../winston/node_modules/cycle/cycle.js | 164 + .../winston/node_modules/cycle/package.json | 33 + .../node_modules/winston/node_modules/eyes/LICENSE | 20 + .../winston/node_modules/eyes/Makefile | 4 + .../winston/node_modules/eyes/README.md | 73 + .../winston/node_modules/eyes/lib/eyes.js | 236 + .../winston/node_modules/eyes/package.json | 44 + .../winston/node_modules/eyes/test/eyes-test.js | 56 + .../winston/node_modules/pkginfo/.npmignore | 2 + .../winston/node_modules/pkginfo/README.md | 85 + .../winston/node_modules/pkginfo/docs/docco.css | 194 + .../winston/node_modules/pkginfo/docs/pkginfo.html | 101 + .../pkginfo/examples/all-properties.js | 19 + .../pkginfo/examples/array-argument.js | 20 + .../pkginfo/examples/multiple-properties.js | 19 + .../pkginfo/examples/object-argument.js | 22 + .../node_modules/pkginfo/examples/package.json | 10 + .../pkginfo/examples/single-property.js | 19 + .../winston/node_modules/pkginfo/lib/pkginfo.js | 132 + .../winston/node_modules/pkginfo/package.json | 39 + .../node_modules/pkginfo/test/pkginfo-test.js | 69 + .../winston/node_modules/request/LICENSE | 55 + .../winston/node_modules/request/README.md | 287 + .../winston/node_modules/request/aws.js | 190 + .../winston/node_modules/request/aws2.js | 128 + .../winston/node_modules/request/forever.js | 103 + .../winston/node_modules/request/main.js | 974 +++ .../winston/node_modules/request/mimetypes.js | 152 + .../winston/node_modules/request/oauth.js | 34 + .../winston/node_modules/request/package.json | 37 + .../node_modules/request/tests/googledoodle.png | Bin 0 -> 38510 bytes .../winston/node_modules/request/tests/run.js | 39 + .../winston/node_modules/request/tests/server.js | 82 + .../winston/node_modules/request/tests/squid.conf | 77 + .../node_modules/request/tests/ssl/ca/ca.cnf | 20 + .../node_modules/request/tests/ssl/ca/ca.crl | 0 .../node_modules/request/tests/ssl/ca/ca.crt | 17 + .../node_modules/request/tests/ssl/ca/ca.csr | 13 + .../node_modules/request/tests/ssl/ca/ca.key | 18 + .../node_modules/request/tests/ssl/ca/ca.srl | 1 + .../node_modules/request/tests/ssl/ca/server.cnf | 19 + .../node_modules/request/tests/ssl/ca/server.crt | 16 + .../node_modules/request/tests/ssl/ca/server.csr | 11 + .../node_modules/request/tests/ssl/ca/server.js | 28 + .../node_modules/request/tests/ssl/ca/server.key | 9 + .../node_modules/request/tests/ssl/npm-ca.crt | 16 + .../node_modules/request/tests/ssl/test.crt | 15 + .../node_modules/request/tests/ssl/test.key | 15 + .../node_modules/request/tests/test-body.js | 80 + .../node_modules/request/tests/test-cookie.js | 29 + .../node_modules/request/tests/test-cookiejar.js | 90 + .../node_modules/request/tests/test-defaults.js | 68 + .../node_modules/request/tests/test-errors.js | 37 + .../node_modules/request/tests/test-headers.js | 52 + .../node_modules/request/tests/test-httpModule.js | 94 + .../request/tests/test-https-strict.js | 97 + .../node_modules/request/tests/test-https.js | 86 + .../node_modules/request/tests/test-oauth.js | 117 + .../node_modules/request/tests/test-params.js | 92 + .../node_modules/request/tests/test-pipes.js | 202 + .../node_modules/request/tests/test-pool.js | 16 + .../node_modules/request/tests/test-proxy.js | 39 + .../winston/node_modules/request/tests/test-qs.js | 28 + .../node_modules/request/tests/test-redirect.js | 154 + .../winston/node_modules/request/tests/test-s3.js | 13 + .../node_modules/request/tests/test-timeout.js | 87 + .../node_modules/request/tests/test-toJSON.js | 14 + .../node_modules/request/tests/test-tunnel.js | 61 + .../winston/node_modules/request/tunnel.js | 229 + .../winston/node_modules/request/uuid.js | 19 + .../node_modules/request/vendor/cookie/index.js | 65 + .../node_modules/request/vendor/cookie/jar.js | 72 + .../winston/node_modules/stack-trace/.npmignore | 1 + .../winston/node_modules/stack-trace/License | 19 + .../winston/node_modules/stack-trace/Makefile | 11 + .../winston/node_modules/stack-trace/Readme.md | 98 + .../node_modules/stack-trace/lib/stack-trace.js | 111 + .../winston/node_modules/stack-trace/package.json | 36 + .../broadway/node_modules/winston/package.json | 54 + .../broadway/node_modules/winston/test/cli-test.js | 40 + .../node_modules/winston/test/container-test.js | 99 + .../winston/test/custom-timestamp-test.js | 62 + .../node_modules/winston/test/exception-test.js | 47 + .../node_modules/winston/test/fixtures/.gitkeep | 0 .../winston/test/fixtures/keys/agent2-cert.pem | 13 + .../winston/test/fixtures/keys/agent2-key.pem | 9 + .../winston/test/fixtures/logs/.gitkeep | 0 .../test/fixtures/scripts/default-exceptions.js | 21 + .../winston/test/fixtures/scripts/exit-on-error.js | 25 + .../test/fixtures/scripts/log-exceptions.js | 25 + .../test/fixtures/scripts/unhandle-exceptions.js | 26 + .../broadway/node_modules/winston/test/helpers.js | 173 + .../winston/test/log-exception-test.js | 60 + .../node_modules/winston/test/log-rewriter-test.js | 98 + .../node_modules/winston/test/logger-test.js | 200 + .../winston/test/transports/console-test.js | 39 + .../winston/test/transports/file-maxfiles-test.js | 102 + .../winston/test/transports/file-maxsize-test.js | 82 + .../winston/test/transports/file-test.js | 60 + .../winston/test/transports/transport.js | 212 + .../winston/test/transports/webhook-test.js | 125 + .../node_modules/winston/test/winston-test.js | 98 + .../node_modules/broadway/package.json | 57 + .../broadway/test/common/directories-test.js | 60 + .../broadway/test/core/app-init-test.js | 100 + .../node_modules/broadway/test/core/app-test.js | 73 + .../broadway/test/core/broadway-test.js | 26 + .../node_modules/broadway/test/fixtures/.gitkeep | 0 .../broadway/test/fixtures/empty-app/.gitkeep | 0 .../broadway/test/fixtures/sample-app.json | 8 + .../broadway/test/fixtures/sample-app/app/index.js | 2 + .../test/fixtures/sample-app/config/topics.json | 5 + .../node_modules/broadway/test/helpers/assert.js | 108 + .../node_modules/broadway/test/helpers/helpers.js | 24 + .../node_modules/broadway/test/helpers/macros.js | 74 + .../broadway/test/plugins/config-test.js | 19 + .../broadway/test/plugins/directories-test.js | 28 + .../node_modules/broadway/test/plugins/log-test.js | 69 + .../node_modules/minimatch/.travis.yml | 4 + .../forever-monitor/node_modules/minimatch/LICENSE | 23 + .../node_modules/minimatch/README.md | 114 + .../node_modules/minimatch/blerg.js | 62 + .../node_modules/minimatch/minimatch.js | 372 + .../minimatch/node_modules/lru-cache/.npmignore | 1 + .../minimatch/node_modules/lru-cache/LICENSE | 23 + .../minimatch/node_modules/lru-cache/README.md | 14 + .../node_modules/lru-cache/lib/lru-cache.js | 106 + .../minimatch/node_modules/lru-cache/package.json | 35 + .../minimatch/node_modules/lru-cache/test/basic.js | 117 + .../node_modules/minimatch/package.json | 44 + .../forever-monitor/node_modules/minimatch/t.js | 4 + .../node_modules/minimatch/test/basic.js | 167 + .../node_modules/ps-tree/.npmignore | 3 + .../forever-monitor/node_modules/ps-tree/index.js | 49 + .../ps-tree/node_modules/event-stream/.gitmodules | 3 + .../ps-tree/node_modules/event-stream/.npmignore | 3 + .../ps-tree/node_modules/event-stream/LICENCE | 22 + .../node_modules/event-stream/examples/pretty.js | 25 + .../ps-tree/node_modules/event-stream/index.js | 504 ++ .../event-stream/node_modules/optimist/.npmignore | 4 + .../event-stream/node_modules/optimist/LICENSE | 21 + .../node_modules/optimist/README.markdown | 474 ++ .../node_modules/optimist/examples/bool.js | 10 + .../optimist/examples/boolean_double.js | 7 + .../optimist/examples/boolean_single.js | 7 + .../node_modules/optimist/examples/default_hash.js | 8 + .../optimist/examples/default_singles.js | 7 + .../node_modules/optimist/examples/divide.js | 8 + .../node_modules/optimist/examples/line_count.js | 20 + .../optimist/examples/line_count_options.js | 29 + .../optimist/examples/line_count_wrap.js | 29 + .../node_modules/optimist/examples/nonopt.js | 4 + .../node_modules/optimist/examples/reflect.js | 2 + .../node_modules/optimist/examples/short.js | 3 + .../node_modules/optimist/examples/string.js | 11 + .../optimist/examples/usage-options.js | 19 + .../node_modules/optimist/examples/xup.js | 10 + .../event-stream/node_modules/optimist/index.js | 457 + .../optimist/node_modules/wordwrap/.npmignore | 1 + .../optimist/node_modules/wordwrap/README.markdown | 70 + .../node_modules/wordwrap/example/center.js | 10 + .../optimist/node_modules/wordwrap/example/meat.js | 3 + .../optimist/node_modules/wordwrap/index.js | 76 + .../optimist/node_modules/wordwrap/package.json | 48 + .../optimist/node_modules/wordwrap/test/break.js | 30 + .../node_modules/wordwrap/test/idleness.txt | 63 + .../optimist/node_modules/wordwrap/test/wrap.js | 31 + .../node_modules/optimist/package.json | 54 + .../event-stream/node_modules/optimist/test/_.js | 66 + .../node_modules/optimist/test/_/argv.js | 2 + .../node_modules/optimist/test/_/bin.js | 3 + .../node_modules/optimist/test/parse.js | 304 + .../node_modules/optimist/test/usage.js | 256 + .../ps-tree/node_modules/event-stream/out | 0 .../ps-tree/node_modules/event-stream/package.json | 34 + .../node_modules/event-stream/readme.markdown | 358 + .../node_modules/event-stream/test/.npmignore | 3 + .../node_modules/event-stream/test/package.json | 11 + .../node_modules/event-stream/test/pipe.async.js | 54 + .../event-stream/test/readArray.asynct.js | 88 + .../node_modules/event-stream/test/readme.markdown | 0 .../event-stream/test/simple-map.asynct.js | 96 + .../node_modules/event-stream/test/split.asynct.js | 34 + .../event-stream/test/writeArray.asynct.js | 31 + .../node_modules/ps-tree/package.json | 27 + .../node_modules/ps-tree/readme.markdown | 48 + .../forever-monitor/node_modules/watch/LICENSE | 55 + .../forever-monitor/node_modules/watch/main.js | 118 + .../node_modules/watch/package.json | 38 + .../forever-monitor/node_modules/watch/readme.mkd | 71 + .../forever-monitor/node_modules/watch/test/d/d/t | 0 .../forever-monitor/node_modules/watch/test/d/t | 0 .../node_modules/watch/test/test_monitor.js | 31 + .../node_modules/watch/test/test_watchTree.js | 9 + .../node_modules/forever-monitor/package.json | 74 + .../test/core/check-process-test.js | 36 + .../forever-monitor/test/fixtures/fork.js | 4 + .../forever-monitor/test/fixtures/gc.js | 1 + .../forever-monitor/test/fixtures/logs.js | 5 + .../forever-monitor/test/fixtures/send-pong.js | 8 + .../forever-monitor/test/fixtures/testnode | 3 + .../test/fixtures/watch/.foreverignore | 3 + .../forever-monitor/test/fixtures/watch/daemon.js | 4 + .../forever-monitor/test/fixtures/watch/file | 1 + .../test/fixtures/watch/ignoredDir/file | 1 + .../forever-monitor/test/fixtures/watch/removeMe | 0 .../forever-monitor/test/helpers/macros.js | 38 + .../forever-monitor/test/monitor/env-spawn-test.js | 109 + .../forever-monitor/test/monitor/fork-test.js | 54 + .../forever-monitor/test/monitor/send-test.js | 33 + .../forever-monitor/test/monitor/signal-test.js | 86 + .../forever-monitor/test/monitor/simple-test.js | 124 + .../forever-monitor/test/monitor/spin-test.js | 46 + .../forever-monitor/test/plugins/logger-test.js | 80 + .../forever-monitor/test/plugins/watch-test.js | 91 + node_modules/forever/node_modules/nconf/.npmignore | 8 + .../forever/node_modules/nconf/.travis.yml | 12 + .../forever/node_modules/nconf/CHANGELOG.md | 9 + node_modules/forever/node_modules/nconf/LICENSE | 19 + node_modules/forever/node_modules/nconf/README.md | 274 + .../forever/node_modules/nconf/docs/docco.css | 194 + .../forever/node_modules/nconf/docs/nconf.html | 20 + .../node_modules/nconf/docs/nconf/common.html | 85 + .../node_modules/nconf/docs/nconf/formats.html | 22 + .../node_modules/nconf/docs/nconf/provider.html | 378 + .../node_modules/nconf/docs/nconf/stores.html | 19 + .../node_modules/nconf/docs/nconf/stores/file.html | 170 + .../nconf/docs/nconf/stores/memory.html | 143 + .../nconf/docs/nconf/stores/system.html | 98 + .../forever/node_modules/nconf/lib/nconf.js | 39 + .../forever/node_modules/nconf/lib/nconf/common.js | 113 + .../node_modules/nconf/lib/nconf/formats.js | 28 + .../node_modules/nconf/lib/nconf/provider.js | 565 ++ .../node_modules/nconf/lib/nconf/stores/argv.js | 61 + .../node_modules/nconf/lib/nconf/stores/env.js | 67 + .../node_modules/nconf/lib/nconf/stores/file.js | 228 + .../node_modules/nconf/lib/nconf/stores/literal.js | 29 + .../node_modules/nconf/lib/nconf/stores/memory.js | 224 + .../nconf/node_modules/async/.gitmodules | 9 + .../nconf/node_modules/async/.npmignore | 4 + .../node_modules/nconf/node_modules/async/LICENSE | 19 + .../node_modules/nconf/node_modules/async/Makefile | 25 + .../nconf/node_modules/async/README.md | 1021 +++ .../node_modules/nconf/node_modules/async/index.js | 3 + .../nconf/node_modules/async/lib/async.js | 692 ++ .../nconf/node_modules/async/package.json | 36 + .../node_modules/nconf/node_modules/ini/LICENSE | 23 + .../node_modules/nconf/node_modules/ini/README.md | 79 + .../node_modules/nconf/node_modules/ini/ini.js | 166 + .../nconf/node_modules/ini/package.json | 36 + .../nconf/node_modules/ini/test/bar.js | 23 + .../nconf/node_modules/ini/test/fixtures/foo.ini | 47 + .../nconf/node_modules/ini/test/foo.js | 71 + .../nconf/node_modules/optimist/.travis.yml | 4 + .../nconf/node_modules/optimist/LICENSE | 21 + .../nconf/node_modules/optimist/example/bool.js | 10 + .../optimist/example/boolean_double.js | 7 + .../optimist/example/boolean_single.js | 7 + .../node_modules/optimist/example/default_hash.js | 8 + .../optimist/example/default_singles.js | 7 + .../nconf/node_modules/optimist/example/divide.js | 8 + .../node_modules/optimist/example/line_count.js | 20 + .../optimist/example/line_count_options.js | 29 + .../optimist/example/line_count_wrap.js | 29 + .../nconf/node_modules/optimist/example/nonopt.js | 4 + .../nconf/node_modules/optimist/example/reflect.js | 2 + .../nconf/node_modules/optimist/example/short.js | 3 + .../nconf/node_modules/optimist/example/string.js | 11 + .../node_modules/optimist/example/usage-options.js | 19 + .../nconf/node_modules/optimist/example/xup.js | 10 + .../nconf/node_modules/optimist/index.js | 478 ++ .../optimist/node_modules/wordwrap/.npmignore | 1 + .../optimist/node_modules/wordwrap/README.markdown | 70 + .../node_modules/wordwrap/example/center.js | 10 + .../optimist/node_modules/wordwrap/example/meat.js | 3 + .../optimist/node_modules/wordwrap/index.js | 76 + .../optimist/node_modules/wordwrap/package.json | 48 + .../optimist/node_modules/wordwrap/test/break.js | 30 + .../node_modules/wordwrap/test/idleness.txt | 63 + .../optimist/node_modules/wordwrap/test/wrap.js | 31 + .../nconf/node_modules/optimist/package.json | 49 + .../nconf/node_modules/optimist/readme.markdown | 487 ++ .../nconf/node_modules/optimist/test/_.js | 71 + .../nconf/node_modules/optimist/test/_/argv.js | 2 + .../nconf/node_modules/optimist/test/_/bin.js | 3 + .../nconf/node_modules/optimist/test/parse.js | 446 + .../nconf/node_modules/optimist/test/usage.js | 292 + .../nconf/node_modules/pkginfo/.npmignore | 2 + .../nconf/node_modules/pkginfo/README.md | 85 + .../nconf/node_modules/pkginfo/docs/docco.css | 194 + .../nconf/node_modules/pkginfo/docs/pkginfo.html | 101 + .../pkginfo/examples/all-properties.js | 19 + .../pkginfo/examples/array-argument.js | 20 + .../pkginfo/examples/multiple-properties.js | 19 + .../pkginfo/examples/object-argument.js | 22 + .../node_modules/pkginfo/examples/package.json | 10 + .../pkginfo/examples/single-property.js | 19 + .../nconf/node_modules/pkginfo/lib/pkginfo.js | 132 + .../nconf/node_modules/pkginfo/package.json | 39 + .../node_modules/pkginfo/test/pkginfo-test.js | 69 + .../forever/node_modules/nconf/package.json | 51 + .../forever/node_modules/nconf/test/common-test.js | 32 + .../node_modules/nconf/test/complete-test.js | 126 + .../node_modules/nconf/test/fixtures/complete.json | 19 + .../node_modules/nconf/test/fixtures/data.js | 30 + .../nconf/test/fixtures/hierarchy/global.json | 5 + .../test/fixtures/hierarchy/hierarchical.json | 3 + .../nconf/test/fixtures/hierarchy/user.json | 4 + .../nconf/test/fixtures/malformed.json | 3 + .../nconf/test/fixtures/merge/file1.json | 16 + .../nconf/test/fixtures/merge/file2.json | 9 + .../nconf/test/fixtures/scripts/nconf-argv.js | 10 + .../test/fixtures/scripts/nconf-change-argv.js | 16 + .../nconf/test/fixtures/scripts/nconf-env.js | 10 + .../scripts/nconf-hierarchical-file-argv.js | 17 + .../scripts/nconf-hierarchical-load-merge.js | 18 + .../scripts/nconf-hierarchical-load-save.js | 32 + .../test/fixtures/scripts/nconf-nested-env.js | 11 + .../nconf/test/fixtures/scripts/provider-argv.js | 12 + .../nconf/test/fixtures/scripts/provider-env.js | 12 + .../forever/node_modules/nconf/test/helpers.js | 68 + .../node_modules/nconf/test/hierarchy-test.js | 113 + .../node_modules/nconf/test/mocks/mock-store.js | 38 + .../forever/node_modules/nconf/test/nconf-test.js | 132 + .../node_modules/nconf/test/provider-save-test.js | 39 + .../node_modules/nconf/test/provider-test.js | 165 + .../node_modules/nconf/test/stores/argv-test.js | 22 + .../node_modules/nconf/test/stores/env-test.js | 24 + .../nconf/test/stores/file-store-test.js | 175 + .../node_modules/nconf/test/stores/literal-test.js | 31 + .../nconf/test/stores/memory-store-test.js | 108 + node_modules/forever/node_modules/nconf/usage.js | 50 + .../forever/node_modules/nssocket/.npmignore | 10 + .../forever/node_modules/nssocket/.travis.yml | 11 + .../forever/node_modules/nssocket/README.md | 143 + .../forever/node_modules/nssocket/examples/bla.js | 18 + .../forever/node_modules/nssocket/examples/foo.js | 10 + .../node_modules/nssocket/examples/reconnect.js | 29 + .../nssocket/examples/simple-protocol.js | 51 + .../nssocket/examples/verbose-protocol.js | 37 + .../forever/node_modules/nssocket/lib/common.js | 105 + .../forever/node_modules/nssocket/lib/nssocket.js | 490 ++ .../nssocket/node_modules/eventemitter2/README.md | 212 + .../nssocket/node_modules/eventemitter2/index.js | 1 + .../eventemitter2/lib/eventemitter2.js | 561 ++ .../node_modules/eventemitter2/package.json | 65 + .../nssocket/node_modules/lazy/.npmignore | 1 + .../nssocket/node_modules/lazy/README.md | 185 + .../nssocket/node_modules/lazy/lazy.js | 349 + .../nssocket/node_modules/lazy/lazy.js~ | 348 + .../nssocket/node_modules/lazy/package.json | 42 + .../nssocket/node_modules/lazy/package.json~ | 32 + .../nssocket/node_modules/lazy/test/bucket.js | 37 + .../nssocket/node_modules/lazy/test/complex.js | 52 + .../nssocket/node_modules/lazy/test/custom.js | 32 + .../nssocket/node_modules/lazy/test/em.js | 33 + .../nssocket/node_modules/lazy/test/filter.js | 27 + .../nssocket/node_modules/lazy/test/foldr.js | 26 + .../nssocket/node_modules/lazy/test/forEach.js | 31 + .../nssocket/node_modules/lazy/test/head.js | 26 + .../nssocket/node_modules/lazy/test/join.js | 26 + .../nssocket/node_modules/lazy/test/lines.js | 89 + .../nssocket/node_modules/lazy/test/map.js | 29 + .../nssocket/node_modules/lazy/test/pipe.js | 38 + .../nssocket/node_modules/lazy/test/product.js | 26 + .../nssocket/node_modules/lazy/test/range.js | 272 + .../nssocket/node_modules/lazy/test/skip.js | 27 + .../nssocket/node_modules/lazy/test/sum.js | 26 + .../nssocket/node_modules/lazy/test/tail.js | 27 + .../nssocket/node_modules/lazy/test/take.js | 26 + .../nssocket/node_modules/lazy/test/takeWhile.js | 26 + .../forever/node_modules/nssocket/package.json | 48 + .../nssocket/test/create-server-test.js | 72 + .../nssocket/test/fixtures/ryans-cert.pem | 16 + .../nssocket/test/fixtures/ryans-csr.pem | 12 + .../nssocket/test/fixtures/ryans-key.pem | 15 + .../nssocket/test/tcp-reconnect-test.js | 80 + .../forever/node_modules/nssocket/test/tcp-test.js | 99 + .../forever/node_modules/nssocket/test/tls-test.js | 106 + .../forever/node_modules/optimist/.travis.yml | 4 + node_modules/forever/node_modules/optimist/LICENSE | 21 + .../forever/node_modules/optimist/example/bool.js | 10 + .../optimist/example/boolean_double.js | 7 + .../optimist/example/boolean_single.js | 7 + .../node_modules/optimist/example/default_hash.js | 8 + .../optimist/example/default_singles.js | 7 + .../node_modules/optimist/example/divide.js | 8 + .../node_modules/optimist/example/line_count.js | 20 + .../optimist/example/line_count_options.js | 29 + .../optimist/example/line_count_wrap.js | 29 + .../node_modules/optimist/example/nonopt.js | 4 + .../node_modules/optimist/example/reflect.js | 2 + .../forever/node_modules/optimist/example/short.js | 3 + .../node_modules/optimist/example/string.js | 11 + .../node_modules/optimist/example/usage-options.js | 19 + .../forever/node_modules/optimist/example/xup.js | 10 + .../forever/node_modules/optimist/index.js | 485 ++ .../optimist/node_modules/wordwrap/.npmignore | 1 + .../optimist/node_modules/wordwrap/README.markdown | 70 + .../node_modules/wordwrap/example/center.js | 10 + .../optimist/node_modules/wordwrap/example/meat.js | 3 + .../optimist/node_modules/wordwrap/index.js | 76 + .../optimist/node_modules/wordwrap/package.json | 48 + .../optimist/node_modules/wordwrap/test/break.js | 30 + .../node_modules/wordwrap/test/idleness.txt | 63 + .../optimist/node_modules/wordwrap/test/wrap.js | 31 + .../forever/node_modules/optimist/package.json | 49 + .../forever/node_modules/optimist/readme.markdown | 500 ++ .../forever/node_modules/optimist/test/_.js | 71 + .../forever/node_modules/optimist/test/_/argv.js | 2 + .../forever/node_modules/optimist/test/_/bin.js | 3 + .../forever/node_modules/optimist/test/parse.js | 446 + .../forever/node_modules/optimist/test/short.js | 16 + .../forever/node_modules/optimist/test/usage.js | 292 + .../forever/node_modules/pkginfo/.npmignore | 2 + node_modules/forever/node_modules/pkginfo/LICENSE | 19 + .../forever/node_modules/pkginfo/README.md | 86 + .../forever/node_modules/pkginfo/docs/docco.css | 194 + .../forever/node_modules/pkginfo/docs/pkginfo.html | 101 + .../pkginfo/examples/all-properties.js | 19 + .../pkginfo/examples/array-argument.js | 20 + .../pkginfo/examples/multiple-properties.js | 19 + .../pkginfo/examples/object-argument.js | 22 + .../node_modules/pkginfo/examples/package.json | 10 + .../pkginfo/examples/single-property.js | 19 + .../pkginfo/examples/subdir/package.json | 11 + .../node_modules/pkginfo/examples/target-dir.js | 20 + .../forever/node_modules/pkginfo/lib/pkginfo.js | 136 + .../forever/node_modules/pkginfo/package.json | 39 + .../node_modules/pkginfo/test/pkginfo-test.js | 83 + .../forever/node_modules/timespan/.npmignore | 3 + .../forever/node_modules/timespan/CHANGELOG.md | 15 + node_modules/forever/node_modules/timespan/LICENSE | 19 + .../forever/node_modules/timespan/README.md | 195 + .../node_modules/timespan/browser/TimeSpan-1.2.js | 226 + .../timespan/browser/TimeSpan-1.2.min.js | 1 + .../forever/node_modules/timespan/lib/time-span.js | 257 + .../forever/node_modules/timespan/package.json | 46 + .../node_modules/timespan/test/time-span-test.js | 59 + node_modules/forever/node_modules/utile/.npmignore | 4 + .../forever/node_modules/utile/.travis.yml | 10 + .../forever/node_modules/utile/CHANGELOG.md | 16 + node_modules/forever/node_modules/utile/LICENSE | 19 + node_modules/forever/node_modules/utile/README.md | 87 + .../forever/node_modules/utile/lib/args.js | 46 + .../forever/node_modules/utile/lib/base64.js | 44 + .../forever/node_modules/utile/lib/file.js | 33 + .../forever/node_modules/utile/lib/format.js | 25 + .../forever/node_modules/utile/lib/index.js | 467 + .../node_modules/utile/node_modules/.bin/ncp | 1 + .../utile/node_modules/async/.gitmodules | 9 + .../utile/node_modules/async/.npmignore | 4 + .../node_modules/utile/node_modules/async/LICENSE | 19 + .../node_modules/utile/node_modules/async/Makefile | 25 + .../utile/node_modules/async/README.md | 1021 +++ .../node_modules/utile/node_modules/async/index.js | 3 + .../utile/node_modules/async/lib/async.js | 692 ++ .../utile/node_modules/async/package.json | 35 + .../utile/node_modules/deep-equal/README.markdown | 55 + .../utile/node_modules/deep-equal/example/cmp.js | 11 + .../utile/node_modules/deep-equal/index.js | 84 + .../utile/node_modules/deep-equal/package.json | 46 + .../utile/node_modules/deep-equal/test/cmp.js | 18 + .../node_modules/utile/node_modules/i/.npmignore | 3 + .../node_modules/utile/node_modules/i/.travis.yml | 9 + .../node_modules/utile/node_modules/i/LICENSE | 18 + .../node_modules/utile/node_modules/i/README.md | 174 + .../utile/node_modules/i/lib/defaults.js | 63 + .../utile/node_modules/i/lib/inflect.js | 11 + .../utile/node_modules/i/lib/inflections.js | 116 + .../utile/node_modules/i/lib/methods.js | 233 + .../utile/node_modules/i/lib/native.js | 26 + .../node_modules/utile/node_modules/i/lib/util.js | 136 + .../node_modules/utile/node_modules/i/package.json | 65 + .../utile/node_modules/i/test/inflector/cases.js | 209 + .../i/test/inflector/inflections-test.js | 87 + .../node_modules/i/test/inflector/methods-test.js | 342 + .../utile/node_modules/i/test/utils/array-test.js | 39 + .../utile/node_modules/i/test/utils/string-test.js | 88 + .../utile/node_modules/mkdirp/.npmignore | 2 + .../utile/node_modules/mkdirp/.travis.yml | 5 + .../node_modules/utile/node_modules/mkdirp/LICENSE | 21 + .../utile/node_modules/mkdirp/examples/pow.js | 6 + .../utile/node_modules/mkdirp/index.js | 82 + .../utile/node_modules/mkdirp/package.json | 37 + .../utile/node_modules/mkdirp/readme.markdown | 63 + .../utile/node_modules/mkdirp/test/chmod.js | 38 + .../utile/node_modules/mkdirp/test/clobber.js | 37 + .../utile/node_modules/mkdirp/test/mkdirp.js | 28 + .../utile/node_modules/mkdirp/test/perm.js | 32 + .../utile/node_modules/mkdirp/test/perm_sync.js | 39 + .../utile/node_modules/mkdirp/test/race.js | 41 + .../utile/node_modules/mkdirp/test/rel.js | 32 + .../utile/node_modules/mkdirp/test/return.js | 25 + .../utile/node_modules/mkdirp/test/return_sync.js | 24 + .../utile/node_modules/mkdirp/test/root.js | 18 + .../utile/node_modules/mkdirp/test/sync.js | 32 + .../utile/node_modules/mkdirp/test/umask.js | 28 + .../utile/node_modules/mkdirp/test/umask_sync.js | 32 + .../node_modules/utile/node_modules/ncp/.npmignore | 4 + .../utile/node_modules/ncp/.travis.yml | 6 + .../node_modules/utile/node_modules/ncp/LICENSE.md | 21 + .../node_modules/utile/node_modules/ncp/README.md | 46 + .../node_modules/utile/node_modules/ncp/bin/ncp | 48 + .../node_modules/utile/node_modules/ncp/lib/ncp.js | 216 + .../utile/node_modules/ncp/package.json | 44 + .../utile/node_modules/ncp/test/fixtures/src/a | 1 + .../utile/node_modules/ncp/test/fixtures/src/b | 1 + .../utile/node_modules/ncp/test/fixtures/src/c | 0 .../utile/node_modules/ncp/test/fixtures/src/d | 0 .../utile/node_modules/ncp/test/fixtures/src/e | 0 .../utile/node_modules/ncp/test/fixtures/src/f | 0 .../utile/node_modules/ncp/test/fixtures/src/sub/a | 1 + .../utile/node_modules/ncp/test/fixtures/src/sub/b | 0 .../utile/node_modules/ncp/test/ncp-test.js | 74 + .../node_modules/utile/node_modules/rimraf/AUTHORS | 5 + .../node_modules/utile/node_modules/rimraf/LICENSE | 23 + .../utile/node_modules/rimraf/README.md | 32 + .../utile/node_modules/rimraf/fiber.js | 86 + .../utile/node_modules/rimraf/package.json | 52 + .../utile/node_modules/rimraf/rimraf.js | 145 + .../utile/node_modules/rimraf/test/run.sh | 10 + .../utile/node_modules/rimraf/test/setup.sh | 47 + .../utile/node_modules/rimraf/test/test-async.js | 5 + .../utile/node_modules/rimraf/test/test-fiber.js | 15 + .../utile/node_modules/rimraf/test/test-sync.js | 3 + .../forever/node_modules/utile/package.json | 48 + .../forever/node_modules/utile/test/file-test.js | 31 + .../utile/test/fixtures/read-json-file/config.json | 9 + .../fixtures/require-directory/directory/index.js | 2 + .../test/fixtures/require-directory/helloWorld.js | 2 + .../forever/node_modules/utile/test/format-test.js | 31 + .../node_modules/utile/test/function-args-test.js | 104 + .../node_modules/utile/test/helpers/macros.js | 37 + .../node_modules/utile/test/random-string-test.js | 39 + .../utile/test/require-directory-test.js | 35 + .../forever/node_modules/utile/test/utile-test.js | 126 + node_modules/forever/node_modules/watch/LICENSE | 55 + node_modules/forever/node_modules/watch/main.js | 121 + .../forever/node_modules/watch/package.json | 38 + node_modules/forever/node_modules/watch/readme.mkd | 72 + node_modules/forever/node_modules/watch/test/d/d/t | 0 node_modules/forever/node_modules/watch/test/d/t | 0 .../node_modules/watch/test/test_monitor.js | 31 + .../node_modules/watch/test/test_watchTree.js | 9 + .../forever/node_modules/winston/.npmignore | 6 + .../forever/node_modules/winston/.travis.yml | 10 + .../forever/node_modules/winston/CHANGELOG.md | 9 + node_modules/forever/node_modules/winston/LICENSE | 19 + .../forever/node_modules/winston/README.md | 854 ++ .../node_modules/winston/docs/transports.md | 345 + .../node_modules/winston/examples/couchdb.js | 18 + .../node_modules/winston/examples/custom-levels.js | 44 + .../node_modules/winston/examples/exception.js | 4 + .../node_modules/winston/examples/raw-mode.js | 10 + .../node_modules/winston/examples/webhook-post.js | 17 + .../forever/node_modules/winston/lib/winston.js | 163 + .../node_modules/winston/lib/winston/common.js | 308 + .../node_modules/winston/lib/winston/config.js | 59 + .../winston/lib/winston/config/cli-config.js | 35 + .../winston/lib/winston/config/npm-config.js | 27 + .../winston/lib/winston/config/syslog-config.js | 31 + .../node_modules/winston/lib/winston/container.js | 101 + .../node_modules/winston/lib/winston/exception.js | 56 + .../node_modules/winston/lib/winston/logger.js | 660 ++ .../node_modules/winston/lib/winston/transports.js | 34 + .../winston/lib/winston/transports/console.js | 89 + .../lib/winston/transports/daily-rotate-file.js | 630 ++ .../winston/lib/winston/transports/file.js | 589 ++ .../winston/lib/winston/transports/http.js | 220 + .../winston/lib/winston/transports/memory.js | 85 + .../winston/lib/winston/transports/transport.js | 121 + .../winston/lib/winston/transports/webhook.js | 138 + .../winston/node_modules/async/LICENSE | 19 + .../winston/node_modules/async/README.md | 1414 +++ .../winston/node_modules/async/component.json | 11 + .../winston/node_modules/async/lib/async.js | 955 +++ .../winston/node_modules/async/package.json | 46 + .../winston/node_modules/cycle/README.md | 45 + .../winston/node_modules/cycle/cycle.js | 164 + .../winston/node_modules/cycle/package.json | 32 + .../node_modules/winston/node_modules/eyes/LICENSE | 20 + .../winston/node_modules/eyes/Makefile | 4 + .../winston/node_modules/eyes/README.md | 73 + .../winston/node_modules/eyes/lib/eyes.js | 236 + .../winston/node_modules/eyes/package.json | 44 + .../winston/node_modules/eyes/test/eyes-test.js | 56 + .../winston/node_modules/request/LICENSE | 55 + .../winston/node_modules/request/README.md | 342 + .../winston/node_modules/request/index.js | 1328 +++ .../request/node_modules/aws-sign/index.js | 202 + .../request/node_modules/aws-sign/package.json | 30 + .../request/node_modules/cookie-jar/index.js | 67 + .../request/node_modules/cookie-jar/jar.js | 72 + .../request/node_modules/cookie-jar/package.json | 33 + .../request/node_modules/cookie-jar/tests/run.js | 40 + .../node_modules/cookie-jar/tests/test-cookie.js | 29 + .../cookie-jar/tests/test-cookiejar.js | 90 + .../request/node_modules/forever-agent/index.js | 103 + .../node_modules/forever-agent/package.json | 30 + .../request/node_modules/form-data/License | 19 + .../request/node_modules/form-data/Readme.md | 146 + .../node_modules/form-data/lib/form_data.js | 292 + .../node_modules/combined-stream/.npmignore | 3 + .../form-data/node_modules/combined-stream/License | 19 + .../node_modules/combined-stream/Makefile | 7 + .../node_modules/combined-stream/Readme.md | 132 + .../combined-stream/lib/combined_stream.js | 185 + .../node_modules/delayed-stream/.npmignore | 2 + .../node_modules/delayed-stream/License | 19 + .../node_modules/delayed-stream/Makefile | 7 + .../node_modules/delayed-stream/Readme.md | 154 + .../delayed-stream/lib/delayed_stream.js | 99 + .../node_modules/delayed-stream/package.json | 35 + .../node_modules/delayed-stream/test/common.js | 6 + .../test/integration/test-delayed-http-upload.js | 38 + .../integration/test-delayed-stream-auto-pause.js | 21 + .../test/integration/test-delayed-stream-pause.js | 14 + .../test/integration/test-delayed-stream.js | 48 + .../test/integration/test-handle-source-errors.js | 15 + .../test/integration/test-max-data-size.js | 18 + .../test/integration/test-pipe-resumes.js | 13 + .../test/integration/test-proxy-readable.js | 13 + .../node_modules/delayed-stream/test/run.js | 7 + .../node_modules/combined-stream/package.json | 36 + .../node_modules/combined-stream/test/common.js | 23 + .../combined-stream/test/fixture/file1.txt | 256 + .../combined-stream/test/fixture/file2.txt | 256 + .../test/integration/test-callback-streams.js | 27 + .../test/integration/test-data-size.js | 34 + ...test-delayed-streams-and-buffers-and-strings.js | 38 + .../test/integration/test-delayed-streams.js | 35 + .../test/integration/test-empty-string.js | 39 + .../test/integration/test-is-stream-like.js | 17 + .../test/integration/test-max-data-size.js | 24 + .../test/integration/test-unpaused-streams.js | 30 + .../node_modules/combined-stream/test/run.js | 7 + .../request/node_modules/form-data/package.json | 43 + .../request/node_modules/hawk/.npmignore | 18 + .../request/node_modules/hawk/.travis.yml | 5 + .../node_modules/request/node_modules/hawk/LICENSE | 24 + .../request/node_modules/hawk/Makefile | 11 + .../request/node_modules/hawk/README.md | 604 ++ .../request/node_modules/hawk/example/usage.js | 77 + .../request/node_modules/hawk/images/hawk.png | Bin 0 -> 6945 bytes .../request/node_modules/hawk/images/logo.png | Bin 0 -> 71732 bytes .../request/node_modules/hawk/index.js | 1 + .../request/node_modules/hawk/lib/client.js | 200 + .../request/node_modules/hawk/lib/crypto.js | 98 + .../request/node_modules/hawk/lib/index.js | 11 + .../request/node_modules/hawk/lib/server.js | 288 + .../request/node_modules/hawk/lib/uri.js | 238 + .../request/node_modules/hawk/lib/utils.js | 167 + .../node_modules/hawk/node_modules/boom/.npmignore | 18 + .../hawk/node_modules/boom/.travis.yml | 5 + .../node_modules/hawk/node_modules/boom/LICENSE | 24 + .../node_modules/hawk/node_modules/boom/Makefile | 11 + .../node_modules/hawk/node_modules/boom/README.md | 6 + .../hawk/node_modules/boom/images/boom.png | Bin 0 -> 29479 bytes .../node_modules/hawk/node_modules/boom/index.js | 1 + .../hawk/node_modules/boom/lib/index.js | 207 + .../hawk/node_modules/boom/package.json | 50 + .../hawk/node_modules/boom/test/index.js | 245 + .../hawk/node_modules/cryptiles/.npmignore | 18 + .../hawk/node_modules/cryptiles/.travis.yml | 5 + .../hawk/node_modules/cryptiles/LICENSE | 24 + .../hawk/node_modules/cryptiles/Makefile | 11 + .../hawk/node_modules/cryptiles/README.md | 6 + .../hawk/node_modules/cryptiles/index.js | 1 + .../hawk/node_modules/cryptiles/lib/index.js | 62 + .../hawk/node_modules/cryptiles/package.json | 51 + .../hawk/node_modules/cryptiles/test/index.js | 95 + .../node_modules/hawk/node_modules/hoek/.npmignore | 18 + .../hawk/node_modules/hoek/.travis.yml | 5 + .../node_modules/hawk/node_modules/hoek/LICENSE | 33 + .../node_modules/hawk/node_modules/hoek/Makefile | 10 + .../node_modules/hawk/node_modules/hoek/README.md | 436 + .../hawk/node_modules/hoek/images/hoek.png | Bin 0 -> 37939 bytes .../node_modules/hawk/node_modules/hoek/index.js | 1 + .../hawk/node_modules/hoek/lib/escape.js | 132 + .../hawk/node_modules/hoek/lib/index.js | 557 ++ .../hawk/node_modules/hoek/package.json | 52 + .../hawk/node_modules/hoek/test/escaper.js | 86 + .../hawk/node_modules/hoek/test/index.js | 983 +++ .../hawk/node_modules/hoek/test/modules/test1.js | 1 + .../hawk/node_modules/hoek/test/modules/test2.js | 1 + .../hawk/node_modules/hoek/test/modules/test3.js | 1 + .../node_modules/hawk/node_modules/sntp/.npmignore | 18 + .../hawk/node_modules/sntp/.travis.yml | 5 + .../node_modules/hawk/node_modules/sntp/LICENSE | 24 + .../node_modules/hawk/node_modules/sntp/Makefile | 11 + .../node_modules/hawk/node_modules/sntp/README.md | 70 + .../hawk/node_modules/sntp/examples/offset.js | 16 + .../hawk/node_modules/sntp/examples/time.js | 25 + .../node_modules/hawk/node_modules/sntp/index.js | 1 + .../hawk/node_modules/sntp/lib/index.js | 398 + .../hawk/node_modules/sntp/package.json | 51 + .../hawk/node_modules/sntp/test/index.js | 339 + .../request/node_modules/hawk/package.json | 55 + .../request/node_modules/hawk/test/client.js | 208 + .../request/node_modules/hawk/test/crypto.js | 86 + .../request/node_modules/hawk/test/index.js | 316 + .../request/node_modules/hawk/test/readme.js | 98 + .../request/node_modules/hawk/test/server.js | 642 ++ .../request/node_modules/hawk/test/uri.js | 457 + .../request/node_modules/hawk/test/utils.js | 73 + .../node_modules/json-stringify-safe/LICENSE | 27 + .../node_modules/json-stringify-safe/README.md | 27 + .../node_modules/json-stringify-safe/package.json | 36 + .../node_modules/json-stringify-safe/stringify.js | 22 + .../node_modules/json-stringify-safe/test.js | 22 + .../node_modules/request/node_modules/mime/LICENSE | 19 + .../request/node_modules/mime/README.md | 66 + .../node_modules/request/node_modules/mime/mime.js | 114 + .../request/node_modules/mime/package.json | 39 + .../node_modules/request/node_modules/mime/test.js | 84 + .../request/node_modules/mime/types/mime.types | 1588 ++++ .../request/node_modules/mime/types/node.types | 77 + .../request/node_modules/node-uuid/.npmignore | 2 + .../request/node_modules/node-uuid/LICENSE.md | 2 + .../request/node_modules/node-uuid/README.md | 207 + .../node_modules/node-uuid/benchmark/README.md | 53 + .../node_modules/node-uuid/benchmark/bench.gnu | 174 + .../node_modules/node-uuid/benchmark/bench.sh | 34 + .../node-uuid/benchmark/benchmark-native.c | 34 + .../node_modules/node-uuid/benchmark/benchmark.js | 84 + .../request/node_modules/node-uuid/component.json | 18 + .../request/node_modules/node-uuid/package.json | 38 + .../node_modules/node-uuid/test/compare_v1.js | 63 + .../request/node_modules/node-uuid/test/test.html | 17 + .../request/node_modules/node-uuid/test/test.js | 228 + .../request/node_modules/node-uuid/uuid.js | 245 + .../request/node_modules/oauth-sign/index.js | 43 + .../request/node_modules/oauth-sign/package.json | 33 + .../request/node_modules/oauth-sign/test.js | 49 + .../request/node_modules/qs/.gitmodules | 6 + .../request/node_modules/qs/.npmignore | 1 + .../request/node_modules/qs/.travis.yml | 4 + .../request/node_modules/qs/History.md | 109 + .../node_modules/request/node_modules/qs/Makefile | 6 + .../node_modules/request/node_modules/qs/Readme.md | 58 + .../request/node_modules/qs/benchmark.js | 17 + .../request/node_modules/qs/component.json | 9 + .../request/node_modules/qs/examples.js | 51 + .../node_modules/request/node_modules/qs/index.js | 268 + .../request/node_modules/qs/package.json | 43 + .../request/node_modules/qs/test/browser/expect.js | 1202 +++ .../node_modules/qs/test/browser/index.html | 18 + .../request/node_modules/qs/test/browser/jquery.js | 8981 ++++++++++++++++++++ .../request/node_modules/qs/test/browser/mocha.css | 163 + .../request/node_modules/qs/test/browser/mocha.js | 4201 +++++++++ .../request/node_modules/qs/test/browser/qs.css | 0 .../request/node_modules/qs/test/browser/qs.js | 351 + .../request/node_modules/qs/test/parse.js | 152 + .../request/node_modules/qs/test/stringify.js | 81 + .../request/node_modules/tunnel-agent/index.js | 227 + .../request/node_modules/tunnel-agent/package.json | 30 + .../winston/node_modules/request/package.json | 50 + .../node_modules/request/tests/googledoodle.jpg | Bin 0 -> 38510 bytes .../winston/node_modules/request/tests/run.js | 40 + .../winston/node_modules/request/tests/server.js | 90 + .../winston/node_modules/request/tests/squid.conf | 77 + .../node_modules/request/tests/ssl/ca/ca.cnf | 20 + .../node_modules/request/tests/ssl/ca/ca.crl | 0 .../node_modules/request/tests/ssl/ca/ca.crt | 17 + .../node_modules/request/tests/ssl/ca/ca.csr | 13 + .../node_modules/request/tests/ssl/ca/ca.key | 18 + .../node_modules/request/tests/ssl/ca/ca.srl | 1 + .../node_modules/request/tests/ssl/ca/server.cnf | 19 + .../node_modules/request/tests/ssl/ca/server.crt | 16 + .../node_modules/request/tests/ssl/ca/server.csr | 11 + .../node_modules/request/tests/ssl/ca/server.js | 28 + .../node_modules/request/tests/ssl/ca/server.key | 9 + .../node_modules/request/tests/ssl/npm-ca.crt | 16 + .../node_modules/request/tests/ssl/test.crt | 15 + .../node_modules/request/tests/ssl/test.key | 15 + .../node_modules/request/tests/test-basic-auth.js | 74 + .../node_modules/request/tests/test-body.js | 122 + .../node_modules/request/tests/test-defaults.js | 129 + .../node_modules/request/tests/test-digest-auth.js | 69 + .../node_modules/request/tests/test-errors.js | 37 + .../request/tests/test-follow-all-303.js | 30 + .../node_modules/request/tests/test-follow-all.js | 35 + .../node_modules/request/tests/test-form.js | 79 + .../node_modules/request/tests/test-hawk.js | 33 + .../node_modules/request/tests/test-headers.js | 52 + .../node_modules/request/tests/test-httpModule.js | 94 + .../request/tests/test-https-strict.js | 97 + .../node_modules/request/tests/test-https.js | 87 + .../node_modules/request/tests/test-oauth.js | 117 + .../node_modules/request/tests/test-params.js | 93 + .../request/tests/test-piped-redirect.js | 42 + .../node_modules/request/tests/test-pipes.js | 216 + .../node_modules/request/tests/test-pool.js | 16 + .../tests/test-protocol-changing-redirect.js | 61 + .../node_modules/request/tests/test-proxy.js | 39 + .../winston/node_modules/request/tests/test-qs.js | 34 + .../node_modules/request/tests/test-redirect.js | 155 + .../winston/node_modules/request/tests/test-s3.js | 13 + .../node_modules/request/tests/test-timeout.js | 87 + .../node_modules/request/tests/test-toJSON.js | 14 + .../node_modules/request/tests/test-tunnel.js | 63 + .../node_modules/request/tests/unicycle.jpg | Bin 0 -> 19806 bytes .../winston/node_modules/stack-trace/.npmignore | 1 + .../winston/node_modules/stack-trace/License | 19 + .../winston/node_modules/stack-trace/Makefile | 11 + .../winston/node_modules/stack-trace/Readme.md | 98 + .../node_modules/stack-trace/lib/stack-trace.js | 111 + .../winston/node_modules/stack-trace/package.json | 35 + .../forever/node_modules/winston/package.json | 54 + .../forever/node_modules/winston/test/cli-test.js | 40 + .../node_modules/winston/test/container-test.js | 99 + .../winston/test/custom-timestamp-test.js | 62 + .../node_modules/winston/test/exception-test.js | 47 + .../node_modules/winston/test/fixtures/.gitkeep | 0 .../winston/test/fixtures/keys/agent2-cert.pem | 13 + .../winston/test/fixtures/keys/agent2-key.pem | 9 + .../winston/test/fixtures/logs/.gitkeep | 0 .../test/fixtures/scripts/default-exceptions.js | 21 + .../winston/test/fixtures/scripts/exit-on-error.js | 25 + .../test/fixtures/scripts/log-exceptions.js | 25 + .../test/fixtures/scripts/unhandle-exceptions.js | 26 + .../forever/node_modules/winston/test/helpers.js | 183 + .../winston/test/log-exception-test.js | 60 + .../node_modules/winston/test/log-rewriter-test.js | 98 + .../node_modules/winston/test/logger-test.js | 324 + .../winston/test/transports/console-test.js | 39 + .../test/transports/daily-rotate-file-test.js | 62 + .../winston/test/transports/file-maxfiles-test.js | 102 + .../winston/test/transports/file-maxsize-test.js | 82 + .../winston/test/transports/file-test.js | 60 + .../winston/test/transports/memory-test.js | 31 + .../winston/test/transports/transport.js | 215 + .../winston/test/transports/webhook-test.js | 125 + .../node_modules/winston/test/winston-test.js | 98 + node_modules/forever/package.json | 76 + node_modules/forever/test/cli-test | 51 + .../forever/test/core/tail-stopall-test.js | 47 + .../forever/test/fixtures/log-on-interval.js | 3 + node_modules/forever/test/fixtures/server.js | 16 + node_modules/forever/test/fixtures/start-daemon.js | 16 + node_modules/forever/test/helpers/macros.js | 93 + .../forever/test/helpers/mocks/child-process.js | 12 + node_modules/forever/test/helpers/mocks/monitor.js | 25 + node_modules/forever/test/helpers/mocks/stream.js | 19 + node_modules/forever/test/service/simple-test.js | 25 + .../forever/test/worker/multiple-workers-test.js | 98 + node_modules/forever/test/worker/simple-test.js | 73 + 1630 files changed, 158657 insertions(+) create mode 100644 node_modules/forever/.npmignore create mode 100644 node_modules/forever/.travis.yml create mode 100644 node_modules/forever/CHANGELOG.md create mode 100644 node_modules/forever/LICENSE create mode 100644 node_modules/forever/README.md create mode 100755 node_modules/forever/bin/forever create mode 100755 node_modules/forever/bin/foreverd create mode 100755 node_modules/forever/bin/monitor create mode 100644 node_modules/forever/lib/forever.js create mode 100644 node_modules/forever/lib/forever/cli.js create mode 100644 node_modules/forever/lib/forever/service/adapters/adapter.js create mode 100644 node_modules/forever/lib/forever/service/adapters/initd/index.js create mode 100644 node_modules/forever/lib/forever/service/adapters/systemv/foreverd create mode 100644 node_modules/forever/lib/forever/service/adapters/systemv/index.js create mode 100644 node_modules/forever/lib/forever/service/cli.js create mode 100644 node_modules/forever/lib/forever/service/index.js create mode 100644 node_modules/forever/lib/forever/service/service.js create mode 100644 node_modules/forever/lib/forever/worker.js create mode 120000 node_modules/forever/node_modules/.bin/flatiron create mode 100644 node_modules/forever/node_modules/cliff/.npmignore create mode 100644 node_modules/forever/node_modules/cliff/LICENSE create mode 100644 node_modules/forever/node_modules/cliff/README.md create mode 100755 node_modules/forever/node_modules/cliff/assets/inspect.png create mode 100755 node_modules/forever/node_modules/cliff/assets/put-object-rows.png create mode 100755 node_modules/forever/node_modules/cliff/assets/put-object.png create mode 100755 node_modules/forever/node_modules/cliff/assets/put-rows-colors.png create mode 100755 node_modules/forever/node_modules/cliff/assets/put-rows.png create mode 100755 node_modules/forever/node_modules/cliff/assets/string-object-rows.png create mode 100755 node_modules/forever/node_modules/cliff/assets/string-rows.png create mode 100644 node_modules/forever/node_modules/cliff/examples/inspect.js create mode 100644 node_modules/forever/node_modules/cliff/examples/put-object-rows.js create mode 100644 node_modules/forever/node_modules/cliff/examples/put-object.js create mode 100644 node_modules/forever/node_modules/cliff/examples/put-rows-colors.js create mode 100644 node_modules/forever/node_modules/cliff/examples/put-rows.js create mode 100644 node_modules/forever/node_modules/cliff/examples/string-object-rows.js create mode 100644 node_modules/forever/node_modules/cliff/examples/string-rows.js create mode 100644 node_modules/forever/node_modules/cliff/lib/cliff.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/eyes/LICENSE create mode 100644 node_modules/forever/node_modules/cliff/node_modules/eyes/Makefile create mode 100644 node_modules/forever/node_modules/cliff/node_modules/eyes/README.md create mode 100644 node_modules/forever/node_modules/cliff/node_modules/eyes/lib/eyes.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/eyes/package.json create mode 100644 node_modules/forever/node_modules/cliff/node_modules/eyes/test/eyes-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/.npmignore create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/.travis.yml create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/LICENSE create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/README.md create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/docs/transports.md create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/examples/couchdb.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/examples/exception.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/examples/raw-mode.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/examples/webhook-post.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/common.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/cli-config.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/npm-config.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/syslog-config.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/container.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/exception.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/logger.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/console.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/file.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/http.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/transport.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/webhook.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/.gitmodules create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/.npmignore create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/LICENSE create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/Makefile create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/README.md create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/index.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/lib/async.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/package.json create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/README.md create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/cycle.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/package.json create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/.npmignore create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/README.md create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/docs/docco.css create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/all-properties.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/array-argument.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/object-argument.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/package.json create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/single-property.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/package.json create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/LICENSE create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/README.md create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/aws.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/aws2.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/forever.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/main.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/mimetypes.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/oauth.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/package.json create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/googledoodle.png create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/run.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/server.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/squid.conf create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.key create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/test.crt create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/test.key create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-body.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-cookie.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-cookiejar.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-defaults.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-errors.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-headers.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-httpModule.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-https-strict.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-https.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-oauth.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-params.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-pipes.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-pool.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-proxy.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-qs.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-redirect.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-s3.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-timeout.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-toJSON.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-tunnel.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tunnel.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/uuid.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/vendor/cookie/index.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/vendor/cookie/jar.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/.npmignore create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/License create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/Makefile create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/Readme.md create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/package.json create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/package.json create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/cli-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/container-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/custom-timestamp-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/exception-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/.gitkeep create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/keys/agent2-cert.pem create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/keys/agent2-key.pem create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/logs/.gitkeep create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/default-exceptions.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/exit-on-error.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/log-exceptions.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/helpers.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/log-exception-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/log-rewriter-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/logger-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/console-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-maxfiles-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-maxsize-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/transport.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/webhook-test.js create mode 100644 node_modules/forever/node_modules/cliff/node_modules/winston/test/winston-test.js create mode 100644 node_modules/forever/node_modules/cliff/package.json create mode 100644 node_modules/forever/node_modules/cliff/test/cliff-test.js create mode 100644 node_modules/forever/node_modules/colors/MIT-LICENSE.txt create mode 100644 node_modules/forever/node_modules/colors/ReadMe.md create mode 100644 node_modules/forever/node_modules/colors/colors.js create mode 100644 node_modules/forever/node_modules/colors/example.html create mode 100644 node_modules/forever/node_modules/colors/example.js create mode 100644 node_modules/forever/node_modules/colors/package.json create mode 100644 node_modules/forever/node_modules/colors/test.js create mode 100644 node_modules/forever/node_modules/flatiron/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/.travis.yml create mode 100644 node_modules/forever/node_modules/flatiron/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/README.md create mode 100755 node_modules/forever/node_modules/flatiron/bin/flatiron create mode 100644 node_modules/forever/node_modules/flatiron/examples/cli-sample/index.js create mode 100644 node_modules/forever/node_modules/flatiron/examples/cli-sample/print.js create mode 100644 node_modules/forever/node_modules/flatiron/examples/http-sample.js create mode 100644 node_modules/forever/node_modules/flatiron/examples/resourceful-app/app.js create mode 100644 node_modules/forever/node_modules/flatiron/examples/resourceful-app/app/resources/creature.js create mode 100644 node_modules/forever/node_modules/flatiron/examples/resourceful-app/package.json create mode 100644 node_modules/forever/node_modules/flatiron/examples/socket.io/index.html create mode 100644 node_modules/forever/node_modules/flatiron/examples/socket.io/server.js create mode 100644 node_modules/forever/node_modules/flatiron/examples/static-app/app.js create mode 100644 node_modules/forever/node_modules/flatiron/examples/static-app/app/assets/style.css create mode 100644 node_modules/forever/node_modules/flatiron/examples/static-app/app/assets/style.js create mode 100644 node_modules/forever/node_modules/flatiron/examples/static-app/package.json create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron.js create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron/app.js create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron/cli/create.js create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron/common.js create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron/constants.js create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/cli.js create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/http.js create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/resourceful.js create mode 100644 node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/static.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/.travis.yml create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/README.md create mode 100755 node_modules/forever/node_modules/flatiron/node_modules/broadway/bin/build create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/app.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/index.html create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/plugins/helloworld.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/nodejs/app.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/nodejs/plugins/helloworld.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/app.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/bootstrapper.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/browser.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/common/directories.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/common/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/features/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/directories.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/exceptions.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/inspect.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/log.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/lib/eventemitter2.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/common.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/perf/benchmark.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/addListener.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/emit.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/reconfigure.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/removeListener.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/setMax.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/ttl.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/addListener.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/all.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/customDelimiter.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/k1.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/options.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/removeListener.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/ttl.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/.travis.yml create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/docs/transports.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/couchdb.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/exception.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/raw-mode.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/webhook-post.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/common.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/cli-config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/npm-config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/syslog-config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/container.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/exception.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/logger.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/console.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/file.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/http.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/transport.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/webhook.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/.gitmodules create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/Makefile create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/lib/async.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/cycle.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/Makefile create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/lib/eyes.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/test/eyes-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/docco.css create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/all-properties.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/array-argument.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/object-argument.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/single-property.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/aws.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/aws2.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/forever.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/main.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/mimetypes.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/oauth.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/googledoodle.png create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/run.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/server.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/squid.conf create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.key create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.crt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.key create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-body.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookie.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookiejar.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-defaults.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-errors.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-headers.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-httpModule.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https-strict.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-oauth.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-params.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pipes.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pool.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-proxy.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-qs.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-redirect.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-s3.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-timeout.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-toJSON.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-tunnel.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tunnel.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/uuid.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/jar.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/License create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Makefile create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Readme.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/cli-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/container-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/custom-timestamp-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/exception-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/.gitkeep create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-cert.pem create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-key.pem create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/logs/.gitkeep create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/default-exceptions.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/exit-on-error.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/log-exceptions.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/helpers.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/log-exception-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/log-rewriter-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/logger-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/console-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-maxfiles-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-maxsize-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/transport.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/webhook-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/winston-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/common/directories-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/app-init-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/app-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/broadway-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/.gitkeep create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/empty-app/.gitkeep create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app/app/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app/config/topics.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/assert.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/helpers.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/macros.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/config-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/directories-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/log-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/.travis.yml create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/README.md create mode 100755 node_modules/forever/node_modules/flatiron/node_modules/director/bin/build create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/build/director.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/build/director.min.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/build/ender.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/examples/http.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/img/director.png create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/img/hashRoute.png create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/lib/director.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/lib/director/browser.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/lib/director/cli.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/lib/director/http/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/lib/director/http/methods.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/lib/director/http/responses.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/lib/director/router.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/backend/backend.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/browserify-harness.html create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/helpers/api.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/html5-routes-harness.html create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/html5-routes-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/routes-harness.html create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/routes-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/dispatch-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/mount-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/path-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/dispatch-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/insert-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/mount-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/on-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/path-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/regifystring-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/helpers/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/helpers/macros.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/accept-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/attach-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/before-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/http-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/methods-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/responses-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/stream-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/.travis.yml create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/README.markdown create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/bool.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/boolean_double.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/boolean_single.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/default_hash.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/default_singles.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/divide.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count_options.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count_wrap.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/nonopt.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/reflect.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/short.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/string.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/usage-options.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/example/xup.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/README.markdown create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/example/center.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/example/meat.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/break.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/idleness.txt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/wrap.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_/argv.js create mode 100755 node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_/bin.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/test/parse.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/test/usage.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/optimist/x.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/.jshintrc create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/.travis.yml create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/CHANGELOG.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/docs/docco.css create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/docs/prompt.html create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/add-properties.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/existing-properties.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/history.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/nested-properties-prompt.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/old-schema.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/override-validation.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/password.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/prompt-override.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/property-prompt.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/simple-prompt.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/yes-or-no-prompt.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/lib/prompt.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/LICENCE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/example/example.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/lib/read.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/node_modules/mute-stream/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/node_modules/mute-stream/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/node_modules/mute-stream/mute.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/node_modules/mute-stream/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/node_modules/mute-stream/test/basic.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/rs.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/test/basic.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/test/defaults.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/test/many.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/.travis.yml create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/CHANGELOG.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/example/webservice.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/lib/revalidator.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/revalidator/test/validator-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/.travis.yml create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/docs/transports.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/examples/couchdb.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/examples/exception.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/examples/raw-mode.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/examples/webhook-post.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/common.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/config/cli-config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/config/npm-config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/config/syslog-config.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/container.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/exception.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/logger.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/transports.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/transports/console.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/transports/file.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/transports/http.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/transports/transport.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/lib/winston/transports/webhook.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/async/.gitmodules create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/async/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/async/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/async/Makefile create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/async/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/async/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/async/lib/async.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/async/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/cycle/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/cycle/cycle.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/cycle/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/eyes/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/eyes/Makefile create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/eyes/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/eyes/lib/eyes.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/eyes/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/eyes/test/eyes-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/docs/docco.css create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/examples/all-properties.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/examples/array-argument.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/examples/object-argument.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/examples/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/examples/single-property.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/LICENSE create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/README.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/aws.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/aws2.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/forever.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/main.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/mimetypes.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/oauth.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/googledoodle.png create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/run.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/server.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/squid.conf create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/server.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/ca/server.key create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/test.crt create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/ssl/test.key create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-body.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-cookie.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-cookiejar.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-defaults.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-errors.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-headers.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-httpModule.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-https-strict.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-https.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-oauth.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-params.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-pipes.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-pool.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-proxy.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-qs.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-redirect.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-s3.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-timeout.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-toJSON.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tests/test-tunnel.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/tunnel.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/uuid.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/vendor/cookie/index.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/request/vendor/cookie/jar.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/stack-trace/.npmignore create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/stack-trace/License create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/stack-trace/Makefile create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/stack-trace/Readme.md create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/node_modules/stack-trace/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/cli-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/container-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/custom-timestamp-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/exception-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/fixtures/.gitkeep create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/fixtures/keys/agent2-cert.pem create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/fixtures/keys/agent2-key.pem create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/fixtures/logs/.gitkeep create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/fixtures/scripts/default-exceptions.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/fixtures/scripts/exit-on-error.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/fixtures/scripts/log-exceptions.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/helpers.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/log-exception-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/log-rewriter-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/logger-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/transports/console-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/transports/file-maxfiles-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/transports/file-maxsize-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/transports/file-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/transports/transport.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/transports/webhook-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/winston/test/winston-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/package.json create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/test/helpers.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/test/interactive-prompt-test.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/test/macros.js create mode 100644 node_modules/forever/node_modules/flatiron/node_modules/prompt/test/prompt-test.js create mode 100644 node_modules/forever/node_modules/flatiron/package.json create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/cli/app.js create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/cli/config/config.json create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/cli/directories.json create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/cli/files.json create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/cli/lib/index.js create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/cli/package.json create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/http/app.js create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/http/config/config.json create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/http/directories.json create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/http/files.json create mode 100644 node_modules/forever/node_modules/flatiron/scaffolds/http/package.json create mode 100644 node_modules/forever/node_modules/flatiron/test/fixtures/sample-app/app/new-york/controller.js create mode 100644 node_modules/forever/node_modules/flatiron/test/fixtures/sample-app/app/new-york/index.js create mode 100644 node_modules/forever/node_modules/flatiron/test/fixtures/sample-app/app/new-york/new-york.js create mode 100644 node_modules/forever/node_modules/flatiron/test/flatiron-test.js create mode 100644 node_modules/forever/node_modules/flatiron/test/plugins/resourceful-test.js create mode 100644 node_modules/forever/node_modules/flatiron/test/plugins/static-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/.travis.yml create mode 100644 node_modules/forever/node_modules/forever-monitor/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/all-env-vars.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/always-throw.js create mode 100755 node_modules/forever/node_modules/forever-monitor/examples/cli-multiple-start create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/count-timer.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/custom-cwd.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/env-server.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/env-vars.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/error-on-timer.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/graceful-exit.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/list-multiple.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/log-on-interval.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/multiple-processes.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/process-send.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/server.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/signal-ignore.js create mode 100644 node_modules/forever/node_modules/forever-monitor/examples/spawn-and-error.js create mode 100644 node_modules/forever/node_modules/forever-monitor/lib/forever-monitor/common.js create mode 100644 node_modules/forever/node_modules/forever-monitor/lib/forever-monitor/monitor.js create mode 100644 node_modules/forever/node_modules/forever-monitor/lib/forever-monitor/plugins/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/lib/forever-monitor/plugins/logger.js create mode 100644 node_modules/forever/node_modules/forever-monitor/lib/forever-monitor/plugins/watch.js create mode 100644 node_modules/forever/node_modules/forever-monitor/lib/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/.travis.yml create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/README.md create mode 100755 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/bin/build create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/examples/browser/app.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/examples/browser/index.html create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/examples/browser/plugins/helloworld.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/examples/nodejs/app.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/examples/nodejs/plugins/helloworld.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/app.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/bootstrapper.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/browser.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/common/directories.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/common/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/features/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/plugins/config.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/plugins/directories.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/plugins/exceptions.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/plugins/inspect.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/lib/broadway/plugins/log.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/lib/eventemitter2.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/common.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/perf/benchmark.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/simple/addListener.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/simple/emit.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/simple/reconfigure.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/simple/removeListener.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/simple/setMax.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/simple/ttl.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/addListener.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/all.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/customDelimiter.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/k1.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/options.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/removeListener.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/ttl.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/.travis.yml create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/docs/transports.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/examples/couchdb.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/examples/exception.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/examples/raw-mode.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/examples/webhook-post.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/common.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/config.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/config/cli-config.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/config/npm-config.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/config/syslog-config.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/container.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/exception.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/logger.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/transports.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/transports/console.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/transports/file.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/transports/http.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/transports/transport.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/lib/winston/transports/webhook.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/async/.gitmodules create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/async/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/async/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/async/Makefile create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/async/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/async/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/async/lib/async.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/async/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/cycle/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/cycle/cycle.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/cycle/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/eyes/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/eyes/Makefile create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/eyes/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/eyes/lib/eyes.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/eyes/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/eyes/test/eyes-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/docco.css create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/all-properties.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/array-argument.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/object-argument.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/single-property.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/aws.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/aws2.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/forever.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/main.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/mimetypes.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/oauth.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/googledoodle.png create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/run.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/server.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/squid.conf create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.key create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.crt create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.key create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-body.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookie.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookiejar.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-defaults.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-errors.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-headers.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-httpModule.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https-strict.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-oauth.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-params.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pipes.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pool.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-proxy.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-qs.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-redirect.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-s3.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-timeout.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-toJSON.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-tunnel.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/tunnel.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/uuid.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/jar.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/stack-trace/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/stack-trace/License create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Makefile create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Readme.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/node_modules/stack-trace/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/cli-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/container-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/custom-timestamp-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/exception-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/fixtures/.gitkeep create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-cert.pem create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-key.pem create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/fixtures/logs/.gitkeep create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/fixtures/scripts/default-exceptions.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/fixtures/scripts/exit-on-error.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/fixtures/scripts/log-exceptions.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/helpers.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/log-exception-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/log-rewriter-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/logger-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/transports/console-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/transports/file-maxfiles-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/transports/file-maxsize-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/transports/file-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/transports/transport.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/transports/webhook-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/node_modules/winston/test/winston-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/common/directories-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/core/app-init-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/core/app-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/core/broadway-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/fixtures/.gitkeep create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/fixtures/empty-app/.gitkeep create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/fixtures/sample-app.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/fixtures/sample-app/app/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/fixtures/sample-app/config/topics.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/helpers/assert.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/helpers/helpers.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/helpers/macros.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/plugins/config-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/plugins/directories-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/broadway/test/plugins/log-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/.travis.yml create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/blerg.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/minimatch.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/node_modules/lru-cache/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/node_modules/lru-cache/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/node_modules/lru-cache/README.md create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/node_modules/lru-cache/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/node_modules/lru-cache/test/basic.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/t.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/minimatch/test/basic.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/.gitmodules create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/LICENCE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/examples/pretty.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/README.markdown create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/bool.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/boolean_double.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/boolean_single.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/default_hash.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/default_singles.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/divide.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/line_count.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/line_count_options.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/line_count_wrap.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/nonopt.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/reflect.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/short.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/string.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/usage-options.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/examples/xup.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/README.markdown create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/example/center.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/example/meat.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/index.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/test/break.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/test/idleness.txt create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/node_modules/wordwrap/test/wrap.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/test/_.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/test/_/argv.js create mode 100755 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/test/_/bin.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/test/parse.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/node_modules/optimist/test/usage.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/out create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/readme.markdown create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/test/.npmignore create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/test/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/test/pipe.async.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/test/readArray.asynct.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/test/readme.markdown create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/test/simple-map.asynct.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/test/split.asynct.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/node_modules/event-stream/test/writeArray.asynct.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/ps-tree/readme.markdown create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/watch/LICENSE create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/watch/main.js create mode 100755 node_modules/forever/node_modules/forever-monitor/node_modules/watch/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/watch/readme.mkd create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/watch/test/d/d/t create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/watch/test/d/t create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/watch/test/test_monitor.js create mode 100644 node_modules/forever/node_modules/forever-monitor/node_modules/watch/test/test_watchTree.js create mode 100644 node_modules/forever/node_modules/forever-monitor/package.json create mode 100644 node_modules/forever/node_modules/forever-monitor/test/core/check-process-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/fork.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/gc.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/logs.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/send-pong.js create mode 100755 node_modules/forever/node_modules/forever-monitor/test/fixtures/testnode create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/watch/.foreverignore create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/watch/daemon.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/watch/file create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/watch/ignoredDir/file create mode 100644 node_modules/forever/node_modules/forever-monitor/test/fixtures/watch/removeMe create mode 100644 node_modules/forever/node_modules/forever-monitor/test/helpers/macros.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/monitor/env-spawn-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/monitor/fork-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/monitor/send-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/monitor/signal-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/monitor/simple-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/monitor/spin-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/plugins/logger-test.js create mode 100644 node_modules/forever/node_modules/forever-monitor/test/plugins/watch-test.js create mode 100644 node_modules/forever/node_modules/nconf/.npmignore create mode 100644 node_modules/forever/node_modules/nconf/.travis.yml create mode 100644 node_modules/forever/node_modules/nconf/CHANGELOG.md create mode 100644 node_modules/forever/node_modules/nconf/LICENSE create mode 100644 node_modules/forever/node_modules/nconf/README.md create mode 100644 node_modules/forever/node_modules/nconf/docs/docco.css create mode 100644 node_modules/forever/node_modules/nconf/docs/nconf.html create mode 100644 node_modules/forever/node_modules/nconf/docs/nconf/common.html create mode 100644 node_modules/forever/node_modules/nconf/docs/nconf/formats.html create mode 100644 node_modules/forever/node_modules/nconf/docs/nconf/provider.html create mode 100644 node_modules/forever/node_modules/nconf/docs/nconf/stores.html create mode 100644 node_modules/forever/node_modules/nconf/docs/nconf/stores/file.html create mode 100644 node_modules/forever/node_modules/nconf/docs/nconf/stores/memory.html create mode 100644 node_modules/forever/node_modules/nconf/docs/nconf/stores/system.html create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf.js create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf/common.js create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf/formats.js create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf/provider.js create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf/stores/argv.js create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf/stores/env.js create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf/stores/file.js create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf/stores/literal.js create mode 100644 node_modules/forever/node_modules/nconf/lib/nconf/stores/memory.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/async/.gitmodules create mode 100644 node_modules/forever/node_modules/nconf/node_modules/async/.npmignore create mode 100644 node_modules/forever/node_modules/nconf/node_modules/async/LICENSE create mode 100644 node_modules/forever/node_modules/nconf/node_modules/async/Makefile create mode 100644 node_modules/forever/node_modules/nconf/node_modules/async/README.md create mode 100644 node_modules/forever/node_modules/nconf/node_modules/async/index.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/async/lib/async.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/async/package.json create mode 100644 node_modules/forever/node_modules/nconf/node_modules/ini/LICENSE create mode 100644 node_modules/forever/node_modules/nconf/node_modules/ini/README.md create mode 100644 node_modules/forever/node_modules/nconf/node_modules/ini/ini.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/ini/package.json create mode 100644 node_modules/forever/node_modules/nconf/node_modules/ini/test/bar.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/ini/test/fixtures/foo.ini create mode 100644 node_modules/forever/node_modules/nconf/node_modules/ini/test/foo.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/.travis.yml create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/LICENSE create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/bool.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/boolean_double.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/boolean_single.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/default_hash.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/default_singles.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/divide.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/line_count.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/line_count_options.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/line_count_wrap.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/nonopt.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/reflect.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/short.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/string.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/usage-options.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/example/xup.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/index.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/.npmignore create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/README.markdown create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/example/center.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/example/meat.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/index.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/package.json create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/test/break.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/test/idleness.txt create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/test/wrap.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/package.json create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/readme.markdown create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/test/_.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/test/_/argv.js create mode 100755 node_modules/forever/node_modules/nconf/node_modules/optimist/test/_/bin.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/test/parse.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/optimist/test/usage.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/.npmignore create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/README.md create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/docs/docco.css create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/docs/pkginfo.html create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/examples/all-properties.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/examples/array-argument.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/examples/multiple-properties.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/examples/object-argument.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/examples/package.json create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/examples/single-property.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/lib/pkginfo.js create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/package.json create mode 100644 node_modules/forever/node_modules/nconf/node_modules/pkginfo/test/pkginfo-test.js create mode 100644 node_modules/forever/node_modules/nconf/package.json create mode 100644 node_modules/forever/node_modules/nconf/test/common-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/complete-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/complete.json create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/data.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/hierarchy/global.json create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/hierarchy/hierarchical.json create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/hierarchy/user.json create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/malformed.json create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/merge/file1.json create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/merge/file2.json create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/nconf-argv.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/nconf-change-argv.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/nconf-env.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/nconf-hierarchical-file-argv.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/nconf-hierarchical-load-merge.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/nconf-hierarchical-load-save.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/nconf-nested-env.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/provider-argv.js create mode 100644 node_modules/forever/node_modules/nconf/test/fixtures/scripts/provider-env.js create mode 100644 node_modules/forever/node_modules/nconf/test/helpers.js create mode 100644 node_modules/forever/node_modules/nconf/test/hierarchy-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/mocks/mock-store.js create mode 100644 node_modules/forever/node_modules/nconf/test/nconf-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/provider-save-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/provider-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/stores/argv-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/stores/env-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/stores/file-store-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/stores/literal-test.js create mode 100644 node_modules/forever/node_modules/nconf/test/stores/memory-store-test.js create mode 100644 node_modules/forever/node_modules/nconf/usage.js create mode 100644 node_modules/forever/node_modules/nssocket/.npmignore create mode 100644 node_modules/forever/node_modules/nssocket/.travis.yml create mode 100644 node_modules/forever/node_modules/nssocket/README.md create mode 100644 node_modules/forever/node_modules/nssocket/examples/bla.js create mode 100644 node_modules/forever/node_modules/nssocket/examples/foo.js create mode 100644 node_modules/forever/node_modules/nssocket/examples/reconnect.js create mode 100644 node_modules/forever/node_modules/nssocket/examples/simple-protocol.js create mode 100644 node_modules/forever/node_modules/nssocket/examples/verbose-protocol.js create mode 100644 node_modules/forever/node_modules/nssocket/lib/common.js create mode 100644 node_modules/forever/node_modules/nssocket/lib/nssocket.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/eventemitter2/README.md create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/eventemitter2/index.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/eventemitter2/lib/eventemitter2.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/eventemitter2/package.json create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/.npmignore create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/README.md create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/lazy.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/lazy.js~ create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/package.json create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/package.json~ create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/bucket.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/complex.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/custom.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/em.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/filter.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/foldr.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/forEach.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/head.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/join.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/lines.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/map.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/pipe.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/product.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/range.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/skip.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/sum.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/tail.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/take.js create mode 100644 node_modules/forever/node_modules/nssocket/node_modules/lazy/test/takeWhile.js create mode 100644 node_modules/forever/node_modules/nssocket/package.json create mode 100644 node_modules/forever/node_modules/nssocket/test/create-server-test.js create mode 100644 node_modules/forever/node_modules/nssocket/test/fixtures/ryans-cert.pem create mode 100644 node_modules/forever/node_modules/nssocket/test/fixtures/ryans-csr.pem create mode 100644 node_modules/forever/node_modules/nssocket/test/fixtures/ryans-key.pem create mode 100644 node_modules/forever/node_modules/nssocket/test/tcp-reconnect-test.js create mode 100644 node_modules/forever/node_modules/nssocket/test/tcp-test.js create mode 100644 node_modules/forever/node_modules/nssocket/test/tls-test.js create mode 100644 node_modules/forever/node_modules/optimist/.travis.yml create mode 100644 node_modules/forever/node_modules/optimist/LICENSE create mode 100644 node_modules/forever/node_modules/optimist/example/bool.js create mode 100644 node_modules/forever/node_modules/optimist/example/boolean_double.js create mode 100644 node_modules/forever/node_modules/optimist/example/boolean_single.js create mode 100644 node_modules/forever/node_modules/optimist/example/default_hash.js create mode 100644 node_modules/forever/node_modules/optimist/example/default_singles.js create mode 100644 node_modules/forever/node_modules/optimist/example/divide.js create mode 100644 node_modules/forever/node_modules/optimist/example/line_count.js create mode 100644 node_modules/forever/node_modules/optimist/example/line_count_options.js create mode 100644 node_modules/forever/node_modules/optimist/example/line_count_wrap.js create mode 100644 node_modules/forever/node_modules/optimist/example/nonopt.js create mode 100644 node_modules/forever/node_modules/optimist/example/reflect.js create mode 100644 node_modules/forever/node_modules/optimist/example/short.js create mode 100644 node_modules/forever/node_modules/optimist/example/string.js create mode 100644 node_modules/forever/node_modules/optimist/example/usage-options.js create mode 100644 node_modules/forever/node_modules/optimist/example/xup.js create mode 100644 node_modules/forever/node_modules/optimist/index.js create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/.npmignore create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/README.markdown create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/example/center.js create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/example/meat.js create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/index.js create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/package.json create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/test/break.js create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/test/idleness.txt create mode 100644 node_modules/forever/node_modules/optimist/node_modules/wordwrap/test/wrap.js create mode 100644 node_modules/forever/node_modules/optimist/package.json create mode 100644 node_modules/forever/node_modules/optimist/readme.markdown create mode 100644 node_modules/forever/node_modules/optimist/test/_.js create mode 100644 node_modules/forever/node_modules/optimist/test/_/argv.js create mode 100755 node_modules/forever/node_modules/optimist/test/_/bin.js create mode 100644 node_modules/forever/node_modules/optimist/test/parse.js create mode 100644 node_modules/forever/node_modules/optimist/test/short.js create mode 100644 node_modules/forever/node_modules/optimist/test/usage.js create mode 100644 node_modules/forever/node_modules/pkginfo/.npmignore create mode 100644 node_modules/forever/node_modules/pkginfo/LICENSE create mode 100644 node_modules/forever/node_modules/pkginfo/README.md create mode 100644 node_modules/forever/node_modules/pkginfo/docs/docco.css create mode 100644 node_modules/forever/node_modules/pkginfo/docs/pkginfo.html create mode 100644 node_modules/forever/node_modules/pkginfo/examples/all-properties.js create mode 100644 node_modules/forever/node_modules/pkginfo/examples/array-argument.js create mode 100644 node_modules/forever/node_modules/pkginfo/examples/multiple-properties.js create mode 100644 node_modules/forever/node_modules/pkginfo/examples/object-argument.js create mode 100644 node_modules/forever/node_modules/pkginfo/examples/package.json create mode 100644 node_modules/forever/node_modules/pkginfo/examples/single-property.js create mode 100644 node_modules/forever/node_modules/pkginfo/examples/subdir/package.json create mode 100644 node_modules/forever/node_modules/pkginfo/examples/target-dir.js create mode 100644 node_modules/forever/node_modules/pkginfo/lib/pkginfo.js create mode 100644 node_modules/forever/node_modules/pkginfo/package.json create mode 100644 node_modules/forever/node_modules/pkginfo/test/pkginfo-test.js create mode 100644 node_modules/forever/node_modules/timespan/.npmignore create mode 100644 node_modules/forever/node_modules/timespan/CHANGELOG.md create mode 100644 node_modules/forever/node_modules/timespan/LICENSE create mode 100644 node_modules/forever/node_modules/timespan/README.md create mode 100644 node_modules/forever/node_modules/timespan/browser/TimeSpan-1.2.js create mode 100644 node_modules/forever/node_modules/timespan/browser/TimeSpan-1.2.min.js create mode 100644 node_modules/forever/node_modules/timespan/lib/time-span.js create mode 100644 node_modules/forever/node_modules/timespan/package.json create mode 100644 node_modules/forever/node_modules/timespan/test/time-span-test.js create mode 100644 node_modules/forever/node_modules/utile/.npmignore create mode 100644 node_modules/forever/node_modules/utile/.travis.yml create mode 100644 node_modules/forever/node_modules/utile/CHANGELOG.md create mode 100644 node_modules/forever/node_modules/utile/LICENSE create mode 100644 node_modules/forever/node_modules/utile/README.md create mode 100644 node_modules/forever/node_modules/utile/lib/args.js create mode 100644 node_modules/forever/node_modules/utile/lib/base64.js create mode 100644 node_modules/forever/node_modules/utile/lib/file.js create mode 100644 node_modules/forever/node_modules/utile/lib/format.js create mode 100644 node_modules/forever/node_modules/utile/lib/index.js create mode 120000 node_modules/forever/node_modules/utile/node_modules/.bin/ncp create mode 100644 node_modules/forever/node_modules/utile/node_modules/async/.gitmodules create mode 100644 node_modules/forever/node_modules/utile/node_modules/async/.npmignore create mode 100644 node_modules/forever/node_modules/utile/node_modules/async/LICENSE create mode 100644 node_modules/forever/node_modules/utile/node_modules/async/Makefile create mode 100644 node_modules/forever/node_modules/utile/node_modules/async/README.md create mode 100644 node_modules/forever/node_modules/utile/node_modules/async/index.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/async/lib/async.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/async/package.json create mode 100644 node_modules/forever/node_modules/utile/node_modules/deep-equal/README.markdown create mode 100644 node_modules/forever/node_modules/utile/node_modules/deep-equal/example/cmp.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/deep-equal/index.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/deep-equal/package.json create mode 100644 node_modules/forever/node_modules/utile/node_modules/deep-equal/test/cmp.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/.npmignore create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/.travis.yml create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/LICENSE create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/README.md create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/lib/defaults.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/lib/inflect.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/lib/inflections.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/lib/methods.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/lib/native.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/lib/util.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/package.json create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/test/inflector/cases.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/test/inflector/inflections-test.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/test/inflector/methods-test.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/test/utils/array-test.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/i/test/utils/string-test.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/.npmignore create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/.travis.yml create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/LICENSE create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/examples/pow.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/index.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/package.json create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/readme.markdown create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/chmod.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/clobber.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/mkdirp.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/perm.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/perm_sync.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/race.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/rel.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/return.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/return_sync.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/root.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/sync.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/umask.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/mkdirp/test/umask_sync.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/.npmignore create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/.travis.yml create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/LICENSE.md create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/README.md create mode 100755 node_modules/forever/node_modules/utile/node_modules/ncp/bin/ncp create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/lib/ncp.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/package.json create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/fixtures/src/a create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/fixtures/src/b create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/fixtures/src/c create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/fixtures/src/d create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/fixtures/src/e create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/fixtures/src/f create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/fixtures/src/sub/a create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/fixtures/src/sub/b create mode 100644 node_modules/forever/node_modules/utile/node_modules/ncp/test/ncp-test.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/AUTHORS create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/LICENSE create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/README.md create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/fiber.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/package.json create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/rimraf.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/test/run.sh create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/test/setup.sh create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/test/test-async.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/test/test-fiber.js create mode 100644 node_modules/forever/node_modules/utile/node_modules/rimraf/test/test-sync.js create mode 100644 node_modules/forever/node_modules/utile/package.json create mode 100644 node_modules/forever/node_modules/utile/test/file-test.js create mode 100644 node_modules/forever/node_modules/utile/test/fixtures/read-json-file/config.json create mode 100644 node_modules/forever/node_modules/utile/test/fixtures/require-directory/directory/index.js create mode 100644 node_modules/forever/node_modules/utile/test/fixtures/require-directory/helloWorld.js create mode 100644 node_modules/forever/node_modules/utile/test/format-test.js create mode 100644 node_modules/forever/node_modules/utile/test/function-args-test.js create mode 100644 node_modules/forever/node_modules/utile/test/helpers/macros.js create mode 100644 node_modules/forever/node_modules/utile/test/random-string-test.js create mode 100644 node_modules/forever/node_modules/utile/test/require-directory-test.js create mode 100644 node_modules/forever/node_modules/utile/test/utile-test.js create mode 100644 node_modules/forever/node_modules/watch/LICENSE create mode 100644 node_modules/forever/node_modules/watch/main.js create mode 100755 node_modules/forever/node_modules/watch/package.json create mode 100644 node_modules/forever/node_modules/watch/readme.mkd create mode 100644 node_modules/forever/node_modules/watch/test/d/d/t create mode 100644 node_modules/forever/node_modules/watch/test/d/t create mode 100644 node_modules/forever/node_modules/watch/test/test_monitor.js create mode 100644 node_modules/forever/node_modules/watch/test/test_watchTree.js create mode 100644 node_modules/forever/node_modules/winston/.npmignore create mode 100644 node_modules/forever/node_modules/winston/.travis.yml create mode 100644 node_modules/forever/node_modules/winston/CHANGELOG.md create mode 100644 node_modules/forever/node_modules/winston/LICENSE create mode 100644 node_modules/forever/node_modules/winston/README.md create mode 100644 node_modules/forever/node_modules/winston/docs/transports.md create mode 100644 node_modules/forever/node_modules/winston/examples/couchdb.js create mode 100644 node_modules/forever/node_modules/winston/examples/custom-levels.js create mode 100644 node_modules/forever/node_modules/winston/examples/exception.js create mode 100644 node_modules/forever/node_modules/winston/examples/raw-mode.js create mode 100644 node_modules/forever/node_modules/winston/examples/webhook-post.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/common.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/config.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/config/cli-config.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/config/npm-config.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/config/syslog-config.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/container.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/exception.js create mode 100755 node_modules/forever/node_modules/winston/lib/winston/logger.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/transports.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/transports/console.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/transports/daily-rotate-file.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/transports/file.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/transports/http.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/transports/memory.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/transports/transport.js create mode 100644 node_modules/forever/node_modules/winston/lib/winston/transports/webhook.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/async/LICENSE create mode 100644 node_modules/forever/node_modules/winston/node_modules/async/README.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/async/component.json create mode 100755 node_modules/forever/node_modules/winston/node_modules/async/lib/async.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/async/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/cycle/README.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/cycle/cycle.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/cycle/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/eyes/LICENSE create mode 100644 node_modules/forever/node_modules/winston/node_modules/eyes/Makefile create mode 100644 node_modules/forever/node_modules/winston/node_modules/eyes/README.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/eyes/lib/eyes.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/eyes/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/eyes/test/eyes-test.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/LICENSE create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/README.md create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/aws-sign/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/aws-sign/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/cookie-jar/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/cookie-jar/jar.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/cookie-jar/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/cookie-jar/tests/run.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/cookie-jar/tests/test-cookie.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/cookie-jar/tests/test-cookiejar.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/forever-agent/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/forever-agent/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/License create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/Readme.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/lib/form_data.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/License create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-empty-string.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-is-stream-like.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/form-data/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/.npmignore create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/.travis.yml create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/LICENSE create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/Makefile create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/README.md create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/example/usage.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/images/hawk.png create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/images/logo.png create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/lib/client.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/lib/crypto.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/lib/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/lib/server.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/lib/uri.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/lib/utils.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/.npmignore create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/.travis.yml create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/LICENSE create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/Makefile create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/README.md create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/images/boom.png create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/lib/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/package.json create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/boom/test/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/.npmignore create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/.travis.yml create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/LICENSE create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/Makefile create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/README.md create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/lib/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/package.json create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/cryptiles/test/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/.npmignore create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/.travis.yml create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/LICENSE create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/Makefile create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/README.md create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/images/hoek.png create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/lib/escape.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/lib/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/test/escaper.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/test/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test1.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test2.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test3.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/.npmignore create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/.travis.yml create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/LICENSE create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/Makefile create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/README.md create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/examples/offset.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/examples/time.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/package.json create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/node_modules/sntp/test/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/package.json create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/test/client.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/test/crypto.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/test/index.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/test/readme.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/test/server.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/test/uri.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/hawk/test/utils.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/json-stringify-safe/LICENSE create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/json-stringify-safe/README.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/json-stringify-safe/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/json-stringify-safe/stringify.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/json-stringify-safe/test.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/mime/LICENSE create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/mime/README.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/mime/mime.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/mime/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/mime/test.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/mime/types/mime.types create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/mime/types/node.types create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/.npmignore create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/LICENSE.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/README.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/benchmark/README.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/benchmark/bench.sh create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/component.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/test/compare_v1.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/test/test.html create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/test/test.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/node-uuid/uuid.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/oauth-sign/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/oauth-sign/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/oauth-sign/test.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/.gitmodules create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/.npmignore create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/.travis.yml create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/History.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/Makefile create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/Readme.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/benchmark.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/component.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/examples.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/browser/expect.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/browser/index.html create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/browser/jquery.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/browser/mocha.css create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/browser/mocha.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/browser/qs.css create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/browser/qs.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/parse.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/qs/test/stringify.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/tunnel-agent/index.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/node_modules/tunnel-agent/package.json create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/package.json create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/googledoodle.jpg create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/run.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/server.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/squid.conf create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/server.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/ca/server.key create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/test.crt create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/ssl/test.key create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-basic-auth.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-body.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-defaults.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-digest-auth.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-errors.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-follow-all-303.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-follow-all.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-form.js create mode 100755 node_modules/forever/node_modules/winston/node_modules/request/tests/test-hawk.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-headers.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-httpModule.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-https-strict.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-https.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-oauth.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-params.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-piped-redirect.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-pipes.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-pool.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-protocol-changing-redirect.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-proxy.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-qs.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-redirect.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-s3.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-timeout.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-toJSON.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/test-tunnel.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/request/tests/unicycle.jpg create mode 100644 node_modules/forever/node_modules/winston/node_modules/stack-trace/.npmignore create mode 100644 node_modules/forever/node_modules/winston/node_modules/stack-trace/License create mode 100644 node_modules/forever/node_modules/winston/node_modules/stack-trace/Makefile create mode 100644 node_modules/forever/node_modules/winston/node_modules/stack-trace/Readme.md create mode 100644 node_modules/forever/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js create mode 100644 node_modules/forever/node_modules/winston/node_modules/stack-trace/package.json create mode 100644 node_modules/forever/node_modules/winston/package.json create mode 100644 node_modules/forever/node_modules/winston/test/cli-test.js create mode 100644 node_modules/forever/node_modules/winston/test/container-test.js create mode 100644 node_modules/forever/node_modules/winston/test/custom-timestamp-test.js create mode 100644 node_modules/forever/node_modules/winston/test/exception-test.js create mode 100644 node_modules/forever/node_modules/winston/test/fixtures/.gitkeep create mode 100644 node_modules/forever/node_modules/winston/test/fixtures/keys/agent2-cert.pem create mode 100644 node_modules/forever/node_modules/winston/test/fixtures/keys/agent2-key.pem create mode 100644 node_modules/forever/node_modules/winston/test/fixtures/logs/.gitkeep create mode 100644 node_modules/forever/node_modules/winston/test/fixtures/scripts/default-exceptions.js create mode 100644 node_modules/forever/node_modules/winston/test/fixtures/scripts/exit-on-error.js create mode 100644 node_modules/forever/node_modules/winston/test/fixtures/scripts/log-exceptions.js create mode 100644 node_modules/forever/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js create mode 100644 node_modules/forever/node_modules/winston/test/helpers.js create mode 100644 node_modules/forever/node_modules/winston/test/log-exception-test.js create mode 100644 node_modules/forever/node_modules/winston/test/log-rewriter-test.js create mode 100755 node_modules/forever/node_modules/winston/test/logger-test.js create mode 100644 node_modules/forever/node_modules/winston/test/transports/console-test.js create mode 100644 node_modules/forever/node_modules/winston/test/transports/daily-rotate-file-test.js create mode 100644 node_modules/forever/node_modules/winston/test/transports/file-maxfiles-test.js create mode 100644 node_modules/forever/node_modules/winston/test/transports/file-maxsize-test.js create mode 100644 node_modules/forever/node_modules/winston/test/transports/file-test.js create mode 100644 node_modules/forever/node_modules/winston/test/transports/memory-test.js create mode 100644 node_modules/forever/node_modules/winston/test/transports/transport.js create mode 100644 node_modules/forever/node_modules/winston/test/transports/webhook-test.js create mode 100644 node_modules/forever/node_modules/winston/test/winston-test.js create mode 100644 node_modules/forever/package.json create mode 100755 node_modules/forever/test/cli-test create mode 100644 node_modules/forever/test/core/tail-stopall-test.js create mode 100644 node_modules/forever/test/fixtures/log-on-interval.js create mode 100644 node_modules/forever/test/fixtures/server.js create mode 100644 node_modules/forever/test/fixtures/start-daemon.js create mode 100644 node_modules/forever/test/helpers/macros.js create mode 100644 node_modules/forever/test/helpers/mocks/child-process.js create mode 100644 node_modules/forever/test/helpers/mocks/monitor.js create mode 100644 node_modules/forever/test/helpers/mocks/stream.js create mode 100644 node_modules/forever/test/service/simple-test.js create mode 100644 node_modules/forever/test/worker/multiple-workers-test.js create mode 100644 node_modules/forever/test/worker/simple-test.js (limited to 'node_modules/forever') diff --git a/node_modules/forever/.npmignore b/node_modules/forever/.npmignore new file mode 100644 index 0000000..0a6526b --- /dev/null +++ b/node_modules/forever/.npmignore @@ -0,0 +1,6 @@ +test/*.log +node_modules/ +node_modules/* +npm-debug.log +.*.sw[op] +test/fixtures/*.log \ No newline at end of file diff --git a/node_modules/forever/.travis.yml b/node_modules/forever/.travis.yml new file mode 100644 index 0000000..1f79f76 --- /dev/null +++ b/node_modules/forever/.travis.yml @@ -0,0 +1,11 @@ +language: node_js +node_js: + - 0.8 + - 0.10 +branches: + only: + - master +notifications: + email: + - travis@nodejitsu.com + irc: "irc.freenode.org#nodejitsu" diff --git a/node_modules/forever/CHANGELOG.md b/node_modules/forever/CHANGELOG.md new file mode 100644 index 0000000..4541079 --- /dev/null +++ b/node_modules/forever/CHANGELOG.md @@ -0,0 +1,138 @@ +## CHANGELOG + +### Version 0.7.0 + +- Added experimental foreverd implementation for working with init.d, systemv, etc +- Expose `Monitor.killTree` for killing process trees for processes spawned by forever (default: true) +- Added commands for working with forever log files +- Added forever.tail() +- Update daemon to 0.3.2 +- Expose Monitor.spawnWith in Monitor.data + +### Version 0.6.9 + +- Add `--plain` option disabling CLI colors + +### Version 0.6.8 + +- Add --watch/-w command line option +- Add implementation to restart processes when a file changes + +### Version 0.6.7 + +- Replace sys module usages with util +- Update winston dependency to 0.4.x + +### Version 0.6.6 + +- Add options.hideEnv to hide default env values + +### Version 0.6.5 + +- Update `forever.Monitor.prototype.restart()` to allow force restarting of processes in less than `.minUptime` + +### Version 0.6.4 + +- Update forever.startServer() to support more liberal arguments. + +### Version 0.6.3 + +- Create `sockPath` if it does not exist already. +- When stopping only respond with those processes which have been stopped. + +### Version 0.6.2 + +- Display warning / error messages to the user when contacting UNIX sockets. + +### Version 0.6.1 + +- Fixed a bug where numbers in the file path caused forever to think +- Process variables are not always available, for example if you execute + +### Version 0.6.0 + +- Dont allow `-` in uuids generated by forever. +- When executing stopall, dont kill the current process. +- Added forever.debug for debugging purposes +- Keep processes silent on `forever restart` if requested. A couple of minor log formatting updates +- Update `forever list` to use cliff +- Added generic hooks for forever.Monitor +- Use default values for log file and pid file (prevents a process from being nuked by being daemonized) +- Default `minUptime` to 0 +- Create `options.uid` by default in `.startDaemon()` if it is already not provided +- Include uids in `forever list` +- Catch `uncaughtException` slightly more intelligently +- Forever no longer uses *.fvr files in-favor of a TCP server in each forever process started by the CLI. Programmatic usage will require an additional call to `forever.createServer()` explicitally in order for your application to be available in `forever list` or `forever.list()` +- Add `portfinder` dependency to package.json +- Expose `forever.columns` and update `forever.format` to generate results dynamically + +### Version 0.5.6 + +- Update winston dependency to 0.3.x + +### Version 0.5.5 + +- Remove .fvr file when a forever.Monitor child exits + +### Version 0.5.4 + +- Add --spinSleepTime to throttle instead of killing spinning scripts + +### Version 0.5.3 + +- Added `preferGlobal` option to package.json +- Improve forever when working with `-c` or `--command` + +### Version 0.5.2 + +- Print help when a valid action isn't given +- Batch the cleaning of *.fvr and *.pid files to avoid file descriptor overload +- Check if processes exist before returning in `.findByScript()`. + +### Version 0.5.1 + +- Readd eyes dependency + +### Version 0.5.0 + +- Added forever.logFilePath utility. +- Added forever.pidFilePath implementation +- Added append log implementation to CLI +- Fix for spawning multiple processes from a single forever process +- Added forever.config using nconf +- Better bookkeeping of *.fvr and *.pid files + +### Version 0.4.1 + +- Remove unnecessary eyes dependency + +### Version 0.4.1 + +- Update sourceDir option to check for file paths relative to root + +### Version 0.4.0 + +- Enable forever to track uptime +- Add `restart` command to forever.Monitor and CLI +- Ensure forever.load() is called on require() +- Better handling for for `-p` CLI option +- Enable options to be passed to child_process.spawn + +### Version 0.3.1 + +- Allow forever to start any script (not just node) from nodejs code +- Array shortcut to set command and options +- Check for scripts with fs.stat before running them +- Improved how *.fvr and *.pid files are managed by Forever CLI +- Ability to delete all historical logs from CLI via 'cleanlogs' +- Ability to stop script by name -- stops ALL scripts with that name. +- Display logfile in 'forever list'. +- Use process.kill() instead of exec('kill'). +- Emit 'save' event when persisting to disk. +- Emit 'start' event when starting a forever child +- Remove 'auto-save' feature from Forever.start() + +#### Breaking Changes + +- Push options hierarchy up one level. e.g. Forever.options.silent is now Forever.silent +- Only 'error' event now emits with an error. All other events simply emit data \ No newline at end of file diff --git a/node_modules/forever/LICENSE b/node_modules/forever/LICENSE new file mode 100644 index 0000000..dffa1ee --- /dev/null +++ b/node_modules/forever/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2010 Nodejitsu Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/README.md b/node_modules/forever/README.md new file mode 100644 index 0000000..52a6c29 --- /dev/null +++ b/node_modules/forever/README.md @@ -0,0 +1,141 @@ +# forever [![Build Status](https://secure.travis-ci.org/nodejitsu/forever.png)](http://travis-ci.org/nodejitsu/forever) + +A simple CLI tool for ensuring that a given script runs continuously (i.e. forever). + +## Installation + +``` bash + $ [sudo] npm install forever -g +``` + +**Note:** If you are using forever _programatically_ you should install [forever-monitor][0]. + +``` bash + $ cd /path/to/your/project + $ [sudo] npm install forever-monitor +``` + +## Usage +There are two distinct ways to use forever: through the command line interface, or by requiring the forever module in your own code. **Note:** If you are using forever _programatically_ you should install [forever-monitor][0]. + +### Using forever from the command line +You can use forever to run any kind of script continuously (whether it is written in node.js or not). The usage options are simple: + +``` + $ forever --help + usage: forever [action] [options] SCRIPT [script-options] + + Monitors the script specified in the current process or as a daemon + + actions: + start Start SCRIPT as a daemon + stop Stop the daemon SCRIPT + stopall Stop all running forever scripts + restart Restart the daemon SCRIPT + restartall Restart all running forever scripts + list List all running forever scripts + config Lists all forever user configuration + set Sets the specified forever config + clear Clears the specified forever config + logs Lists log files for all forever processes + logs Tails the logs for + columns add Adds the specified column to the output in `forever list` + columns rm Removed the specified column from the output in `forever list` + columns set Set all columns for the output in `forever list` + cleanlogs [CAREFUL] Deletes all historical forever log files + + options: + -m MAX Only run the specified script MAX times + -l LOGFILE Logs the forever output to LOGFILE + -o OUTFILE Logs stdout from child script to OUTFILE + -e ERRFILE Logs stderr from child script to ERRFILE + -p PATH Base path for all forever related files (pid files, etc.) + -c COMMAND COMMAND to execute (defaults to node) + -a, --append Append logs + -f, --fifo Stream logs to stdout + -n, --number Number of log lines to print + --pidFile The pid file + --sourceDir The source directory for which SCRIPT is relative to + --minUptime Minimum uptime (millis) for a script to not be considered "spinning" + --spinSleepTime Time to wait (millis) between launches of a spinning script. + --plain Disable command line colors + -d, --debug Forces forever to log debug output + -v, --verbose Turns on the verbose messages from Forever + -s, --silent Run the child script silencing stdout and stderr + -w, --watch Watch for file changes + --watchDirectory Top-level directory to watch from + -h, --help You're staring at it + + [Long Running Process] + The forever process will continue to run outputting log messages to the console. + ex. forever -o out.log -e err.log my-script.js + + [Daemon] + The forever process will run as a daemon which will make the target process start + in the background. This is extremely useful for remote starting simple node.js scripts + without using nohup. It is recommended to run start with -o -l, & -e. + ex. forever start -l forever.log -o out.log -e err.log my-daemon.js + forever stop my-daemon.js +``` + +There are [several examples][1] designed to test the fault tolerance of forever. Here's a simple usage example: + +``` bash + $ forever -m 5 examples/error-on-timer.js +``` + +## Using forever module from node.js +In addition to using a Forever object, the forever module also exposes some useful methods. Each method returns an instance of an EventEmitter which emits when complete. See the [forever cli commands][2] for sample usage. + +**Remark:** As of `forever@0.6.0` processes will not automatically be available in `forever.list()`. In order to get your processes into `forever.list()` or `forever list` you must instantiate the `forever` socket server: + +``` js + forever.startServer(child); +``` + +### forever.load (config) +_Synchronously_ sets the specified configuration (config) for the forever module. There are two important options: + +* root: Directory to put all default forever log files +* pidPath: Directory to put all forever *.pid files + +### forever.start (file, options) +Starts a script with forever. + +### forever.startDaemon (file, options) +Starts a script with forever as a daemon. WARNING: Will daemonize the current process. + +### forever.stop (index) +Stops the forever daemon script at the specified index. These indices are the same as those returned by forever.list(). This method returns an EventEmitter that raises the 'stop' event when complete. + +### forever.stopAll (format) +Stops all forever scripts currently running. This method returns an EventEmitter that raises the 'stopAll' event when complete. + +### forever.list (format, callback) +Returns a list of metadata objects about each process that is being run using forever. This method is synchronous and will return the list of metadata as such. Only processes which have invoked `forever.startServer()` will be available from `forever.list()` + +### forever.tail (target, options, callback) +Responds with the logs from the target script(s) from `tail`. There are two important options: + +* `length` (numeric): is is used as the `-n` parameter to `tail`. +* `stream` (boolean): is is used as the `-f` parameter to `tail`. + +### forever.cleanUp () +Cleans up any extraneous forever *.pid files that are on the target system. This method returns an EventEmitter that raises the 'cleanUp' event when complete. + +### forever.cleanLogsSync (processes) +Removes all log files from the root forever directory that do not belong to current running forever processes. + +## Run Tests + +``` bash + $ npm test +``` + +#### License: MIT +#### Author: [Charlie Robbins](http://github.com/indexzero) +#### Contributors: [Fedor Indutny](http://github.com/indutny), [James Halliday](http://substack.net/), [Charlie McConnell](http://github.com/avianflu), [Maciej Malecki](http://github.com/mmalecki), [John Lancaster](http://jlank.com) + +[0]: http://github.com/nodejitsu/forever-monitor +[1]: http://github.com/nodejitsu/forever-monitor/tree/master/examples +[2]: https://github.com/nodejitsu/forever/blob/master/lib/forever/cli.js diff --git a/node_modules/forever/bin/forever b/node_modules/forever/bin/forever new file mode 100755 index 0000000..5190d32 --- /dev/null +++ b/node_modules/forever/bin/forever @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../lib/forever').cli.start(); diff --git a/node_modules/forever/bin/foreverd b/node_modules/forever/bin/foreverd new file mode 100755 index 0000000..e7015ba --- /dev/null +++ b/node_modules/forever/bin/foreverd @@ -0,0 +1,4 @@ +#!/usr/bin/env node + +require('../lib/forever/service/cli').startCLI(); + diff --git a/node_modules/forever/bin/monitor b/node_modules/forever/bin/monitor new file mode 100755 index 0000000..2bd9fd9 --- /dev/null +++ b/node_modules/forever/bin/monitor @@ -0,0 +1,83 @@ +var fs = require('fs'), + path = require('path'), + forever = require(path.resolve(__dirname, '..', 'lib', 'forever')), + started; + +// +// ### @function (file, pid) +// #### @file {string} Location of the pid file. +// #### @pid {number} pid to write to disk. +// Write the pidFile to disk for later use +// +function writePid(file, pid) { + fs.writeFileSync(file, pid, 'utf8'); +} + +// +// ### @function start (options) +// #### @options {Object} Options for the `forever.Monitor` instance. +// Starts the child process and disconnects from the IPC channel. +// +function start(options) { + var script = process.argv[2], + monitor = new forever.Monitor(script, options); + + forever.logEvents(monitor); + monitor.start(); + + monitor.on('start', function () { + // + // This starts an nssocket server, which the forever CLI uses to + // communicate with this monitor process after it's detached. + // Without this, `forever list` won't show the process, even though it + // would still be running in the background unaffected. + // + forever.startServer(monitor); + + // + // Disconnect the IPC channel, letting this monitor's parent process know + // that the child has started successfully. + // + process.disconnect(); + + // + // Write the pidFile to disk + // + writePid(options.pidFile, monitor.child.pid); + }); + + // + // When the monitor restarts update the pid in the pidFile + // + monitor.on('restart', function () { + writePid(options.pidFile, monitor.child.pid); + }); + + + // + // When the monitor stops or exits, remove the pid and log files + // + function cleanUp(){ + try { + fs.unlinkSync(options.pidFile); + } + catch(e){} + } + monitor.on('stop', cleanUp); + monitor.on('exit', cleanUp); +} + +// +// When we receive the first message from the parent process, start +// an instance of `forever.Monitor` with the options supplied. +// +process.on('message', function (data) { + // + // TODO: Find out if this data will ever get split into two message events. + // + var options = JSON.parse(data.toString()); + if (!started) { + started = true; + start(options); + } +}); \ No newline at end of file diff --git a/node_modules/forever/lib/forever.js b/node_modules/forever/lib/forever.js new file mode 100644 index 0000000..290be83 --- /dev/null +++ b/node_modules/forever/lib/forever.js @@ -0,0 +1,907 @@ +/* + * forever.js: Top level include for the forever module + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var fs = require('fs'), + path = require('path'), + events = require('events'), + exec = require('child_process').exec, + spawn = require('child_process').spawn, + cliff = require('cliff'), + nconf = require('nconf'), + nssocket = require('nssocket'), + timespan = require('timespan'), + utile = require('utile'), + winston = require('winston'), + mkdirp = utile.mkdirp, + async = utile.async; + +var forever = exports; + +// +// Setup `forever.log` to be a custom `winston` logger. +// +forever.log = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)() + ] +}); + +forever.log.cli(); + +// +// Setup `forever out` for logEvents with `winston` custom logger. +// +forever.out = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)() + ] +}); + +// +// ### Export Components / Settings +// Export `version` and important Prototypes from `lib/forever/*` +// +forever.initialized = false; +forever.kill = require('forever-monitor').kill; +forever.checkProcess = require('forever-monitor').checkProcess; +forever.root = path.join(process.env.HOME || process.env.USERPROFILE || '/root', '.forever'); +forever.config = new nconf.File({ file: path.join(forever.root, 'config.json') }); +forever.Forever = forever.Monitor = require('forever-monitor').Monitor; +forever.Worker = require('./forever/worker').Worker; +forever.cli = require('./forever/cli'); + +// +// Expose version through `pkginfo` +// +require('pkginfo')(module, 'version'); + +// +// Expose the global forever service +// +forever.__defineGetter__('service', function () { + return require('./forever/service'); +}); + +// +// ### function getSockets (sockPath, callback) +// #### @sockPath {string} Path in which to look for UNIX domain sockets +// #### @callback {function} Continuation to pass control to when complete +// Attempts to read the files from `sockPath` if the directory does not exist, +// then it is created using `mkdirp`. +// +function getSockets(sockPath, callback) { + var sockets; + + try { + sockets = fs.readdirSync(sockPath); + } + catch (ex) { + if (ex.code !== 'ENOENT') { + return callback(ex); + } + + return mkdirp(sockPath, '0755', function (err) { + return err ? callback(err) : callback(null, []); + }); + } + + callback(null, sockets); +} + +// +// ### function getAllProcess (callback) +// #### @callback {function} Continuation to respond to when complete. +// Returns all data for processes managed by forever. +// +function getAllProcesses(callback) { + var sockPath = forever.config.get('sockPath'); + + function getProcess(name, next) { + var fullPath = path.join(sockPath, name), + socket = new nssocket.NsSocket(); + + socket.connect(fullPath, function (err) { + if (err) { + next(err); + } + + socket.dataOnce(['data'], function (data) { + data.socket = fullPath; + next(null, data); + socket.end(); + }); + + socket.send(['data']); + }); + + socket.on('error', function (err) { + if (err.code === 'ECONNREFUSED') { + fs.unlink(fullPath, function () { + next(); + }); + } + else { + next(); + } + }); + } + + getSockets(sockPath, function (err, sockets) { + if (err || (sockets && sockets.length === 0)) { + return callback(err); + } + + async.map(sockets, getProcess, function (err, processes) { + callback(processes.filter(Boolean)); + }); + }); +} + +// +// ### function getAllPids () +// Returns the set of all pids managed by forever. +// e.x. [{ pid: 12345, foreverPid: 12346 }, ...] +// +function getAllPids(processes) { + return !processes ? null : processes.map(function (proc) { + return { + pid: proc.pid, + foreverPid: proc.foreverPid + }; + }); +} + +function stopOrRestart(action, event, format, target) { + var emitter = new events.EventEmitter(), + results = []; + + function sendAction(proc, next) { + var socket = new nssocket.NsSocket(); + + socket.connect(proc.socket, function (err) { + if (err) { + next(err); + } + + socket.dataOnce([action, 'ok'], function (data) { + next(); + socket.end(); + }); + + socket.send([action]); + }); + + socket.on('error', function (err) { + next(err); + }); + } + + getAllProcesses(function (processes) { + var procs = processes; + + if (target !== undefined && target !== null) { + procs = forever.findByIndex(target, processes) + || forever.findByScript(target, processes) + || forever.findByUid(target, processes); + } + + if (procs && procs.length > 0) { + async.map(procs, sendAction, function (err, results) { + if (err) { + emitter.emit('error', err); + } + + emitter.emit(event, forever.format(format, procs)); + }); + } + else { + process.nextTick(function () { + emitter.emit('error', new Error('Cannot find forever process: ' + target)); + }); + } + }); + + return emitter; +} + +// +// ### function load (options, [callback]) +// #### @options {Object} Options to load into the forever module +// Initializes configuration for forever module +// +forever.load = function (options) { + // + // Setup the incoming options with default options. + // + options = options || {}; + options.loglength = options.loglength || 100; + options.logstream = options.logstream || false; + options.root = options.root || forever.root; + options.pidPath = options.pidPath || path.join(options.root, 'pids'); + options.sockPath = options.sockPath || path.join(options.root, 'sock'); + + // + // If forever is initalized and the config directories are identical + // simply return without creating directories + // + if (forever.initialized && forever.config.get('root') === options.root && + forever.config.get('pidPath') === options.pidPath) { + return; + } + + forever.config = new nconf.File({ file: path.join(options.root, 'config.json') }); + + // + // Try to load the forever `config.json` from + // the specified location. + // + try { + forever.config.loadSync(); + } + catch (ex) { } + + // + // Setup the columns for `forever list`. + // + options.columns = options.columns || forever.config.get('columns'); + if (!options.columns) { + options.columns = [ + 'uid', 'command', 'script', 'forever', 'pid', 'logfile', 'uptime' + ]; + } + + forever.config.set('root', options.root); + forever.config.set('pidPath', options.pidPath); + forever.config.set('sockPath', options.sockPath); + forever.config.set('loglength', options.loglength); + forever.config.set('logstream', options.logstream); + forever.config.set('columns', options.columns); + + // + // Setup timestamp to event logger + // + forever.out.transports.console.timestamp = forever.config.get('timestamp') === 'true'; + + // + // Attempt to see if `forever` has been configured to + // run in debug mode. + // + options.debug = options.debug || forever.config.get('debug') || false; + + if (options.debug) { + // + // If we have been indicated to debug this forever process + // then setup `forever._debug` to be an instance of `winston.Logger`. + // + forever._debug(); + } + + // + // Syncronously create the `root` directory + // and the `pid` directory for forever. Although there is + // an additional overhead here of the sync action. It simplifies + // the setup of forever dramatically. + // + function tryCreate(dir) { + try { + fs.mkdirSync(dir, '0755'); + } + catch (ex) { } + } + + tryCreate(forever.config.get('root')); + tryCreate(forever.config.get('pidPath')); + tryCreate(forever.config.get('sockPath')); + + // + // Attempt to save the new `config.json` for forever + // + try { + forever.config.saveSync(); + } + catch (ex) { } + + forever.initialized = true; +}; + +// +// ### @private function _debug () +// Sets up debugging for this forever process +// +forever._debug = function () { + var debug = forever.config.get('debug'); + + if (!debug) { + forever.config.set('debug', true); + forever.log.add(winston.transports.File, { + level: 'silly', + filename: path.join(forever.config.get('root'), 'forever.debug.log') + }); + } +}; + +// +// Ensure forever will always be loaded the first time it is required. +// +forever.load(); + +// +// ### function stat (logFile, script, callback) +// #### @logFile {string} Path to the log file for this script +// #### @logAppend {boolean} Optional. True Prevent failure if the log file exists. +// #### @script {string} Path to the target script. +// #### @callback {function} Continuation to pass control back to +// Ensures that the logFile doesn't exist and that +// the target script does exist before executing callback. +// +forever.stat = function (logFile, script, callback) { + var logAppend; + + if (arguments.length === 4) { + logAppend = callback; + callback = arguments[3]; + } + + fs.stat(script, function (err, stats) { + if (err) { + return callback(new Error('script ' + script + ' does not exist.')); + } + + return logAppend ? callback(null) : fs.stat(logFile, function (err, stats) { + return !err + ? callback(new Error('log file ' + logFile + ' exists. Use the -a or --append option to append log.')) + : callback(null); + }); + }); +}; + +// +// ### function start (script, options) +// #### @script {string} Location of the script to run. +// #### @options {Object} Configuration for forever instance. +// Starts a script with forever +// +forever.start = function (script, options) { + if (!options.uid) { + options.uid = options.uid || utile.randomString(4).replace(/^\-/, '_'); + } + + if (!options.logFile) { + options.logFile = forever.logFilePath(options.uid + '.log'); + } + + // + // Create the monitor, log events, and start. + // + var monitor = new forever.Monitor(script, options); + forever.logEvents(monitor); + return monitor.start(); +}; + +// +// ### function startDaemon (script, options) +// #### @script {string} Location of the script to run. +// #### @options {Object} Configuration for forever instance. +// Starts a script with forever as a daemon +// +forever.startDaemon = function (script, options) { + options = options || {}; + options.uid = options.uid || utile.randomString(4).replace(/^\-/, '_'); + options.logFile = forever.logFilePath(options.logFile || options.uid + '.log'); + options.pidFile = forever.pidFilePath(options.pidFile || options.uid + '.pid'); + + var monitor, outFD, errFD, workerPath; + + // + // This log file is forever's log file - the user's outFile and errFile + // options are not taken into account here. This will be an aggregate of all + // the app's output, as well as messages from the monitor process, where + // applicable. + // + outFD = fs.openSync(options.logFile, 'a'); + errFD = fs.openSync(options.logFile, 'a'); + monitorPath = path.resolve(__dirname, '..', 'bin', 'monitor'); + + monitor = spawn(process.execPath, [monitorPath, script], { + stdio: ['ipc', outFD, errFD], + detached: true + }); + + monitor.on('exit', function (code) { + console.error('Monitor died unexpectedly with exit code %d', code); + }); + + monitor.send(JSON.stringify(options)); + monitor.unref(); + return monitor; +}; + +// +// ### function startServer () +// #### @arguments {forever.Monitor...} A list of forever.Monitor instances +// Starts the `forever` HTTP server for communication with the forever CLI. +// **NOTE:** This will change your `process.title`. +// +forever.startServer = function () { + var args = Array.prototype.slice.call(arguments), + monitors = [], + callback; + + args.forEach(function (a) { + if (Array.isArray(a)) { + monitors = monitors.concat(a.filter(function (m) { + return m instanceof forever.Monitor; + })); + } + else if (a instanceof forever.Monitor) { + monitors.push(a); + } + else if (typeof a === 'function') { + callback = a; + } + }); + + async.map(monitors, function (monitor, next) { + var worker = new forever.Worker({ + monitor: monitor, + sockPath: forever.config.get('sockPath'), + exitOnStop: true + }); + + worker.start(function (err) { + return err ? next(err) : next(null, worker); + }); + }, callback || function () {}); +}; + + +// +// ### function stop (target, [format]) +// #### @target {string} Index or script name to stop +// #### @format {boolean} Indicated if we should CLI format the returned output. +// Stops the process(es) with the specified index or script name +// in the list of all processes +// +forever.stop = function (target, format) { + return stopOrRestart('stop', 'stop', format, target); +}; + +// +// ### function restart (target, format) +// #### @target {string} Index or script name to restart +// #### @format {boolean} Indicated if we should CLI format the returned output. +// Restarts the process(es) with the specified index or script name +// in the list of all processes +// +forever.restart = function (target, format) { + return stopOrRestart('restart', 'restart', format, target); +}; + +// +// ### function restartAll (format) +// #### @format {boolean} Value indicating if we should format output +// Restarts all processes managed by forever. +// +forever.restartAll = function (format) { + return stopOrRestart('restart', 'restartAll', format); +}; + +// +// ### function stopAll (format) +// #### @format {boolean} Value indicating if we should format output +// Stops all processes managed by forever. +// +forever.stopAll = function (format) { + return stopOrRestart('stop', 'stopAll', format); +}; + +// +// ### function list (format, procs, callback) +// #### @format {boolean} If set, will return a formatted string of data +// #### @callback {function} Continuation to respond to when complete. +// Returns the list of all process data managed by forever. +// +forever.list = function (format, callback) { + getAllProcesses(function (processes) { + callback(null, forever.format(format, processes)); + }); +}; + +// +// ### function tail (target, length, callback) +// #### @target {string} Target script to list logs for +// #### @options {length|stream} **Optional** Length of the logs to tail, boolean stream +// #### @callback {function} Continuation to respond to when complete. +// Responds with the latest `length` logs for the specified `target` process +// managed by forever. If no `length` is supplied then `forever.config.get('loglength`)` +// is used. +// +forever.tail = function (target, options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options.length = 0; + options.stream = false; + } + + length = options.length || forever.config.get('loglength'); + stream = options.stream || forever.config.get('logstream'); + + var that = this, + blanks = function (e, i, a) { return e !== '' }, + title = function (e, i, a) { return e.match(/^==>/) }, + args = ['-n', length], + logs; + + if (stream) args.unshift('-f'); + + function tailProcess(procs, next) { + var map = {}, + count = 0; + + procs.forEach(function (proc) { + args.push(proc.logFile); + map[proc.logFile] = { pid: proc.pid, file: proc.file }; + count++; + }); + + tail = spawn('tail', args, { + stdio: [null, 'pipe', 'pipe'], + }); + + tail.stdio[1].setEncoding('utf8'); + tail.stdio[2].setEncoding('utf8'); + + tail.stdio[1].on('data', function (data) { + chunk = data.split('\n\n'); + chunk.forEach(function (logs) { + var logs = logs.split('\n').filter(blanks), + file = logs.filter(title), + lines, + proc; + + file.length + ? proc = map[file[0].split(' ')[1]] + : proc = map[procs[0].logFile]; + + count === 1 + ? lines = logs + : lines = logs.slice(1); + + lines.forEach(function (line) { + callback(null, { file: proc.file, pid: proc.pid, line: line }); + }); + }); + }); + + tail.stdio[2].on('data', function (err) { + return callback(err); + }); + } + + getAllProcesses(function (processes) { + if (!processes) { + return callback(new Error('Cannot find forever process: ' + target)); + } + + var procs = forever.findByIndex(target, processes) + || forever.findByScript(target, processes); + + if (!procs) { + return callback(new Error('No logs available for process: ' + target)); + } + + tailProcess(procs, callback); + }); +}; + +// +// ### function findByIndex (index, processes) +// #### @index {string} Index of the process to find. +// #### @processes {Array} Set of processes to find in. +// Finds the process with the specified index. +// +forever.findByIndex = function (index, processes) { + var indexAsNum = parseInt(index, 10); + if (indexAsNum == index) { + var proc = processes && processes[indexAsNum]; + } + return proc ? [proc] : null; +}; + +// +// ### function findByScript (script, processes) +// #### @script {string} The name of the script to find. +// #### @processes {Array} Set of processes to find in. +// Finds the process with the specified script name. +// +forever.findByScript = function (script, processes) { + if (!processes) return null; + + var procs = processes.filter(function (p) { + return p.file === script; + }); + + if (procs.length === 0) procs = null; + + return procs; +}; + +// +// ### function findByUid (uid, processes) +// #### @uid {string} The uid of the process to find. +// #### @processes {Array} Set of processes to find in. +// Finds the process with the specified uid. +// +forever.findByUid = function (script, processes) { + return !processes + ? null + : processes.filter(function (p) { + return p.uid === script; + }); +}; + +// +// ### function format (format, procs) +// #### @format {Boolean} Value indicating if processes should be formatted +// #### @procs {Array} Processes to format +// Returns a formatted version of the `procs` supplied based on the column +// configuration in `forever.config`. +// +forever.format = function (format, procs) { + if (!procs || procs.length === 0) { + return null; + } + + var index = 0, + columns = forever.config.get('columns'), + rows = [[' '].concat(columns)], + formatted; + + function mapColumns(prefix, mapFn) { + return [prefix].concat(columns.map(mapFn)); + } + + if (format) { + // + // Iterate over the procs to see which has the + // longest options string + // + procs.forEach(function (proc) { + rows.push(mapColumns('[' + index + ']', function (column) { + return forever.columns[column] + ? forever.columns[column].get(proc) + : 'MISSING'; + })); + + index++; + }); + + formatted = cliff.stringifyRows(rows, mapColumns('white', function (column) { + return forever.columns[column] + ? forever.columns[column].color + : 'white'; + })); + } + + return format ? formatted : procs; +}; + +// +// ### function cleanUp () +// Utility function for removing excess pid and +// config, and log files used by forever. +// +forever.cleanUp = function (cleanLogs, allowManager) { + var emitter = new events.EventEmitter(), + pidPath = forever.config.get('pidPath'); + + getAllProcesses(function (processes) { + if (cleanLogs) { + forever.cleanLogsSync(processes); + } + + function unlinkProcess(proc, done) { + fs.unlink(path.join(pidPath, proc.uid + '.pid'), function () { + // + // Ignore errors (in case the file doesnt exist). + // + + if (cleanLogs && proc.logFile) { + // + // If we are cleaning logs then do so if the process + // has a logfile. + // + return fs.unlink(proc.logFile, function () { + done(); + }); + } + + done(); + }); + } + + function cleanProcess(proc, done) { + if (proc.child && proc.manager) { + return done(); + } + else if (!proc.child && !proc.manager + || (!proc.child && proc.manager && allowManager) + || proc.dead) { + return unlinkProcess(proc, done); + } + + // + // If we have a manager but no child, wait a moment + // in-case the child is currently restarting, but **only** + // if we have not already waited for this process + // + if (!proc.waited) { + proc.waited = true; + return setTimeout(function () { + checkProcess(proc, done); + }, 500); + } + + done(); + } + + function checkProcess(proc, next) { + proc.child = forever.checkProcess(proc.pid); + proc.manager = forever.checkProcess(proc.foreverPid); + cleanProcess(proc, next); + } + + if (processes && processes.length > 0) { + (function cleanBatch(batch) { + async.forEach(batch, checkProcess, function () { + return processes.length > 0 + ? cleanBatch(processes.splice(0, 10)) + : emitter.emit('cleanUp'); + }); + })(processes.splice(0, 10)); + } + else { + process.nextTick(function () { + emitter.emit('cleanUp'); + }); + } + }); + + return emitter; +}; + +// +// ### function cleanLogsSync (processes) +// #### @processes {Array} The set of all forever processes +// Removes all log files from the root forever directory +// that do not belong to current running forever processes. +// +forever.cleanLogsSync = function (processes) { + var root = forever.config.get('root'), + files = fs.readdirSync(root), + running, + runningLogs; + + running = processes && processes.filter(function (p) { + return p && p.logFile; + }); + + runningLogs = running && running.map(function (p) { + return p.logFile.split('/').pop(); + }); + + files.forEach(function (file) { + if (/\.log$/.test(file) && (!runningLogs || runningLogs.indexOf(file) === -1)) { + fs.unlinkSync(path.join(root, file)); + } + }); +}; + +// +// ### function logFilePath (logFile) +// #### @logFile {string} Log file path +// Determines the full logfile path name +// +forever.logFilePath = function (logFile, uid) { + return logFile && (logFile[0] === '/' || logFile[1] === ':') + ? logFile + : path.join(forever.config.get('root'), logFile || (uid || 'forever') + '.log'); +}; + +// +// ### function pidFilePath (pidFile) +// #### @logFile {string} Pid file path +// Determines the full pid file path name +// +forever.pidFilePath = function (pidFile) { + return pidFile && (pidFile[0] === '/' || pidFile[1] === ':') + ? pidFile + : path.join(forever.config.get('pidPath'), pidFile); +}; + +// +// ### @function logEvents (monitor) +// #### @monitor {forever.Monitor} Monitor to log events for +// Logs important restart and error events to `console.error` +// +forever.logEvents = function (monitor) { + monitor.on('watch:error', function (info) { + forever.out.error(info.message); + forever.out.error(info.error); + }); + + monitor.on('watch:restart', function (info) { + forever.out.error('restarting script because ' + info.file + ' changed') + }); + + monitor.on('restart', function () { + forever.out.error('Forever restarting script for ' + monitor.times + ' time') + }); + + monitor.on('exit:code', function (code, signal) { + forever.out.error(code + ? 'Forever detected script exited with code: ' + code + : 'Forever detected script was killed by signal: ' + signal); + }); +}; + +// +// ### @columns {Object} +// Property descriptors for accessing forever column information +// through `forever list` and `forever.list()` +// +forever.columns = { + uid: { + color: 'white', + get: function (proc) { + return proc.uid; + } + }, + command: { + color: 'grey', + get: function (proc) { + return (proc.command || 'node').grey; + } + }, + script: { + color: 'grey', + get: function (proc) { + return [proc.file].concat(proc.options).join(' ').grey; + } + }, + forever: { + color: 'white', + get: function (proc) { + return proc.foreverPid; + } + }, + pid: { + color: 'white', + get: function (proc) { + return proc.pid; + } + }, + logfile: { + color: 'magenta', + get: function (proc) { + return proc.logFile ? proc.logFile.magenta : ''; + } + }, + dir: { + color: 'grey', + get: function (proc) { + return proc.sourceDir.grey; + } + }, + uptime: { + color: 'yellow', + get: function (proc) { + return timespan.fromDates(new Date(proc.ctime), new Date()).toString().yellow; + } + } +}; diff --git a/node_modules/forever/lib/forever/cli.js b/node_modules/forever/lib/forever/cli.js new file mode 100644 index 0000000..01107b2 --- /dev/null +++ b/node_modules/forever/lib/forever/cli.js @@ -0,0 +1,564 @@ +/* + * cli.js: Handlers for the forever CLI commands. + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var fs = require('fs'), + path = require('path'), + util = require('util'), + colors = require('colors'), + cliff = require('cliff'), + flatiron = require('flatiron'), + forever = require('../forever'); + +var cli = exports; + +var help = [ + 'usage: forever [action] [options] SCRIPT [script-options]', + '', + 'Monitors the script specified in the current process or as a daemon', + '', + 'actions:', + ' start Start SCRIPT as a daemon', + ' stop Stop the daemon SCRIPT', + ' stopall Stop all running forever scripts', + ' restart Restart the daemon SCRIPT', + ' restartall Restart all running forever scripts', + ' list List all running forever scripts', + ' config Lists all forever user configuration', + ' set Sets the specified forever config ', + ' clear Clears the specified forever config ', + ' logs Lists log files for all forever processes', + ' logs Tails the logs for ', + ' columns add Adds the specified column to the output in `forever list`', + ' columns rm Removed the specified column from the output in `forever list`', + ' columns set Set all columns for the output in `forever list`', + ' cleanlogs [CAREFUL] Deletes all historical forever log files', + '', + 'options:', + ' -m MAX Only run the specified script MAX times', + ' -l LOGFILE Logs the forever output to LOGFILE', + ' -o OUTFILE Logs stdout from child script to OUTFILE', + ' -e ERRFILE Logs stderr from child script to ERRFILE', + ' -p PATH Base path for all forever related files (pid files, etc.)', + ' -c COMMAND COMMAND to execute (defaults to node)', + ' -a, --append Append logs', + ' -f, --fifo Stream logs to stdout', + ' -n, --number Number of log lines to print', + ' --pidFile The pid file', + ' --sourceDir The source directory for which SCRIPT is relative to', + ' --minUptime Minimum uptime (millis) for a script to not be considered "spinning"', + ' --spinSleepTime Time to wait (millis) between launches of a spinning script.', + ' --colors --no-colors will disable output coloring', + ' --plain alias of --no-colors', + ' -d, --debug Forces forever to log debug output', + ' -v, --verbose Turns on the verbose messages from Forever', + ' -s, --silent Run the child script silencing stdout and stderr', + ' -w, --watch Watch for file changes', + ' --watchDirectory Top-level directory to watch from', + ' --watchIgnore To ignore pattern when watch is enabled (multiple option is allowed)', + ' -h, --help You\'re staring at it', + '', + '[Long Running Process]', + ' The forever process will continue to run outputting log messages to the console.', + ' ex. forever -o out.log -e err.log my-script.js', + '', + '[Daemon]', + ' The forever process will run as a daemon which will make the target process start', + ' in the background. This is extremely useful for remote starting simple node.js scripts', + ' without using nohup. It is recommended to run start with -o -l, & -e.', + ' ex. forever start -l forever.log -o out.log -e err.log my-daemon.js', + ' forever stop my-daemon.js', + '' +]; + +var app = flatiron.app; + +var actions = [ + 'start', + 'stop', + 'stopall', + 'restart', + 'restartall', + 'list', + 'config', + 'set', + 'clear', + 'logs', + 'columns', + 'cleanlogs' +]; + +var argvOptions = cli.argvOptions = { + 'command': {alias: 'c'}, + 'errFile': {alias: 'e'}, + 'logFile': {alias: 'l'}, + 'append': {alias: 'a', boolean: true}, + 'fifo': {alias: 'f', boolean: false}, + 'number': {alias: 'n'}, + 'max': {alias: 'm'}, + 'outFile': {alias: 'o'}, + 'path': {alias: 'p'}, + 'help': {alias: 'h'}, + 'silent': {alias: 's', boolean: true}, + 'verbose': {alias: 'v', boolean: true}, + 'watch': {alias: 'w', boolean: true}, + 'debug': {alias: 'd', boolean: true}, + 'plain': {boolean: true} +}; + +app.use(flatiron.plugins.cli, { + argv: argvOptions, + usage: help +}); + +var reserved = ['root', 'pidPath']; + +// +// ### @private function (file, options, callback) +// #### @file {string} Target script to start +// #### @options {Object} Options to start the script with +// #### @callback {function} Continuation to respond to when complete. +// Helper function that sets up the pathing for the specified `file` +// then stats the appropriate files and responds. +// +function tryStart(file, options, callback) { + var fullLog, fullScript; + + if (options.path) forever.config.set('root', options.path); + fullLog = forever.logFilePath(options.logFile, options.uid); + fullScript = path.join(options.sourceDir, file); + + forever.stat(fullLog, fullScript, options.append, function (err) { + if (err) { + forever.log.error('Cannot start forever'); + forever.log.error(err.message); + process.exit(-1); + } + + callback(); + }); +} + +// +// ### @private function updateConfig (updater) +// #### @updater {function} Function which updates the forever config +// Helper which runs the specified `updater` and then saves the forever +// config to `forever.config.get('root')`. +// +function updateConfig(updater) { + updater(); + forever.config.save(function (err) { + if (err) { + return forever.log.error('Error saving config: ' + err.message); + } + + cli.config(); + var configFile = path.join(forever.config.get('root'), 'config.json'); + forever.log.info('Forever config saved: ' + configFile.yellow); + }); +} + +// +// ### @private function checkColumn (name) +// #### @name {string} Column to check +// Checks if column `name` exists +// +function checkColumn(name) { + if (!forever.columns[name]) { + forever.log.error('Unknown column: ' + name.magenta); + return false; + } + return true; +} + +// +// ### function getOptions (file) +// #### @file {string} File to run. **Optional** +// Returns `options` object for use with `forever.start` and +// `forever.startDaemon` +// +var getOptions = cli.getOptions = function (file) { + var options = {}; + // + // First isolate options which should be passed to file + // + options.options = process.argv.splice(process.argv.indexOf(file) + 1); + + // + // Now we have to force optimist to reparse command line options because + // we've removed some before. + // + app.config.stores.argv.store = {}; + app.config.use('argv', argvOptions); + + [ + 'pidFile', 'logFile', 'errFile', 'watch', 'minUptime', 'append', + 'silent', 'outFile', 'max', 'command', 'path', 'spinSleepTime', + 'sourceDir', 'uid', 'watchDirectory', 'watchIgnore', 'killTree', 'killSignal' + ].forEach(function (key) { + options[key] = app.config.get(key); + }); + + options.watchIgnore = options.watchIgnore || []; + options.watchIgnorePatterns = !Array.isArray(options.watchIgnore) + ? options.watchIgnore + : [options.watchIgnore]; + + if (!options.minUptime) { + forever.log.warn('--minUptime not set. Defaulting to: 1000ms'); + options.minUptime = 1000; + } + + if (!options.spinSleepTime) { + forever.log.warn([ + '--spinSleepTime not set. Your script', + 'will exit if it does not stay up for', + 'at least ' + options.minUptime + 'ms' + ].join(' ')); + } + + options.sourceDir = options.sourceDir || (file && file[0] !== '/' ? process.cwd() : '/'); + if (options.sourceDir) { + options.spawnWith = {cwd: options.sourceDir}; + } + + return options; +} + +// +// ### function cleanLogs +// Deletes all historical forever log files +// +app.cmd('cleanlogs', cli.cleanLogs = function () { + forever.log.silly('Tidying ' + forever.config.get('root')); + forever.cleanUp(true).on('cleanUp', function () { + forever.log.silly(forever.config.get('root') + ' tidied.'); + }); +}); + +// +// ### function start (file) +// #### @file {string} Location of the script to spawn with forever +// Starts a forever process for the script located at `file` as daemon +// process. +// +app.cmd(/start (.+)/, cli.startDaemon = function () { + var file = app.argv._[1], + options = getOptions(file); + + forever.log.info('Forever processing file: ' + file.grey); + tryStart(file, options, function () { + forever.startDaemon(file, options); + }); +}); + +// +// ### function stop (file) +// #### @file {string} Target forever process to stop +// Stops the forever process specified by `file`. +// +app.cmd(/stop (.+)/, cli.stop = function (file) { + var runner = forever.stop(file, true); + + runner.on('stop', function (process) { + forever.log.info('Forever stopped process:'); + forever.log.data(process); + }); + + runner.on('error', function (err) { + forever.log.error('Forever cannot find process with index: ' + file); + process.exit(1); + }); +}); + +// +// ### function stopall () +// Stops all currently running forever processes. +// +app.cmd('stopall', cli.stopall = function () { + var runner = forever.stopAll(true); + runner.on('stopAll', function (processes) { + if (processes) { + forever.log.info('Forever stopped processes:'); + processes.split('\n').forEach(function (line) { + forever.log.data(line); + }); + } + else { + forever.log.info('No forever processes running'); + } + }); + + runner.on('error', function () { + forever.log.info('No forever processes running'); + process.exit(1); + }); +}); + +// +// ### function restartall () +// Restarts all currently running forever processes. +// +app.cmd('restartall', cli.restartAll = function () { + var runner = forever.restartAll(true); + runner.on('restartAll', function (processes) { + if (processes) { + forever.log.info('Forever restarted processes:'); + processes.split('\n').forEach(function (line) { + forever.log.data(line); + }); + } + else { + forever.log.info('No forever processes running'); + } + }); + + runner.on('error', function () { + forever.log.info('No forever processes running'); + }); +}); + +// +// ### function restart (file) +// #### @file {string} Target process to restart +// Restarts the forever process specified by `file`. +// +app.cmd(/restart (.+)/, cli.restart = function (file) { + var runner = forever.restart(file, true); + runner.on('restart', function (processes) { + if (processes) { + forever.log.info('Forever restarted process(es):'); + processes.split('\n').forEach(function (line) { + forever.log.data(line); + }); + } + else { + forever.log.info('No forever processes running'); + } + }); + + runner.on('error', function (err) { + forever.log.error('Error restarting process: ' + file.grey); + forever.log.error(err.message); + process.exit(1); + }); +}); + +// +// ### function list () +// Lists all currently running forever processes. +// +app.cmd('list', cli.list = function () { + forever.list(true, function (err, processes) { + if (processes) { + forever.log.info('Forever processes running'); + processes.split('\n').forEach(function (line) { + forever.log.data(line); + }); + } + else { + forever.log.info('No forever processes running'); + } + }); +}); + +// +// ### function config () +// Lists all of the configuration in `~/.forever/config.json`. +// +app.cmd('config', cli.config = function () { + var keys = Object.keys(forever.config.store), + conf = cliff.inspect(forever.config.store); + + if (keys.length <= 2) { + conf = conf.replace(/\{\s/, '{ \n') + .replace(/\}/, '\n}') + .replace('\\033[90m', ' \\033[90m') + .replace(/, /ig, ',\n '); + } + else { + conf = conf.replace(/\n\s{4}/ig, '\n '); + } + + conf.split('\n').forEach(function (line) { + forever.log.data(line); + }); +}); + +// +// ### function set (key, value) +// #### @key {string} Key to set in forever config +// #### @value {string} Value to set for `key` +// Sets the specified `key` / `value` pair in the +// forever user config. +// +app.cmd(/set ([\w-_]+) (.+)/, cli.set = function (key, value) { + updateConfig(function () { + forever.log.info('Setting forever config: ' + key.grey); + forever.config.set(key, value); + }); +}); + +// +// ### function clear (key) +// #### @key {string} Key to remove from `~/.forever/config.json` +// Removes the specified `key` from the forever user config. +// +app.cmd('clear :key', cli.clear = function (key) { + if (reserved.indexOf(key) !== -1) { + forever.log.warn('Cannot clear reserved config: ' + key.grey); + forever.log.warn('Use `forever set ' + key + '` instead'); + return; + } + + updateConfig(function () { + forever.log.info('Clearing forever config: ' + key.grey); + forever.config.clear(key); + }); +}); + +// +// ### function logs (target) +// #### @target {string} Target script or index to list logs for +// Displays the logs using `tail` for the specified `target`. +// +app.cmd('logs :index', cli.logs = function (index) { + var options = { + stream: app.argv.fifo, + length: app.argv.number + }; + + forever.tail(index, options, function (err, log) { + if (err) { + return forever.log.error(err.message); + } + + forever.log.data(log.file.magenta + ':' + log.pid + ' - ' + log.line); + + }); +}); + +// +// ### function logFiles () +// Display log files for all running forever processes. +// +app.cmd('logs', cli.logFiles = function (index) { + if (typeof index !== 'undefined') { + return; + } + + var rows = [[' ', 'script', 'logfile']]; + index = 0; + + forever.list(false, function (err, processes) { + if (!processes) { + return forever.log.warn('No forever logfiles in ' + forever.config.get('root').magenta); + } + + forever.log.info('Logs for running Forever processes'); + rows = rows.concat(processes.map(function (proc) { + return ['[' + index++ + ']', proc.file.grey, proc.logFile.magenta]; + })); + + cliff.putRows('data', rows, ['white', 'grey', 'magenta']); + }); +}); + + +app.cmd('columns add :name', cli.addColumn = function (name) { + if (checkColumn(name)) { + var columns = forever.config.get('columns'); + + if (~columns.indexOf(name)) { + return forever.log.warn(name.magenta + ' already exists in forever'); + } + + forever.log.info('Adding column: ' + name.magenta); + columns.push(name); + + forever.config.set('columns', columns); + forever.config.saveSync(); + } +}); + +app.cmd('columns rm :name', cli.rmColumn = function (name) { + if (checkColumn(name)) { + var columns = forever.config.get('columns'); + + if (!~columns.indexOf(name)) { + return forever.log.warn(name.magenta + ' doesn\'t exist in forever'); + } + + forever.log.info('Removing column: ' + name.magenta); + columns.splice(columns.indexOf(name), 1); + + forever.config.set('columns', columns); + forever.config.saveSync(); + } +}); + +app.cmd(/columns set (.*)/, cli.setColumns = function (columns) { + forever.log.info('Setting columns: ' + columns.magenta); + + forever.config.set('columns', columns.split(' ')); + forever.config.saveSync(); +}); + +// +// ### function help () +// Shows help +// +app.cmd('help', cli.help = function () { + util.puts(help.join('\n')); +}); + +// +// ### function start (file) +// #### @file {string} Location of the script to spawn with forever +// Starts a forever process for the script located at `file` as non-daemon +// process. +// +// Remark: this regex matches everything. It has to be added at the end to +// make executing other commands possible. +// +cli.run = function () { + var file = app.argv._[0], + options = getOptions(file); + + tryStart(file, options, function () { + var monitor = forever.start(file, options); + monitor.on('start', function () { + forever.startServer(monitor); + }); + }); +}; + +cli.start = function () { + if (app.argv.v || app.argv.version) { + return console.log('v' + forever.version); + } + + // + // Check for --no-colors/--colors and --plain option + // + if ((typeof app.argv.colors !== 'undefined' && !app.argv.colors) || app.argv.plain) { + colors.mode = 'none'; + } + + if (app.config.get('help')) { + return util.puts(help.join('\n')); + } + + app.init(function () { + if (app.argv._.length && actions.indexOf(app.argv._[0]) === -1) { + return cli.run(); + } + + app.start(); + }); +}; + diff --git a/node_modules/forever/lib/forever/service/adapters/adapter.js b/node_modules/forever/lib/forever/service/adapters/adapter.js new file mode 100644 index 0000000..bf23411 --- /dev/null +++ b/node_modules/forever/lib/forever/service/adapters/adapter.js @@ -0,0 +1,96 @@ +/* + * adapter.js: Abstract base class used by foreverd service adapters + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var Adapter = module.exports = function Adapter(service) { + this.service = service; +}; + +// +// This should install assets to appropriate places for initialization, +// configuration, and storage +// +// The script will be used on startup to load Service +// +// Service should listen on something that the management events +// can respond to in full duplex +// +// The installed adapter should send the following events in nssocket protocol +// to the Service and invoke methods as appropriate +// +Adapter.prototype.install = function install() { + throw new Error('not implemented'); +}; + +// +// This should do a rollback of install completely except for logs +// +Adapter.prototype.uninstall = function uninstall() { + throw new Error('not implemented'); +}; + +// +// This should call back with an array of [{file:...,options:...},] to pass to Monitors +// this will be invoked when foreverd is created (not started) +// +Adapter.prototype.load = function load(callback) { + throw new Error('not implemented'); +}; + +// +// This should tell the OS to start the service +// this will not start any applications +// make sure the adapter is installed and sending events to foreverd's listener +// +Adapter.prototype.start = function start(monitors) { + throw new Error('not implemented'); +}; + +// +// This should tell the OS to start the service +// this will not stop any applications +// make sure the adapter is installed and sending events to foreverd's listener +// +Adapter.prototype.stop = function stop(monitors) { + throw new Error('not implemented'); +}; + +// +// This should tell the OS to reply with info about applications in the service +// this will not change any applications +// make sure the adapter is installed and sending events to foreverd's listener +// +Adapter.prototype.status = function status(monitors) { + throw new Error('not implemented'); +}; + +// +// This should tell the OS to restart the service +// this will not restart any applications +// make sure the adapter is installed and sending events to foreverd's listener +// +Adapter.prototype.restart = function restart(monitors) { + throw new Error('not implemented'); +}; + +// +// This should tell the OS to pause the service +// this will prevent any addition or removal of applications +// make sure the adapter is installed and sending events to foreverd's listener +// +Adapter.prototype.pause = function pause(monitors) { + throw new Error('not implemented'); +}; + +// +// This should tell the OS to resume the service +// this will enable any addition or removal of applications +// make sure the adapter is installed and sending events to foreverd's listener +// +Adapter.prototype.resume = function resume(monitors) { + throw new Error('not implemented'); +}; \ No newline at end of file diff --git a/node_modules/forever/lib/forever/service/adapters/initd/index.js b/node_modules/forever/lib/forever/service/adapters/initd/index.js new file mode 100644 index 0000000..1162d37 --- /dev/null +++ b/node_modules/forever/lib/forever/service/adapters/initd/index.js @@ -0,0 +1,9 @@ +/* + * index.js: Top-level include for the init.d foreverd service adapter. + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +module.exports = require('../systemv'); \ No newline at end of file diff --git a/node_modules/forever/lib/forever/service/adapters/systemv/foreverd b/node_modules/forever/lib/forever/service/adapters/systemv/foreverd new file mode 100644 index 0000000..bdd9a5c --- /dev/null +++ b/node_modules/forever/lib/forever/service/adapters/systemv/foreverd @@ -0,0 +1,82 @@ +#!/bin/bash +# +# initd-example Node init.d +# +# chkconfig: 345 80 20 +# description: Node init.d example +# processname: node +# pidfile: /var/run/initd-example.pid +# logfile: /var/log/initd-example.log +# + +# Source function library. +. /lib/lsb/init-functions +PATH=$PATH:/usr/local/bin + +NAME=foreverd +pidfile=/var/run/$NAME.pid +logfile=/var/log/$NAME.log +forever_dir=/var/local/forever # Forever root directory. + +node=node +foreverd=`which foreverd` +awk=awk +sed=sed + +start() { + echo "Starting $NAME: " + + if [ "$id" = "" ]; then + # Launch the application + $foreverd -p $forever_dir run + else + echo "Instance already running" + fi + RETVAL=$? +} + +restart() { + echo -n "Restarting $NAME: " + if [ "$id" != "" ]; then + $foreverd -p $forever_dir restart + RETVAL=$? + else + start + fi +} + +stop() { + echo -n "Shutting down $NAME: " + if [ "$id" != "" ]; then + $foreverd -p $forever_dir stop + else + echo "Instance is not running"; + fi + RETVAL=$? +} + +getForeverId() { + local pid=$(pidofproc -p $pidfile) + $foreverd list -p $forever_dir | $sed -e 's/\x1b\[[0-9; ]*m//g' | $awk "\$4 == \"$pid]\" { gsub(/[\[\]]/, \"\", \$1); print \$1; }" +} +id=$(getForeverId) + +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + $foreverd -p $forever_dir list + ;; + restart) + restart + ;; + *) + echo "Usage: {start|stop|status|restart}" + exit 1 + ;; +esac +exit $RETVAL diff --git a/node_modules/forever/lib/forever/service/adapters/systemv/index.js b/node_modules/forever/lib/forever/service/adapters/systemv/index.js new file mode 100644 index 0000000..2877b77 --- /dev/null +++ b/node_modules/forever/lib/forever/service/adapters/systemv/index.js @@ -0,0 +1,199 @@ +/* + * index.js: Top-level include for the systemv foreverd service adapter + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var fs = require('fs'), + util = require('util'), + path = require('path'), + spawn = require('child_process').spawn, + nssocket = require('nssocket'), + forever = require('../../../../forever'), + Adapter = require('../adapter'); + +// +// Classic init.d script adapter +// Sometimes called inittab, but its origin is called systemv +// +var SystemVAdapter = module.exports = function SystemVAdapter(service) { + Adapter.call(this, service); + this.daemonized = false; +}; + +util.inherits(SystemVAdapter, Adapter); + +SystemVAdapter.prototype.install = function install(callback) { + // + // Copy the init.d script to the right location + // TODO Distribution fixes? + // + forever.config.set('root', path.join('/var', 'local', 'foreverd')); + var initdPath = path.join('/etc', 'init.d', 'foreverd'), + script, + target; + + try { + fs.mkdirSync(forever.config.get('root'), '0777'); + fs.mkdirSync(path.join(forever.config.get('root'), 'services'), '0777'); + } + catch (e) { + if (e.code !== 'EEXIST') { + return callback && callback(e); + } + } + + try { + script = fs.createReadStream(path.join(__dirname, 'foreverd')); + target = fs.createWriteStream(initdPath, { flags: 'w', mode: '0777' }); + + script.pipe(target); + script.on('end', function () { + var directories = fs.readdirSync('/etc'); + directories.forEach(function (directory) { + var match = directory.match(/^rc(\d+)\.d$/), + killOrStart; + + if (match) { + killOrStart = { 0: true, 1: true, 6: true }[match[1]] ? 'K' : 'S'; + + try { + fs.symlinkSync(initdPath, path.join('/etc', directory, killOrStart + '20foreverd')); + } + catch (e) { + if (e.code !== 'EEXIST') { + return callback && callback(e); + } + } + } + }); + + return callback && callback(); + }); + } + catch (e) { + if (e.code !== 'EEXIST') { + return callback && callback(e); + } + } +}; + +// +// +// +SystemVAdapter.prototype.load = function load(callback) { + forever.config.set('root', path.join('/var', 'local', 'foreverd')); + var serviceFiles = fs.readdirSync(path.join(forever.config.get('root'), 'services')), + services = []; + + if (serviceFiles.length !== 0) { + serviceFiles.forEach(function loadServiceFiles(serviceFile, index) { + var serviceFilePath = path.join(forever.config.get('root'), 'services', serviceFile), + service = JSON.parse(fs.readFileSync(serviceFilePath)), + file = service.file, + options = service.options; + + options.minUptime = 200; + services.push({ + file: service.file, + options: service.options + }); + }); + } + + callback(services); +}; + +SystemVAdapter.prototype.start = function start(callback) { + spawn('/etc/init.d/foreverd', ['start']); + return callback && callback(); +}; + +SystemVAdapter.prototype.run = function run(callback) { + if (this.daemonized) { + return callback(); + } + + var self = this, + pidFilePath = path.join('/var', 'run', 'foreverd.pid'), + logFilePath = path.join('/var', 'log', 'foreverd'); + + process.on('exit', function removePIDFile() { + try { + fs.unlinkSync(pidFilePath); + } + catch (err) { + // we are exiting anyway. this may have some noexist error already + } + }); + + fs.open(logFilePath, 'w+', function serviceLogOpened(err, logFile) { + if (err) { + throw err; + } + + self.service.startServer(function () { + try { + // + // TODO: Create a pseudo-daemon to replace this. + // + // daemon.start(logFile); + // daemon.lock(pidFilePath); + self.daemonized = true; + return callback && callback(); + } + catch (err) { + console.error(err); + return callback && callback(err); + } + }); + }); +}; + +SystemVAdapter.prototype.add = function add(file, options, callback) { + forever.config.set('root', path.join('/var', 'local', 'foreverd')); + // + // Add descriptor to our service list + // this is just a json file in $root/services/*.json + // + var filePath, service = { + file: file, + options: options || {} + }; + + options.appendLog = true; + filePath = path.join(forever.config.get('root'), 'services', options.uid + '.json'); + + fs.writeFile(filePath, JSON.stringify(service), function (err) { + return callback && callback(err); + }); +}; + +SystemVAdapter.prototype.list = function list(callback) { + forever.config.set('root', path.join('/var', 'local', 'foreverd')); + + var sockPath = path.join(forever.config.get('root'), 'foreverd.sock'), + client; + + client = dnode.connect(sockPath, function onConnect(remote, client) { + if (callback) { + callback(false, remote.applications); + } + + client.end(); + }); + + client.on('error', function onError(err) { + if (err.code === 'ECONNREFUSED') { + try { + fs.unlinkSync(fullPath); + } + catch (ex) { } + return callback && callback(false, []); + } + + return callback && callback(err); + }); +}; \ No newline at end of file diff --git a/node_modules/forever/lib/forever/service/cli.js b/node_modules/forever/lib/forever/service/cli.js new file mode 100644 index 0000000..674e15b --- /dev/null +++ b/node_modules/forever/lib/forever/service/cli.js @@ -0,0 +1,102 @@ +/* + * cli.js: Handlers for the foreverd CLI commands. + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var utile = require('utile'), + flatiron = require('flatiron'), + optimist = require('optimist'), + forever = require('../../forever'), + Service = require('./service'), + argv; + +var cli = exports; + +var app = flatiron.app; + +app.use(flatiron.plugins.cli, { + usage: forever.cli.usage +}); + +app.config.argv().env(); + +var service = new Service({ + adapter: optimist.argv.adapter +}); + +app.cmd('install', cli.install = function () { + service.install(function onInstall(err) { + if (err) { + forever.log.error(err); + } + else { + forever.log.info('foreverd installed'); + } + }); +}); + +//TODO +app.cmd('run', cli.run = function () { + service.load(function () { + service.run(); + }); +}); + +app.cmd('uninstall', cli.uninstall = function () { + service.uninstall(); +}); + +app.cmd(/add (.*)/, cli.add = function (file) { + service.add(file, forever.cli.getOptions(file)); +}); + +//TODO +app.cmd(/remove (.*)/, cli.remove = function (file) { + service.remove(file, forever.cli.getOptions(file)); +}); + +app.cmd('start', cli.start = function () { + service.start(); +}); + +//TODO +app.cmd('stop', cli.stop = function () { + service.stop(); +}); + +app.cmd('restart', cli.restart = function () { + service.restart(); +}); + +app.cmd('list', cli.list = function () { + service.list(function (err, applications) { + if (err) { + app.log.error('Error running command: ' + 'list'.magenta); + app.log.error(err.message); + err.stack && err.stack.split('\n').forEach(function (line) { + app.log.error(line); + }) + return; + } + + applications.forEach(function printApplication(application) { + console.log(application.monitor.uid, application.monitor.command, application.file, application.monitor.child.pid, application.monitor.logFile, application.monitor.pidFile); + }); + }); +}); + +app.cmd('pause', cli.pause = function () { + service.pause(); +}); + +app.cmd('resume', cli.resume = function () { + service.resume(); +}); + +cli.startCLI = function () { + app.start(); +}; + diff --git a/node_modules/forever/lib/forever/service/index.js b/node_modules/forever/lib/forever/service/index.js new file mode 100644 index 0000000..5addced --- /dev/null +++ b/node_modules/forever/lib/forever/service/index.js @@ -0,0 +1,22 @@ +/* + * index.js: Top-level include for the `forever.service` module. + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var fs = require('fs'), + path = require('path'); + +var service = exports; + +service.Service = require('./service'); +service.adapters = {}; + +fs.readdirSync(path.join(__dirname, 'adapters')).forEach(function (file) { + file = file.replace(/\.js/, ''); + service.adapters.__defineGetter__(file, function () { + return require(__dirname + '/adapters/' + file); + }); +}); diff --git a/node_modules/forever/lib/forever/service/service.js b/node_modules/forever/lib/forever/service/service.js new file mode 100644 index 0000000..2cc878d --- /dev/null +++ b/node_modules/forever/lib/forever/service/service.js @@ -0,0 +1,268 @@ +/* + * service.js: Object responsible for managing the foreverd daemon. + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var fs = require('fs'), + path = require('path'), + util = require('util'), + events = require('events'), + forever = require('../../forever'), + SystemVAdapter = require('./adapters/systemv'); + +// options +// directories {log, pid, conf, run, local} +var Service = module.exports = function Service(options) { + events.EventEmitter.call(this); + options = options || {}; + + var self = this, + AdapterType; + + this.applications = [ + //{ + //file: + //options: + //monitor: + //} + ]; + + this.servers = []; + if (typeof options.adapter === 'string') { + options.adapter = Service.adapter[options.adapter]; + } + + AdapterType = options.adapter || SystemVAdapter; + this.adapter = new AdapterType(this); +}; + +util.inherits(Service, events.EventEmitter); + +Service.prototype.startServer = function startServer(callback) { + var socket = path.join(forever.config.get('sockPath'), 'forever.sock'), + monitors = [], + self = this, + server; + + server = dnode(this); + server.on('error', function onServerError() { + // + // TODO: This is really bad. + // + }); + + server.on('ready', function onServerReady(err) { + self.listen(server); + if (callback) { + if (err) { + callback(err); + } + else { + callback(null, server, socket); + } + } + }); + + server.listen(socket); + + return this; +}; + +Service.prototype.listen = function listen(server) { + var dnodeServer = dnode(this); + + this.servers.push(dnodeServer); + dnodeServer.listen(server); + + return this; +}; + +Service.prototype.load = function load() { + var self = this; + this.adapter.load(function onLoaded(applications) { + applications.forEach(function startApplication(application, index) { + var monitor = application.monitor = new forever.Monitor(application.file, application.options); + + monitor.start(); + self.applications.push(application); + + if (index === applications.length - 1) { + self.listen(path.join(forever.config.get('root'), 'foreverd.sock')); + } + + self.emit('foreverd::loaded'); + }); + }); + return this; +}; + +// +// Function add(file, options) +// add the application to the service manager +// DOES NOT START THE APPLICATION +// call's the service manager's add method +// +Service.prototype.add = function add(file, options, callback) { + if (this.paused) { + return callback && callback(new Error('foreverd is paused')); + } + + this.adapter.add(file, options, callback); +}; + +// +// Function remove(file, options) +// remove the application from the service manager +// call's the service manager's remove method +// +Service.prototype.remove = function remove(file, options, callback) { + if (this.paused) { + return callback(new Error('foreverd is paused')); + } + + var applicationsToRemove = this.applications, + self = this, + optionStr, + fileStr; + + if (file) { + fileStr = JSON.stringify(file); + applicationsToRemove = applicationsToRemove.filter(function compareFile(application) { + return fileStr !== JSON.stringify(application.file); + }); + } + + if (options) { + optionStr = JSON.stringify(options); + applicationsToRemove = applicationsToRemove.filter(function compareOptions(application) { + return optionStr !== JSON.stringify(application.options); + }); + } + + applicationsToRemove.forEach(function removeApplication(application) { + if (application.monitor) { + application.monitor.stop(); + } + + self.applications.splice(self.applications.indexOf(application), 1); + }); + + if (callback) { + callback(); + } + + return this; +}; + +// +// Function install() +// installs all the required to run foreverd +// call's the service manager's install(options) +// +Service.prototype.install = function install(callback) { + this.adapter.install(callback); + return this; +}; + +// +// Function uninstall(options) +// uninstalls all the required to run foreverd +// call's the service manager's uninstall(options) +// +Service.prototype.uninstall = function uninstall(callback) { + this.adapter.uninstall(callback); + return this; +}; + +// +// Function start() +// calls the appropriate OS functionality to start this service +// +Service.prototype.start = function start(callback) { + this.adapter.start(callback); + return this; +}; + +// +// Function run() +// creates monitors for all the services +// +Service.prototype.run = function run(callback) { + var self = this; + this.adapter.run(function adapterStarted() { + self.applications.forEach(function startApplication(application) { + application.monitor = new forever.Monitor(application.file, application.options); + application.monitor.start(); + }); + + return callback && callback(); + }); + + return this; +}; + +// +// Function stop(monitors) +// +Service.prototype.stop = function stop(callback) { + var self = this; + this.adapter.start(function adapterStopped() { + self.applications.forEach(function stopApplication(application) { + application.monitor.stop(); + }); + + return callback && callback(); + }); + + return this; +}; + +// +// Function restart() +// +Service.prototype.restart = function restart(callback) { + var self = this; + this.adapter.start(function adapterRestarted() { + self.applications.forEach(function restartApplication(application) { + application.monitor.restart(); + }); + + return callback && callback(); + }); + + return this; +}; + +// +// Function pause() +// disables adding / removing applications +// +Service.prototype.pause = function pause(callback) { + this.paused = true; + if (callback) { + callback(); + } + + return this; +}; + +// +// Function resume() +// reenables adding / removing applications +// +Service.prototype.resume = function resume(callback) { + this.paused = false; + if (callback) { + callback(); + } + + return this; +}; + +Service.prototype.list = function list(callback) { + this.adapter.list(callback); + return this; +}; \ No newline at end of file diff --git a/node_modules/forever/lib/forever/worker.js b/node_modules/forever/lib/forever/worker.js new file mode 100644 index 0000000..895a6d5 --- /dev/null +++ b/node_modules/forever/lib/forever/worker.js @@ -0,0 +1,122 @@ +var events = require('events'), + fs = require('fs'), + path = require('path'), + nssocket = require('nssocket'), + utile = require('utile'), + forever = require(path.resolve(__dirname, '..', 'forever')); + +var Worker = exports.Worker = function (options) { + events.EventEmitter.call(this); + options || (options = {}); + + this.monitor = options.monitor; + this.sockPath = options.sockPath || forever.config.get('sockPath'); + this.exitOnStop = options.exitOnStop === true; + + this._socket = null; +}; + +utile.inherits(Worker, events.EventEmitter); + +Worker.prototype.start = function (callback) { + var self = this, + err; + + if (this._socket) { + err = new Error("Can't start already started worker"); + if (callback) { + return callback(err); + } + + throw err; + } + + // + // Defines a simple `nssocket` protocol for communication + // with a parent process. + // + function workerProtocol(socket) { + socket.on('error', function() { + socket.destroy(); + }) + + socket.data(['ping'], function () { + socket.send(['pong']); + }); + + socket.data(['data'], function () { + socket.send(['data'], self.monitor.data); + }); + + socket.data(['spawn'], function (data) { + if (!data.script) { + return socket.send(['spawn', 'error'], { error: new Error('No script given') }); + } + + if (self.monitor) { + return socket.send(['spawn', 'error'], { error: new Error("Already running") }); + } + + var monitor = new (forever.Monitor)(data.script, data.options); + monitor.start(); + + monitor.on('start', function () { + socket.send(['spawn', 'start'], monitor.data); + }); + }); + + socket.data(['stop'], function () { + self.monitor.once('stop', function () { + socket.send(['stop', 'ok']); + self.exitOnStop && process.exit(); + }); + + self.monitor.stop(); + }); + + socket.data(['restart'], function () { + self.monitor.once('restart', function () { + socket.send(['restart', 'ok']); + }); + + self.monitor.restart(); + }); + } + + function findAndStart() { + self._socket = nssocket.createServer(workerProtocol); + self._socket.on('listening', function () { + // + // `listening` listener doesn't take error as the first parameter + // + self.emit('start'); + callback && callback(null, self._sockFile); + }); + + self._socket.on('error', function (err) { + if (err.code === 'EADDRINUSE') { + return findAndStart(); + } + + callback && callback(err); + }); + + // + // Create a unique socket file based on the current microtime. + // + var sock = self._sockFile = path.join(self.sockPath, [ + 'worker', + new Date().getTime() + utile.randomString(3), + 'sock' + ].join('.')); + + self._socket.listen(sock); + } + + // + // Attempt to start the server the first time + // + findAndStart(); + return this; +}; + diff --git a/node_modules/forever/node_modules/.bin/flatiron b/node_modules/forever/node_modules/.bin/flatiron new file mode 120000 index 0000000..cdca976 --- /dev/null +++ b/node_modules/forever/node_modules/.bin/flatiron @@ -0,0 +1 @@ +../flatiron/bin/flatiron \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/.npmignore b/node_modules/forever/node_modules/cliff/.npmignore new file mode 100644 index 0000000..5171c54 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/.npmignore @@ -0,0 +1,2 @@ +node_modules +npm-debug.log \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/LICENSE b/node_modules/forever/node_modules/cliff/LICENSE new file mode 100644 index 0000000..56217ca --- /dev/null +++ b/node_modules/forever/node_modules/cliff/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Nodejitsu Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/README.md b/node_modules/forever/node_modules/cliff/README.md new file mode 100644 index 0000000..a0f0cd8 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/README.md @@ -0,0 +1,227 @@ +# cliff + +CLI output formatting tools: "Your CLI Formatting Friend". + +## Installation + +### Installing npm (node package manager) +``` + curl http://npmjs.org/install.sh | sh +``` + +### Installing cliff +``` + [sudo] npm install cliff +``` + +## Usage +There are a number of methods available in Cliff for common logging tasks in command-line tools. If you're looking for more usage, checkout the [examples in this repository][3]: + +1. Logging rows of data +2. Inspecting Objects + +### Logging rows of data + +**cliff.stringifyRows(rows[, colors])** + +Takes a set of Arrays and row headers and returns properly formatted and padded rows. Here's a sample: + +``` js + var cliff = require('../lib/cliff'); + + var rows = [ + ['Name', 'Flavor', 'Dessert'], + ['Alice', 'cherry', 'yogurt'], + ['Bob', 'carmel', 'apples'], + ['Joe', 'chocolate', 'cake'], + ['Nick', 'vanilla', 'ice cream'] + ]; + + console.log(cliff.stringifyRows(rows, ['red', 'blue', 'green'])); +``` + +![output from string-rows.js][string-rows] + +**cliff.putRows(level, rows[, colors])** + +The `putRows` method is a simple helper that takes a set of Arrays and row headers and logs properly formatted and padded rows (logs `stringifyRows` to [winston][0]). Here's a quick sample: + +``` js + var cliff = require('../lib/cliff'); + + var rows = [ + ['Name', 'Flavor', 'Dessert'], + ['Alice', 'cherry', 'yogurt'], + ['Bob', 'carmel', 'apples'], + ['Joe', 'chocolate', 'cake'], + ['Nick', 'vanilla', 'ice cream'] + ]; + + cliff.putRows('data', rows, ['red', 'blue', 'green']); +``` + +The resulting output on the command-line would be: + +![output from put-rows.js][put-rows] + +**cliff.stringifyObjectRows(objs, properties[, colors])** +*used to be: cliff.rowifyObjects(objs, properties, colors)* + +Takes a set of Objects and the properties to extract from them and returns properly formatted and padded rows. Here's a sample: + +``` js + var cliff = require('../lib/cliff'); + + var objs = [], obj = { + name: "bazz", + address: "1234 Nowhere Dr.", + }; + + for (var i = 0; i < 10; i++) { + objs.push({ + name: obj.name, + address: obj.address, + id: Math.random().toString() + }); + } + + console.log(cliff.stringifyObjectRows(objs, ['id', 'name', 'address'], ['red', 'blue', 'green'])); +``` + +![output from string-object-rows.js][string-object-rows] + +**cliff.putObjectRows(level, objs, properties[, colors])** + +Takes a set of Objects and the properties to extract from them and it will log to the console. (it prints `stringifyObjectRows` with [winston][0]). Here's a sample: + +``` js + var cliff = require('../lib/cliff'); + + var objs = [], obj = { + name: "bazz", + address: "1234 Nowhere Dr.", + }; + + for (var i = 0; i < 10; i++) { + objs.push({ + name: obj.name, + address: obj.address, + id: Math.random().toString() + }); + } + + cliff.putObjectRows('data', objs, ['id', 'name', 'address']); +``` + +![output from string-object-rows.js][string-object-rows] + +**Colors Parameter** + +The `colors` parameter is an array that colors the first row. It uses the [colors.js][2]. You can use any of those. + +``` js + var cliff = require('../lib/cliff'); + + var rows = [ + ['Name', 'Flavor', 'Dessert'], + ['Alice'.grey, 'cherry'.cyan, 'yogurt'.yellow], + ['Bob'.magenta, 'carmel'.rainbow, 'apples'.white], + ['Joe'.italic, 'chocolate'.underline, 'cake'.inverse], + ['Nick'.bold, 'vanilla', 'ice cream'] + ]; + + cliff.putRows('data', rows, ['red', 'blue', 'green']); +``` + +The resulting output on the command-line would be: + +![output from puts-rows-colors.js][put-rows-colors] + +### Inspecting Objects + +**cliff.inspect(obj)** + +The `inspect` method is a lightweight wrapper to a pre-configured [eyes][1] inspector. If you wish to change the coloring of objects that are logged using `cliff` you only need to override `cliff.inspect` with a new [eyes][1] inspector. Here is how to use it: + +``` js + var cliff = require('../lib/cliff'); + + console.log(cliff.inspect({ + literal: "bazz", + arr: [ + "one", + 2, + ], + obj: { + host: "localhost", + port: 5984, + auth: { + username: "admin", + password: "password" + } + } + })); +``` + +![output from inspect.js][inspect] + +**cliff.putObject(obj, [rewriters, padding])** + +The `putObject` method is a simple helper function for prefixing and styling inspected object output from [eyes][1]. Here's a quick sample: + +``` js +var cliff = require('cliff'); + +cliff.putObject({ + literal: "bazz", + arr: [ + "one", + 2, + ], + obj: { + host: "localhost", + port: 5984, + auth: { + username: "admin", + password: "password" + } + } +}); +``` + +The resulting output on the command-line would be: + +![output from put-object.js][put-object] + +## Run Tests + +All of the cliff tests are written in [vows][4], and cover all of the use cases described above. + +``` + npm test +``` + +## Motivation + +Cliff is the swiss army knife of CLI formatting tools. It is based on highly flexible and powerful libraries: + +* [winston][0]: A multi-transport async logging library for node.js +* [eyes][1]: A customizable value inspector for node.js +* [colors][2]: Get colors in your node.js console like what + + +#### Author: [Charlie Robbins](http://twitter.com/indexzero) + +[0]: http://github.com/indexzero/winston +[1]: http://github.com/cloudhead/eyes.js +[2]: http://github.com/marak/colors.js +[3]: http://github.com/flatiron/cliff/tree/master/examples +[4]: http://vowsjs.org + +[inspect]: https://github.com/flatiron/cliff/raw/master/assets/inspect.png +[put-object-rows]: https://github.com/flatiron/cliff/raw/master/assets/put-object-rows.png +[put-object]: https://github.com/flatiron/cliff/raw/master/assets/put-object.png +[put-rows-colors]: https://github.com/flatiron/cliff/raw/master/assets/put-rows-colors.png +[put-rows]: https://github.com/flatiron/cliff/raw/master/assets/put-rows.png +[string-object-rows]: https://github.com/flatiron/cliff/raw/master/assets/string-object-rows.png +[string-rows]: https://github.com/flatiron/cliff/raw/master/assets/string-rows.png \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/assets/inspect.png b/node_modules/forever/node_modules/cliff/assets/inspect.png new file mode 100755 index 0000000..15f0eb0 Binary files /dev/null and b/node_modules/forever/node_modules/cliff/assets/inspect.png differ diff --git a/node_modules/forever/node_modules/cliff/assets/put-object-rows.png b/node_modules/forever/node_modules/cliff/assets/put-object-rows.png new file mode 100755 index 0000000..044270f Binary files /dev/null and b/node_modules/forever/node_modules/cliff/assets/put-object-rows.png differ diff --git a/node_modules/forever/node_modules/cliff/assets/put-object.png b/node_modules/forever/node_modules/cliff/assets/put-object.png new file mode 100755 index 0000000..1138854 Binary files /dev/null and b/node_modules/forever/node_modules/cliff/assets/put-object.png differ diff --git a/node_modules/forever/node_modules/cliff/assets/put-rows-colors.png b/node_modules/forever/node_modules/cliff/assets/put-rows-colors.png new file mode 100755 index 0000000..93252ff Binary files /dev/null and b/node_modules/forever/node_modules/cliff/assets/put-rows-colors.png differ diff --git a/node_modules/forever/node_modules/cliff/assets/put-rows.png b/node_modules/forever/node_modules/cliff/assets/put-rows.png new file mode 100755 index 0000000..6f045d7 Binary files /dev/null and b/node_modules/forever/node_modules/cliff/assets/put-rows.png differ diff --git a/node_modules/forever/node_modules/cliff/assets/string-object-rows.png b/node_modules/forever/node_modules/cliff/assets/string-object-rows.png new file mode 100755 index 0000000..0d383a2 Binary files /dev/null and b/node_modules/forever/node_modules/cliff/assets/string-object-rows.png differ diff --git a/node_modules/forever/node_modules/cliff/assets/string-rows.png b/node_modules/forever/node_modules/cliff/assets/string-rows.png new file mode 100755 index 0000000..9260507 Binary files /dev/null and b/node_modules/forever/node_modules/cliff/assets/string-rows.png differ diff --git a/node_modules/forever/node_modules/cliff/examples/inspect.js b/node_modules/forever/node_modules/cliff/examples/inspect.js new file mode 100644 index 0000000..eb45927 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/examples/inspect.js @@ -0,0 +1,24 @@ +/* + * put-object.js: Example usage for `cliff.putObject`. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var cliff = require('../lib/cliff'); + +console.log(cliff.inspect({ + literal: "bazz", + arr: [ + "one", + 2, + ], + obj: { + host: "localhost", + port: 5984, + auth: { + username: "admin", + password: "password" + } + } +})); diff --git a/node_modules/forever/node_modules/cliff/examples/put-object-rows.js b/node_modules/forever/node_modules/cliff/examples/put-object-rows.js new file mode 100644 index 0000000..d7e8a80 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/examples/put-object-rows.js @@ -0,0 +1,23 @@ +/* + * put-object-rows.js: Example usage for `cliff.putObjectRows`. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var cliff = require('../lib/cliff'); + +var objs = [], obj = { + name: "bazz", + address: "1234 Nowhere Dr.", +}; + +for (var i = 0; i < 10; i++) { + objs.push({ + name: obj.name, + address: obj.address, + id: Math.random().toString() + }); +} + +cliff.putObjectRows('data', objs, ['id', 'name', 'address']); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/examples/put-object.js b/node_modules/forever/node_modules/cliff/examples/put-object.js new file mode 100644 index 0000000..7821514 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/examples/put-object.js @@ -0,0 +1,24 @@ +/* + * put-object.js: Example usage for `cliff.putObject`. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var cliff = require('../lib/cliff'); + +cliff.putObject({ + literal: "bazz", + arr: [ + "one", + 2, + ], + obj: { + host: "localhost", + port: 5984, + auth: { + username: "admin", + password: "password" + } + } +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/examples/put-rows-colors.js b/node_modules/forever/node_modules/cliff/examples/put-rows-colors.js new file mode 100644 index 0000000..ac46d84 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/examples/put-rows-colors.js @@ -0,0 +1,12 @@ +var cliff = require('../lib/cliff'); + +var rows = [ + ['Name', 'Flavor', 'Dessert'], + ['Alice'.grey, 'cherry'.cyan, 'yogurt'.yellow], + ['Bob'.magenta, 'carmel'.rainbow, 'apples'.white], + ['Joe'.italic, 'chocolate'.underline, 'cake'.inverse], + ['Nick'.bold, 'vanilla', 'ice cream'] +]; + +cliff.putRows('data', rows, ['red', 'blue', 'green']); + diff --git a/node_modules/forever/node_modules/cliff/examples/put-rows.js b/node_modules/forever/node_modules/cliff/examples/put-rows.js new file mode 100644 index 0000000..4de1038 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/examples/put-rows.js @@ -0,0 +1,11 @@ +var cliff = require('../lib/cliff'); + +var rows = [ + ['Name', 'Flavor', 'Dessert'], + ['Alice', 'cherry', 'yogurt'], + ['Bob', 'carmel', 'apples'], + ['Joe', 'chocolate', 'cake'], + ['Nick', 'vanilla', 'ice cream'] +]; + +cliff.putRows('data', rows, ['red', 'blue', 'green']); diff --git a/node_modules/forever/node_modules/cliff/examples/string-object-rows.js b/node_modules/forever/node_modules/cliff/examples/string-object-rows.js new file mode 100644 index 0000000..7f1bd9b --- /dev/null +++ b/node_modules/forever/node_modules/cliff/examples/string-object-rows.js @@ -0,0 +1,23 @@ +/* + * put-object-rows.js: Example usage for `cliff.putObjectRows`. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var cliff = require('../lib/cliff'); + +var objs = [], obj = { + name: "bazz", + address: "1234 Nowhere Dr.", +}; + +for (var i = 0; i < 10; i++) { + objs.push({ + name: obj.name, + address: obj.address, + id: Math.random().toString() + }); +} + +console.log(cliff.stringifyObjectRows(objs, ['id', 'name', 'address'], ['red', 'blue', 'green'])); diff --git a/node_modules/forever/node_modules/cliff/examples/string-rows.js b/node_modules/forever/node_modules/cliff/examples/string-rows.js new file mode 100644 index 0000000..a4aaa81 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/examples/string-rows.js @@ -0,0 +1,11 @@ +var cliff = require('../lib/cliff'); + +var rows = [ + ['Name', 'Flavor', 'Dessert'], + ['Alice', 'cherry', 'yogurt'], + ['Bob', 'carmel', 'apples'], + ['Joe', 'chocolate', 'cake'], + ['Nick', 'vanilla', 'ice cream'] +]; + +console.log(cliff.stringifyRows(rows, ['red', 'blue', 'green'])); diff --git a/node_modules/forever/node_modules/cliff/lib/cliff.js b/node_modules/forever/node_modules/cliff/lib/cliff.js new file mode 100644 index 0000000..c9fd723 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/lib/cliff.js @@ -0,0 +1,280 @@ +/* + * cliff.js: CLI output formatting tools: "Your CLI Formatting Friend". + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var colors = require('colors'), + eyes = require('eyes'), + winston = require('winston'); + +var cliff = exports, + logger; + +cliff.__defineGetter__('logger', function () { + delete cliff.logger; + return cliff.logger = logger; +}); + +cliff.__defineSetter__('logger', function (val) { + logger = val; + + // + // Setup winston to use the `cli` formats + // + if (logger.cli) { + logger.cli(); + } +}); + +// +// Set the default logger for cliff. +// +cliff.logger = new winston.Logger({ + transports: [new winston.transports.Console()] +}); + +// +// Expose a default `eyes` inspector. +// +cliff.inspector = eyes.inspector; +cliff.inspect = eyes.inspector({ stream: null, + styles: { // Styles applied to stdout + all: null, // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'grey', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + number: 'blue', // 0, 1, 2... + bool: 'magenta', // true false + regexp: 'green' // /\d+/ + } +}); + +// +// ### function extractFrom (obj, properties) +// #### @obj {Object} Object to extract properties from. +// #### @properties {Array} List of properties to output. +// Creates an array representing the values for `properties` in `obj`. +// +cliff.extractFrom = function (obj, properties) { + return properties.map(function (p) { + return obj[p]; + }); +}; + +// +// ### function columnMajor (rows) +// #### @rows {ArrayxArray} Row-major Matrix to transpose +// Transposes the row-major Matrix, represented as an array of rows, +// into column major form (i.e. an array of columns). +// +cliff.columnMajor = function (rows) { + var columns = []; + + rows.forEach(function (row) { + for (var i = 0; i < row.length; i += 1) { + if (!columns[i]) { + columns[i] = []; + } + + columns[i].push(row[i]); + } + }); + + return columns; +}; + +// +// ### arrayLengths (arrs) +// #### @arrs {ArrayxArray} Arrays to calculate lengths for +// Creates an array with values each representing the length +// of an array in the set provided. +// +cliff.arrayLengths = function (arrs) { + var i, lengths = []; + for (i = 0; i < arrs.length; i += 1) { + lengths.push(longestElement(arrs[i].map(cliff.stringifyLiteral))); + } + return lengths; +}; + +// +// ### function stringifyRows (rows, colors) +// #### @rows {ArrayxArray} Matrix of properties to output in row major form +// #### @colors {Array} Set of colors to use for the headers +// Outputs the specified `rows` as fixed-width columns, adding +// colorized headers if `colors` are supplied. +// +cliff.stringifyRows = function (rows, colors) { + var lengths, columns, output = [], headers; + + columns = cliff.columnMajor(rows); + lengths = cliff.arrayLengths(columns); + + function stringifyRow(row, colorize) { + var rowtext = '', padding, item, i, length; + for (i = 0; i < row.length; i += 1) { + item = cliff.stringifyLiteral(row[i]); + item = colorize ? item[colors[i]] : item; + length = realLength(item); + padding = length < lengths[i] ? lengths[i] - length + 2 : 2; + rowtext += item + new Array(padding).join(' '); + } + + output.push(rowtext); + } + + // If we were passed colors, then assume the first row + // is the headers for the rows + if (colors) { + headers = rows.splice(0, 1)[0]; + stringifyRow(headers, true); + } + + rows.forEach(function (row) { + stringifyRow(row, false); + }); + + return output.join('\n'); +}; + +// +// ### function rowifyObjects (objs, properties, colors) +// #### @objs {Array} List of objects to create output for +// #### @properties {Array} List of properties to output +// #### @colors {Array} Set of colors to use for the headers +// Extracts the lists of `properties` from the specified `objs` +// and formats them according to `cliff.stringifyRows`. +// +cliff.stringifyObjectRows = cliff.rowifyObjects = function (objs, properties, colors) { + var rows = [properties].concat(objs.map(function (obj) { + return cliff.extractFrom(obj, properties); + })); + + return cliff.stringifyRows(rows, colors); +}; + +// +// ### function putRows (level, rows, colors) +// #### @level {String} Log-level to use +// #### @rows {Array} Array of rows to log at the specified level +// #### @colors {Array} Set of colors to use for the specified row(s) headers. +// Logs the stringified table result from `rows` at the appropriate `level` using +// `cliff.logger`. If `colors` are supplied then use those when stringifying `rows`. +// +cliff.putRows = function (level, rows, colors) { + cliff.stringifyRows(rows, colors).split('\n').forEach(function (str) { + logger.log(level, str); + }); +}; + +// +// ### function putObjectRows (level, rows, colors) +// #### @level {String} Log-level to use +// #### @objs {Array} List of objects to create output for +// #### @properties {Array} List of properties to output +// #### @colors {Array} Set of colors to use for the headers +// Logs the stringified table result from `objs` at the appropriate `level` using +// `cliff.logger`. If `colors` are supplied then use those when stringifying `objs`. +// +cliff.putObjectRows = function (level, objs, properties, colors) { + cliff.rowifyObjects(objs, properties, colors).split('\n').forEach(function (str) { + logger.log(level, str); + }); +}; + +// +// ### function putObject (obj, [rewriters, padding]) +// #### @obj {Object} Object to log to the command line +// #### @rewriters {Object} **Optional** Set of methods to rewrite certain object keys +// #### @padding {Number} **Optional** Length of padding to put around the output. +// Inspects the object `obj` on the command line rewriting any properties which match +// keys in `rewriters` if any. Adds additional `padding` if supplied. +// +cliff.putObject = function (/*obj, [rewriters, padding] */) { + var args = Array.prototype.slice.call(arguments), + obj = args.shift(), + padding = typeof args[args.length - 1] === 'number' && args.pop(), + rewriters = typeof args[args.length -1] === 'object' && args.pop(), + keys = Object.keys(obj).sort(), + sorted = {}, + matchers = {}, + inspected; + + padding = padding || 0; + rewriters = rewriters || {}; + + function pad () { + for (var i = 0; i < padding / 2; i++) { + logger.data(''); + } + } + + keys.forEach(function (key) { + sorted[key] = obj[key]; + }); + + inspected = cliff.inspect(sorted); + + Object.keys(rewriters).forEach(function (key) { + matchers[key] = new RegExp(key); + }); + + pad(); + inspected.split('\n').forEach(function (line) { + Object.keys(rewriters).forEach(function (key) { + if (matchers[key].test(line)) { + line = rewriters[key](line); + } + }); + logger.data(line); + }); + pad(); +}; + +cliff.stringifyLiteral = function stringifyLiteral (literal) { + switch (cliff.typeOf(literal)) { + case 'number' : return literal + ''; + case 'null' : return 'null'; + case 'undefined': return 'undefined'; + case 'boolean' : return literal + ''; + default : return literal; + } +}; + +cliff.typeOf = function typeOf(value) { + var s = typeof(value), + types = [Object, Array, String, RegExp, Number, Function, Boolean, Date]; + + if (s === 'object' || s === 'function') { + if (value) { + types.forEach(function (t) { + if (value instanceof t) { + s = t.name.toLowerCase(); + } + }); + } else { + s = 'null'; + } + } + + return s; +}; + +function realLength(str) { + return ("" + str).replace(/\u001b\[\d+m/g,'').length; +} + +function longestElement(a) { + var l = 0; + for (var i = 0; i < a.length; i++) { + var new_l = realLength(a[i]); + if (l < new_l) { + l = new_l; + } + } + + return l; +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/eyes/LICENSE b/node_modules/forever/node_modules/cliff/node_modules/eyes/LICENSE new file mode 100644 index 0000000..a1edd93 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/eyes/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009 cloudhead + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/forever/node_modules/cliff/node_modules/eyes/Makefile b/node_modules/forever/node_modules/cliff/node_modules/eyes/Makefile new file mode 100644 index 0000000..a121dea --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/eyes/Makefile @@ -0,0 +1,4 @@ +test: + @@node test/eyes-test.js + +.PHONY: test diff --git a/node_modules/forever/node_modules/cliff/node_modules/eyes/README.md b/node_modules/forever/node_modules/cliff/node_modules/eyes/README.md new file mode 100644 index 0000000..c4f6f76 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/eyes/README.md @@ -0,0 +1,73 @@ +eyes +==== + +a customizable value inspector for Node.js + +synopsis +-------- + +I was tired of looking at cluttered output in the console -- something needed to be done, +`sys.inspect()` didn't display regexps correctly, and was too verbose, and I had an hour or two to spare. +So I decided to have some fun. _eyes_ were born. + +![eyes-ss](http://dl.dropbox.com/u/251849/eyes-js-ss.gif) + +_example of the output of a user-customized eyes.js inspector_ + +*eyes* also deals with circular objects in an intelligent way, and can pretty-print object literals. + +usage +----- + + var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); + + inspect(something); // inspect with the settings passed to `inspector` + +or + + var eyes = require('eyes'); + + eyes.inspect(something); // inspect with the default settings + +you can pass a _label_ to `inspect()`, to keep track of your inspections: + + eyes.inspect(something, "a random value"); + +If you want to return the output of eyes without printing it, you can set it up this way: + + var inspect = require('eyes').inspector({ stream: null }); + + sys.puts(inspect({ something: 42 })); + +customization +------------- + +These are the default styles and settings used by _eyes_. + + styles: { // Styles applied to stdout + all: 'cyan', // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + string: 'green', + number: 'magenta', + bool: 'blue', // true false + regexp: 'green', // /\d+/ + }, + + pretty: true, // Indent object literals + hideFunctions: false, // Don't output functions at all + stream: process.stdout, // Stream to write to, or null + maxLength: 2048 // Truncate output if longer + +You can overwrite them with your own, by passing a similar object to `inspector()` or `inspect()`. + + var inspect = require('eyes').inspector({ + styles: { + all: 'magenta', + special: 'bold' + }, + maxLength: 512 + }); + diff --git a/node_modules/forever/node_modules/cliff/node_modules/eyes/lib/eyes.js b/node_modules/forever/node_modules/cliff/node_modules/eyes/lib/eyes.js new file mode 100644 index 0000000..10d964b --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/eyes/lib/eyes.js @@ -0,0 +1,236 @@ +// +// Eyes.js - a customizable value inspector for Node.js +// +// usage: +// +// var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); +// inspect(something); // inspect with the settings passed to `inspector` +// +// or +// +// var eyes = require('eyes'); +// eyes.inspect(something); // inspect with the default settings +// +var eyes = exports, + stack = []; + +eyes.defaults = { + styles: { // Styles applied to stdout + all: 'cyan', // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + string: 'green', + number: 'magenta', + bool: 'blue', // true false + regexp: 'green', // /\d+/ + }, + pretty: true, // Indent object literals + hideFunctions: false, + showHidden: false, + stream: process.stdout, + maxLength: 2048 // Truncate output if longer +}; + +// Return a curried inspect() function, with the `options` argument filled in. +eyes.inspector = function (options) { + var that = this; + return function (obj, label, opts) { + return that.inspect.call(that, obj, label, + merge(options || {}, opts || {})); + }; +}; + +// If we have a `stream` defined, use it to print a styled string, +// if not, we just return the stringified object. +eyes.inspect = function (obj, label, options) { + options = merge(this.defaults, options || {}); + + if (options.stream) { + return this.print(stringify(obj, options), label, options); + } else { + return stringify(obj, options) + (options.styles ? '\033[39m' : ''); + } +}; + +// Output using the 'stream', and an optional label +// Loop through `str`, and truncate it after `options.maxLength` has been reached. +// Because escape sequences are, at this point embeded within +// the output string, we can't measure the length of the string +// in a useful way, without separating what is an escape sequence, +// versus a printable character (`c`). So we resort to counting the +// length manually. +eyes.print = function (str, label, options) { + for (var c = 0, i = 0; i < str.length; i++) { + if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5 + else if (c === options.maxLength) { + str = str.slice(0, i - 1) + '…'; + break; + } else { c++ } + } + return options.stream.write.call(options.stream, (label ? + this.stylize(label, options.styles.label, options.styles) + ': ' : '') + + this.stylize(str, options.styles.all, options.styles) + '\033[0m' + "\n"); +}; + +// Apply a style to a string, eventually, +// I'd like this to support passing multiple +// styles. +eyes.stylize = function (str, style, styles) { + var codes = { + 'bold' : [1, 22], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'cyan' : [36, 39], + 'magenta' : [35, 39], + 'blue' : [34, 39], + 'yellow' : [33, 39], + 'green' : [32, 39], + 'red' : [31, 39], + 'grey' : [90, 39] + }, endCode; + + if (style && codes[style]) { + endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0] + : codes[style][1]; + return '\033[' + codes[style][0] + 'm' + str + + '\033[' + endCode + 'm'; + } else { return str } +}; + +// Convert any object to a string, ready for output. +// When an 'array' or an 'object' are encountered, they are +// passed to specialized functions, which can then recursively call +// stringify(). +function stringify(obj, options) { + var that = this, stylize = function (str, style) { + return eyes.stylize(str, options.styles[style], options.styles) + }, index, result; + + if ((index = stack.indexOf(obj)) !== -1) { + return stylize(new(Array)(stack.length - index + 1).join('.'), 'special'); + } + stack.push(obj); + + result = (function (obj) { + switch (typeOf(obj)) { + case "string" : obj = stringifyString(obj.indexOf("'") === -1 ? "'" + obj + "'" + : '"' + obj + '"'); + return stylize(obj, 'string'); + case "regexp" : return stylize('/' + obj.source + '/', 'regexp'); + case "number" : return stylize(obj + '', 'number'); + case "function" : return options.stream ? stylize("Function", 'other') : '[Function]'; + case "null" : return stylize("null", 'special'); + case "undefined": return stylize("undefined", 'special'); + case "boolean" : return stylize(obj + '', 'bool'); + case "date" : return stylize(obj.toUTCString()); + case "array" : return stringifyArray(obj, options, stack.length); + case "object" : return stringifyObject(obj, options, stack.length); + } + })(obj); + + stack.pop(); + return result; +}; + +// Escape invisible characters in a string +function stringifyString (str, options) { + return str.replace(/\\/g, '\\\\') + .replace(/\n/g, '\\n') + .replace(/[\u0001-\u001F]/g, function (match) { + return '\\0' + match[0].charCodeAt(0).toString(8); + }); +} + +// Convert an array to a string, such as [1, 2, 3]. +// This function calls stringify() for each of the elements +// in the array. +function stringifyArray(ary, options, level) { + var out = []; + var pretty = options.pretty && (ary.length > 4 || ary.some(function (o) { + return (o !== null && typeof(o) === 'object' && Object.keys(o).length > 0) || + (Array.isArray(o) && o.length > 0); + })); + var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; + + for (var i = 0; i < ary.length; i++) { + out.push(stringify(ary[i], options)); + } + + if (out.length === 0) { + return '[]'; + } else { + return '[' + ws + + out.join(',' + (pretty ? ws : ' ')) + + (pretty ? ws.slice(0, -4) : ws) + + ']'; + } +}; + +// Convert an object to a string, such as {a: 1}. +// This function calls stringify() for each of its values, +// and does not output functions or prototype values. +function stringifyObject(obj, options, level) { + var out = []; + var pretty = options.pretty && (Object.keys(obj).length > 2 || + Object.keys(obj).some(function (k) { return typeof(obj[k]) === 'object' })); + var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; + + var keys = options.showHidden ? Object.keys(obj) : Object.getOwnPropertyNames(obj); + keys.forEach(function (k) { + if (Object.prototype.hasOwnProperty.call(obj, k) + && !(obj[k] instanceof Function && options.hideFunctions)) { + out.push(eyes.stylize(k, options.styles.key, options.styles) + ': ' + + stringify(obj[k], options)); + } + }); + + if (out.length === 0) { + return '{}'; + } else { + return "{" + ws + + out.join(',' + (pretty ? ws : ' ')) + + (pretty ? ws.slice(0, -4) : ws) + + "}"; + } +}; + +// A better `typeof` +function typeOf(value) { + var s = typeof(value), + types = [Object, Array, String, RegExp, Number, Function, Boolean, Date]; + + if (s === 'object' || s === 'function') { + if (value) { + types.forEach(function (t) { + if (value instanceof t) { s = t.name.toLowerCase() } + }); + } else { s = 'null' } + } + return s; +} + +function merge(/* variable args */) { + var objs = Array.prototype.slice.call(arguments); + var target = {}; + + objs.forEach(function (o) { + Object.keys(o).forEach(function (k) { + if (k === 'styles') { + if (! o.styles) { + target.styles = false; + } else { + target.styles = {} + for (var s in o.styles) { + target.styles[s] = o.styles[s]; + } + } + } else { + target[k] = o[k]; + } + }); + }); + return target; +} + diff --git a/node_modules/forever/node_modules/cliff/node_modules/eyes/package.json b/node_modules/forever/node_modules/cliff/node_modules/eyes/package.json new file mode 100644 index 0000000..53d9d19 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/eyes/package.json @@ -0,0 +1,44 @@ +{ + "name": "eyes", + "description": "a customizable value inspector", + "url": "http://github.com/cloudhead/eyes.js", + "keywords": [ + "inspector", + "debug", + "inspect", + "print" + ], + "author": { + "name": "Alexis Sellier", + "email": "self@cloudhead.net" + }, + "contributors": [ + { + "name": "Charlie Robbins", + "email": "charlie@nodejitsu.com" + } + ], + "licenses": [ + "MIT" + ], + "main": "./lib/eyes", + "version": "0.1.8", + "scripts": { + "test": "node test/*-test.js" + }, + "directories": { + "lib": "./lib", + "test": "./test" + }, + "engines": { + "node": "> 0.1.90" + }, + "readme": "eyes\n====\n\na customizable value inspector for Node.js\n\nsynopsis\n--------\n\nI was tired of looking at cluttered output in the console -- something needed to be done,\n`sys.inspect()` didn't display regexps correctly, and was too verbose, and I had an hour or two to spare. \nSo I decided to have some fun. _eyes_ were born.\n\n![eyes-ss](http://dl.dropbox.com/u/251849/eyes-js-ss.gif)\n\n_example of the output of a user-customized eyes.js inspector_\n\n*eyes* also deals with circular objects in an intelligent way, and can pretty-print object literals.\n\nusage\n-----\n\n var inspect = require('eyes').inspector({styles: {all: 'magenta'}});\n\n inspect(something); // inspect with the settings passed to `inspector`\n\nor\n\n var eyes = require('eyes');\n\n eyes.inspect(something); // inspect with the default settings\n\nyou can pass a _label_ to `inspect()`, to keep track of your inspections:\n\n eyes.inspect(something, \"a random value\");\n\nIf you want to return the output of eyes without printing it, you can set it up this way:\n\n var inspect = require('eyes').inspector({ stream: null });\n\n sys.puts(inspect({ something: 42 }));\n\ncustomization\n-------------\n\nThese are the default styles and settings used by _eyes_.\n\n styles: { // Styles applied to stdout\n all: 'cyan', // Overall style applied to everything\n label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]`\n other: 'inverted', // Objects which don't have a literal representation, such as functions\n key: 'bold', // The keys in object literals, like 'a' in `{a: 1}`\n special: 'grey', // null, undefined...\n string: 'green',\n number: 'magenta',\n bool: 'blue', // true false\n regexp: 'green', // /\\d+/\n },\n \n pretty: true, // Indent object literals\n hideFunctions: false, // Don't output functions at all\n stream: process.stdout, // Stream to write to, or null\n maxLength: 2048 // Truncate output if longer\n\nYou can overwrite them with your own, by passing a similar object to `inspector()` or `inspect()`.\n\n var inspect = require('eyes').inspector({\n styles: {\n all: 'magenta',\n special: 'bold'\n },\n maxLength: 512\n });\n\n", + "readmeFilename": "README.md", + "_id": "eyes@0.1.8", + "dist": { + "shasum": "7660dc70104b97f6bb6c77b53e335e95503c813b" + }, + "_from": "eyes@0.1.x", + "_resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/eyes/test/eyes-test.js b/node_modules/forever/node_modules/cliff/node_modules/eyes/test/eyes-test.js new file mode 100644 index 0000000..1f9606a --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/eyes/test/eyes-test.js @@ -0,0 +1,56 @@ +var util = require('util'); +var eyes = require('../lib/eyes'); + +eyes.inspect({ + number: 42, + string: "John Galt", + regexp: /[a-z]+/, + array: [99, 168, 'x', {}], + func: function () {}, + bool: false, + nil: null, + undef: undefined, + object: {attr: []} +}, "native types"); + +eyes.inspect({ + number: new(Number)(42), + string: new(String)("John Galt"), + regexp: new(RegExp)(/[a-z]+/), + array: new(Array)(99, 168, 'x', {}), + bool: new(Boolean)(false), + object: new(Object)({attr: []}), + date: new(Date) +}, "wrapped types"); + +var obj = {}; +obj.that = { self: obj }; +obj.self = obj; + +eyes.inspect(obj, "circular object"); +eyes.inspect({hello: 'moto'}, "small object"); +eyes.inspect({hello: new(Array)(6) }, "big object"); +eyes.inspect(["hello 'world'", 'hello "world"'], "quotes"); +eyes.inspect({ + recommendations: [{ + id: 'a7a6576c2c822c8e2bd81a27e41437d8', + key: [ 'spree', 3.764316258020699 ], + value: { + _id: 'a7a6576c2c822c8e2bd81a27e41437d8', + _rev: '1-2e2d2f7fd858c4a5984bcf809d22ed98', + type: 'domain', + domain: 'spree', + weight: 3.764316258020699, + product_id: 30 + } + }] +}, 'complex'); + +eyes.inspect([null], "null in array"); + +var inspect = eyes.inspector({ stream: null }); + +util.puts(inspect('something', "something")); +util.puts(inspect("something else")); + +util.puts(inspect(["no color"], null, { styles: false })); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/.npmignore b/node_modules/forever/node_modules/cliff/node_modules/winston/.npmignore new file mode 100644 index 0000000..2c5c40a --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/.npmignore @@ -0,0 +1,6 @@ +test/*.log +test/fixtures/*.json +test/fixtures/logs/*.log +node_modules/ +node_modules/* +npm-debug.log \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/.travis.yml b/node_modules/forever/node_modules/cliff/node_modules/winston/.travis.yml new file mode 100644 index 0000000..b250521 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - 0.4 + - 0.6 +branches: + only: + - master +notifications: + email: + - travis@nodejitsu.com + irc: "irc.freenode.org#nodejitsu" + diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/LICENSE b/node_modules/forever/node_modules/cliff/node_modules/winston/LICENSE new file mode 100644 index 0000000..948d80d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Charlie Robbins + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/README.md b/node_modules/forever/node_modules/cliff/node_modules/winston/README.md new file mode 100644 index 0000000..2fc4798 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/README.md @@ -0,0 +1,790 @@ +# winston [![Build Status](https://secure.travis-ci.org/flatiron/winston.png)](http://travis-ci.org/flatiron/winston) + +A multi-transport async logging library for node.js. "CHILL WINSTON! ... I put it in the logs." + +## Motivation +Winston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file. + +There also seemed to be a lot of logging libraries out there that coupled their implementation of logging (i.e. how the logs are stored / indexed) to the API that they exposed to the programmer. This library aims to decouple those parts of the process to make it more flexible and extensible. + +## Usage +There are two different ways to use winston: directly via the default logger, or by instantiating your own Logger. The former is merely intended to be a convenient shared logger to use throughout your application if you so choose. + +* [Logging](#logging) + * [Using the Default Logger](#using-the-default-logger) + * [Instantiating your own Logger](#instantiating-your-own-logger) + * [Logging with Metadata](#logging-with-metadata) +* [Transports](https://github.com/flatiron/winston/blob/master/docs/transports.md) +* [Profiling](#profiling) +* [Streaming Logs](#streaming-logs) +* [Querying Logs](#querying-logs) +* [Exceptions](#exceptions) + * [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston) + * [To Exit or Not to Exit](#to-exit-or-not-to-exit) +* [Logging Levels](#logging-levels) + * [Using Logging Levels](#using-logging-levels) + * [Using Custom Logging Levels](#using-custom-logging-levels) +* [Further Reading](#further-reading) + * [Events and Callbacks in Winston](#events-and-callbacks-in-winston) + * [Working with multiple Loggers in winston](#working-with-multiple-loggers-in-winston) + * [Using winston in a CLI tool](#using-winston-in-a-cli-tool) + * [Extending another object with Logging](#extending-another-object-with-logging) + * [Adding Custom Transports](#adding-custom-transports) + +## Logging + +### Using the Default Logger +The default logger is accessible through the winston module directly. Any method that you could call on an instance of a logger is available on the default logger: + +``` js + var winston = require('winston'); + + winston.log('info', 'Hello distributed log files!'); + winston.info('Hello again distributed logs'); +``` + +By default, only the Console transport is set on the default logger. You can add or remove transports via the add() and remove() methods: + +``` js + winston.add(winston.transports.File, { filename: 'somefile.log' }); + winston.remove(winston.transports.Console); +``` + +For more documenation about working with each individual transport supported by Winston see the "Working with Transports" section below. + +### Instantiating your own Logger +If you would prefer to manage the object lifetime of loggers you are free to instantiate them yourself: + +``` js + var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.File)({ filename: 'somefile.log' }) + ] + }); +``` + +You can work with this logger in the same way that you work with the default logger: + +``` js + // + // Logging + // + logger.log('info', 'Hello distributed log files!'); + logger.info('Hello again distributed logs'); + + // + // Adding / Removing Transports + // (Yes It's chainable) + // + logger.add(winston.transports.File) + .remove(winston.transports.Console); +``` + +### Logging with Metadata +In addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple: + +``` js + winston.log('info', 'Test Log Message', { anything: 'This is metadata' }); +``` + +The way these objects is stored varies from transport to transport (to best support the storage mechanisms offered). Here's a quick summary of how each transports handles metadata: + +1. __Console:__ Logged via util.inspect(meta) +2. __File:__ Logged via util.inspect(meta) + +## Profiling +In addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger: + +``` js + // + // Start profile of 'test' + // Remark: Consider using Date.now() with async operations + // + winston.profile('test'); + + setTimeout(function () { + // + // Stop profile of 'test'. Logging will now take place: + // "17 Jan 21:00:00 - info: test duration=1000ms" + // + winston.profile('test'); + }, 1000); +``` + +All profile messages are set to the 'info' by default and both message and metadata are optional There are no plans in the Roadmap to make this configurable, but I'm open to suggestions / issues. + + +## Querying Logs +Winston supports querying of logs with Loggly-like options. +Specifically: `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`. + +``` js + var options = { + from: new Date - 24 * 60 * 60 * 1000, + until: new Date + }; + + // + // Find items logged between today and yesterday. + // + winston.query(options, function (err, results) { + if (err) { + throw err; + } + + console.log(results); + }); +``` + +## Streaming Logs +Streaming allows you to stream your logs back from your chosen transport. + +``` js + // + // Start at the end. + // + winston.stream({ start: -1 }).on('log', function(log) { + console.log(log); + }); +``` + +## Exceptions + +### Handling Uncaught Exceptions with winston + +With `winston`, it is possible to catch and log `uncaughtException` events from your process. There are two distinct ways of enabling this functionality either through the default winston logger or your own logger instance. + +If you want to use this feature with the default logger simply call `.handleExceptions()` with a transport instance. + +``` js + // + // You can add a separate exception logger by passing it to `.handleExceptions` + // + winston.handleExceptions(new winston.transports.File({ filename: 'path/to/exceptions.log' })) + + // + // Alternatively you can set `.handleExceptions` to true when adding transports to winston + // + winston.add(winston.transports.File, { + filename: 'path/to/all-logs.log', + handleExceptions: true + }); +``` + +### To Exit or Not to Exit + +by default, winston will exit after logging an uncaughtException. if this is not the behavior you want, +set `exitOnError = false` + +``` js + var logger = new (winston.Logger)({ exitOnError: false }); + + // + // or, like this: + // + logger.exitOnError = false; +``` + +When working with custom logger instances, you can pass in separate transports to the `exceptionHandlers` property or set `.handleExceptions` on any transport. + +Example 1 + +``` js + var logger = new (winston.Logger)({ + transports: [ + new winston.transports.File({ filename: 'path/to/all-logs.log' }) + ] + exceptionHandlers: [ + new winston.transports.File({ filename: 'path/to/exceptions.log' }) + ] + }); +``` + +Example 2 + +``` +var logger = new winston.Logger({ + transports: [ + new winston.transports.Console({ + handleExceptions: true, + json: true + }) + ], + exitOnError: false +}); +``` + +The `exitOnError` option can also be a function to prevent exit on only certain types of errors: + +``` js + function ignoreEpipe(err) { + return err.code !== 'EPIPE'; + } + + var logger = new (winston.Logger)({ exitOnError: ignoreEpipe }); + + // + // or, like this: + // + logger.exitOnError = ignoreEpipe; +``` + +## Logging Levels + +### Using Logging Levels +Setting the level for your logging message can be accomplished in one of two ways. You can pass a string representing the logging level to the log() method or use the level specified methods defined on every winston Logger. + +``` js + // + // Any logger instance + // + logger.log('info', "127.0.0.1 - there's no place like home"); + logger.log('warn', "127.0.0.1 - there's no place like home"); + logger.log('error', "127.0.0.1 - there's no place like home"); + logger.info("127.0.0.1 - there's no place like home"); + logger.warn("127.0.0.1 - there's no place like home"); + logger.error("127.0.0.1 - there's no place like home"); + + // + // Default logger + // + winston.log('info', "127.0.0.1 - there's no place like home"); + winston.info("127.0.0.1 - there's no place like home"); +``` + +Winston allows you to set a `level` on each transport that specifies the level of messages this transport should log. For example, you could log only errors to the console, with the full logs in a file: + +``` js + var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)({ level: 'error' }), + new (winston.transports.File)({ filename: 'somefile.log' }) + ] + }); +``` + +As of 0.2.0, winston supports customizable logging levels, defaulting to [npm][0] style logging levels. Changing logging levels is easy: + +``` js + // + // Change levels on the default winston logger + // + winston.setLevels(winston.config.syslog.levels); + + // + // Change levels on an instance of a logger + // + logger.setLevels(winston.config.syslog.levels); +``` + +Calling `.setLevels` on a logger will remove all of the previous helper methods for the old levels and define helper methods for the new levels. Thus, you should be careful about the logging statements you use when changing levels. For example, if you ran this code after changing to the syslog levels: + +``` js + // + // Logger does not have 'silly' defined since that level is not in the syslog levels + // + logger.silly('some silly message'); +``` + +### Using Custom Logging Levels +In addition to the predefined `npm` and `syslog` levels available in Winston, you can also choose to define your own: + +``` js + var myCustomLevels = { + levels: { + foo: 0, + bar: 1, + baz: 2, + foobar: 3 + }, + colors: { + foo: 'blue', + bar: 'green', + baz: 'yellow', + foobar: 'red' + } + }; + + var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels }); + customLevelLogger.foobar('some foobar level-ed message'); +``` + +Although there is slight repetition in this data structure, it enables simple encapsulation if you not to have colors. If you do wish to have colors, in addition to passing the levels to the Logger itself, you must make winston aware of them: + +``` js + // + // Make winston aware of these colors + // + winston.addColors(myCustomLevels.colors); +``` + +This enables transports with the 'colorize' option set to appropriately color the output of custom levels. + +## Further Reading + +### Events and Callbacks in Winston +Each instance of winston.Logger is also an instance of an [EventEmitter][1]. A log event will be raised each time a transport successfully logs a message: + +``` js + logger.on('logging', function (transport, level, msg, meta) { + // [msg] and [meta] have now been logged at [level] to [transport] + }); + + logger.info('CHILL WINSTON!', { seriously: true }); +``` + +It is also worth mentioning that the logger also emits an 'error' event which you should handle or suppress if you don't want unhandled exceptions: + +``` js + // + // Handle errors + // + logger.on('error', function (err) { /* Do Something */ }); + + // + // Or just suppress them. + // + logger.emitErrs = false; +``` + +Every logging method described in the previous section also takes an optional callback which will be called only when all of the transports have logged the specified message. + +``` js + logger.info('CHILL WINSTON!', { seriously: true }, function (err, level, msg, meta) { + // [msg] and [meta] have now been logged at [level] to **every** transport. + }); +``` + +### Working with multiple Loggers in winston + +Often in larger, more complex applications it is necessary to have multiple logger instances with different settings. Each logger is responsible for a different feature area (or category). This is exposed in `winston` in two ways: through `winston.loggers` and instances of `winston.Container`. In fact, `winston.loggers` is just a predefined instance of `winston.Container`: + +``` js + var winston = require('winston'); + + // + // Configure the logger for `category1` + // + winston.loggers.add('category1', { + console: { + level: 'silly', + colorize: 'true' + }, + file: { + filename: '/path/to/some/file' + } + }); + + // + // Configure the logger for `category2` + // + winston.loggers.add('category2', { + couchdb: { + host: '127.0.0.1', + port: 5984 + } + }); +``` + +Now that your loggers are setup you can require winston _in any file in your application_ and access these pre-configured loggers: + +``` js + var winston = require('winston'); + + // + // Grab your preconfigured logger + // + var category1 = winston.loggers.get('category1'); + + category1.info('logging from your IoC container-based logger'); +``` + +If you prefer to manage the `Container` yourself you can simply instantiate one: + +``` js + var winston = require('winston'), + container = new winston.Container(); + + container.add('category1', { + console: { + level: 'silly', + colorize: 'true' + }, + file: { + filename: '/path/to/some/file' + } + }); +``` + +### Sharing transports between Loggers in winston + +``` js + var winston = require('winston'); + + // + // Setup transports to be shared across all loggers + // in three ways: + // + // 1. By setting it on the default Container + // 2. By passing `transports` into the constructor function of winston.Container + // 3. By passing `transports` into the `.get()` or `.add()` methods + // + + // + // 1. By setting it on the default Container + // + winston.loggers.options.transports = [ + // Setup your shared transports here + ]; + + // + // 2. By passing `transports` into the constructor function of winston.Container + // + var container = new winston.Container({ + transports: [ + // Setup your shared transports here + ] + }); + + // + // 3. By passing `transports` into the `.get()` or `.add()` methods + // + winston.loggers.add('some-category', { + transports: [ + // Setup your shared transports here + ] + }); + + container.add('some-category', { + transports: [ + // Setup your shared transports here + ] + }); +``` + +### Using winston in a CLI tool +A common use-case for logging is output to a CLI tool. Winston has a special helper method which will pretty print output from your CLI tool. Here's an example from the [require-analyzer][2] written by [Nodejitsu][3]: + +``` + info: require-analyzer starting in /Users/Charlie/Nodejitsu/require-analyzer + info: Found existing dependencies + data: { + data: colors: '0.x.x', + data: eyes: '0.1.x', + data: findit: '0.0.x', + data: npm: '1.0.x', + data: optimist: '0.2.x', + data: semver: '1.0.x', + data: winston: '0.2.x' + data: } + info: Analyzing dependencies... + info: Done analyzing raw dependencies + info: Retrieved packages from npm + warn: No additional dependencies found +``` + +Configuring output for this style is easy, just use the `.cli()` method on `winston` or an instance of `winston.Logger`: + +``` js + var winston = require('winston'); + + // + // Configure CLI output on the default logger + // + winston.cli(); + + // + // Configure CLI on an instance of winston.Logger + // + var logger = new winston.Logger({ + transports: [ + new (winston.transports.Console)() + ] + }); + + logger.cli(); +``` + +### Extending another object with Logging +Often in a given code base with lots of Loggers it is useful to add logging methods a different object so that these methods can be called with less syntax. Winston exposes this functionality via the 'extend' method: + +``` js + var myObject = {}; + + logger.extend(myObject); + + // + // You can now call logger methods on 'myObject' + // + myObject.info('127.0.0.1 - there's no place like home'); +``` + +## Working with Transports +Right now there are four transports supported by winston core. If you have a transport you would like to add either open an issue or fork and submit a pull request. Commits are welcome, but I'll give you extra street cred if you __add tests too :D__ + +1. __Console:__ Output to the terminal +2. __Files:__ Append to a file +3. __Loggly:__ Log to Logging-as-a-Service platform Loggly + +### Console Transport +``` js + winston.add(winston.transports.Console, options) +``` + +The Console transport takes two simple options: + +* __level:__ Level of messages that this transport should log (default 'info'). +* __silent:__ Boolean flag indicating whether to suppress output (default false). +* __colorize:__ Boolean flag indicating if we should colorize output (default false). +* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps. + +*Metadata:* Logged via util.inspect(meta); + +### File Transport +``` js + winston.add(winston.transports.File, options) +``` + +The File transport should really be the 'Stream' transport since it will accept any [WritableStream][14]. It is named such because it will also accept filenames via the 'filename' option: + +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. +* __colorize:__ Boolean flag indicating if we should colorize output. +* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default true). If function is specified, its return value will be used instead of timestamps. +* __filename:__ The filename of the logfile to write output to. +* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created. +* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded. +* __stream:__ The WriteableStream to write output to. +* __json:__ If true, messages will be logged as JSON (default true). + +*Metadata:* Logged via util.inspect(meta); + +### Loggly Transport +``` js + var Loggly = require('winston-loggly').Loggly + winston.add(Loggly, options); +``` + +The Loggly transport is based on [Nodejitsu's][5] [node-loggly][6] implementation of the [Loggly][7] API. If you haven't heard of Loggly before, you should probably read their [value proposition][8]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required: + +* __level:__ Level of messages that this transport should log. +* __subdomain:__ The subdomain of your Loggly account. *[required]* +* __auth__: The authentication information for your Loggly account. *[required with inputName]* +* __inputName:__ The name of the input this instance should log to. +* __inputToken:__ The input token of the input this instance should log to. +* __json:__ If true, messages will be sent to Loggly as JSON. + +*Metadata:* Logged in suggested [Loggly format][2] + +### Riak Transport +As of `0.3.0` the Riak transport has been broken out into a new module: [winston-riak][17]. Using it is just as easy: + +``` js + var Riak = require('winston-riak').Riak; + winston.add(Riak, options); +``` + +In addition to the options accepted by the [riak-js][3] [client][4], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default: + +* __level:__ Level of messages that this transport should log. +* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically. + +``` js + // Use a single bucket for all your logs + var singleBucketTransport = new (Riak)({ bucket: 'some-logs-go-here' }); + + // Generate a dynamic bucket based on the date and level + var dynamicBucketTransport = new (Riak)({ + bucket: function (level, msg, meta, now) { + var d = new Date(now); + return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-'); + } + }); +``` + +*Metadata:* Logged as JSON literal in Riak + +### MongoDB Transport +As of `0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][16]. Using it is just as easy: + +``` js + var MongoDB = require('winston-mongodb').MongoDB; + winston.add(MongoDB, options); +``` + +The MongoDB transport takes the following options. 'db' is required: + +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. +* __db:__ The name of the database you want to log to. *[required]* +* __collection__: The name of the collection you want to store log messages in, defaults to 'log'. +* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true. +* __host:__ The host running MongoDB, defaults to localhost. +* __port:__ The port on the host that MongoDB is running on, defaults to MongoDB's default port. + +*Metadata:* Logged as a native JSON object. + +### SimpleDB Transport + +The [winston-simpledb][18] transport is just as easy: + +``` js + var SimpleDB = require('winston-simpledb').SimpleDB; + winston.add(SimpleDB, options); +``` + +The SimpleDB transport takes the following options. All items marked with an asterisk are required: + +* __awsAccessKey__:* your AWS Access Key +* __secretAccessKey__:* your AWS Secret Access Key +* __awsAccountId__:* your AWS Account Id +* __domainName__:* a string or function that returns the domain name to log to +* __region__:* the region your domain resides in +* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log + +*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item. + +### Mail Transport + +The [winston-mail][19] is an email transport: + +``` js + var Mail = require('winston-mail').Mail; + winston.add(Mail, options); +``` + +The Mail transport uses [emailjs](https://github.com/eleith/emailjs) behind the scenes. Options are the following: + +* __to:__ The address(es) you want to send to. *[required]* +* __from:__ The address you want to send from. (default: `winston@[server-host-name]`) +* __host:__ SMTP server hostname (default: localhost) +* __port:__ SMTP port (default: 587 or 25) +* __username__ User for server auth +* __password__ Password for server auth +* __ssl:__ Use SSL (boolean or object { key, ca, cert }) +* __tls:__ Boolean (if true, use starttls) +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. + +*Metadata:* Stringified as JSON in email. + +### Amazon SNS (Simple Notification System) Transport + +The [winston-sns][21] transport uses amazon SNS to send emails, texts, or a bunch of other notifications. + +``` js + require('winston-sns').SNS; + winston.add(winston.transports.SNS, options); +``` + +Options: + +* __aws_key:__ Your Amazon Web Services Key. *[required]* +* __aws_secret:__ Your Amazon Web Services Secret. *[required]* +* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]* +* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]* +* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`) +* __subject:__ Subject for notifications. (default: "Winston Error Report") +* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Level '%l' Error:\n%e\n\nMetadata:\n%m") +* __level:__ lowest level this transport will log. (default: `info`) + +### Graylog2 Transport + +[winston-graylog2][22] is a Graylog2 transport: + +``` js + var Graylog2 = require('winston-graylog2').Graylog2; + winston.add(Graylog2, options); +``` + +The Graylog2 transport connects to a Graylog2 server over UDP using the following options: + +* __level:__ Level of messages this transport should log. (default: info) +* __silent:__ Boolean flag indicating whether to suppress output. (default: false) + +* __graylogHost:__ IP address or hostname of the graylog2 server. (default: localhost) +* __graylogPort:__ Port to send messages to on the graylog2 server. (default: 12201) +* __graylogHostname:__ The hostname associated with graylog2 messages. (default: require('os').hostname()) +* __graylogFacility:__ The graylog2 facility to send log messages.. (default: nodejs) + +*Metadata:* Stringified as JSON in the full message GELF field. + +### Adding Custom Transports +Adding a custom transport (say for one of the datastore on the Roadmap) is actually pretty easy. All you need to do is accept a couple of options, set a name, implement a log() method, and add it to the set of transports exposed by winston. + +``` js + var util = require('util'), + winston = require('winston'); + + var CustomLogger = winston.transports.CustomerLogger = function (options) { + // + // Name this logger + // + this.name = 'customLogger'; + + // + // Set the level from your options + // + this.level = options.level || 'info'; + + // + // Configure your storage backing as you see fit + // + }; + + // + // Inherit from `winston.Transport` so you can take advantage + // of the base functionality and `.handleExceptions()`. + // + util.inherits(CustomLogger, winston.Transport); + + CustomLogger.prototype.log = function (level, msg, meta, callback) { + // + // Store this message and metadata, maybe use some custom logic + // then callback indicating success. + // + callback(null, true); + }; +``` + +### Inspirations +1. [npm][0] +2. [log.js][4] +3. [socket.io][5] +4. [node-rlog][6] +5. [BigBrother][7] +6. [Loggly][8] + +## Installation + +### Installing npm (node package manager) +``` + curl http://npmjs.org/install.sh | sh +``` + +### Installing winston +``` + [sudo] npm install winston +``` + +## Run Tests +All of the winston tests are written in [vows][9], and designed to be run with npm. + +``` bash + $ npm test +``` + +#### Author: [Charlie Robbins](http://twitter.com/indexzero) +#### Contributors: [Matthew Bergman](http://github.com/fotoverite), [Marak Squires](http://github.com/marak) + +[0]: https://github.com/isaacs/npm/blob/master/lib/utils/log.js +[1]: http://nodejs.org/docs/v0.3.5/api/events.html#events.EventEmitter +[2]: http://github.com/nodejitsu/require-analyzer +[3]: http://nodejitsu.com +[4]: https://github.com/visionmedia/log.js +[5]: http://socket.io +[6]: https://github.com/jbrisbin/node-rlog +[7]: https://github.com/feisty/BigBrother +[8]: http://loggly.com +[9]: http://vowsjs.org diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/docs/transports.md b/node_modules/forever/node_modules/cliff/node_modules/winston/docs/transports.md new file mode 100644 index 0000000..5930ad4 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/docs/transports.md @@ -0,0 +1,342 @@ +# Winston Transports + +In `winston` a transport a transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file. + +There are several [core transports](#winston-core) included in `winston`, which leverage the built-in networking and file I/O offered by node.js core. In addition, there are [third-party transports which are supported by the winston core team](#winston-more). And last (but not least) there are [additional transports written by members of the community](#additional-transports). + +* **[Winston Core](#winston-core)** + * [Console](#console-transport) + * [File](#file-transport) + * [Http](#http-transport) + * [Webhook](#webhook-transport) + +* **[Winston More](#winston-more)** + * [CouchDB](#couchdb-transport) + * [Loggly](#loggly-transport) + * [MongoDB](#mongodb-transport) + * [Redis](#redis-transport) + * [Riak](#riak-transport) + +* **[Additional Transports](#additional-transports)** + * [SimpleDB](#simpledb-transport) + * [Mail](#mail-transport) + * [Amazon SNS](#amazon-sns-simple-notification-system-transport) + * [Graylog2](#graylog2-transport) + +## Winston Core + +There are several core transports included in `winston`, which leverage the built-in networking and file I/O offered by node.js core. + +* [Console](#console-transport) +* [File](#file-transport) +* [Http](#http-transport) +* [Webhook](#webhook-transport) + +### Console Transport + +``` js + winston.add(winston.transports.Console, options) +``` + +The Console transport takes two simple options: + +* __level:__ Level of messages that this transport should log (default 'debug'). +* __silent:__ Boolean flag indicating whether to suppress output (default false). +* __colorize:__ Boolean flag indicating if we should colorize output (default false). +* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps. + +*Metadata:* Logged via util.inspect(meta); + +### File Transport + +``` js + winston.add(winston.transports.File, options) +``` + +The File transport should really be the 'Stream' transport since it will accept any [WritableStream][0]. It is named such because it will also accept filenames via the 'filename' option: + +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. +* __colorize:__ Boolean flag indicating if we should colorize output. +* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps. +* __filename:__ The filename of the logfile to write output to. +* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created. +* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded. +* __stream:__ The WriteableStream to write output to. +* __json:__ If true, messages will be logged as JSON (default true). + +*Metadata:* Logged via util.inspect(meta); + +### Http Transport + +``` js + winston.add(winston.transports.Http, options) +``` + +The `Http` transport is a generic way to log, query, and stream logs from an arbitrary Http endpoint, preferably [winstond][1]. It takes options that are passed to the node.js `http` or `https` request: + +* __host:__ (Default: **localhost**) Remote host of the HTTP logging endpoint +* __port:__ (Default: **80 or 443**) Remote port of the HTTP logging endpoint +* __path:__ (Default: **/**) Remote URI of the HTTP logging endpoint +* __auth:__ (Default: **None**) An object representing the `username` and `password` for HTTP Basic Auth +* __ssl:__ (Default: **false**) Value indicating if we should us HTTPS + +## Winston More + +Starting with `winston@0.3.0` an effort was made to remove any transport which added additional dependencies to `winston`. At the time there were several transports already in `winston` which will **always be supported by the winston core team.** + +* [CouchDB](#couchdb-transport) +* [Redis](#redis-transport) +* [MongoDB](#mongodb-transport) +* [Riak](#riak-transport) +* [Loggly](#loggly-transport) + +### CouchDB Transport + +_As of `winston@0.6.0` the CouchDB transport has been broken out into a new module: [winston-couchdb][2]._ + +``` js + winston.add(winston.transports.Couchdb, options) +``` + +The `Couchdb` will place your logs in a remote CouchDB database. It will also create a [Design Document][3], `_design/Logs` for later querying and streaming your logs from CouchDB. The transport takes the following options: + +* __host:__ (Default: **localhost**) Remote host of the HTTP logging endpoint +* __port:__ (Default: **5984**) Remote port of the HTTP logging endpoint +* __db:__ (Default: **winston**) Remote URI of the HTTP logging endpoint +* __auth:__ (Default: **None**) An object representing the `username` and `password` for HTTP Basic Auth +* __ssl:__ (Default: **false**) Value indicating if we should us HTTPS + +### Redis Transport + +``` js + winston.add(winston.transports.Redis, options) +``` + +This transport accepts the options accepted by the [node-redis][4] client: + +* __host:__ (Default **localhost**) Remote host of the Redis server +* __port:__ (Default **6379**) Port the Redis server is running on. +* __auth:__ (Default **None**) Password set on the Redis server + +In addition to these, the Redis transport also accepts the following options. + +* __length:__ (Default **200**) Number of log messages to store. +* __container:__ (Default **winston**) Name of the Redis container you wish your logs to be in. +* __channel:__ (Default **None**) Name of the Redis channel to stream logs from. + +*Metadata:* Logged as JSON literal in Redis + +### Loggly Transport + +_As of `winston@0.6.0` the Loggly transport has been broken out into a new module: [winston-loggly][5]._ + +``` js + winston.add(winston.transports.Loggly, options); +``` + +The Loggly transport is based on [Nodejitsu's][6] [node-loggly][7] implementation of the [Loggly][8] API. If you haven't heard of Loggly before, you should probably read their [value proposition][9]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required: + +* __level:__ Level of messages that this transport should log. +* __subdomain:__ The subdomain of your Loggly account. *[required]* +* __auth__: The authentication information for your Loggly account. *[required with inputName]* +* __inputName:__ The name of the input this instance should log to. +* __inputToken:__ The input token of the input this instance should log to. +* __json:__ If true, messages will be sent to Loggly as JSON. + +*Metadata:* Logged in suggested [Loggly format][10] + +### Riak Transport + +_As of `winston@0.3.0` the Riak transport has been broken out into a new module: [winston-riak][11]._ Using it is just as easy: + +``` js + var Riak = require('winston-riak').Riak; + winston.add(Riak, options); +``` + +In addition to the options accepted by the [riak-js][12] [client][13], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default: + +* __level:__ Level of messages that this transport should log. +* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically. + +``` js + // Use a single bucket for all your logs + var singleBucketTransport = new (Riak)({ bucket: 'some-logs-go-here' }); + + // Generate a dynamic bucket based on the date and level + var dynamicBucketTransport = new (Riak)({ + bucket: function (level, msg, meta, now) { + var d = new Date(now); + return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-'); + } + }); +``` + +*Metadata:* Logged as JSON literal in Riak + +### MongoDB Transport + +As of `winston@0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][14]. Using it is just as easy: + +``` js + var MongoDB = require('winston-mongodb').MongoDB; + winston.add(MongoDB, options); +``` + +The MongoDB transport takes the following options. 'db' is required: + +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. +* __db:__ The name of the database you want to log to. *[required]* +* __collection__: The name of the collection you want to store log messages in, defaults to 'log'. +* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true. +* __host:__ The host running MongoDB, defaults to localhost. +* __port:__ The port on the host that MongoDB is running on, defaults to MongoDB's default port. + +*Metadata:* Logged as a native JSON object. + +## Additional Transports + +The community has truly embraced `winston`; there are over **23** winston transports and over half of them are maintained by authors external to the winston core team. If you want to check them all out, just search `npm`: + +``` bash + $ npm search winston +``` + +**If you have an issue using one of these modules you should contact the module author directly** + +### SimpleDB Transport + +The [winston-simpledb][15] transport is just as easy: + +``` js + var SimpleDB = require('winston-simpledb').SimpleDB; + winston.add(SimpleDB, options); +``` + +The SimpleDB transport takes the following options. All items marked with an asterisk are required: + +* __awsAccessKey__:* your AWS Access Key +* __secretAccessKey__:* your AWS Secret Access Key +* __awsAccountId__:* your AWS Account Id +* __domainName__:* a string or function that returns the domain name to log to +* __region__:* the region your domain resides in +* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log + +*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item. + +### Mail Transport + +The [winston-mail][16] is an email transport: + +``` js + var Mail = require('winston-mail').Mail; + winston.add(Mail, options); +``` + +The Mail transport uses [node-mail][17] behind the scenes. Options are the following, `to` and `host` are required: + +* __to:__ The address(es) you want to send to. *[required]* +* __from:__ The address you want to send from. (default: `winston@[server-host-name]`) +* __host:__ SMTP server hostname +* __port:__ SMTP port (default: 587 or 25) +* __secure:__ Use secure +* __username__ User for server auth +* __password__ Password for server auth +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. + +*Metadata:* Stringified as JSON in email. + +### Amazon SNS (Simple Notification System) Transport + +The [winston-sns][18] transport uses amazon SNS to send emails, texts, or a bunch of other notifications. + +``` js + require('winston-sns').SNS; + winston.add(winston.transports.SNS, options); +``` + +Options: + +* __aws_key:__ Your Amazon Web Services Key. *[required]* +* __aws_secret:__ Your Amazon Web Services Secret. *[required]* +* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]* +* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]* +* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`) +* __subject:__ Subject for notifications. (default: "Winston Error Report") +* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Level '%l' Error:\n%e\n\nMetadata:\n%m") +* __level:__ lowest level this transport will log. (default: `info`) + +### Graylog2 Transport + +[winston-graylog2][19] is a Graylog2 transport: + +``` js + var Graylog2 = require('winston-graylog2').Graylog2; + winston.add(Graylog2, options); +``` + +The Graylog2 transport connects to a Graylog2 server over UDP using the following options: + +* __level:__ Level of messages this transport should log. (default: info) +* __silent:__ Boolean flag indicating whether to suppress output. (default: false) + +* __graylogHost:__ IP address or hostname of the graylog2 server. (default: localhost) +* __graylogPort:__ Port to send messages to on the graylog2 server. (default: 12201) +* __graylogHostname:__ The hostname associated with graylog2 messages. (default: require('os').hostname()) +* __graylogFacility:__ The graylog2 facility to send log messages.. (default: nodejs) + +*Metadata:* Stringified as JSON in the full message GELF field. + +## Find more Transports + +``` bash + $ npm search winston + (...) + winston-amon Winston transport for Amon logging =zoramite + winston-amqp An AMQP transport for winston =kr1sp1n + winston-couchdb a couchdb transport for winston =alz + winston-express Express middleware to let you use winston from the browser. =regality + winston-graylog2 A graylog2 transport for winston =smithclay + winston-hbase A HBase transport for winston =ddude + winston-loggly A Loggly transport for winston =indexzero + winston-mail A mail transport for winston =wavded + winston-mail2 A mail transport for winston =ivolo + winston-mongodb A MongoDB transport for winston =indexzero + winston-nodemail A mail transport for winston =reinpk + winston-nssocket nssocket transport for winston =mmalecki + winston-papertrail A Papertrail transport for winston =kenperkins + winston-redis A fixed-length Redis transport for winston =indexzero + winston-riak A Riak transport for winston =indexzero + winston-scribe A scribe transport for winston =wnoronha + winston-simpledb A Winston transport for Amazon SimpleDB =chilts + winston-skywriter A Windows Azure table storage transport for winston =pofallon + winston-sns A Simple Notification System Transport for winston =jesseditson + winston-syslog A syslog transport for winston =indexzero + winston-syslog-ain2 An ain2 based syslog transport for winston =lamtha + winston-winlog Windows Event Log logger for Winston =jfromaniello + winston-zmq A 0MQ transport for winston =dhendo +``` + +[0]: http://nodejs.org/docs/v0.3.5/api/streams.html#writable_Stream +[1]: https://github.com/flatiron/winstond +[2]: https://github.com/indexzero/winston-couchdb +[3]: http://guide.couchdb.org/draft/design.html +[4]: https://github.com/mranney/node_redis +[5]: https://github.com/indexzero/winston-loggly +[6]: http://nodejitsu.com +[7]: https://github.com/nodejitsu/node-loggly +[8]: http://loggly.com +[9]: http://www.loggly.com/product/ +[10]: http://wiki.loggly.com/loggingfromcode +[11]: https://github.com/indexzero/winston-riak +[12]: http://riakjs.org +[13]: https://github.com/frank06/riak-js/blob/master/src/http_client.coffee#L10 +[14]: http://github.com/indexzero/winston-mongodb +[15]: http://github.com/appsattic/winston-simpledb +[16]: http://github.com/wavded/winston-mail +[17]: https://github.com/weaver/node-mail +[18]: https://github.com/jesseditson/winston-sns +[19]: https://github.com/flite/winston-graylog2 diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/examples/couchdb.js b/node_modules/forever/node_modules/cliff/node_modules/winston/examples/couchdb.js new file mode 100644 index 0000000..ce2d960 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/examples/couchdb.js @@ -0,0 +1,18 @@ +var winston = require('../lib/winston'); + +// +// Create a new winston logger instance with two tranports: Console, and Couchdb +// +// +// The Console transport will simply output to the console screen +// The Couchdb tranport will perform an HTTP POST request to the specified CouchDB instance +// +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.Couchdb)({ 'host': 'localhost', 'db': 'logs' }) + // if you need auth do this: new (winston.transports.Couchdb)({ 'user': 'admin', 'pass': 'admin', 'host': 'localhost', 'db': 'logs' }) + ] +}); + +logger.log('info', 'Hello webhook log files!', { 'foo': 'bar' }); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/examples/exception.js b/node_modules/forever/node_modules/cliff/node_modules/winston/examples/exception.js new file mode 100644 index 0000000..99f605b --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/examples/exception.js @@ -0,0 +1,4 @@ +var winston = require('../'); +winston.handleExceptions(new winston.transports.Console({ colorize: true, json: true })); + +throw new Error('Hello, winston!'); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/examples/raw-mode.js b/node_modules/forever/node_modules/cliff/node_modules/winston/examples/raw-mode.js new file mode 100644 index 0000000..89e070d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/examples/raw-mode.js @@ -0,0 +1,10 @@ +var winston = require('../lib/winston'); + +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)({ raw: true }), + ] +}); + +logger.log('info', 'Hello, this is a raw logging event', { 'foo': 'bar' }); +logger.log('info', 'Hello, this is a raw logging event 2', { 'foo': 'bar' }); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/examples/webhook-post.js b/node_modules/forever/node_modules/cliff/node_modules/winston/examples/webhook-post.js new file mode 100644 index 0000000..0fa1c8d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/examples/webhook-post.js @@ -0,0 +1,17 @@ +var winston = require('../lib/winston'); + +// +// Create a new winston logger instance with two tranports: Console, and Webhook +// +// +// The Console transport will simply output to the console screen +// The Webhook tranports will perform an HTTP POST request to an abritrary end-point ( for post/recieve webhooks ) +// +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.Webhook)({ 'host': 'localhost', 'port': 8080, 'path': '/collectdata' }) + ] +}); + +logger.log('info', 'Hello webhook log files!', { 'foo': 'bar' }); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston.js new file mode 100644 index 0000000..b8fea28 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston.js @@ -0,0 +1,145 @@ +/* + * winston.js: Top-level include defining Winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var winston = exports; + +// +// Expose version using `pkginfo` +// +require('pkginfo')(module, 'version'); + +// +// Include transports defined by default by winston +// +winston.transports = require('./winston/transports'); + +// +// Expose utility methods +// +var common = require('./winston/common'); +winston.hash = common.hash; +winston.clone = common.clone; +winston.longestElement = common.longestElement; +winston.exception = require('./winston/exception'); +winston.config = require('./winston/config'); +winston.addColors = winston.config.addColors; + +// +// Expose core Logging-related prototypes. +// +winston.Container = require('./winston/container').Container; +winston.Logger = require('./winston/logger').Logger; +winston.Transport = require('./winston/transports/transport').Transport; + +// +// We create and expose a default `Container` to `winston.loggers` so that the +// programmer may manage multiple `winston.Logger` instances without any additional overhead. +// +// ### some-file1.js +// +// var logger = require('winston').loggers.get('something'); +// +// ### some-file2.js +// +// var logger = require('winston').loggers.get('something'); +// +winston.loggers = new winston.Container(); + +// +// We create and expose a 'defaultLogger' so that the programmer may do the +// following without the need to create an instance of winston.Logger directly: +// +// var winston = require('winston'); +// winston.log('info', 'some message'); +// winston.error('some error'); +// +var defaultLogger = new winston.Logger({ + transports: [new winston.transports.Console()] +}); + +// +// Pass through the target methods onto `winston. +// +var methods = [ + 'log', + 'query', + 'stream', + 'add', + 'remove', + 'profile', + 'startTimer', + 'extend', + 'cli', + 'handleExceptions', + 'unhandleExceptions' +]; +common.setLevels(winston, null, defaultLogger.levels); +methods.forEach(function (method) { + winston[method] = function () { + return defaultLogger[method].apply(defaultLogger, arguments); + }; +}); + +// +// ### function cli () +// Configures the default winston logger to have the +// settings for command-line interfaces: no timestamp, +// colors enabled, padded output, and additional levels. +// +winston.cli = function () { + winston.padLevels = true; + common.setLevels(winston, defaultLogger.levels, winston.config.cli.levels); + defaultLogger.setLevels(winston.config.cli.levels); + winston.config.addColors(winston.config.cli.colors); + + if (defaultLogger.transports.console) { + defaultLogger.transports.console.colorize = true; + defaultLogger.transports.console.timestamp = false; + } + + return winston; +}; + +// +// ### function setLevels (target) +// #### @target {Object} Target levels to use +// Sets the `target` levels specified on the default winston logger. +// +winston.setLevels = function (target) { + common.setLevels(winston, defaultLogger.levels, target); + defaultLogger.setLevels(target); +}; + +// +// Define getters / setters for appropriate properties of the +// default logger which need to be exposed by winston. +// +['emitErrs', 'exitOnError', 'padLevels', 'level', 'levelLength', 'stripColors'].forEach(function (prop) { + Object.defineProperty(winston, prop, { + get: function () { + return defaultLogger[prop]; + }, + set: function (val) { + defaultLogger[prop] = val; + } + }); +}); + +// +// @default {Object} +// The default transports and exceptionHandlers for +// the default winston logger. +// +Object.defineProperty(winston, 'default', { + get: function () { + return { + transports: defaultLogger.transports, + exceptionHandlers: defaultLogger.exceptionHandlers + }; + } +}); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/common.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/common.js new file mode 100644 index 0000000..c67a878 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/common.js @@ -0,0 +1,259 @@ +/* + * common.js: Internal helper and utility functions for winston + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var util = require('util'), + crypto = require('crypto'), + cycle = require('cycle'), + config = require('./config'); + +// +// ### function setLevels (target, past, current) +// #### @target {Object} Object on which to set levels. +// #### @past {Object} Previous levels set on target. +// #### @current {Object} Current levels to set on target. +// Create functions on the target objects for each level +// in current.levels. If past is defined, remove functions +// for each of those levels. +// +exports.setLevels = function (target, past, current, isDefault) { + if (past) { + Object.keys(past).forEach(function (level) { + delete target[level]; + }); + } + + target.levels = current || config.npm.levels; + if (target.padLevels) { + target.levelLength = exports.longestElement(Object.keys(target.levels)); + } + + // + // Define prototype methods for each log level + // e.g. target.log('info', msg) <=> target.info(msg) + // + Object.keys(target.levels).forEach(function (level) { + target[level] = function (msg) { + var args = Array.prototype.slice.call(arguments), + callback = typeof args[args.length - 1] === 'function' || !args[args.length - 1] ? args.pop() : null, + meta = args.length === 2 ? args.pop() : null; + + return target.log(level, msg, meta, callback); + }; + }); + + return target; +}; + +// +// ### function longestElement +// #### @xs {Array} Array to calculate against +// Returns the longest element in the `xs` array. +// +exports.longestElement = function (xs) { + return Math.max.apply( + null, + xs.map(function (x) { return x.length; }) + ); +}; + +// +// ### function clone (obj) +// #### @obj {Object} Object to clone. +// Helper method for deep cloning pure JSON objects +// i.e. JSON objects that are either literals or objects (no Arrays, etc) +// +exports.clone = function (obj) { + // we only need to clone refrence types (Object) + if (!(obj instanceof Object)) { + return obj; + } + else if (obj instanceof Date) { + return obj; + } + + var copy = {}; + for (var i in obj) { + if (Array.isArray(obj[i])) { + copy[i] = obj[i].slice(0); + } + else if (obj[i] instanceof Buffer) { + copy[i] = obj[i].slice(0); + } + else if (typeof obj[i] != 'function') { + copy[i] = obj[i] instanceof Object ? exports.clone(obj[i]) : obj[i]; + } + } + + return copy; +}; + +// +// ### function log (options) +// #### @options {Object} All information about the log serialization. +// Generic logging function for returning timestamped strings +// with the following options: +// +// { +// level: 'level to add to serialized message', +// message: 'message to serialize', +// meta: 'additional logging metadata to serialize', +// colorize: false, // Colorizes output (only if `.json` is false) +// timestamp: true // Adds a timestamp to the serialized message +// } +// +exports.log = function (options) { + var timestampFn = typeof options.timestamp === 'function' + ? options.timestamp + : exports.timestamp, + timestamp = options.timestamp ? timestampFn() : null, + meta = options.meta ? exports.clone(cycle.decycle(options.meta)) : null, + output; + + // + // raw mode is intended for outputing winston as streaming JSON to STDOUT + // + if (options.raw) { + if (typeof meta !== 'object' && meta != null) { + meta = { meta: meta }; + } + output = exports.clone(meta) || {}; + output.level = options.level; + output.message = options.message.stripColors; + return JSON.stringify(output); + } + + // + // json mode is intended for pretty printing multi-line json to the terminal + // + if (options.json) { + if (typeof meta !== 'object' && meta != null) { + meta = { meta: meta }; + } + + output = exports.clone(meta) || {}; + output.level = options.level; + output.message = options.message; + + if (timestamp) { + output.timestamp = timestamp; + } + + if (typeof options.stringify === 'function') { + return options.stringify(output); + } + + return JSON.stringify(output, function (key, value) { + return value instanceof Buffer + ? value.toString('base64') + : value; + }); + } + + output = timestamp ? timestamp + ' - ' : ''; + output += options.colorize ? config.colorize(options.level) : options.level; + output += (': ' + options.message); + + if (meta) { + if (typeof meta !== 'object') { + output += ' ' + meta; + } + else if (Object.keys(meta).length > 0) { + output += ' ' + (options.prettyPrint ? ('\n' + util.inspect(meta, false, null, options.colorize)) : exports.serialize(meta)); + } + } + + return output; +}; + +exports.capitalize = function (str) { + return str && str[0].toUpperCase() + str.slice(1); +}; + +// +// ### function hash (str) +// #### @str {string} String to hash. +// Utility function for creating unique ids +// e.g. Profiling incoming HTTP requests on the same tick +// +exports.hash = function (str) { + return crypto.createHash('sha1').update(str).digest('hex'); +}; + +// +// ### function pad (n) +// Returns a padded string if `n < 10`. +// +exports.pad = function (n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +}; + +// +// ### function timestamp () +// Returns a timestamp string for the current time. +// +exports.timestamp = function () { + return new Date().toISOString(); +}; + +// +// ### function serialize (obj, key) +// #### @obj {Object|literal} Object to serialize +// #### @key {string} **Optional** Optional key represented by obj in a larger object +// Performs simple comma-separated, `key=value` serialization for Loggly when +// logging to non-JSON inputs. +// +exports.serialize = function (obj, key) { + if (obj === null) { + obj = 'null'; + } + else if (obj === undefined) { + obj = 'undefined'; + } + else if (obj === false) { + obj = 'false'; + } + + if (typeof obj !== 'object') { + return key ? key + '=' + obj : obj; + } + + if (obj instanceof Buffer) { + return key ? key + '=' + obj.toString('base64') : obj.toString('base64'); + } + + var msg = '', + keys = Object.keys(obj), + length = keys.length; + + for (var i = 0; i < length; i++) { + if (Array.isArray(obj[keys[i]])) { + msg += keys[i] + '=['; + + for (var j = 0, l = obj[keys[i]].length; j < l; j++) { + msg += exports.serialize(obj[keys[i]][j]); + if (j < l - 1) { + msg += ', '; + } + } + + msg += ']'; + } + else if (obj[keys[i]] instanceof Date) { + msg += keys[i] + '=' + obj[keys[i]]; + } + else { + msg += exports.serialize(obj[keys[i]], keys[i]); + } + + if (i < length - 1) { + msg += ', '; + } + } + + return msg; +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config.js new file mode 100644 index 0000000..a466086 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config.js @@ -0,0 +1,45 @@ +/* + * config.js: Default settings for all levels that winston knows about + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var colors = require('colors'); + +var config = exports, + allColors = exports.allColors = {}; + +config.addColors = function (colors) { + mixin(allColors, colors); +}; + +config.colorize = function (level) { + return level[allColors[level]]; +}; + +// +// Export config sets +// +config.cli = require('./config/cli-config'); +config.npm = require('./config/npm-config'); +config.syslog = require('./config/syslog-config'); + +// +// Add colors for pre-defined config sets +// +config.addColors(config.npm.colors); +config.addColors(config.syslog.colors); + +function mixin (target) { + var args = Array.prototype.slice.call(arguments, 1); + + args.forEach(function (a) { + var keys = Object.keys(a); + for (var i = 0; i < keys.length; i++) { + target[keys[i]] = a[keys[i]]; + } + }); + return target; +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/cli-config.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/cli-config.js new file mode 100644 index 0000000..ec4c40f --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/cli-config.js @@ -0,0 +1,35 @@ +/* + * cli-config.js: Config that conform to commonly used CLI logging levels. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var cliConfig = exports; + +cliConfig.levels = { + silly: 0, + input: 1, + verbose: 2, + prompt: 3, + info: 4, + data: 5, + help: 6, + warn: 7, + debug: 8, + error: 9 +}; + +cliConfig.colors = { + silly: 'magenta', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/npm-config.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/npm-config.js new file mode 100644 index 0000000..176f9ac --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/npm-config.js @@ -0,0 +1,27 @@ +/* + * npm-config.js: Config that conform to npm logging levels. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var npmConfig = exports; + +npmConfig.levels = { + silly: 0, + verbose: 1, + info: 2, + warn: 3, + debug: 4, + error: 5 +}; + +npmConfig.colors = { + silly: 'magenta', + verbose: 'cyan', + info: 'green', + warn: 'yellow', + debug: 'blue', + error: 'red' +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/syslog-config.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/syslog-config.js new file mode 100644 index 0000000..00c1f31 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/config/syslog-config.js @@ -0,0 +1,31 @@ +/* + * syslog-config.js: Config that conform to syslog logging levels. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var syslogConfig = exports; + +syslogConfig.levels = { + debug: 0, + info: 1, + notice: 2, + warning: 3, + error: 4, + crit: 5, + alert: 6, + emerg: 7 +}; + +syslogConfig.colors = { + debug: 'blue', + info: 'green', + notice: 'yellow', + warning: 'red', + error: 'red', + crit: 'red', + alert: 'yellow', + emerg: 'red' +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/container.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/container.js new file mode 100644 index 0000000..574f25a --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/container.js @@ -0,0 +1,101 @@ +/* + * container.js: Inversion of control container for winston logger instances + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var common = require('./common'), + winston = require('../winston'); + +// +// ### function Container (options) +// #### @options {Object} Default pass-thru options for Loggers +// Constructor function for the Container object responsible for managing +// a set of `winston.Logger` instances based on string ids. +// +var Container = exports.Container = function (options) { + this.loggers = {}; + this.options = options || {}; + this.default = { + transports: [ + new winston.transports.Console({ + level: 'silly', + colorize: false + }) + ] + } +}; + +// +// ### function get / add (id, options) +// #### @id {string} Id of the Logger to get +// #### @options {Object} **Optional** Options for the Logger instance +// Retreives a `winston.Logger` instance for the specified `id`. If +// an instance does not exist, one is created. +// +Container.prototype.get = Container.prototype.add = function (id, options) { + if (!this.loggers[id]) { + options = common.clone(options || this.options || this.default); + options.transports = options.transports || []; + + if (options.transports.length === 0 && (!options || !options['console'])) { + options.transports.push(this.default.transports[0]); + } + + Object.keys(options).forEach(function (key) { + if (key === 'transports') { + return; + } + + var name = common.capitalize(key); + + if (!winston.transports[name]) { + throw new Error('Cannot add unknown transport: ' + name); + } + + var namedOptions = options[key]; + namedOptions.id = id; + options.transports.push(new (winston.transports[name])(namedOptions)); + }); + + this.loggers[id] = new winston.Logger(options); + } + + return this.loggers[id]; +}; + +// +// ### function close (id) +// #### @id {string} **Optional** Id of the Logger instance to find +// Returns a boolean value indicating if this instance +// has a logger with the specified `id`. +// +Container.prototype.has = function (id) { + return !!this.loggers[id]; +}; + +// +// ### function close (id) +// #### @id {string} **Optional** Id of the Logger instance to close +// Closes a `Logger` instance with the specified `id` if it exists. +// If no `id` is supplied then all Loggers are closed. +// +Container.prototype.close = function (id) { + var self = this; + + function _close (id) { + if (!self.loggers[id]) { + return; + } + + self.loggers[id].close(); + delete self.loggers[id]; + } + + return id ? _close(id) : Object.keys(this.loggers).forEach(function (id) { + _close(id); + }); +}; + diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/exception.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/exception.js new file mode 100644 index 0000000..22717dd --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/exception.js @@ -0,0 +1,56 @@ +/* + * exception.js: Utility methods for gathing information about uncaughtExceptions. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var os = require('os'), + stackTrace = require('stack-trace'); + +var exception = exports; + +exception.getAllInfo = function (err) { + return { + date: new Date().toString(), + process: exception.getProcessInfo(), + os: exception.getOsInfo(), + trace: exception.getTrace(err), + stack: err.stack && err.stack.split('\n') + }; +}; + +exception.getProcessInfo = function () { + return { + pid: process.pid, + uid: process.getuid ? process.getuid() : null, + gid: process.getgid ? process.getgid() : null, + cwd: process.cwd(), + execPath: process.execPath, + version: process.version, + argv: process.argv, + memoryUsage: process.memoryUsage() + }; +}; + +exception.getOsInfo = function () { + return { + loadavg: os.loadavg(), + uptime: os.uptime() + }; +}; + +exception.getTrace = function (err) { + var trace = err ? stackTrace.parse(err) : stackTrace.get(); + return trace.map(function (site) { + return { + column: site.getColumnNumber(), + file: site.getFileName(), + function: site.getFunctionName(), + line: site.getLineNumber(), + method: site.getMethodName(), + native: site.isNative(), + } + }); +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/logger.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/logger.js new file mode 100644 index 0000000..49e6d4c --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/logger.js @@ -0,0 +1,668 @@ +/* + * logger.js: Core logger object used by winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var events = require('events'), + util = require('util'), + async = require('async'), + config = require('./config'), + common = require('./common'), + exception = require('./exception'), + Stream = require('stream').Stream; + +// +// Time constants +// +var ticksPerMillisecond = 10000; + +// +// ### function Logger (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Logger object responsible +// for persisting log messages and metadata to one or more transports. +// +var Logger = exports.Logger = function (options) { + events.EventEmitter.call(this); + options = options || {}; + + var self = this, + handleExceptions = false; + + // + // Set Levels and default logging level + // + this.padLevels = options.padLevels || false; + this.setLevels(options.levels); + if (options.colors) { + config.addColors(options.colors); + } + + // + // Hoist other options onto this instance. + // + this.level = options.level || 'info'; + this.emitErrs = options.emitErrs || false; + this.stripColors = options.stripColors || false; + this.exitOnError = typeof options.exitOnError !== 'undefined' + ? options.exitOnError + : true; + + // + // Setup other intelligent default settings. + // + this.transports = {}; + this.rewriters = []; + this.exceptionHandlers = {}; + this.profilers = {}; + this._names = []; + this._hnames = []; + + if (options.transports) { + options.transports.forEach(function (transport) { + self.add(transport, null, true); + + if (transport.handleExceptions) { + handleExceptions = true; + } + }); + } + + if (options.rewriters) { + options.rewriters.forEach(function (rewriter) { + self.addRewriter(rewriter); + }); + } + + if (options.exceptionHandlers) { + handleExceptions = true; + options.exceptionHandlers.forEach(function (handler) { + self._hnames.push(handler.name); + self.exceptionHandlers[handler.name] = handler; + }); + } + + if (options.handleExceptions || handleExceptions) { + this.handleExceptions(); + } +}; + +// +// Inherit from `events.EventEmitter`. +// +util.inherits(Logger, events.EventEmitter); + +// +// ### function extend (target) +// #### @target {Object} Target to extend. +// Extends the target object with a 'log' method +// along with a method for each level in this instance. +// +Logger.prototype.extend = function (target) { + var self = this; + ['log', 'profile', 'startTimer'].concat(Object.keys(this.levels)).forEach(function (method) { + target[method] = function () { + return self[method].apply(self, arguments); + }; + }); + + return this; +}; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +Logger.prototype.log = function (level, msg) { + var self = this, + callback, + meta; + + if (arguments.length === 3) { + if (typeof arguments[2] === 'function') { + meta = {}; + callback = arguments[2]; + } + else if (typeof arguments[2] === 'object') { + meta = arguments[2]; + } + } + else if (arguments.length === 4) { + meta = arguments[2]; + callback = arguments[3]; + } + + // If we should pad for levels, do so + if (this.padLevels) { + msg = new Array(this.levelLength - level.length + 1).join(' ') + msg; + } + + function onError (err) { + if (callback) { + callback(err); + } + else if (self.emitErrs) { + self.emit('error', err); + }; + } + + if (this.transports.length === 0) { + return onError(new Error('Cannot log with no transports.')); + } + else if (typeof self.levels[level] === 'undefined') { + return onError(new Error('Unknown log level: ' + level)); + } + + this.rewriters.forEach(function (rewriter) { + meta = rewriter(level, msg, meta); + }); + + // + // For consideration of terminal 'color" programs like colors.js, + // which can add ANSI escape color codes to strings, we destyle the + // ANSI color escape codes when `this.stripColors` is set. + // + // see: http://en.wikipedia.org/wiki/ANSI_escape_code + // + if (this.stripColors) { + var code = /\u001b\[(\d+(;\d+)*)?m/g; + msg = ('' + msg).replace(code, ''); + } + + // + // Log for each transport and emit 'logging' event + // + function emit(name, next) { + var transport = self.transports[name]; + if ((transport.level && self.levels[transport.level] <= self.levels[level]) + || (!transport.level && self.levels[self.level] <= self.levels[level])) { + transport.log(level, msg, meta, function (err) { + if (err) { + err.transport = transport; + cb(err); + return next(); + } + self.emit('logging', transport, level, msg, meta); + next(); + }); + } else { + next(); + } + } + + // + // Respond to the callback + // + function cb(err) { + if (callback) { + if (err) return callback(err); + callback(null, level, msg, meta); + } + callback = null; + } + + async.forEach(this._names, emit, cb); + + return this; +}; + +// +// ### function query (options, callback) +// #### @options {Object} Query options for this instance. +// #### @callback {function} Continuation to respond to when complete. +// Queries the all transports for this instance with the specified `options`. +// This will aggregate each transport's results into one object containing +// a property per transport. +// +Logger.prototype.query = function (options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + var self = this, + options = options || {}, + results = {}, + query = common.clone(options.query) || {}, + transports; + + // + // Helper function to query a single transport + // + function queryTransport(transport, next) { + if (options.query) { + options.query = transport.formatQuery(query); + } + + transport.query(options, function (err, results) { + if (err) { + return next(err); + } + + next(null, transport.formatResults(results, options.format)); + }); + } + + // + // Helper function to accumulate the results from + // `queryTransport` into the `results`. + // + function addResults (transport, next) { + queryTransport(transport, function (err, result) { + result = err || result; + if (result) { + results[transport.name] = result; + } + next(); + }); + } + + // + // If an explicit transport is being queried then + // respond with the results from only that transport + // + if (options.transport) { + options.transport = options.transport.toLowerCase(); + return queryTransport(this.transports[options.transport], callback); + } + + // + // Create a list of all transports for this instance. + // + transports = this._names.map(function (name) { + return self.transports[name]; + }).filter(function (transport) { + return !!transport.query; + }); + + // + // Iterate over the transports in parallel setting the + // appropriate key in the `results` + // + async.forEach(transports, addResults, function () { + callback(null, results); + }); +}; + +// +// ### function stream (options) +// #### @options {Object} Stream options for this instance. +// Returns a log stream for all transports. Options object is optional. +// +Logger.prototype.stream = function (options) { + var self = this, + options = options || {}, + out = new Stream, + streams = [], + transports; + + if (options.transport) { + var transport = this.transports[options.transport]; + delete options.transport; + if (transport && transport.stream) { + return transport.stream(options); + } + } + + out._streams = streams; + out.destroy = function () { + var i = streams.length; + while (i--) streams[i].destroy(); + }; + + // + // Create a list of all transports for this instance. + // + transports = this._names.map(function (name) { + return self.transports[name]; + }).filter(function (transport) { + return !!transport.stream; + }); + + transports.forEach(function (transport) { + var stream = transport.stream(options); + if (!stream) return; + + streams.push(stream); + + stream.on('log', function (log) { + log.transport = log.transport || []; + log.transport.push(transport.name); + out.emit('log', log); + }); + + stream.on('error', function (err) { + err.transport = err.transport || []; + err.transport.push(transport.name); + out.emit('error', err); + }); + }); + + return out; +}; + +// +// ### function close () +// Cleans up resources (streams, event listeners) for all +// transports associated with this instance (if necessary). +// +Logger.prototype.close = function () { + var self = this; + + this._names.forEach(function (name) { + var transport = self.transports[name]; + if (transport && transport.close) { + transport.close(); + } + }); +}; + +// +// ### function handleExceptions () +// Handles `uncaughtException` events for the current process +// +Logger.prototype.handleExceptions = function () { + var args = Array.prototype.slice.call(arguments), + handlers = [], + self = this; + + args.forEach(function (a) { + if (Array.isArray(a)) { + handlers = handlers.concat(a); + } + else { + handlers.push(a); + } + }); + + handlers.forEach(function (handler) { + self.exceptionHandlers[handler.name] = handler; + }); + + this._hnames = Object.keys(self.exceptionHandlers); + + if (!this.catchExceptions) { + this.catchExceptions = this._uncaughtException.bind(this); + process.on('uncaughtException', this.catchExceptions); + } +}; + +// +// ### function unhandleExceptions () +// Removes any handlers to `uncaughtException` events +// for the current process +// +Logger.prototype.unhandleExceptions = function () { + var self = this; + + if (this.catchExceptions) { + Object.keys(this.exceptionHandlers).forEach(function (name) { + if (handler.close) { + handler.close(); + } + }); + + this.exceptionHandlers = {}; + Object.keys(this.transports).forEach(function (name) { + var transport = self.transports[name]; + if (transport.handleExceptions) { + transport.handleExceptions = false; + } + }) + + process.removeListener('uncaughtException', this.catchExceptions); + this.catchExceptions = false; + } +}; + +// +// ### function add (transport, [options]) +// #### @transport {Transport} Prototype of the Transport object to add. +// #### @options {Object} **Optional** Options for the Transport to add. +// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated. +// Adds a transport of the specified type to this instance. +// +Logger.prototype.add = function (transport, options, created) { + var instance = created ? transport : (new (transport)(options)); + + if (!instance.name && !instance.log) { + throw new Error('Unknown transport with no log() method'); + } + else if (this.transports[instance.name]) { + throw new Error('Transport already attached: ' + instance.name); + } + + this.transports[instance.name] = instance; + this._names = Object.keys(this.transports); + + // + // Listen for the `error` event on the new Transport + // + instance._onError = this._onError.bind(this, instance) + instance.on('error', instance._onError); + + // + // If this transport has `handleExceptions` set to `true` + // and we are not already handling exceptions, do so. + // + if (instance.handleExceptions && !this.catchExceptions) { + this.handleExceptions(); + } + + return this; +}; + +// +// ### function addRewriter (transport, [options]) +// #### @transport {Transport} Prototype of the Transport object to add. +// #### @options {Object} **Optional** Options for the Transport to add. +// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated. +// Adds a transport of the specified type to this instance. +// +Logger.prototype.addRewriter = function (rewriter) { + this.rewriters.push(rewriter); +} + +// +// ### function clear () +// Remove all transports from this instance +// +Logger.prototype.clear = function () { + for (var name in this.transports) { + this.remove({ name: name }); + } +}; + +// +// ### function remove (transport) +// #### @transport {Transport} Transport to remove. +// Removes a transport of the specified type from this instance. +// +Logger.prototype.remove = function (transport) { + var name = transport.name || transport.prototype.name; + + if (!this.transports[name]) { + throw new Error('Transport ' + name + ' not attached to this instance'); + } + + var instance = this.transports[name]; + delete this.transports[name]; + this._names = Object.keys(this.transports); + + if (instance.close) { + instance.close(); + } + + instance.removeListener('error', instance._onError); + return this; +}; + +var ProfileHandler = function (logger) { + this.logger = logger; + + this.start = Date.now(); + + this.done = function (msg) { + var args, callback, meta; + args = Array.prototype.slice.call(arguments); + callback = typeof args[args.length - 1] === 'function' ? args.pop() : null; + meta = typeof args[args.length - 1] === 'object' ? args.pop() : {}; + + meta.duration = (Date.now()) - this.start + 'ms'; + + return this.logger.info(msg, meta, callback); + } +} + +Logger.prototype.startTimer = function () { + return new ProfileHandler(this); +} + +// +// ### function profile (id, [msg, meta, callback]) +// #### @id {string} Unique id of the profiler +// #### @msg {string} **Optional** Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Tracks the time inbetween subsequent calls to this method +// with the same `id` parameter. The second call to this method +// will log the difference in milliseconds along with the message. +// +Logger.prototype.profile = function (id) { + var now = Date.now(), then, args, + msg, meta, callback; + + if (this.profilers[id]) { + then = this.profilers[id]; + delete this.profilers[id]; + + // Support variable arguments: msg, meta, callback + args = Array.prototype.slice.call(arguments); + callback = typeof args[args.length - 1] === 'function' ? args.pop() : null; + meta = typeof args[args.length - 1] === 'object' ? args.pop() : {}; + msg = args.length === 2 ? args[1] : id; + + // Set the duration property of the metadata + meta.duration = now - then + 'ms'; + return this.info(msg, meta, callback); + } + else { + this.profilers[id] = now; + } + + return this; +}; + +// +// ### function setLevels (target) +// #### @target {Object} Target levels to use on this instance +// Sets the `target` levels specified on this instance. +// +Logger.prototype.setLevels = function (target) { + return common.setLevels(this, this.levels, target); +}; + +// +// ### function cli () +// Configures this instance to have the default +// settings for command-line interfaces: no timestamp, +// colors enabled, padded output, and additional levels. +// +Logger.prototype.cli = function () { + this.padLevels = true; + this.setLevels(config.cli.levels); + config.addColors(config.cli.colors); + + if (this.transports.console) { + this.transports.console.colorize = true; + this.transports.console.timestamp = false; + } + + return this; +}; + +// +// ### @private function _uncaughtException (err) +// #### @err {Error} Error to handle +// Logs all relevant information around the `err` and +// exits the current process. +// +Logger.prototype._uncaughtException = function (err) { + var self = this, + responded = false, + info = exception.getAllInfo(err), + handlers = this._getExceptionHandlers(), + timeout, + doExit; + + // + // Calculate if we should exit on this error + // + doExit = typeof this.exitOnError === 'function' + ? this.exitOnError(err) + : this.exitOnError; + + function logAndWait(transport, next) { + transport.logException('uncaughtException', info, next, err); + } + + function gracefulExit() { + if (doExit && !responded) { + // + // Remark: Currently ignoring any exceptions from transports + // when catching uncaught exceptions. + // + clearTimeout(timeout); + responded = true; + process.exit(1); + } + } + + if (!handlers || handlers.length === 0) { + return gracefulExit(); + } + + // + // Log to all transports and allow the operation to take + // only up to `3000ms`. + // + async.forEach(handlers, logAndWait, gracefulExit); + if (doExit) { + timeout = setTimeout(gracefulExit, 3000); + } +}; + +// +// ### @private function _getExceptionHandlers () +// Returns the list of transports and exceptionHandlers +// for this instance. +// +Logger.prototype._getExceptionHandlers = function () { + var self = this; + + return this._hnames.map(function (name) { + return self.exceptionHandlers[name]; + }).concat(this._names.map(function (name) { + return self.transports[name].handleExceptions && self.transports[name]; + })).filter(Boolean); +}; + +// +// ### @private function _onError (transport, err) +// #### @transport {Object} Transport on which the error occured +// #### @err {Error} Error that occurred on the transport +// Bubbles the error, `err`, that occured on the specified `transport` +// up from this instance if `emitErrs` has been set. +// +Logger.prototype._onError = function (transport, err) { + if (this.emitErrs) { + this.emit('error', err, transport); + } +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports.js new file mode 100644 index 0000000..1bd9f05 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports.js @@ -0,0 +1,29 @@ +/* + * transports.js: Set of all transports Winston knows about + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var fs = require('fs'), + path = require('path'), + common = require('./common'); + +var transports = exports; + +// +// Setup all transports as lazy-loaded getters. +// +fs.readdirSync(path.join(__dirname, 'transports')).forEach(function (file) { + var transport = file.replace('.js', ''), + name = common.capitalize(transport); + + if (transport === 'transport') { + return; + } + + transports.__defineGetter__(name, function () { + return require('./transports/' + transport)[name]; + }); +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/console.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/console.js new file mode 100644 index 0000000..43cdee3 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/console.js @@ -0,0 +1,88 @@ +/* + * console.js: Transport for outputting to the console + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var events = require('events'), + util = require('util'), + colors = require('colors'), + common = require('../common'), + Transport = require('./transport').Transport; + +// +// ### function Console (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Console transport object responsible +// for persisting log messages and metadata to a terminal or TTY. +// +var Console = exports.Console = function (options) { + Transport.call(this, options); + options = options || {}; + + this.name = 'console'; + this.json = options.json || false; + this.colorize = options.colorize || false; + this.prettyPrint = options.prettyPrint || false; + this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false; + + if (this.json) { + this.stringify = options.stringify || function (obj) { + return JSON.stringify(obj, null, 2); + }; + } +}; + +// +// Inherit from `winston.Transport`. +// +util.inherits(Console, Transport); + +// +// Expose the name of this Transport on the prototype +// +Console.prototype.name = 'console'; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +Console.prototype.log = function (level, msg, meta, callback) { + if (this.silent) { + return callback(null, true); + } + + var self = this, + output; + + output = common.log({ + colorize: this.colorize, + json: this.json, + level: level, + message: msg, + meta: meta, + stringify: this.stringify, + timestamp: this.timestamp, + prettyPrint: this.prettyPrint, + raw: this.raw + }); + + if (level === 'error' || level === 'debug') { + console.error(output); + } else { + console.log(output); + } + + // + // Emit the `logged` event immediately because the event loop + // will not exit until `process.stdout` has drained anyway. + // + self.emit('logged'); + callback(null, true); +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/file.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/file.js new file mode 100644 index 0000000..7080e28 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/file.js @@ -0,0 +1,575 @@ +/* + * file.js: Transport for outputting to a local log file + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var events = require('events'), + fs = require('fs'), + path = require('path'), + util = require('util'), + colors = require('colors'), + common = require('../common'), + Transport = require('./transport').Transport, + Stream = require('stream').Stream; + +// +// ### function File (options) +// #### @options {Object} Options for this instance. +// Constructor function for the File transport object responsible +// for persisting log messages and metadata to one or more files. +// +var File = exports.File = function (options) { + Transport.call(this, options); + + // + // Helper function which throws an `Error` in the event + // that any of the rest of the arguments is present in `options`. + // + function throwIf (target /*, illegal... */) { + Array.prototype.slice.call(arguments, 1).forEach(function (name) { + if (options[name]) { + throw new Error('Cannot set ' + name + ' and ' + target + 'together'); + } + }); + } + + if (options.filename || options.dirname) { + throwIf('filename or dirname', 'stream'); + this._basename = this.filename = path.basename(options.filename) || 'winston.log'; + this.dirname = options.dirname || path.dirname(options.filename); + this.options = options.options || { flags: 'a' }; + } + else if (options.stream) { + throwIf('stream', 'filename', 'maxsize'); + this._stream = options.stream; + + // + // We need to listen for drain events when + // write() returns false. This can make node + // mad at times. + // + this._stream.setMaxListeners(Infinity); + } + else { + throw new Error('Cannot log to file without filename or stream.'); + } + + this.json = options.json !== false; + this.colorize = options.colorize || false; + this.maxsize = options.maxsize || null; + this.maxFiles = options.maxFiles || null; + this.prettyPrint = options.prettyPrint || false; + this.timestamp = options.timestamp != null ? options.timestamp : true; + + if (this.json) { + this.stringify = options.stringify; + } + + // + // Internal state variables representing the number + // of files this instance has created and the current + // size (in bytes) of the current logfile. + // + this._size = 0; + this._created = 0; + this._buffer = []; + this._draining = false; +}; + +// +// Inherit from `winston.Transport`. +// +util.inherits(File, Transport); + +// +// Expose the name of this Transport on the prototype +// +File.prototype.name = 'file'; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +File.prototype.log = function (level, msg, meta, callback) { + if (this.silent) { + return callback(null, true); + } + + var self = this; + + var output = common.log({ + level: level, + message: msg, + meta: meta, + json: this.json, + colorize: this.colorize, + prettyPrint: this.prettyPrint, + timestamp: this.timestamp, + stringify: this.stringify + }) + '\n'; + + this._size += output.length; + + if (!this.filename) { + // + // If there is no `filename` on this instance then it was configured + // with a raw `WriteableStream` instance and we should not perform any + // size restrictions. + // + this._write(output, callback); + this._lazyDrain(); + } + else { + this.open(function (err) { + if (err) { + // + // If there was an error enqueue the message + // + return self._buffer.push([output, callback]); + } + + self._write(output, callback); + self._lazyDrain(); + }); + } +}; + +// +// ### function _write (data, cb) +// #### @data {String|Buffer} Data to write to the instance's stream. +// #### @cb {function} Continuation to respond to when complete. +// Write to the stream, ensure execution of a callback on completion. +// +File.prototype._write = function(data, callback) { + // If this is a file write stream, we could use the builtin + // callback functionality, however, the stream is not guaranteed + // to be an fs.WriteStream. + var ret = this._stream.write(data); + if (!callback) return; + if (ret === false) { + return this._stream.once('drain', function() { + callback(null, true); + }); + } + callback(null, true); +}; + +// +// ### function query (options, callback) +// #### @options {Object} Loggly-like query options for this instance. +// #### @callback {function} Continuation to respond to when complete. +// Query the transport. Options object is optional. +// +File.prototype.query = function (options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + var file = path.join(this.dirname, this.filename), + options = this.normalizeQuery(options), + buff = '', + results = [], + row = 0; + + var stream = fs.createReadStream(file, { + encoding: 'utf8' + }); + + stream.on('error', function (err) { + if (stream.readable) { + stream.destroy(); + } + if (!callback) return; + return err.code !== 'ENOENT' + ? callback(err) + : callback(null, results); + }); + + stream.on('data', function (data) { + var data = (buff + data).split(/\n+/), + l = data.length - 1, + i = 0; + + for (; i < l; i++) { + if (!options.start || row >= options.start) { + add(data[i]); + } + row++; + } + + buff = data[l]; + }); + + stream.on('close', function () { + if (buff) add(buff, true); + if (options.order === 'desc') { + results = results.reverse(); + } + if (callback) callback(null, results); + }); + + function add(buff, attempt) { + try { + var log = JSON.parse(buff); + if (check(log)) push(log); + } catch (e) { + if (!attempt) { + stream.emit('error', e); + } + } + } + + function push(log) { + if (options.rows && results.length >= options.rows) { + if (stream.readable) { + stream.destroy(); + } + return; + } + + if (options.fields) { + var obj = {}; + options.fields.forEach(function (key) { + obj[key] = log[key]; + }); + log = obj; + } + + results.push(log); + } + + function check(log) { + if (!log) return; + + if (typeof log !== 'object') return; + + var time = new Date(log.timestamp); + if ((options.from && time < options.from) + || (options.until && time > options.until)) { + return; + } + + return true; + } +}; + +// +// ### function _tail (options, callback) +// #### @options {Object} Options for tail. +// #### @callback {function} Callback to execute on every line. +// `tail -f` a file. Options must include file. +// +File.prototype._tail = function tail(options, callback) { + var stream = fs.createReadStream(options.file, { encoding: 'utf8' }), + buff = '', + destroy, + row = 0; + + destroy = stream.destroy.bind(stream); + stream.destroy = function () {}; + + if (options.start === -1) { + delete options.start; + } + + if (options.start == null) { + stream.once('end', bind); + } else { + bind(); + } + + function bind() { + stream.on('data', function (data) { + var data = (buff + data).split(/\n+/), + l = data.length - 1, + i = 0; + + for (; i < l; i++) { + if (options.start == null || row > options.start) { + stream.emit('line', data[i]); + } + row++; + } + + buff = data[l]; + }); + + stream.on('line', function (data) { + if (callback) callback(data); + }); + + stream.on('error', function (err) { + destroy(); + }); + + stream.on('end', function () { + if (buff) { + stream.emit('line', buff); + buff = ''; + } + + resume(); + }); + + resume(); + } + + function resume() { + setTimeout(function () { + stream.resume(); + }, 1000); + } + + return destroy; +}; + +// +// ### function stream (options) +// #### @options {Object} Stream options for this instance. +// Returns a log stream for this transport. Options object is optional. +// +File.prototype.stream = function (options) { + var file = path.join(this.dirname, this.filename), + options = options || {}, + stream = new Stream; + + var tail = { + file: file, + start: options.start + }; + + stream.destroy = this._tail(tail, function (line) { + try { + stream.emit('data', line); + line = JSON.parse(line); + stream.emit('log', line); + } catch (e) { + stream.emit('error', e); + } + }); + + return stream; +}; + +// +// ### function open (callback) +// #### @callback {function} Continuation to respond to when complete +// Checks to see if a new file needs to be created based on the `maxsize` +// (if any) and the current size of the file used. +// +File.prototype.open = function (callback) { + if (this.opening) { + // + // If we are already attempting to open the next + // available file then respond with a value indicating + // that the message should be buffered. + // + return callback(true); + } + else if (!this._stream || (this.maxsize && this._size >= this.maxsize)) { + // + // If we dont have a stream or have exceeded our size, then create + // the next stream and respond with a value indicating that + // the message should be buffered. + // + callback(true); + return this._createStream(); + } + + // + // Otherwise we have a valid (and ready) stream. + // + callback(); +}; + +// +// ### function close () +// Closes the stream associated with this instance. +// +File.prototype.close = function () { + var self = this; + + if (this._stream) { + this._stream.end(); + this._stream.destroySoon(); + + this._stream.once('drain', function () { + self.emit('flush'); + self.emit('closed'); + }); + } +}; + +// +// ### function flush () +// Flushes any buffered messages to the current `stream` +// used by this instance. +// +File.prototype.flush = function () { + var self = this; + + // + // Iterate over the `_buffer` of enqueued messaged + // and then write them to the newly created stream. + // + this._buffer.forEach(function (item) { + var str = item[0], + callback = item[1]; + + process.nextTick(function () { + self._write(str, callback); + self._size += str.length; + }); + }); + + // + // Quickly truncate the `_buffer` once the write operations + // have been started + // + self._buffer.length = 0; + + // + // When the stream has drained we have flushed + // our buffer. + // + self._stream.once('drain', function () { + self.emit('flush'); + self.emit('logged'); + }); +}; + +// +// ### @private function _createStream () +// Attempts to open the next appropriate file for this instance +// based on the common state (such as `maxsize` and `_basename`). +// +File.prototype._createStream = function () { + var self = this; + this.opening = true; + + (function checkFile (target) { + var fullname = path.join(self.dirname, target); + + // + // Creates the `WriteStream` and then flushes any + // buffered messages. + // + function createAndFlush (size) { + if (self._stream) { + self._stream.end(); + self._stream.destroySoon(); + } + + self._size = size; + self.filename = target; + self._stream = fs.createWriteStream(fullname, self.options); + + // + // We need to listen for drain events when + // write() returns false. This can make node + // mad at times. + // + self._stream.setMaxListeners(Infinity); + + // + // When the current stream has finished flushing + // then we can be sure we have finished opening + // and thus can emit the `open` event. + // + self.once('flush', function () { + self.opening = false; + self.emit('open', fullname); + }); + + // + // Remark: It is possible that in the time it has taken to find the + // next logfile to be written more data than `maxsize` has been buffered, + // but for sensible limits (10s - 100s of MB) this seems unlikely in less + // than one second. + // + self.flush(); + } + + fs.stat(fullname, function (err, stats) { + if (err) { + if (err.code !== 'ENOENT') { + return self.emit('error', err); + } + + return createAndFlush(0); + } + + if (!stats || (self.maxsize && stats.size >= self.maxsize)) { + // + // If `stats.size` is greater than the `maxsize` for + // this instance then try again + // + return checkFile(self._getFile(true)); + } + + createAndFlush(stats.size); + }); + })(this._getFile()); +}; + +// +// ### @private function _getFile () +// Gets the next filename to use for this instance +// in the case that log filesizes are being capped. +// +File.prototype._getFile = function (inc) { + var self = this, + ext = path.extname(this._basename), + basename = path.basename(this._basename, ext), + remaining; + + if (inc) { + // + // Increment the number of files created or + // checked by this instance. + // + // Check for maxFiles option and delete file + if (this.maxFiles && (this._created >= (this.maxFiles - 1))) { + remaining = this._created - (this.maxFiles - 1); + if (remaining === 0) { + fs.unlinkSync(path.join(this.dirname, basename + ext)); + } + else { + fs.unlinkSync(path.join(this.dirname, basename + remaining + ext)); + } + } + + this._created += 1; + } + + return this._created + ? basename + this._created + ext + : basename + ext; +}; + +// +// ### @private function _lazyDrain () +// Lazily attempts to emit the `logged` event when `this.stream` has +// drained. This is really just a simple mutex that only works because +// Node.js is single-threaded. +// +File.prototype._lazyDrain = function () { + var self = this; + + if (!this._draining && this._stream) { + this._draining = true; + + this._stream.once('drain', function () { + this._draining = false; + self.emit('logged'); + }); + } +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/http.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/http.js new file mode 100644 index 0000000..9b9c61d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/http.js @@ -0,0 +1,200 @@ +var util = require('util'), + winston = require('../../winston'), + request = require('request'), + Stream = require('stream').Stream; + +// +// ### function Http (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Http transport object responsible +// for persisting log messages and metadata to a terminal or TTY. +// +var Http = exports.Http = function (options) { + options = options || {}; + + this.name = 'http'; + this.ssl = !!options.ssl; + this.host = options.host || 'localhost'; + this.port = options.port; + this.auth = options.auth; + this.path = options.path || ''; + + if (!this.port) { + this.port = this.ssl ? 443 : 80; + } +}; + +util.inherits(Http, winston.Transport); + +// +// Expose the name of this Transport on the prototype +// +Http.prototype.name = 'http'; + +// +// ### function _request (options, callback) +// #### @callback {function} Continuation to respond to when complete. +// Make a request to a winstond server or any http server which can +// handle json-rpc. +// +Http.prototype._request = function (options, callback) { + var options = options || {}, + auth = options.auth || this.auth, + path = options.path || this.path || ''; + + delete options.auth; + delete options.path; + + options = { json: options }; + options.method = 'POST'; + options.url = 'http' + + (this.ssl ? 's' : '') + + '://' + + (auth ? auth.username + ':' : '') + + (auth ? auth.password + '@' : '') + + this.host + + ':' + + this.port + + '/' + + path; + + return request(options, callback); +}; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +Http.prototype.log = function (level, msg, meta, callback) { + var self = this; + + if (typeof meta === 'function') { + callback = meta; + meta = {}; + } + + var options = { + method: 'collect', + params: { + level: level, + message: msg, + meta: meta + } + }; + + // hack + if (meta.auth) { + options.auth = meta.auth; + delete meta.auth; + } + + // hack + if (meta.path) { + options.path = meta.path; + delete meta.path; + } + + this._request(options, function (err, res, body) { + if (res && res.statusCode !== 200) { + err = new Error('HTTP Status Code: ' + res.statusCode); + } + + if (err) return callback(err); + + // TODO: emit 'logged' correctly, + // keep track of pending logs. + self.emit('logged'); + + if (callback) callback(null, true); + }); +}; + +// +// ### function query (options, callback) +// #### @options {Object} Loggly-like query options for this instance. +// #### @callback {function} Continuation to respond to when complete. +// Query the transport. Options object is optional. +// +Http.prototype.query = function (options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + var self = this, + options = this.normalizeQuery(options); + + options = { + method: 'query', + params: options + }; + + this._request(options, function (err, res, body) { + if (res && res.statusCode !== 200) { + err = new Error('HTTP Status Code: ' + res.statusCode); + } + + if (err) return callback(err); + + if (typeof body === 'string') { + try { + body = JSON.parse(body); + } catch (e) { + return callback(e); + } + } + + callback(null, body); + }); +}; + +// +// ### function stream (options) +// #### @options {Object} Stream options for this instance. +// Returns a log stream for this transport. Options object is optional. +// +Http.prototype.stream = function (options) { + var self = this, + options = options || {}, + stream = new Stream, + req, + buff; + + stream.destroy = function () { + req.destroy(); + }; + + options = { + method: 'stream', + params: options + }; + + req = this._request(options); + buff = ''; + + req.on('data', function (data) { + var data = (buff + data).split(/\n+/), + l = data.length - 1, + i = 0; + + for (; i < l; i++) { + try { + stream.emit('log', JSON.parse(data[i])); + } catch (e) { + stream.emit('error', e); + } + } + + buff = data[l]; + }); + + req.on('error', function (err) { + stream.emit('error', err); + }); + + return stream; +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/transport.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/transport.js new file mode 100644 index 0000000..e04410e --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/transport.js @@ -0,0 +1,120 @@ +/* + * transport.js: Base Transport object for all Winston transports. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var events = require('events'), + util = require('util'); + +// +// ### function Transport (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Tranport object responsible +// base functionality for all winston transports. +// +var Transport = exports.Transport = function (options) { + events.EventEmitter.call(this); + + options = options || {}; + this.level = options.level || 'info'; + this.silent = options.silent || false; + this.raw = options.raw || false; + + this.handleExceptions = options.handleExceptions || false; +}; + +// +// Inherit from `events.EventEmitter`. +// +util.inherits(Transport, events.EventEmitter); + +// +// ### function formatQuery (query) +// #### @query {string|Object} Query to format +// Formats the specified `query` Object (or string) to conform +// with the underlying implementation of this transport. +// +Transport.prototype.formatQuery = function (query) { + return query; +}; + +// +// ### function normalizeQuery (query) +// #### @options {string|Object} Query to normalize +// Normalize options for query +// +Transport.prototype.normalizeQuery = function (options) { + // + // Use options similar to loggly. + // [See Loggly Search API](http://wiki.loggly.com/retrieve_events#optional) + // + + options = options || {}; + + // limit + options.rows = options.rows || options.limit || 10; + + // starting row offset + options.start = options.start || 0; + + // now - 24 + options.from = options.from || new Date - (24 * 60 * 60 * 1000); + if (typeof options.from !== 'object') { + options.from = new Date(options.from); + } + + // now + options.until = options.until || new Date; + if (typeof options.until !== 'object') { + options.until = new Date(options.until); + } + + // 'asc' or 'desc' + options.order = options.order || 'desc'; + + // which fields to select + options.fields = options.fields; + + return options; +}; + +// +// ### function formatResults (results, options) +// #### @results {Object|Array} Results returned from `.query`. +// #### @options {Object} **Optional** Formatting options +// Formats the specified `results` with the given `options` accordinging +// to the implementation of this transport. +// +Transport.prototype.formatResults = function (results, options) { + return results; +}; + +// +// ### function logException (msg, meta, callback) +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Logs the specified `msg`, `meta` and responds to the callback once the log +// operation is complete to ensure that the event loop will not exit before +// all logging has completed. +// +Transport.prototype.logException = function (msg, meta, callback) { + var self = this; + + function onLogged () { + self.removeListener('error', onError); + callback(); + } + + function onError () { + self.removeListener('logged', onLogged); + callback(); + } + + this.once('logged', onLogged); + this.once('error', onError); + this.log('error', msg, meta, function () { }); +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/webhook.js b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/webhook.js new file mode 100644 index 0000000..34b4a35 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/lib/winston/transports/webhook.js @@ -0,0 +1,136 @@ +/* + * webhook.js: Transport for logging to remote http endpoints ( POST / RECEIVE webhooks ) + * + * (C) 2011 Marak Squires + * MIT LICENCE + * + */ + +var events = require('events'), + http = require('http'), + https = require('https'), + util = require('util'), + cycle = require('cycle'), + common = require('../common'), + Transport = require('./transport').Transport; + +// +// ### function WebHook (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Console transport object responsible +// for making arbitrary HTTP requests whenever log messages and metadata +// are received. +// +var Webhook = exports.Webhook = function (options) { + Transport.call(this, options); + + this.name = 'webhook'; + this.host = options.host || 'localhost'; + this.port = options.port || 8080; + this.method = options.method || 'POST'; + this.path = options.path || '/winston-log'; + + if (options.auth) { + this.auth = {}; + this.auth.username = options.auth.username || ''; + this.auth.password = options.auth.password || ''; + } + + if (options.ssl) { + this.ssl = {}; + this.ssl.key = options.ssl.key || null; + this.ssl.cert = options.ssl.cert || null; + this.ssl.ca = options.ssl.ca; + } +}; + +// +// Inherit from `winston.Transport`. +// +util.inherits(Webhook, Transport); + +// +// Expose the name of this Transport on the prototype +// +Webhook.prototype.name = 'webhook'; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +Webhook.prototype.log = function (level, msg, meta, callback) { + if (this.silent) { + return callback(null, true); + } + + var self = this, + meta = cycle.decycle(meta), + message = common.clone(meta), + options, + req; + + // Prepare options for outgoing HTTP request + options = { + host: this.host, + port: this.port, + path: this.path, + method: this.method, + headers: { 'Content-Type': 'application/json' } + }; + + if (this.ssl) { + options.ca = this.ssl.ca; + options.key = this.ssl.key; + options.cert = this.ssl.cert; + } + + if (this.auth) { + // Encode `Authorization` header used by Basic Auth + options.headers['Authorization'] = 'Basic ' + new Buffer( + this.auth.username + ':' + this.auth.password, 'utf8' + ).toString('base64'); + } + + // Perform HTTP logging request + req = (self.ssl ? https : http).request(options, function (res) { + // TODO: emit 'logged' correctly, + // keep track of pending logs. + self.emit('logged'); + if (callback) callback(null, true); + callback = null; + }); + + req.on('error', function (err) { + // + // Propagate the `error` back up to the `Logger` that this + // instance belongs to. + // + self.emit('error', err); + if (callback) callback(err, false); + callback = null; + }); + + // + // Write logging event to the outgoing request body + // + // jsonMessage is currently conforming to JSON-RPC v1.0, + // but without the unique id since there is no anticipated response + // see: http://en.wikipedia.org/wiki/JSON-RPC + // + + var params = common.clone(meta) || {}; + params.timestamp = new Date(); + params.message = msg; + params.level = level; + + req.write(JSON.stringify({ + method: 'log', + params: params + })); + + req.end(); +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/.gitmodules b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/.gitmodules new file mode 100644 index 0000000..a9aae98 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/.gitmodules @@ -0,0 +1,9 @@ +[submodule "deps/nodeunit"] + path = deps/nodeunit + url = git://github.com/caolan/nodeunit.git +[submodule "deps/UglifyJS"] + path = deps/UglifyJS + url = https://github.com/mishoo/UglifyJS.git +[submodule "deps/nodelint"] + path = deps/nodelint + url = https://github.com/tav/nodelint.git diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/.npmignore b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/.npmignore new file mode 100644 index 0000000..9bdfc97 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/.npmignore @@ -0,0 +1,4 @@ +deps +dist +test +nodelint.cfg \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/LICENSE b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/LICENSE new file mode 100644 index 0000000..b7f9d50 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Caolan McMahon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/Makefile b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/Makefile new file mode 100644 index 0000000..bad647c --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/Makefile @@ -0,0 +1,25 @@ +PACKAGE = asyncjs +NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node) +CWD := $(shell pwd) +NODEUNIT = $(CWD)/node_modules/nodeunit/bin/nodeunit +UGLIFY = $(CWD)/node_modules/uglify-js/bin/uglifyjs +NODELINT = $(CWD)/node_modules/nodelint/nodelint + +BUILDDIR = dist + +all: clean test build + +build: $(wildcard lib/*.js) + mkdir -p $(BUILDDIR) + $(UGLIFY) lib/async.js > $(BUILDDIR)/async.min.js + +test: + $(NODEUNIT) test + +clean: + rm -rf $(BUILDDIR) + +lint: + $(NODELINT) --config nodelint.cfg lib/async.js + +.PHONY: test build all diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/README.md b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/README.md new file mode 100644 index 0000000..1bbbc47 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/README.md @@ -0,0 +1,1021 @@ +# Async.js + +Async is a utility module which provides straight-forward, powerful functions +for working with asynchronous JavaScript. Although originally designed for +use with [node.js](http://nodejs.org), it can also be used directly in the +browser. + +Async provides around 20 functions that include the usual 'functional' +suspects (map, reduce, filter, forEach…) as well as some common patterns +for asynchronous control flow (parallel, series, waterfall…). All these +functions assume you follow the node.js convention of providing a single +callback as the last argument of your async function. + + +## Quick Examples + + async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file + }); + + async.filter(['file1','file2','file3'], path.exists, function(results){ + // results now equals an array of the existing files + }); + + async.parallel([ + function(){ ... }, + function(){ ... } + ], callback); + + async.series([ + function(){ ... }, + function(){ ... } + ]); + +There are many more functions available so take a look at the docs below for a +full list. This module aims to be comprehensive, so if you feel anything is +missing please create a GitHub issue for it. + + +## Download + +Releases are available for download from +[GitHub](http://github.com/caolan/async/downloads). +Alternatively, you can install using Node Package Manager (npm): + + npm install async + + +__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 17.5kb Uncompressed + +__Production:__ [async.min.js](https://github.com/caolan/async/raw/master/dist/async.min.js) - 1.7kb Packed and Gzipped + + +## In the Browser + +So far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage: + + + + + +## Documentation + +### Collections + +* [forEach](#forEach) +* [map](#map) +* [filter](#filter) +* [reject](#reject) +* [reduce](#reduce) +* [detect](#detect) +* [sortBy](#sortBy) +* [some](#some) +* [every](#every) +* [concat](#concat) + +### Control Flow + +* [series](#series) +* [parallel](#parallel) +* [whilst](#whilst) +* [until](#until) +* [waterfall](#waterfall) +* [queue](#queue) +* [auto](#auto) +* [iterator](#iterator) +* [apply](#apply) +* [nextTick](#nextTick) + +### Utils + +* [memoize](#memoize) +* [unmemoize](#unmemoize) +* [log](#log) +* [dir](#dir) +* [noConflict](#noConflict) + + +## Collections + + +### forEach(arr, iterator, callback) + +Applies an iterator function to each item in an array, in parallel. +The iterator is called with an item from the list and a callback for when it +has finished. If the iterator passes an error to this callback, the main +callback for the forEach function is immediately called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + + // assuming openFiles is an array of file names and saveFile is a function + // to save the modified contents of that file: + + async.forEach(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error + }); + +--------------------------------------- + + +### forEachSeries(arr, iterator, callback) + +The same as forEach only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. This means the iterator functions will complete in order. + + +--------------------------------------- + + +### forEachLimit(arr, limit, iterator, callback) + +The same as forEach only the iterator is applied to batches of items in the +array, in series. The next batch of iterators is only called once the current +one has completed processing. + +__Arguments__ + +* arr - An array to iterate over. +* limit - How many items should be in each batch. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + + // Assume documents is an array of JSON objects and requestApi is a + // function that interacts with a rate-limited REST api. + + async.forEachLimit(documents, 20, requestApi, function(err){ + // if any of the saves produced an error, err would equal that error + }); +--------------------------------------- + + +### map(arr, iterator, callback) + +Produces a new array of values by mapping each value in the given array through +the iterator function. The iterator is called with an item from the array and a +callback for when it has finished processing. The callback takes 2 arguments, +an error and the transformed item from the array. If the iterator passes an +error to this callback, the main callback for the map function is immediately +called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order, however +the results array will be in the same order as the original array. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + + async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file + }); + +--------------------------------------- + + +### mapSeries(arr, iterator, callback) + +The same as map only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +--------------------------------------- + + +### filter(arr, iterator, callback) + +__Alias:__ select + +Returns a new array of all the values which pass an async truth test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(results) - A callback which is called after all the iterator + functions have finished. + +__Example__ + + async.filter(['file1','file2','file3'], path.exists, function(results){ + // results now equals an array of the existing files + }); + +--------------------------------------- + + +### filterSeries(arr, iterator, callback) + +__alias:__ selectSeries + +The same as filter only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + +--------------------------------------- + + +### reject(arr, iterator, callback) + +The opposite of filter. Removes values that pass an async truth test. + +--------------------------------------- + + +### rejectSeries(arr, iterator, callback) + +The same as filter, only the iterator is applied to each item in the array +in series. + + +--------------------------------------- + + +### reduce(arr, memo, iterator, callback) + +__aliases:__ inject, foldl + +Reduces a list of values into a single value using an async iterator to return +each successive step. Memo is the initial state of the reduction. This +function only operates in series. For performance reasons, it may make sense to +split a call to this function into a parallel map, then use the normal +Array.prototype.reduce on the results. This function is for situations where +each step in the reduction needs to be async, if you can get the data before +reducing it then its probably a good idea to do so. + +__Arguments__ + +* arr - An array to iterate over. +* memo - The initial state of the reduction. +* iterator(memo, item, callback) - A function applied to each item in the + array to produce the next step in the reduction. The iterator is passed a + callback which accepts an optional error as its first argument, and the state + of the reduction as the second. If an error is passed to the callback, the + reduction is stopped and the main callback is immediately called with the + error. +* callback(err, result) - A callback which is called after all the iterator + functions have finished. Result is the reduced value. + +__Example__ + + async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); + }, function(err, result){ + // result is now equal to the last value of memo, which is 6 + }); + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, callback) + +__Alias:__ foldr + +Same as reduce, only operates on the items in the array in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, callback) + +Returns the first value in a list that passes an async truth test. The +iterator is applied in parallel, meaning the first iterator to return true will +fire the detect callback with that result. That means the result might not be +the first item in the original array (in terms of order) that passes the test. + +If order within the original array is important then look at detectSeries. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value undefined if none passed. + +__Example__ + + async.detect(['file1','file2','file3'], path.exists, function(result){ + // result now equals the first file in the list that exists + }); + +--------------------------------------- + + +### detectSeries(arr, iterator, callback) + +The same as detect, only the iterator is applied to each item in the array +in series. This means the result is always the first in the original array (in +terms of array order) that passes the truth test. + + +--------------------------------------- + + +### sortBy(arr, iterator, callback) + +Sorts a list by the results of running each value through an async iterator. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and a value to use as the sort criteria. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is the items from + the original array sorted by the values returned by the iterator calls. + +__Example__ + + async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); + }, function(err, results){ + // results is now the original array of files sorted by + // modified date + }); + + +--------------------------------------- + + +### some(arr, iterator, callback) + +__Alias:__ any + +Returns true if at least one element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. Once any iterator +call returns true, the main callback is immediately called. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + either true or false depending on the values of the async tests. + +__Example__ + + async.some(['file1','file2','file3'], path.exists, function(result){ + // if result is true then at least one of the files exists + }); + +--------------------------------------- + + +### every(arr, iterator, callback) + +__Alias:__ all + +Returns true if every element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called after all the iterator + functions have finished. Result will be either true or false depending on + the values of the async tests. + +__Example__ + + async.every(['file1','file2','file3'], path.exists, function(result){ + // if result is true then every file exists + }); + +--------------------------------------- + + +### concat(arr, iterator, callback) + +Applies an iterator to each item in a list, concatenating the results. Returns the +concatenated list. The iterators are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of the arguments passed to the iterator function. + +__Arguments__ + +* arr - An array to iterate over +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and an array of results. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array containing + the concatenated results of the iterator function. + +__Example__ + + async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories + }); + +--------------------------------------- + + +### concatSeries(arr, iterator, callback) + +Same as async.concat, but executes in series instead of parallel. + + +## Control Flow + + +### series(tasks, [callback]) + +Run an array of functions in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run and the callback for the series is +immediately called with the value of the error. Once the tasks have completed, +the results are passed to the final callback as an array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.series. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback it must call on completion. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets an array of all the arguments passed to + the callbacks used in the array. + +__Example__ + + async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + }, + ], + // optional callback + function(err, results){ + // results is now equal to ['one', 'two'] + }); + + + // an example using an object instead of an array + async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + }, + }, + function(err, results) { + // results is now equal to: {one: 1, two: 2} + }); + + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run an array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main callback is immediately called with the value of the error. +Once the tasks have completed, the results are passed to the final callback as an +array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.parallel. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed a + callback it must call on completion. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets an array of all the arguments passed to + the callbacks used in the array. + +__Example__ + + async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + }, + ], + // optional callback + function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. + }); + + + // an example using an object instead of an array + async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + }, + }, + function(err, results) { + // results is now equals to: {one: 1, two: 2} + }); + + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call fn, while test returns true. Calls the callback when stopped, +or an error occurs. + +__Arguments__ + +* test() - synchronous truth test to perform before each execution of fn. +* fn(callback) - A function to call each time the test passes. The function is + passed a callback which must be called once it has completed with an optional + error as the first argument. +* callback(err) - A callback which is called after the test fails and repeated + execution of fn has stopped. + +__Example__ + + var count = 0; + + async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } + ); + + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call fn, until test returns true. Calls the callback when stopped, +or an error occurs. + +The inverse of async.whilst. + + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs an array of functions in series, each passing their results to the next in +the array. However, if any of the functions pass an error to the callback, the +next function is not executed and the main callback is immediately called with +the error. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a callback it + must call on completion. +* callback(err, [results]) - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + + async.waterfall([ + function(callback){ + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback){ + callback(null, 'three'); + }, + function(arg1, callback){ + // arg1 now equals 'three' + callback(null, 'done'); + } + ], function (err, result) { + // result now equals 'done' + }); + + +--------------------------------------- + + +### queue(worker, concurrency) + +Creates a queue object with the specified concurrency. Tasks added to the +queue will be processed in parallel (up to the concurrency limit). If all +workers are in progress, the task is queued until one is available. Once +a worker has completed a task, the task's callback is called. + +__Arguments__ + +* worker(task, callback) - An asynchronous function for processing a queued + task. +* concurrency - An integer for determining how many worker functions should be + run in parallel. + +__Queue objects__ + +The queue object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* concurrency - an integer for determining how many worker functions should be + run in parallel. This property can be changed after a queue is created to + alter the concurrency on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + + // create a queue object with concurrency 2 + + var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); + }, 2); + + + // assign a callback + q.drain = function() { + console.log('all items have been processed'); + } + + // add some items to the queue + + q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); + }); + q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); + }); + + // add some items to the queue (batch-wise) + + q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing bar'); + }); + + +--------------------------------------- + + +### auto(tasks, [callback]) + +Determines the best order for running functions based on their requirements. +Each function can optionally depend on other functions being completed first, +and each function is run as soon as its requirements are satisfied. If any of +the functions pass an error to their callback, that function will not complete +(so any other functions depending on it will not run) and the main callback +will be called immediately with the error. Functions also receive an object +containing the results of functions which have completed so far. + +__Arguments__ + +* tasks - An object literal containing named functions or an array of + requirements, with the function itself the last item in the array. The key + used for each function or array is used when specifying requirements. The + syntax is easier to understand by looking at the example. +* callback(err, results) - An optional callback which is called when all the + tasks have been completed. The callback will receive an error as an argument + if any tasks pass an error to their callback. If all tasks complete + successfully, it will receive an object containing their results. + +__Example__ + + async.auto({ + get_data: function(callback){ + // async code to get some data + }, + make_folder: function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + }, + write_file: ['get_data', 'make_folder', function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, filename); + }], + email_link: ['write_file', function(callback, results){ + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + }] + }); + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + + async.parallel([ + function(callback){ + // async code to get some data + }, + function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + } + ], + function(results){ + async.series([ + function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + }, + email_link: function(callback){ + // once the file is written let's email a link to it... + } + ]); + }); + +For a complicated series of async tasks using the auto function makes adding +new tasks much easier and makes the code more readable. + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the array, +returning a continuation to call the next one after that. Its also possible to +'peek' the next iterator by doing iterator.next(). + +This function is used internally by the async module but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a callback it + must call on completion. + +__Example__ + + var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } + ]); + + node> var iterator2 = iterator(); + 'one' + node> var iterator3 = iterator2(); + 'two' + node> iterator3(); + 'three' + node> var nextfn = iterator2.next(); + node> nextfn(); + 'three' + + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied, a useful +shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + + // using apply + + async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), + ]); + + + // the same process without using apply + + async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + }, + ]); + +It's possible to pass any number of additional arguments when calling the +continuation: + + node> var fn = async.apply(sys.puts, 'one'); + node> fn('two', 'three'); + one + two + three + +--------------------------------------- + + +### nextTick(callback) + +Calls the callback on a later loop around the event loop. In node.js this just +calls process.nextTick, in the browser it falls back to setTimeout(callback, 0), +which means other higher priority events may precede the execution of the callback. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* callback - The function to call on a later loop around the event loop. + +__Example__ + + var call_order = []; + async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two] + }); + call_order.push('one') + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an async function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +__Arguments__ + +* fn - the function you to proxy and cache results from. +* hasher - an optional function for generating a custom hash for storing + results, it has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + + var slow_fn = function (name, callback) { + // do something + callback(null, result); + }; + var fn = async.memoize(slow_fn); + + // fn can now be used as if it were slow_fn + fn('some name', function () { + // callback + }); + + +### unmemoize(fn) + +Undoes a memoized function, reverting it to the original, unmemoized +form. Comes handy in tests. + +__Arguments__ + +* fn - the memoized function + + +### log(function, arguments) + +Logs the result of an async function to the console. Only works in node.js or +in browsers that support console.log and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.log is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + + var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); + }; + + node> async.log(hello, 'world'); + 'hello world' + + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an async function to the console using console.dir to +display the properties of the resulting object. Only works in node.js or +in browsers that support console.dir and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.dir is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + + var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); + }; + + node> async.dir(hello, 'world'); + {hello: 'world'} + + +--------------------------------------- + + +### noConflict() + +Changes the value of async back to its original value, returning a reference to the +async object. diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/index.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/index.js new file mode 100644 index 0000000..8e23845 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/index.js @@ -0,0 +1,3 @@ +// This file is just added for convenience so this repository can be +// directly checked out into a project's deps folder +module.exports = require('./lib/async'); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/lib/async.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/lib/async.js new file mode 100644 index 0000000..7cc4f5e --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/lib/async.js @@ -0,0 +1,692 @@ +/*global setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root = this, + previous_async = root.async; + + if (typeof module !== 'undefined' && module.exports) { + module.exports = async; + } + else { + root.async = async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + //// cross-browser compatiblity functions //// + + var _forEach = function (arr, iterator) { + if (arr.forEach) { + return arr.forEach(iterator); + } + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; + + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _forEach(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _forEach(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + async.nextTick = function (fn) { + setTimeout(fn, 0); + }; + } + else { + async.nextTick = process.nextTick; + } + + async.forEach = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + _forEach(arr, function (x) { + iterator(x, function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed === arr.length) { + callback(null); + } + } + }); + }); + }; + + async.forEachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed === arr.length) { + callback(null); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + + async.forEachLimit = function (arr, limit, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; + + (function replenish () { + if (completed === arr.length) { + return callback(); + } + + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed === arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + + + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.forEach].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.forEachSeries].concat(args)); + }; + }; + + + var _asyncMap = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.forEachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; + + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; + + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; + + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); + + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); + + async.some = function (arr, iterator, main_callback) { + async.forEach(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; + + async.every = function (arr, iterator, main_callback) { + async.forEach(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + if (!keys.length) { + return callback(null); + } + + var results = {}; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + _forEach(listeners.slice(0), function (fn) { + fn(); + }); + }; + + addListener(function () { + if (_keys(results).length === keys.length) { + callback(null, results); + callback = function () {}; + } + }); + + _forEach(keys, function (k) { + var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var taskCallback = function (err) { + if (err) { + callback(err); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + taskComplete(); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } + }); + }; + + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.nextTick(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + async.parallel = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.forEach(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.forEachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.queue = function (worker, concurrency) { + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _forEach(data, function(task) { + q.tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + if (q.saturated && q.tasks.length == concurrency) { + q.saturated(); + } + async.nextTick(q.process); + }); + }, + process: function () { + if (workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if(q.empty && q.tasks.length == 0) q.empty(); + workers += 1; + worker(task.data, function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if(q.drain && q.tasks.length + workers == 0) q.drain(); + q.process(); + }); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + } + }; + return q; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _forEach(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + callback.apply(null, memo[key]); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + +}()); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/package.json b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/package.json new file mode 100644 index 0000000..4e606ee --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/async/package.json @@ -0,0 +1,36 @@ +{ + "name": "async", + "description": "Higher-order functions and common patterns for asynchronous code", + "main": "./index", + "author": { + "name": "Caolan McMahon" + }, + "version": "0.1.22", + "repository": { + "type": "git", + "url": "http://github.com/caolan/async.git" + }, + "bugs": { + "url": "http://github.com/caolan/async/issues" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/caolan/async/raw/master/LICENSE" + } + ], + "devDependencies": { + "nodeunit": ">0.0.0", + "uglify-js": "1.2.x", + "nodelint": ">0.0.0" + }, + "readme": "# Async.js\n\nAsync is a utility module which provides straight-forward, powerful functions\nfor working with asynchronous JavaScript. Although originally designed for\nuse with [node.js](http://nodejs.org), it can also be used directly in the\nbrowser.\n\nAsync provides around 20 functions that include the usual 'functional'\nsuspects (map, reduce, filter, forEach…) as well as some common patterns\nfor asynchronous control flow (parallel, series, waterfall…). All these\nfunctions assume you follow the node.js convention of providing a single\ncallback as the last argument of your async function.\n\n\n## Quick Examples\n\n async.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n });\n\n async.filter(['file1','file2','file3'], path.exists, function(results){\n // results now equals an array of the existing files\n });\n\n async.parallel([\n function(){ ... },\n function(){ ... }\n ], callback);\n\n async.series([\n function(){ ... },\n function(){ ... }\n ]);\n\nThere are many more functions available so take a look at the docs below for a\nfull list. This module aims to be comprehensive, so if you feel anything is\nmissing please create a GitHub issue for it.\n\n\n## Download\n\nReleases are available for download from\n[GitHub](http://github.com/caolan/async/downloads).\nAlternatively, you can install using Node Package Manager (npm):\n\n npm install async\n\n\n__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 17.5kb Uncompressed\n\n__Production:__ [async.min.js](https://github.com/caolan/async/raw/master/dist/async.min.js) - 1.7kb Packed and Gzipped\n\n\n## In the Browser\n\nSo far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:\n\n \n \n\n\n## Documentation\n\n### Collections\n\n* [forEach](#forEach)\n* [map](#map)\n* [filter](#filter)\n* [reject](#reject)\n* [reduce](#reduce)\n* [detect](#detect)\n* [sortBy](#sortBy)\n* [some](#some)\n* [every](#every)\n* [concat](#concat)\n\n### Control Flow\n\n* [series](#series)\n* [parallel](#parallel)\n* [whilst](#whilst)\n* [until](#until)\n* [waterfall](#waterfall)\n* [queue](#queue)\n* [auto](#auto)\n* [iterator](#iterator)\n* [apply](#apply)\n* [nextTick](#nextTick)\n\n### Utils\n\n* [memoize](#memoize)\n* [unmemoize](#unmemoize)\n* [log](#log)\n* [dir](#dir)\n* [noConflict](#noConflict)\n\n\n## Collections\n\n\n### forEach(arr, iterator, callback)\n\nApplies an iterator function to each item in an array, in parallel.\nThe iterator is called with an item from the list and a callback for when it\nhas finished. If the iterator passes an error to this callback, the main\ncallback for the forEach function is immediately called with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n // assuming openFiles is an array of file names and saveFile is a function\n // to save the modified contents of that file:\n\n async.forEach(openFiles, saveFile, function(err){\n // if any of the saves produced an error, err would equal that error\n });\n\n---------------------------------------\n\n\n### forEachSeries(arr, iterator, callback)\n\nThe same as forEach only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. This means the iterator functions will complete in order.\n\n\n---------------------------------------\n\n\n### forEachLimit(arr, limit, iterator, callback)\n\nThe same as forEach only the iterator is applied to batches of items in the\narray, in series. The next batch of iterators is only called once the current\none has completed processing.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - How many items should be in each batch.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n // Assume documents is an array of JSON objects and requestApi is a\n // function that interacts with a rate-limited REST api.\n\n async.forEachLimit(documents, 20, requestApi, function(err){\n // if any of the saves produced an error, err would equal that error\n });\n---------------------------------------\n\n\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in the given array through\nthe iterator function. The iterator is called with an item from the array and a\ncallback for when it has finished processing. The callback takes 2 arguments, \nan error and the transformed item from the array. If the iterator passes an\nerror to this callback, the main callback for the map function is immediately\ncalled with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order, however\nthe results array will be in the same order as the original array.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n async.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n });\n\n---------------------------------------\n\n\n### mapSeries(arr, iterator, callback)\n\nThe same as map only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n---------------------------------------\n\n\n### filter(arr, iterator, callback)\n\n__Alias:__ select\n\nReturns a new array of all the values which pass an async truth test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(results) - A callback which is called after all the iterator\n functions have finished.\n\n__Example__\n\n async.filter(['file1','file2','file3'], path.exists, function(results){\n // results now equals an array of the existing files\n });\n\n---------------------------------------\n\n\n### filterSeries(arr, iterator, callback)\n\n__alias:__ selectSeries\n\nThe same as filter only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n---------------------------------------\n\n\n### reject(arr, iterator, callback)\n\nThe opposite of filter. Removes values that pass an async truth test.\n\n---------------------------------------\n\n\n### rejectSeries(arr, iterator, callback)\n\nThe same as filter, only the iterator is applied to each item in the array\nin series.\n\n\n---------------------------------------\n\n\n### reduce(arr, memo, iterator, callback)\n\n__aliases:__ inject, foldl\n\nReduces a list of values into a single value using an async iterator to return\neach successive step. Memo is the initial state of the reduction. This\nfunction only operates in series. For performance reasons, it may make sense to\nsplit a call to this function into a parallel map, then use the normal\nArray.prototype.reduce on the results. This function is for situations where\neach step in the reduction needs to be async, if you can get the data before\nreducing it then its probably a good idea to do so.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* memo - The initial state of the reduction.\n* iterator(memo, item, callback) - A function applied to each item in the\n array to produce the next step in the reduction. The iterator is passed a\n callback which accepts an optional error as its first argument, and the state\n of the reduction as the second. If an error is passed to the callback, the\n reduction is stopped and the main callback is immediately called with the\n error.\n* callback(err, result) - A callback which is called after all the iterator\n functions have finished. Result is the reduced value.\n\n__Example__\n\n async.reduce([1,2,3], 0, function(memo, item, callback){\n // pointless async:\n process.nextTick(function(){\n callback(null, memo + item)\n });\n }, function(err, result){\n // result is now equal to the last value of memo, which is 6\n });\n\n---------------------------------------\n\n\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ foldr\n\nSame as reduce, only operates on the items in the array in reverse order.\n\n\n---------------------------------------\n\n\n### detect(arr, iterator, callback)\n\nReturns the first value in a list that passes an async truth test. The\niterator is applied in parallel, meaning the first iterator to return true will\nfire the detect callback with that result. That means the result might not be\nthe first item in the original array (in terms of order) that passes the test.\n\nIf order within the original array is important then look at detectSeries.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n the first item in the array that passes the truth test (iterator) or the\n value undefined if none passed.\n\n__Example__\n\n async.detect(['file1','file2','file3'], path.exists, function(result){\n // result now equals the first file in the list that exists\n });\n\n---------------------------------------\n\n\n### detectSeries(arr, iterator, callback)\n\nThe same as detect, only the iterator is applied to each item in the array\nin series. This means the result is always the first in the original array (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each value through an async iterator.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and a value to use as the sort criteria.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is the items from\n the original array sorted by the values returned by the iterator calls.\n\n__Example__\n\n async.sortBy(['file1','file2','file3'], function(file, callback){\n fs.stat(file, function(err, stats){\n callback(err, stats.mtime);\n });\n }, function(err, results){\n // results is now the original array of files sorted by\n // modified date\n });\n\n\n---------------------------------------\n\n\n### some(arr, iterator, callback)\n\n__Alias:__ any\n\nReturns true if at least one element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists. Once any iterator\ncall returns true, the main callback is immediately called.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n either true or false depending on the values of the async tests.\n\n__Example__\n\n async.some(['file1','file2','file3'], path.exists, function(result){\n // if result is true then at least one of the files exists\n });\n\n---------------------------------------\n\n\n### every(arr, iterator, callback)\n\n__Alias:__ all\n\nReturns true if every element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called after all the iterator\n functions have finished. Result will be either true or false depending on\n the values of the async tests.\n\n__Example__\n\n async.every(['file1','file2','file3'], path.exists, function(result){\n // if result is true then every file exists\n });\n\n---------------------------------------\n\n\n### concat(arr, iterator, callback)\n\nApplies an iterator to each item in a list, concatenating the results. Returns the\nconcatenated list. The iterators are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of the arguments passed to the iterator function.\n\n__Arguments__\n\n* arr - An array to iterate over\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and an array of results.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array containing\n the concatenated results of the iterator function.\n\n__Example__\n\n async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n // files is now a list of filenames that exist in the 3 directories\n });\n\n---------------------------------------\n\n\n### concatSeries(arr, iterator, callback)\n\nSame as async.concat, but executes in series instead of parallel.\n\n\n## Control Flow\n\n\n### series(tasks, [callback])\n\nRun an array of functions in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run and the callback for the series is\nimmediately called with the value of the error. Once the tasks have completed,\nthe results are passed to the final callback as an array.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.series.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed\n a callback it must call on completion.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets an array of all the arguments passed to\n the callbacks used in the array.\n\n__Example__\n\n async.series([\n function(callback){\n // do some stuff ...\n callback(null, 'one');\n },\n function(callback){\n // do some more stuff ...\n callback(null, 'two');\n },\n ],\n // optional callback\n function(err, results){\n // results is now equal to ['one', 'two']\n });\n\n\n // an example using an object instead of an array\n async.series({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n },\n },\n function(err, results) {\n // results is now equal to: {one: 1, two: 2}\n });\n\n\n---------------------------------------\n\n\n### parallel(tasks, [callback])\n\nRun an array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main callback is immediately called with the value of the error.\nOnce the tasks have completed, the results are passed to the final callback as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.parallel.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed a\n callback it must call on completion.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets an array of all the arguments passed to\n the callbacks used in the array.\n\n__Example__\n\n async.parallel([\n function(callback){\n setTimeout(function(){\n callback(null, 'one');\n }, 200);\n },\n function(callback){\n setTimeout(function(){\n callback(null, 'two');\n }, 100);\n },\n ],\n // optional callback\n function(err, results){\n // the results array will equal ['one','two'] even though\n // the second function had a shorter timeout.\n });\n\n\n // an example using an object instead of an array\n async.parallel({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n },\n },\n function(err, results) {\n // results is now equals to: {one: 1, two: 2}\n });\n\n\n---------------------------------------\n\n\n### whilst(test, fn, callback)\n\nRepeatedly call fn, while test returns true. Calls the callback when stopped,\nor an error occurs.\n\n__Arguments__\n\n* test() - synchronous truth test to perform before each execution of fn.\n* fn(callback) - A function to call each time the test passes. The function is\n passed a callback which must be called once it has completed with an optional\n error as the first argument.\n* callback(err) - A callback which is called after the test fails and repeated\n execution of fn has stopped.\n\n__Example__\n\n var count = 0;\n\n async.whilst(\n function () { return count < 5; },\n function (callback) {\n count++;\n setTimeout(callback, 1000);\n },\n function (err) {\n // 5 seconds have passed\n }\n );\n\n\n---------------------------------------\n\n\n### until(test, fn, callback)\n\nRepeatedly call fn, until test returns true. Calls the callback when stopped,\nor an error occurs.\n\nThe inverse of async.whilst.\n\n\n---------------------------------------\n\n\n### waterfall(tasks, [callback])\n\nRuns an array of functions in series, each passing their results to the next in\nthe array. However, if any of the functions pass an error to the callback, the\nnext function is not executed and the main callback is immediately called with\nthe error.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a callback it\n must call on completion.\n* callback(err, [results]) - An optional callback to run once all the functions\n have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n async.waterfall([\n function(callback){\n callback(null, 'one', 'two');\n },\n function(arg1, arg2, callback){\n callback(null, 'three');\n },\n function(arg1, callback){\n // arg1 now equals 'three'\n callback(null, 'done');\n }\n ], function (err, result) {\n // result now equals 'done' \n });\n\n\n---------------------------------------\n\n\n### queue(worker, concurrency)\n\nCreates a queue object with the specified concurrency. Tasks added to the\nqueue will be processed in parallel (up to the concurrency limit). If all\nworkers are in progress, the task is queued until one is available. Once\na worker has completed a task, the task's callback is called.\n\n__Arguments__\n\n* worker(task, callback) - An asynchronous function for processing a queued\n task.\n* concurrency - An integer for determining how many worker functions should be\n run in parallel.\n\n__Queue objects__\n\nThe queue object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* concurrency - an integer for determining how many worker functions should be\n run in parallel. This property can be changed after a queue is created to\n alter the concurrency on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n // create a queue object with concurrency 2\n\n var q = async.queue(function (task, callback) {\n console.log('hello ' + task.name);\n callback();\n }, 2);\n\n\n // assign a callback\n q.drain = function() {\n console.log('all items have been processed');\n }\n\n // add some items to the queue\n\n q.push({name: 'foo'}, function (err) {\n console.log('finished processing foo');\n });\n q.push({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n });\n\n // add some items to the queue (batch-wise)\n\n q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n console.log('finished processing bar');\n });\n\n\n---------------------------------------\n\n\n### auto(tasks, [callback])\n\nDetermines the best order for running functions based on their requirements.\nEach function can optionally depend on other functions being completed first,\nand each function is run as soon as its requirements are satisfied. If any of\nthe functions pass an error to their callback, that function will not complete\n(so any other functions depending on it will not run) and the main callback\nwill be called immediately with the error. Functions also receive an object\ncontaining the results of functions which have completed so far.\n\n__Arguments__\n\n* tasks - An object literal containing named functions or an array of\n requirements, with the function itself the last item in the array. The key\n used for each function or array is used when specifying requirements. The\n syntax is easier to understand by looking at the example.\n* callback(err, results) - An optional callback which is called when all the\n tasks have been completed. The callback will receive an error as an argument\n if any tasks pass an error to their callback. If all tasks complete\n successfully, it will receive an object containing their results.\n\n__Example__\n\n async.auto({\n get_data: function(callback){\n // async code to get some data\n },\n make_folder: function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n },\n write_file: ['get_data', 'make_folder', function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n callback(null, filename);\n }],\n email_link: ['write_file', function(callback, results){\n // once the file is written let's email a link to it...\n // results.write_file contains the filename returned by write_file.\n }]\n });\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n async.parallel([\n function(callback){\n // async code to get some data\n },\n function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n }\n ],\n function(results){\n async.series([\n function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n },\n email_link: function(callback){\n // once the file is written let's email a link to it...\n }\n ]);\n });\n\nFor a complicated series of async tasks using the auto function makes adding\nnew tasks much easier and makes the code more readable.\n\n\n---------------------------------------\n\n\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the array,\nreturning a continuation to call the next one after that. Its also possible to\n'peek' the next iterator by doing iterator.next().\n\nThis function is used internally by the async module but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a callback it\n must call on completion.\n\n__Example__\n\n var iterator = async.iterator([\n function(){ sys.p('one'); },\n function(){ sys.p('two'); },\n function(){ sys.p('three'); }\n ]);\n\n node> var iterator2 = iterator();\n 'one'\n node> var iterator3 = iterator2();\n 'two'\n node> iterator3();\n 'three'\n node> var nextfn = iterator2.next();\n node> nextfn();\n 'three'\n\n\n---------------------------------------\n\n\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied, a useful\nshorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to automatically apply when the\n continuation is called.\n\n__Example__\n\n // using apply\n\n async.parallel([\n async.apply(fs.writeFile, 'testfile1', 'test1'),\n async.apply(fs.writeFile, 'testfile2', 'test2'),\n ]);\n\n\n // the same process without using apply\n\n async.parallel([\n function(callback){\n fs.writeFile('testfile1', 'test1', callback);\n },\n function(callback){\n fs.writeFile('testfile2', 'test2', callback);\n },\n ]);\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n node> var fn = async.apply(sys.puts, 'one');\n node> fn('two', 'three');\n one\n two\n three\n\n---------------------------------------\n\n\n### nextTick(callback)\n\nCalls the callback on a later loop around the event loop. In node.js this just\ncalls process.nextTick, in the browser it falls back to setTimeout(callback, 0),\nwhich means other higher priority events may precede the execution of the callback.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* callback - The function to call on a later loop around the event loop.\n\n__Example__\n\n var call_order = [];\n async.nextTick(function(){\n call_order.push('two');\n // call_order now equals ['one','two]\n });\n call_order.push('one')\n\n\n## Utils\n\n\n### memoize(fn, [hasher])\n\nCaches the results of an async function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\n__Arguments__\n\n* fn - the function you to proxy and cache results from.\n* hasher - an optional function for generating a custom hash for storing\n results, it has all the arguments applied to it apart from the callback, and\n must be synchronous.\n\n__Example__\n\n var slow_fn = function (name, callback) {\n // do something\n callback(null, result);\n };\n var fn = async.memoize(slow_fn);\n\n // fn can now be used as if it were slow_fn\n fn('some name', function () {\n // callback\n });\n\n\n### unmemoize(fn)\n\nUndoes a memoized function, reverting it to the original, unmemoized\nform. Comes handy in tests.\n\n__Arguments__\n\n* fn - the memoized function\n\n\n### log(function, arguments)\n\nLogs the result of an async function to the console. Only works in node.js or\nin browsers that support console.log and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.log is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n var hello = function(name, callback){\n setTimeout(function(){\n callback(null, 'hello ' + name);\n }, 1000);\n };\n\n node> async.log(hello, 'world');\n 'hello world'\n\n\n---------------------------------------\n\n\n### dir(function, arguments)\n\nLogs the result of an async function to the console using console.dir to\ndisplay the properties of the resulting object. Only works in node.js or\nin browsers that support console.dir and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.dir is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n var hello = function(name, callback){\n setTimeout(function(){\n callback(null, {hello: name});\n }, 1000);\n };\n\n node> async.dir(hello, 'world');\n {hello: 'world'}\n\n\n---------------------------------------\n\n\n### noConflict()\n\nChanges the value of async back to its original value, returning a reference to the\nasync object.\n", + "readmeFilename": "README.md", + "_id": "async@0.1.22", + "dist": { + "shasum": "2f3a2dc03739e1d7d7a333bbc0b747c14716f285" + }, + "_from": "async@0.1.x", + "_resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", + "scripts": {} +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/README.md b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/README.md new file mode 100644 index 0000000..5ca8d51 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/README.md @@ -0,0 +1,45 @@ +Fork of https://github.com/douglascrockford/JSON-js, maintained in npm as `cycle`. + +Original readme follows + +# JSON in JavaScript + +Douglas Crockford +douglas@crockford.com + +2010-11-18 + + +JSON is a light-weight, language independent, data interchange format. +See http://www.JSON.org/ + +The files in this collection implement JSON encoders/decoders in JavaScript. + +JSON became a built-in feature of JavaScript when the ECMAScript Programming +Language Standard - Fifth Edition was adopted by the ECMA General Assembly +in December 2009. Most of the files in this collection are for applications +that are expected to run in obsolete web browsers. For most purposes, json2.js +is the best choice. + + +json2.js: This file creates a JSON property in the global object, if there +isn't already one, setting its value to an object containing a stringify +method and a parse method. The parse method uses the eval method to do the +parsing, guarding it with several regular expressions to defend against +accidental code execution hazards. On current browsers, this file does nothing, +prefering the built-in JSON object. + +json.js: This file does everything that json2.js does. It also adds a +toJSONString method and a parseJSON method to Object.prototype. Use of this +file is not recommended. + +json_parse.js: This file contains an alternative JSON parse function that +uses recursive descent instead of eval. + +json_parse_state.js: This files contains an alternative JSON parse function that +uses a state machine instead of eval. + +cycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle, +which make it possible to encode cyclical structures and dags in JSON, and to +then recover them. JSONPath is used to represent the links. +http://GOESSNER.net/articles/JsonPath/ diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/cycle.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/cycle.js new file mode 100644 index 0000000..4382285 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/cycle.js @@ -0,0 +1,164 @@ +// cycle.js +// 2011-08-24 + +/*jslint evil: true, regexp: true */ + +/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push, + retrocycle, stringify, test, toString +*/ +var cycle = exports; + +cycle.decycle = function decycle(object) { + 'use strict'; + +// Make a deep copy of an object or array, assuring that there is at most +// one instance of each object or array in the resulting structure. The +// duplicate references (which might be forming cycles) are replaced with +// an object of the form +// {$ref: PATH} +// where the PATH is a JSONPath string that locates the first occurance. +// So, +// var a = []; +// a[0] = a; +// return JSON.stringify(JSON.decycle(a)); +// produces the string '[{"$ref":"$"}]'. + +// JSONPath is used to locate the unique object. $ indicates the top level of +// the object or array. [NUMBER] or [STRING] indicates a child member or +// property. + + var objects = [], // Keep a reference to each unique object or array + paths = []; // Keep the path to each unique object or array + + return (function derez(value, path) { + +// The derez recurses through the object, producing the deep copy. + + var i, // The loop counter + name, // Property name + nu; // The new object or array + + switch (typeof value) { + case 'object': + +// typeof null === 'object', so get out if this value is not really an object. +// Also get out if it is a weird builtin object. + + if (value === null || + value instanceof Boolean || + value instanceof Date || + value instanceof Number || + value instanceof RegExp || + value instanceof String) { + return value; + } + +// If the value is an object or array, look to see if we have already +// encountered it. If so, return a $ref/path object. This is a hard way, +// linear search that will get slower as the number of unique objects grows. + + for (i = 0; i < objects.length; i += 1) { + if (objects[i] === value) { + return {$ref: paths[i]}; + } + } + +// Otherwise, accumulate the unique value and its path. + + objects.push(value); + paths.push(path); + +// If it is an array, replicate the array. + + if (Object.prototype.toString.apply(value) === '[object Array]') { + nu = []; + for (i = 0; i < value.length; i += 1) { + nu[i] = derez(value[i], path + '[' + i + ']'); + } + } else { + +// If it is an object, replicate the object. + + nu = {}; + for (name in value) { + if (Object.prototype.hasOwnProperty.call(value, name)) { + nu[name] = derez(value[name], + path + '[' + JSON.stringify(name) + ']'); + } + } + } + return nu; + case 'number': + case 'string': + case 'boolean': + return value; + } + }(object, '$')); +}; + +cycle.retrocycle = function retrocycle($) { + 'use strict'; + +// Restore an object that was reduced by decycle. Members whose values are +// objects of the form +// {$ref: PATH} +// are replaced with references to the value found by the PATH. This will +// restore cycles. The object will be mutated. + +// The eval function is used to locate the values described by a PATH. The +// root object is kept in a $ variable. A regular expression is used to +// assure that the PATH is extremely well formed. The regexp contains nested +// * quantifiers. That has been known to have extremely bad performance +// problems on some browsers for very long strings. A PATH is expected to be +// reasonably short. A PATH is allowed to belong to a very restricted subset of +// Goessner's JSONPath. + +// So, +// var s = '[{"$ref":"$"}]'; +// return JSON.retrocycle(JSON.parse(s)); +// produces an array containing a single element which is the array itself. + + var px = + /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/; + + (function rez(value) { + +// The rez function walks recursively through the object looking for $ref +// properties. When it finds one that has a value that is a path, then it +// replaces the $ref object with a reference to the value that is found by +// the path. + + var i, item, name, path; + + if (value && typeof value === 'object') { + if (Object.prototype.toString.apply(value) === '[object Array]') { + for (i = 0; i < value.length; i += 1) { + item = value[i]; + if (item && typeof item === 'object') { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[i] = eval(path); + } else { + rez(item); + } + } + } + } else { + for (name in value) { + if (typeof value[name] === 'object') { + item = value[name]; + if (item) { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[name] = eval(path); + } else { + rez(item); + } + } + } + } + } + } + }($)); + return $; +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/package.json b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/package.json new file mode 100644 index 0000000..82f5ba2 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/cycle/package.json @@ -0,0 +1,33 @@ +{ + "name": "cycle", + "description": "decycle your json", + "author": "", + "version": "1.0.2", + "main": "./cycle.js", + "homepage": "https://github.com/douglascrockford/JSON-js", + "repository": { + "type": "git", + "url": "http://github.com/dscape/cycle.git" + }, + "bugs": { + "url": "http://github.com/douglascrockford/JSON-js/issues" + }, + "keywords": [ + "json", + "cycle", + "stringify", + "parse" + ], + "engines": { + "node": ">=0.4.0" + }, + "readme": "Fork of https://github.com/douglascrockford/JSON-js, maintained in npm as `cycle`.\n\nOriginal readme follows\n\n# JSON in JavaScript\n\nDouglas Crockford\ndouglas@crockford.com\n\n2010-11-18\n\n\nJSON is a light-weight, language independent, data interchange format.\nSee http://www.JSON.org/\n\nThe files in this collection implement JSON encoders/decoders in JavaScript.\n\nJSON became a built-in feature of JavaScript when the ECMAScript Programming\nLanguage Standard - Fifth Edition was adopted by the ECMA General Assembly\nin December 2009. Most of the files in this collection are for applications\nthat are expected to run in obsolete web browsers. For most purposes, json2.js\nis the best choice.\n\n\njson2.js: This file creates a JSON property in the global object, if there\nisn't already one, setting its value to an object containing a stringify\nmethod and a parse method. The parse method uses the eval method to do the\nparsing, guarding it with several regular expressions to defend against\naccidental code execution hazards. On current browsers, this file does nothing,\nprefering the built-in JSON object.\n\njson.js: This file does everything that json2.js does. It also adds a\ntoJSONString method and a parseJSON method to Object.prototype. Use of this\nfile is not recommended.\n\njson_parse.js: This file contains an alternative JSON parse function that\nuses recursive descent instead of eval.\n\njson_parse_state.js: This files contains an alternative JSON parse function that\nuses a state machine instead of eval.\n\ncycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle,\nwhich make it possible to encode cyclical structures and dags in JSON, and to\nthen recover them. JSONPath is used to represent the links.\nhttp://GOESSNER.net/articles/JsonPath/\n", + "readmeFilename": "README.md", + "_id": "cycle@1.0.2", + "dist": { + "shasum": "23f65cde66a289df1739ab1213a3d042ea0194b5" + }, + "_from": "cycle@1.0.x", + "_resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.2.tgz", + "scripts": {} +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/.npmignore b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/.npmignore new file mode 100644 index 0000000..9303c34 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/README.md b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/README.md new file mode 100644 index 0000000..07ba942 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/README.md @@ -0,0 +1,85 @@ +# node-pkginfo + +An easy way to expose properties on a module from a package.json + +## Installation + +### Installing npm (node package manager) +``` + curl http://npmjs.org/install.sh | sh +``` + +### Installing pkginfo +``` + [sudo] npm install pkginfo +``` + +## Motivation +How often when writing node.js modules have you written the following line(s) of code? + +* Hard code your version string into your code + +``` js + exports.version = '0.1.0'; +``` + +* Programmatically expose the version from the package.json + +``` js + exports.version = JSON.parse(fs.readFileSync('/path/to/package.json', 'utf8')).version; +``` + +In other words, how often have you wanted to expose basic information from your package.json onto your module programmatically? **WELL NOW YOU CAN!** + +## Usage + +Using `pkginfo` is idiot-proof, just require and invoke it. + +``` js + var pkginfo = require('pkginfo')(module); + + console.dir(module.exports); +``` + +By invoking the `pkginfo` module all of the properties in your `package.json` file will be automatically exposed on the callee module (i.e. the parent module of `pkginfo`). + +Here's a sample of the output: + +``` + { name: 'simple-app', + description: 'A test fixture for pkginfo', + version: '0.1.0', + author: 'Charlie Robbins ', + keywords: [ 'test', 'fixture' ], + main: './index.js', + scripts: { test: 'vows test/*-test.js --spec' }, + engines: { node: '>= 0.4.0' } } +``` + +### Expose specific properties +If you don't want to expose **all** properties on from your `package.json` on your module then simple pass those properties to the `pkginfo` function: + +``` js + var pkginfo = require('pkginfo')(module, 'version', 'author'); + + console.dir(module.exports); +``` + +``` + { version: '0.1.0', + author: 'Charlie Robbins ' } +``` + +If you're looking for further usage see the [examples][0] included in this repository. + +## Run Tests +Tests are written in [vows][1] and give complete coverage of all APIs. + +``` + vows test/*-test.js --spec +``` + +[0]: https://github.com/indexzero/node-pkginfo/tree/master/examples +[1]: http://vowsjs.org + +#### Author: [Charlie Robbins](http://nodejitsu.com) \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/docs/docco.css b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/docs/docco.css new file mode 100644 index 0000000..bd54134 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/docs/docco.css @@ -0,0 +1,194 @@ +/*--------------------- Layout and Typography ----------------------------*/ +body { + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 15px; + line-height: 22px; + color: #252519; + margin: 0; padding: 0; +} +a { + color: #261a3b; +} + a:visited { + color: #261a3b; + } +p { + margin: 0 0 15px 0; +} +h4, h5, h6 { + color: #333; + margin: 6px 0 6px 0; + font-size: 13px; +} + h2, h3 { + margin-bottom: 0; + color: #000; + } + h1 { + margin-top: 40px; + margin-bottom: 15px; + color: #000; + } +#container { + position: relative; +} +#background { + position: fixed; + top: 0; left: 525px; right: 0; bottom: 0; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + z-index: -1; +} +#jump_to, #jump_page { + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 10px Arial; + text-transform: uppercase; + cursor: pointer; + text-align: right; +} +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 5px 10px; +} + #jump_wrapper { + padding: 0; + display: none; + } + #jump_to:hover #jump_wrapper { + display: block; + } + #jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; + } + #jump_page .source { + display: block; + padding: 5px 10px; + text-decoration: none; + border-top: 1px solid #eee; + } + #jump_page .source:hover { + background: #f5f5ff; + } + #jump_page .source:first-child { + } +table td { + border: 0; + outline: 0; +} + td.docs, th.docs { + max-width: 450px; + min-width: 450px; + min-height: 5px; + padding: 10px 25px 1px 50px; + overflow-x: hidden; + vertical-align: top; + text-align: left; + } + .docs pre { + margin: 15px 0 15px; + padding-left: 15px; + } + .docs p tt, .docs p code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } + .pilwrap { + position: relative; + } + .pilcrow { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + td.docs:hover .pilcrow { + opacity: 1; + } + td.code, th.code { + padding: 14px 15px 16px 25px; + width: 100%; + vertical-align: top; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + } + pre, tt, code { + font-size: 12px; line-height: 18px; + font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + + +/*---------------------- Syntax Highlighting -----------------------------*/ +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +body .hll { background-color: #ffffcc } +body .c { color: #408080; font-style: italic } /* Comment */ +body .err { border: 1px solid #FF0000 } /* Error */ +body .k { color: #954121 } /* Keyword */ +body .o { color: #666666 } /* Operator */ +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +body .cp { color: #BC7A00 } /* Comment.Preproc */ +body .c1 { color: #408080; font-style: italic } /* Comment.Single */ +body .cs { color: #408080; font-style: italic } /* Comment.Special */ +body .gd { color: #A00000 } /* Generic.Deleted */ +body .ge { font-style: italic } /* Generic.Emph */ +body .gr { color: #FF0000 } /* Generic.Error */ +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +body .gi { color: #00A000 } /* Generic.Inserted */ +body .go { color: #808080 } /* Generic.Output */ +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +body .gs { font-weight: bold } /* Generic.Strong */ +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +body .gt { color: #0040D0 } /* Generic.Traceback */ +body .kc { color: #954121 } /* Keyword.Constant */ +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ +body .kp { color: #954121 } /* Keyword.Pseudo */ +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ +body .kt { color: #B00040 } /* Keyword.Type */ +body .m { color: #666666 } /* Literal.Number */ +body .s { color: #219161 } /* Literal.String */ +body .na { color: #7D9029 } /* Name.Attribute */ +body .nb { color: #954121 } /* Name.Builtin */ +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +body .no { color: #880000 } /* Name.Constant */ +body .nd { color: #AA22FF } /* Name.Decorator */ +body .ni { color: #999999; font-weight: bold } /* Name.Entity */ +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +body .nf { color: #0000FF } /* Name.Function */ +body .nl { color: #A0A000 } /* Name.Label */ +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +body .nt { color: #954121; font-weight: bold } /* Name.Tag */ +body .nv { color: #19469D } /* Name.Variable */ +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +body .w { color: #bbbbbb } /* Text.Whitespace */ +body .mf { color: #666666 } /* Literal.Number.Float */ +body .mh { color: #666666 } /* Literal.Number.Hex */ +body .mi { color: #666666 } /* Literal.Number.Integer */ +body .mo { color: #666666 } /* Literal.Number.Oct */ +body .sb { color: #219161 } /* Literal.String.Backtick */ +body .sc { color: #219161 } /* Literal.String.Char */ +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ +body .s2 { color: #219161 } /* Literal.String.Double */ +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +body .sh { color: #219161 } /* Literal.String.Heredoc */ +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +body .sx { color: #954121 } /* Literal.String.Other */ +body .sr { color: #BB6688 } /* Literal.String.Regex */ +body .s1 { color: #219161 } /* Literal.String.Single */ +body .ss { color: #19469D } /* Literal.String.Symbol */ +body .bp { color: #954121 } /* Name.Builtin.Pseudo */ +body .vc { color: #19469D } /* Name.Variable.Class */ +body .vg { color: #19469D } /* Name.Variable.Global */ +body .vi { color: #19469D } /* Name.Variable.Instance */ +body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html new file mode 100644 index 0000000..bf615fa --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html @@ -0,0 +1,101 @@ + pkginfo.js

pkginfo.js

/*
+ * pkginfo.js: Top-level include for the pkginfo module
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+ 
+var fs = require('fs'),
+    path = require('path');

function pkginfo ([options, 'property', 'property' ..])

+ +

@pmodule {Module} Parent module to read from.

+ +

@options {Object|Array|string} Optional Options used when exposing properties.

+ +

@arguments {string...} Optional Specified properties to expose.

+ +

Exposes properties from the package.json file for the parent module on +it's exports. Valid usage:

+ +

require('pkginfo')()

+ +

require('pkginfo')('version', 'author');

+ +

require('pkginfo')(['version', 'author']);

+ +

require('pkginfo')({ include: ['version', 'author'] });

var pkginfo = module.exports = function (pmodule, options) {
+  var args = [].slice.call(arguments, 2).filter(function (arg) {
+    return typeof arg === 'string';
+  });
+  

Parse variable arguments

  if (Array.isArray(options)) {

If the options passed in is an Array assume that +it is the Array of properties to expose from the +on the package.json file on the parent module.

    options = { include: options };
+  }
+  else if (typeof options === 'string') {

Otherwise if the first argument is a string, then +assume that it is the first property to expose from +the package.json file on the parent module.

    options = { include: [options] };
+  }
+  

Setup default options

  options = options || { include: [] };
+  
+  if (args.length > 0) {

If additional string arguments have been passed in +then add them to the properties to expose on the +parent module.

    options.include = options.include.concat(args);
+  }
+  
+  var pkg = pkginfo.read(pmodule, options.dir).package;
+  Object.keys(pkg).forEach(function (key) {
+    if (options.include.length > 0 && !~options.include.indexOf(key)) {
+      return;
+    }
+    
+    if (!pmodule.exports[key]) {
+      pmodule.exports[key] = pkg[key];
+    }
+  });
+  
+  return pkginfo;
+};

function find (dir)

+ +

@pmodule {Module} Parent module to read from.

+ +

@dir {string} Optional Directory to start search from.

+ +

Searches up the directory tree from dir until it finds a directory +which contains a package.json file.

pkginfo.find = function (pmodule, dir) {
+  dir = dir || pmodule.filename;
+  dir = path.dirname(dir); 
+  
+  var files = fs.readdirSync(dir);
+  
+  if (~files.indexOf('package.json')) {
+    return path.join(dir, 'package.json');
+  }
+  
+  if (dir === '/') {
+    throw new Error('Could not find package.json up from: ' + dir);
+  }
+  
+  return pkginfo.find(dir);
+};

function read (pmodule, dir)

+ +

@pmodule {Module} Parent module to read from.

+ +

@dir {string} Optional Directory to start search from.

+ +

Searches up the directory tree from dir until it finds a directory +which contains a package.json file and returns the package information.

pkginfo.read = function (pmodule, dir) { 
+  dir = pkginfo.find(pmodule, dir);
+  
+  var data = fs.readFileSync(dir).toString();
+      
+  return {
+    dir: dir, 
+    package: JSON.parse(data)
+  };
+};

Call pkginfo on this module and expose version.

pkginfo(module, {
+  dir: __dirname,
+  include: ['version'],
+  target: pkginfo
+});
+
+
\ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/all-properties.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/all-properties.js new file mode 100644 index 0000000..fd1d831 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/all-properties.js @@ -0,0 +1,19 @@ +/* + * all-properties.js: Sample of including all properties from a package.json file + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/array-argument.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/array-argument.js new file mode 100644 index 0000000..b1b6848 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/array-argument.js @@ -0,0 +1,20 @@ +/* + * array-argument.js: Sample of including specific properties from a package.json file + * using Array argument syntax. + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module, ['version', 'author']); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js new file mode 100644 index 0000000..b4b5fd6 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js @@ -0,0 +1,19 @@ +/* + * multiple-properties.js: Sample of including multiple properties from a package.json file + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module, 'version', 'author'); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/object-argument.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/object-argument.js new file mode 100644 index 0000000..28420c8 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/object-argument.js @@ -0,0 +1,22 @@ +/* + * object-argument.js: Sample of including specific properties from a package.json file + * using Object argument syntax. + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module, { + include: ['version', 'author'] + }); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/package.json b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/package.json new file mode 100644 index 0000000..1f2f01c --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/package.json @@ -0,0 +1,10 @@ +{ + "name": "simple-app", + "description": "A test fixture for pkginfo", + "version": "0.1.0", + "author": "Charlie Robbins ", + "keywords": ["test", "fixture"], + "main": "./index.js", + "scripts": { "test": "vows test/*-test.js --spec" }, + "engines": { "node": ">= 0.4.0" } +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/single-property.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/single-property.js new file mode 100644 index 0000000..4f44561 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/examples/single-property.js @@ -0,0 +1,19 @@ +/* + * single-property.js: Sample of including a single specific properties from a package.json file + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module, 'version'); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js new file mode 100644 index 0000000..a4a6227 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js @@ -0,0 +1,132 @@ +/* + * pkginfo.js: Top-level include for the pkginfo module + * + * (C) 2011, Charlie Robbins + * + */ + +var fs = require('fs'), + path = require('path'); + +// +// ### function pkginfo ([options, 'property', 'property' ..]) +// #### @pmodule {Module} Parent module to read from. +// #### @options {Object|Array|string} **Optional** Options used when exposing properties. +// #### @arguments {string...} **Optional** Specified properties to expose. +// Exposes properties from the package.json file for the parent module on +// it's exports. Valid usage: +// +// `require('pkginfo')()` +// +// `require('pkginfo')('version', 'author');` +// +// `require('pkginfo')(['version', 'author']);` +// +// `require('pkginfo')({ include: ['version', 'author'] });` +// +var pkginfo = module.exports = function (pmodule, options) { + var args = [].slice.call(arguments, 2).filter(function (arg) { + return typeof arg === 'string'; + }); + + // + // **Parse variable arguments** + // + if (Array.isArray(options)) { + // + // If the options passed in is an Array assume that + // it is the Array of properties to expose from the + // on the package.json file on the parent module. + // + options = { include: options }; + } + else if (typeof options === 'string') { + // + // Otherwise if the first argument is a string, then + // assume that it is the first property to expose from + // the package.json file on the parent module. + // + options = { include: [options] }; + } + + // + // **Setup default options** + // + options = options || { include: [] }; + + if (args.length > 0) { + // + // If additional string arguments have been passed in + // then add them to the properties to expose on the + // parent module. + // + options.include = options.include.concat(args); + } + + var pkg = pkginfo.read(pmodule, options.dir).package; + Object.keys(pkg).forEach(function (key) { + if (options.include.length > 0 && !~options.include.indexOf(key)) { + return; + } + + if (!pmodule.exports[key]) { + pmodule.exports[key] = pkg[key]; + } + }); + + return pkginfo; +}; + +// +// ### function find (dir) +// #### @pmodule {Module} Parent module to read from. +// #### @dir {string} **Optional** Directory to start search from. +// Searches up the directory tree from `dir` until it finds a directory +// which contains a `package.json` file. +// +pkginfo.find = function (pmodule, dir) { + dir = dir || pmodule.filename; + dir = path.dirname(dir); + + var files = fs.readdirSync(dir); + + if (~files.indexOf('package.json')) { + return path.join(dir, 'package.json'); + } + + if (dir === '/') { + throw new Error('Could not find package.json up from: ' + dir); + } + else if (!dir || dir === '.') { + throw new Error('Cannot find package.json from unspecified directory'); + } + + return pkginfo.find(pmodule, dir); +}; + +// +// ### function read (pmodule, dir) +// #### @pmodule {Module} Parent module to read from. +// #### @dir {string} **Optional** Directory to start search from. +// Searches up the directory tree from `dir` until it finds a directory +// which contains a `package.json` file and returns the package information. +// +pkginfo.read = function (pmodule, dir) { + dir = pkginfo.find(pmodule, dir); + + var data = fs.readFileSync(dir).toString(); + + return { + dir: dir, + package: JSON.parse(data) + }; +}; + +// +// Call `pkginfo` on this module and expose version. +// +pkginfo(module, { + dir: __dirname, + include: ['version'], + target: pkginfo +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/package.json b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/package.json new file mode 100644 index 0000000..a9efcfc --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/package.json @@ -0,0 +1,39 @@ +{ + "name": "pkginfo", + "version": "0.2.3", + "description": "An easy way to expose properties on a module from a package.json", + "author": { + "name": "Charlie Robbins", + "email": "charlie.robbins@gmail.com" + }, + "repository": { + "type": "git", + "url": "http://github.com/indexzero/node-pkginfo.git" + }, + "keywords": [ + "info", + "tools", + "package.json" + ], + "devDependencies": { + "vows": "0.6.x" + }, + "main": "./lib/pkginfo", + "scripts": { + "test": "vows test/*-test.js --spec" + }, + "engines": { + "node": ">= 0.4.0" + }, + "readme": "# node-pkginfo\n\nAn easy way to expose properties on a module from a package.json\n\n## Installation\n\n### Installing npm (node package manager)\n```\n curl http://npmjs.org/install.sh | sh\n```\n\n### Installing pkginfo\n```\n [sudo] npm install pkginfo\n```\n\n## Motivation\nHow often when writing node.js modules have you written the following line(s) of code? \n\n* Hard code your version string into your code\n\n``` js\n exports.version = '0.1.0';\n```\n\n* Programmatically expose the version from the package.json\n\n``` js\n exports.version = JSON.parse(fs.readFileSync('/path/to/package.json', 'utf8')).version;\n```\n\nIn other words, how often have you wanted to expose basic information from your package.json onto your module programmatically? **WELL NOW YOU CAN!**\n\n## Usage\n\nUsing `pkginfo` is idiot-proof, just require and invoke it. \n\n``` js\n var pkginfo = require('pkginfo')(module);\n \n console.dir(module.exports);\n```\n\nBy invoking the `pkginfo` module all of the properties in your `package.json` file will be automatically exposed on the callee module (i.e. the parent module of `pkginfo`). \n\nHere's a sample of the output:\n\n```\n { name: 'simple-app',\n description: 'A test fixture for pkginfo',\n version: '0.1.0',\n author: 'Charlie Robbins ',\n keywords: [ 'test', 'fixture' ],\n main: './index.js',\n scripts: { test: 'vows test/*-test.js --spec' },\n engines: { node: '>= 0.4.0' } }\n```\n\n### Expose specific properties\nIf you don't want to expose **all** properties on from your `package.json` on your module then simple pass those properties to the `pkginfo` function:\n\n``` js\n var pkginfo = require('pkginfo')(module, 'version', 'author');\n \n console.dir(module.exports);\n```\n\n```\n { version: '0.1.0',\n author: 'Charlie Robbins ' }\n```\n\nIf you're looking for further usage see the [examples][0] included in this repository. \n\n## Run Tests\nTests are written in [vows][1] and give complete coverage of all APIs.\n\n```\n vows test/*-test.js --spec\n```\n\n[0]: https://github.com/indexzero/node-pkginfo/tree/master/examples\n[1]: http://vowsjs.org\n\n#### Author: [Charlie Robbins](http://nodejitsu.com)", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/indexzero/node-pkginfo/issues" + }, + "_id": "pkginfo@0.2.3", + "dist": { + "shasum": "923bb29a2074ebc554f518c02ce1d9f6ada4660c" + }, + "_from": "pkginfo@0.2.x", + "_resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.2.3.tgz" +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js new file mode 100644 index 0000000..3156c00 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js @@ -0,0 +1,69 @@ +/* + * pkginfo-test.js: Tests for the pkginfo module. + * + * (C) 2011, Charlie Robbins + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + pkginfo = require('../lib/pkginfo'); + +function assertProperties (source, target) { + assert.lengthOf(source, target.length + 1); + target.forEach(function (prop) { + assert.isTrue(!!~source.indexOf(prop)); + }); +} + +function testExposes (options) { + return { + topic: function () { + exec('node ' + path.join(__dirname, '..', 'examples', options.script), this.callback); + }, + "should expose that property correctly": function (err, stdout, stderr) { + assert.isNull(err); + + var exposed = stderr.match(/'(\w+)'/ig).map(function (p) { + return p.substring(1, p.length - 1); + }); + + return !options.assert + ? assertProperties(exposed, options.properties) + : options.assert(exposed); + } + } +} + +vows.describe('pkginfo').addBatch({ + "When using the pkginfo module": { + "and passed a single `string` argument": testExposes({ + script: 'single-property.js', + properties: ['version'] + }), + "and passed multiple `string` arguments": testExposes({ + script: 'multiple-properties.js', + properties: ['version', 'author'] + }), + "and passed an `object` argument": testExposes({ + script: 'object-argument.js', + properties: ['version', 'author'] + }), + "and passed an `array` argument": testExposes({ + script: 'array-argument.js', + properties: ['version', 'author'] + }), + "and passed no arguments": testExposes({ + script: 'all-properties.js', + assert: function (exposed) { + var pkg = fs.readFileSync(path.join(__dirname, '..', 'examples', 'package.json')).toString(), + keys = Object.keys(JSON.parse(pkg)); + + assertProperties(exposed, keys); + } + }) + } +}).export(module); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/LICENSE b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/LICENSE new file mode 100644 index 0000000..a4a9aee --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/LICENSE @@ -0,0 +1,55 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/README.md b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/README.md new file mode 100644 index 0000000..8713a80 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/README.md @@ -0,0 +1,287 @@ +# Request -- Simplified HTTP request method + +## Install + +
+  npm install request
+
+ +Or from source: + +
+  git clone git://github.com/mikeal/request.git 
+  cd request
+  npm link
+
+ +## Super simple to use + +Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default. + +```javascript +var request = require('request'); +request('http://www.google.com', function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log(body) // Print the google web page. + } +}) +``` + +## Streaming + +You can stream any response to a file stream. + +```javascript +request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')) +``` + +You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers. + +```javascript +fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json')) +``` + +Request can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers. + +```javascript +request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png')) +``` + +Now let's get fancy. + +```javascript +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + if (req.method === 'PUT') { + req.pipe(request.put('http://mysite.com/doodle.png')) + } else if (req.method === 'GET' || req.method === 'HEAD') { + request.get('http://mysite.com/doodle.png').pipe(resp) + } + } +}) +``` + +You can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do: + +```javascript +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + var x = request('http://mysite.com/doodle.png') + req.pipe(x) + x.pipe(resp) + } +}) +``` + +And since pipe() returns the destination stream in node 0.5.x you can do one line proxying :) + +```javascript +req.pipe(request('http://mysite.com/doodle.png')).pipe(resp) +``` + +Also, none of this new functionality conflicts with requests previous features, it just expands them. + +```javascript +var r = request.defaults({'proxy':'http://localproxy.com'}) + +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + r.get('http://google.com/doodle.png').pipe(resp) + } +}) +``` + +You can still use intermediate proxies, the requests will still follow HTTP forwards, etc. + +## OAuth Signing + +```javascript +// Twitter OAuth +var qs = require('querystring') + , oauth = + { callback: 'http://mysite.com/callback/' + , consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + } + , url = 'https://api.twitter.com/oauth/request_token' + ; +request.post({url:url, oauth:oauth}, function (e, r, body) { + // Assume by some stretch of magic you aquired the verifier + var access_token = qs.parse(body) + , oauth = + { consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + , token: access_token.oauth_token + , verifier: VERIFIER + , token_secret: access_token.oauth_token_secret + } + , url = 'https://api.twitter.com/oauth/access_token' + ; + request.post({url:url, oauth:oauth}, function (e, r, body) { + var perm_token = qs.parse(body) + , oauth = + { consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + , token: perm_token.oauth_token + , token_secret: perm_token.oauth_token_secret + } + , url = 'https://api.twitter.com/1/users/show.json?' + , params = + { screen_name: perm_token.screen_name + , user_id: perm_token.user_id + } + ; + url += qs.stringify(params) + request.get({url:url, oauth:oauth, json:true}, function (e, r, user) { + console.log(user) + }) + }) +}) +``` + + + +### request(options, callback) + +The first argument can be either a url or an options object. The only required option is uri, all others are optional. + +* `uri` || `url` - fully qualified uri or a parsed url object from url.parse() +* `qs` - object containing querystring values to be appended to the uri +* `method` - http method, defaults to GET +* `headers` - http headers, defaults to {} +* `body` - entity body for POST and PUT requests. Must be buffer or string. +* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. +* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. +* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below. +* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true. +* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false. +* `maxRedirects` - the maximum number of redirects to follow, defaults to 10. +* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer. +* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets. +* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool. +* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request +* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri. +* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above. +* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option. +* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section) + + +The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer. + +## Convenience methods + +There are also shorthand methods for different HTTP METHODs and some other conveniences. + +### request.defaults(options) + +This method returns a wrapper around the normal request API that defaults to whatever options you pass in to it. + +### request.put + +Same as request() but defaults to `method: "PUT"`. + +```javascript +request.put(url) +``` + +### request.post + +Same as request() but defaults to `method: "POST"`. + +```javascript +request.post(url) +``` + +### request.head + +Same as request() but defaults to `method: "HEAD"`. + +```javascript +request.head(url) +``` + +### request.del + +Same as request() but defaults to `method: "DELETE"`. + +```javascript +request.del(url) +``` + +### request.get + +Alias to normal request method for uniformity. + +```javascript +request.get(url) +``` +### request.cookie + +Function that creates a new cookie. + +```javascript +request.cookie('cookie_string_here') +``` +### request.jar + +Function that creates a new cookie jar. + +```javascript +request.jar() +``` + + +## Examples: + +```javascript + var request = require('request') + , rand = Math.floor(Math.random()*100000000).toString() + ; + request( + { method: 'PUT' + , uri: 'http://mikeal.iriscouch.com/testjs/' + rand + , multipart: + [ { 'content-type': 'application/json' + , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) + } + , { body: 'I am an attachment' } + ] + } + , function (error, response, body) { + if(response.statusCode == 201){ + console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand) + } else { + console.log('error: '+ response.statusCode) + console.log(body) + } + } + ) +``` +Cookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent). + +```javascript +var request = request.defaults({jar: false}) +request('http://www.google.com', function () { + request('http://images.google.com') +}) +``` + +If you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option: + +```javascript +var j = request.jar() +var request = request.defaults({jar:j}) +request('http://www.google.com', function () { + request('http://images.google.com') +}) +``` +OR + +```javascript +var j = request.jar() +var cookie = request.cookie('your_cookie_here') +j.add(cookie) +request({url: 'http://www.google.com', jar: j}, function () { + request('http://images.google.com') +}) +``` diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/aws.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/aws.js new file mode 100644 index 0000000..4e87bff --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/aws.js @@ -0,0 +1,190 @@ + +/*! + * knox - auth + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var crypto = require('crypto') + , parse = require('url').parse; + +/** + * Valid keys. + */ + +var keys = [ + 'acl' + , 'location' + , 'logging' + , 'notification' + , 'partNumber' + , 'policy' + , 'requestPayment' + , 'torrent' + , 'uploadId' + , 'uploads' + , 'versionId' + , 'versioning' + , 'versions' + , 'website' +]; + +/** + * Return an "Authorization" header value with the given `options` + * in the form of "AWS :" + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.authorization = function(options){ + return 'AWS ' + options.key + ':' + exports.sign(options); +}; + +/** + * Simple HMAC-SHA1 Wrapper + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.hmacSha1 = function(options){ + return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64'); +}; + +/** + * Create a base64 sha1 HMAC for `options`. + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.sign = function(options){ + options.message = exports.stringToSign(options); + return exports.hmacSha1(options); +}; + +/** + * Create a base64 sha1 HMAC for `options`. + * + * Specifically to be used with S3 presigned URLs + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.signQuery = function(options){ + options.message = exports.queryStringToSign(options); + return exports.hmacSha1(options); +}; + +/** + * Return a string for sign() with the given `options`. + * + * Spec: + * + * \n + * \n + * \n + * \n + * [headers\n] + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.stringToSign = function(options){ + var headers = options.amazonHeaders || ''; + if (headers) headers += '\n'; + return [ + options.verb + , options.md5 + , options.contentType + , options.date.toUTCString() + , headers + options.resource + ].join('\n'); +}; + +/** + * Return a string for sign() with the given `options`, but is meant exclusively + * for S3 presigned URLs + * + * Spec: + * + * \n + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.queryStringToSign = function(options){ + return 'GET\n\n\n' + + options.date + '\n' + + options.resource; +}; + +/** + * Perform the following: + * + * - ignore non-amazon headers + * - lowercase fields + * - sort lexicographically + * - trim whitespace between ":" + * - join with newline + * + * @param {Object} headers + * @return {String} + * @api private + */ + +exports.canonicalizeHeaders = function(headers){ + var buf = [] + , fields = Object.keys(headers); + for (var i = 0, len = fields.length; i < len; ++i) { + var field = fields[i] + , val = headers[field] + , field = field.toLowerCase(); + if (0 !== field.indexOf('x-amz')) continue; + buf.push(field + ':' + val); + } + return buf.sort().join('\n'); +}; + +/** + * Perform the following: + * + * - ignore non sub-resources + * - sort lexicographically + * + * @param {String} resource + * @return {String} + * @api private + */ + +exports.canonicalizeResource = function(resource){ + var url = parse(resource, true) + , path = url.pathname + , buf = []; + + Object.keys(url.query).forEach(function(key){ + if (!~keys.indexOf(key)) return; + var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]); + buf.push(key + val); + }); + + return path + (buf.length + ? '?' + buf.sort().join('&') + : ''); +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/aws2.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/aws2.js new file mode 100644 index 0000000..eb683f7 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/aws2.js @@ -0,0 +1,128 @@ +var crypto = require('crypto') + +// The Authentication Header +// +// The Amazon S3 REST API uses the standard HTTPAuthorization header to pass authentication information. (The name of the standard header is unfortunate because it carries authentication information, not authorization).Under the Amazon S3 authentication scheme, the Authorization header has the following form. +// +// Authorization: AWS AWSAccessKeyId:Signature +// +// Developers are issued an AWS Access Key ID and AWS SecretAccess Key when they register. For request authentication, theAWSAccessKeyId element identifies the secret key that was used to compute the signature, and (indirectly) the developer making the request. +// +// The Signature element is the RFC 2104HMAC-SHA1 of selected elements from the request, and so theSignature part of the Authorization header will vary from request to request. If the request signature calculated by the system matches theSignature included with the request, then the requester will have demonstrated possession to the AWSSecret Access Key. The request will then be processed under the identity, and with the authority, of the developer to whom the key was issued. +// +// Following is pseudo-grammar that illustrates the construction of the Authorization request header (\nmeans the Unicode code point U+000A commonly called newline). + +function authorizationHeader (accessKey) { + // Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature; + + var authorization = 'AWS' + " " + accessKey + ":" + signature() + + return authorization +} + +// + +function signature (secret, verb, md5, contenttype, date, amzheaders, bucket, path) { + // Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of( YourSecretAccessKeyID, StringToSign ) ) ); + + function encodeSignature (stringToSign) { + return crypto.createHash('sha1').update(stringToSign).digest('base64') + } + + // + // StringToSign = HTTP-Verb + "\n" + + // Content-MD5 + "\n" + + // Content-Type + "\n" + + // Date + "\n" + + // CanonicalizedAmzHeaders + + // CanonicalizedResource; + + function compileStringToSign () { + var s = + verb + '\n' + (md5 || '') + '\n' + (contenttype || '') + '\n' + date.toUTCString() + '\n' + canonicalizeAmzHeaders(amzheaders) + + canonicalizeResource() + return s + } + + // + // CanonicalizedResource = [ "/" + Bucket ] + + // + + // [ sub-resource, if present. For example "?acl", "?location", "?logging", or "?torrent"]; + + function canonicalizeResource () { + return '/' + bucket + path + } + + // + // CanonicalizedAmzHeaders = + // + // HMAC-SHA1 is an algorithm defined by RFC 2104 (go to RFC 2104 - Keyed-Hashing for Message Authentication ). The algorithm takes as input two byte-strings: a key and a message. For Amazon S3 Request authentication, use your AWS Secret Access Key (YourSecretAccessKeyID) as the key, and the UTF-8 encoding of the StringToSign as the message. The output of HMAC-SHA1 is also a byte string, called the digest. The Signature request parameter is constructed by Base64 encoding this digest. + // Request Canonicalization for Signing + // + // Recall that when the system receives an authenticated request, it compares the computed request signature with the signature provided in the request in StringToSign. For that reason, you must compute the signature using the same method used by Amazon S3. We call the process of putting a request in an agreed-upon form for signing "canonicalization". + +} + + + +// Constructing the CanonicalizedResource Element +// +// CanonicalizedResource represents the Amazon S3 resource targeted by the request. Construct it for a REST request as follows: +// +// Launch Process +// +// 1 +// +// +// Start with the empty string (""). +// +// 2 +// +// +// If the request specifies a bucket using the HTTP Host header (virtual hosted-style), append the bucket name preceded by a "/" (e.g., "/bucketname"). For path-style requests and requests that don't address a bucket, do nothing. For more information on virtual hosted-style requests, see Virtual Hosting of Buckets. +// +// 3 +// +// +// Append the path part of the un-decoded HTTP Request-URI, up-to but not including the query string. +// +// 4 +// +// +// If the request addresses a sub-resource, like ?versioning, ?location, ?acl, ?torrent, ?lifecycle, or ?versionid append the sub-resource, its value if it has one, and the question mark. Note that in case of multiple sub-resources, sub-resources must be lexicographically sorted by sub-resource name and separated by '&'. e.g. ?acl&versionId=value. +// +// The list of sub-resources that must be included when constructing the CanonicalizedResource Element are: acl, lifecycle, location, logging, notification, partNumber, policy, requestPayment, torrent, uploadId, uploads, versionId, versioning, versions and website. +// +// If the request specifies query string parameters overriding the response header values (see Get Object), append the query string parameters, and its values. When signing you do not encode these values. However, when making the request, you must encode these parameter values. The query string parameters in a GET request include response-content-type, response-content-language, response-expires, response-cache-control, response-content-disposition, response-content-encoding. +// +// The delete query string parameter must be including when creating the CanonicalizedResource for a Multi-Object Delete request. +// +// Elements of the CanonicalizedResource that come from the HTTP Request-URI should be signed literally as they appear in the HTTP request, including URL-Encoding meta characters. +// +// The CanonicalizedResource might be different than the HTTP Request-URI. In particular, if your request uses the HTTP Host header to specify a bucket, the bucket does appear in the HTTP Request-URI. However, the CanonicalizedResource continues to include the bucket. Query string parameters might also appear in the Request-URI but are not included in CanonicalizedResource. For more information, see Virtual Hosting of Buckets. +// Constructing the CanonicalizedAmzHeaders Element +// +// To construct the CanonicalizedAmzHeaders part of StringToSign, select all HTTP request headers that start with 'x-amz-' (using a case-insensitive comparison) and use the following process. +// +// CanonicalizedAmzHeaders Process +// 1 Convert each HTTP header name to lower-case. For example, 'X-Amz-Date' becomes 'x-amz-date'. +// 2 Sort the collection of headers lexicographically by header name. +// 3 Combine header fields with the same name into one "header-name:comma-separated-value-list" pair as prescribed by RFC 2616, section 4.2, without any white-space between values. For example, the two metadata headers 'x-amz-meta-username: fred' and 'x-amz-meta-username: barney' would be combined into the single header 'x-amz-meta-username: fred,barney'. +// 4 "Unfold" long headers that span multiple lines (as allowed by RFC 2616, section 4.2) by replacing the folding white-space (including new-line) by a single space. +// 5 Trim any white-space around the colon in the header. For example, the header 'x-amz-meta-username: fred,barney' would become 'x-amz-meta-username:fred,barney' +// 6 Finally, append a new-line (U+000A) to each canonicalized header in the resulting list. Construct the CanonicalizedResource element by concatenating all headers in this list into a single string. +// +// Positional versus Named HTTP Header StringToSign Elements +// +// The first few header elements of StringToSign (Content-Type, Date, and Content-MD5) are positional in nature. StringToSign does not include the names of these headers, only their values from the request. In contrast, the 'x-amz-' elements are named; Both the header names and the header values appear in StringToSign. +// +// If a positional header called for in the definition of StringToSign is not present in your request, (Content-Type or Content-MD5, for example, are optional for PUT requests, and meaningless for GET requests), substitute the empty string ("") in for that position. +// Time Stamp Requirement +// +// A valid time stamp (using either the HTTP Date header or an x-amz-date alternative) is mandatory for authenticated requests. Furthermore, the client time-stamp included with an authenticated request must be within 15 minutes of the Amazon S3 system time when the request is received. If not, the request will fail with the RequestTimeTooSkewed error status code. The intention of these restrictions is to limit the possibility that intercepted requests could be replayed by an adversary. For stronger protection against eavesdropping, use the HTTPS transport for authenticated requests. +// +// Some HTTP client libraries do not expose the ability to set the Date header for a request. If you have trouble including the value of the 'Date' header in the canonicalized headers, you can set the time-stamp for the request using an 'x-amz-date' header instead. The value of the x-amz-date header must be in one of the RFC 2616 formats (http://www.ietf.org/rfc/rfc2616.txt). When an x-amz-date header is present in a request, the system will ignore any Date header when computing the request signature. Therefore, if you include the x-amz-date header, use the empty string for the Date when constructing the StringToSign. See the next section for an example. diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/forever.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/forever.js new file mode 100644 index 0000000..ac853c0 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/forever.js @@ -0,0 +1,103 @@ +module.exports = ForeverAgent +ForeverAgent.SSL = ForeverAgentSSL + +var util = require('util') + , Agent = require('http').Agent + , net = require('net') + , tls = require('tls') + , AgentSSL = require('https').Agent + +function ForeverAgent(options) { + var self = this + self.options = options || {} + self.requests = {} + self.sockets = {} + self.freeSockets = {} + self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets + self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets + self.on('free', function(socket, host, port) { + var name = host + ':' + port + if (self.requests[name] && self.requests[name].length) { + self.requests[name].shift().onSocket(socket) + } else if (self.sockets[name].length < self.minSockets) { + if (!self.freeSockets[name]) self.freeSockets[name] = [] + self.freeSockets[name].push(socket) + + // if an error happens while we don't use the socket anyway, meh, throw the socket away + function onIdleError() { + socket.destroy() + } + socket._onIdleError = onIdleError + socket.on('error', onIdleError) + } else { + // If there are no pending requests just destroy the + // socket and it will get removed from the pool. This + // gets us out of timeout issues and allows us to + // default to Connection:keep-alive. + socket.destroy(); + } + }) + +} +util.inherits(ForeverAgent, Agent) + +ForeverAgent.defaultMinSockets = 5 + + +ForeverAgent.prototype.createConnection = net.createConnection +ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest +ForeverAgent.prototype.addRequest = function(req, host, port) { + var name = host + ':' + port + if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { + var idleSocket = this.freeSockets[name].pop() + idleSocket.removeListener('error', idleSocket._onIdleError) + delete idleSocket._onIdleError + req._reusedSocket = true + req.onSocket(idleSocket) + } else { + this.addRequestNoreuse(req, host, port) + } +} + +ForeverAgent.prototype.removeSocket = function(s, name, host, port) { + if (this.sockets[name]) { + var index = this.sockets[name].indexOf(s); + if (index !== -1) { + this.sockets[name].splice(index, 1); + } + } else if (this.sockets[name] && this.sockets[name].length === 0) { + // don't leak + delete this.sockets[name]; + delete this.requests[name]; + } + + if (this.freeSockets[name]) { + var index = this.freeSockets[name].indexOf(s) + if (index !== -1) { + this.freeSockets[name].splice(index, 1) + if (this.freeSockets[name].length === 0) { + delete this.freeSockets[name] + } + } + } + + if (this.requests[name] && this.requests[name].length) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(name, host, port).emit('free'); + } +} + +function ForeverAgentSSL (options) { + ForeverAgent.call(this, options) +} +util.inherits(ForeverAgentSSL, ForeverAgent) + +ForeverAgentSSL.prototype.createConnection = createConnectionSSL +ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest + +function createConnectionSSL (port, host, options) { + options.port = port + options.host = host + return tls.connect(options) +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/main.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/main.js new file mode 100644 index 0000000..2407a93 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/main.js @@ -0,0 +1,974 @@ +// Copyright 2010-2012 Mikeal Rogers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var http = require('http') + , https = false + , tls = false + , url = require('url') + , util = require('util') + , stream = require('stream') + , qs = require('querystring') + , mimetypes = require('./mimetypes') + , oauth = require('./oauth') + , uuid = require('./uuid') + , ForeverAgent = require('./forever') + , Cookie = require('./vendor/cookie') + , CookieJar = require('./vendor/cookie/jar') + , cookieJar = new CookieJar + , tunnel = require('./tunnel') + , aws = require('./aws') + ; + +if (process.logging) { + var log = process.logging('request') +} + +try { + https = require('https') +} catch (e) {} + +try { + tls = require('tls') +} catch (e) {} + +function toBase64 (str) { + return (new Buffer(str || "", "ascii")).toString("base64") +} + +// Hacky fix for pre-0.4.4 https +if (https && !https.Agent) { + https.Agent = function (options) { + http.Agent.call(this, options) + } + util.inherits(https.Agent, http.Agent) + https.Agent.prototype._getConnection = function (host, port, cb) { + var s = tls.connect(port, host, this.options, function () { + // do other checks here? + if (cb) cb() + }) + return s + } +} + +function isReadStream (rs) { + if (rs.readable && rs.path && rs.mode) { + return true + } +} + +function copy (obj) { + var o = {} + Object.keys(obj).forEach(function (i) { + o[i] = obj[i] + }) + return o +} + +var isUrl = /^https?:/ + +var globalPool = {} + +function Request (options) { + stream.Stream.call(this) + this.readable = true + this.writable = true + + if (typeof options === 'string') { + options = {uri:options} + } + + var reserved = Object.keys(Request.prototype) + for (var i in options) { + if (reserved.indexOf(i) === -1) { + this[i] = options[i] + } else { + if (typeof options[i] === 'function') { + delete options[i] + } + } + } + options = copy(options) + + this.init(options) +} +util.inherits(Request, stream.Stream) +Request.prototype.init = function (options) { + var self = this + + if (!options) options = {} + + if (!self.pool && self.pool !== false) self.pool = globalPool + self.dests = [] + self.__isRequestRequest = true + + // Protect against double callback + if (!self._callback && self.callback) { + self._callback = self.callback + self.callback = function () { + if (self._callbackCalled) return // Print a warning maybe? + self._callback.apply(self, arguments) + self._callbackCalled = true + } + self.on('error', self.callback.bind()) + self.on('complete', self.callback.bind(self, null)) + } + + if (self.url) { + // People use this property instead all the time so why not just support it. + self.uri = self.url + delete self.url + } + + if (!self.uri) { + throw new Error("options.uri is a required argument") + } else { + if (typeof self.uri == "string") self.uri = url.parse(self.uri) + } + if (self.proxy) { + if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy) + + // do the HTTP CONNECT dance using koichik/node-tunnel + if (http.globalAgent && self.uri.protocol === "https:") { + self.tunnel = true + var tunnelFn = self.proxy.protocol === "http:" + ? tunnel.httpsOverHttp : tunnel.httpsOverHttps + + var tunnelOptions = { proxy: { host: self.proxy.hostname + , port: +self.proxy.port + , proxyAuth: self.proxy.auth } + , ca: this.ca } + + self.agent = tunnelFn(tunnelOptions) + self.tunnel = true + } + } + + if (!self.uri.host || !self.uri.pathname) { + // Invalid URI: it may generate lot of bad errors, like "TypeError: Cannot call method 'indexOf' of undefined" in CookieJar + // Detect and reject it as soon as possible + var faultyUri = url.format(self.uri) + var message = 'Invalid URI "' + faultyUri + '"' + if (Object.keys(options).length === 0) { + // No option ? This can be the sign of a redirect + // As this is a case where the user cannot do anything (he didn't call request directly with this URL) + // he should be warned that it can be caused by a redirection (can save some hair) + message += '. This can be caused by a crappy redirection.' + } + self.emit('error', new Error(message)) + return // This error was fatal + } + + self._redirectsFollowed = self._redirectsFollowed || 0 + self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10 + self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true + self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false; + if (self.followRedirect || self.followAllRedirects) + self.redirects = self.redirects || [] + + self.headers = self.headers ? copy(self.headers) : {} + + self.setHost = false + if (!self.headers.host) { + self.headers.host = self.uri.hostname + if (self.uri.port) { + if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && + !(self.uri.port === 443 && self.uri.protocol === 'https:') ) + self.headers.host += (':'+self.uri.port) + } + self.setHost = true + } + + self.jar(self._jar || options.jar) + + if (!self.uri.pathname) {self.uri.pathname = '/'} + if (!self.uri.port) { + if (self.uri.protocol == 'http:') {self.uri.port = 80} + else if (self.uri.protocol == 'https:') {self.uri.port = 443} + } + + if (self.proxy && !self.tunnel) { + self.port = self.proxy.port + self.host = self.proxy.hostname + } else { + self.port = self.uri.port + self.host = self.uri.hostname + } + + self.clientErrorHandler = function (error) { + if (self._aborted) return + + if (self.setHost) delete self.headers.host + if (self.req._reusedSocket && error.code === 'ECONNRESET' + && self.agent.addRequestNoreuse) { + self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } + self.start() + self.req.end() + return + } + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + self.emit('error', error) + } + + if (options.form) { + self.form(options.form) + } + + if (options.oauth) { + self.oauth(options.oauth) + } + + if (options.aws) { + self.aws(options.aws) + } + + if (self.uri.auth && !self.headers.authorization) { + self.headers.authorization = "Basic " + toBase64(self.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) + } + if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization'] && !self.tunnel) { + self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) + } + + if (options.qs) self.qs(options.qs) + + if (self.uri.path) { + self.path = self.uri.path + } else { + self.path = self.uri.pathname + (self.uri.search || "") + } + + if (self.path.length === 0) self.path = '/' + + if (self.proxy && !self.tunnel) self.path = (self.uri.protocol + '//' + self.uri.host + self.path) + + if (options.json) { + self.json(options.json) + } else if (options.multipart) { + self.boundary = uuid() + self.multipart(options.multipart) + } + + if (self.body) { + var length = 0 + if (!Buffer.isBuffer(self.body)) { + if (Array.isArray(self.body)) { + for (var i = 0; i < self.body.length; i++) { + length += self.body[i].length + } + } else { + self.body = new Buffer(self.body) + length = self.body.length + } + } else { + length = self.body.length + } + if (length) { + self.headers['content-length'] = length + } else { + throw new Error('Argument error, options.body.') + } + } + + var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol + , defaultModules = {'http:':http, 'https:':https} + , httpModules = self.httpModules || {} + ; + self.httpModule = httpModules[protocol] || defaultModules[protocol] + + if (!self.httpModule) throw new Error("Invalid protocol") + + if (options.ca) self.ca = options.ca + + if (!self.agent) { + if (options.agentOptions) self.agentOptions = options.agentOptions + + if (options.agentClass) { + self.agentClass = options.agentClass + } else if (options.forever) { + self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL + } else { + self.agentClass = self.httpModule.Agent + } + } + + if (self.pool === false) { + self.agent = false + } else { + self.agent = self.agent || self.getAgent() + if (self.maxSockets) { + // Don't use our pooling if node has the refactored client + self.agent.maxSockets = self.maxSockets + } + if (self.pool.maxSockets) { + // Don't use our pooling if node has the refactored client + self.agent.maxSockets = self.pool.maxSockets + } + } + + self.once('pipe', function (src) { + if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.") + self.src = src + if (isReadStream(src)) { + if (!self.headers['content-type'] && !self.headers['Content-Type']) + self.headers['content-type'] = mimetypes.lookup(src.path.slice(src.path.lastIndexOf('.')+1)) + } else { + if (src.headers) { + for (var i in src.headers) { + if (!self.headers[i]) { + self.headers[i] = src.headers[i] + } + } + } + if (src.method && !self.method) { + self.method = src.method + } + } + + self.on('pipe', function () { + console.error("You have already piped to this stream. Pipeing twice is likely to break the request.") + }) + }) + + process.nextTick(function () { + if (self._aborted) return + + if (self.body) { + if (Array.isArray(self.body)) { + self.body.forEach(function (part) { + self.write(part) + }) + } else { + self.write(self.body) + } + self.end() + } else if (self.requestBodyStream) { + console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.") + self.requestBodyStream.pipe(self) + } else if (!self.src) { + if (self.method !== 'GET' && typeof self.method !== 'undefined') { + self.headers['content-length'] = 0; + } + self.end(); + } + self.ntick = true + }) +} + +Request.prototype.getAgent = function () { + var Agent = this.agentClass + var options = {} + if (this.agentOptions) { + for (var i in this.agentOptions) { + options[i] = this.agentOptions[i] + } + } + if (this.ca) options.ca = this.ca + + var poolKey = '' + + // different types of agents are in different pools + if (Agent !== this.httpModule.Agent) { + poolKey += Agent.name + } + + if (!this.httpModule.globalAgent) { + // node 0.4.x + options.host = this.host + options.port = this.port + if (poolKey) poolKey += ':' + poolKey += this.host + ':' + this.port + } + + if (options.ca) { + if (poolKey) poolKey += ':' + poolKey += options.ca + } + + if (!poolKey && Agent === this.httpModule.Agent && this.httpModule.globalAgent) { + // not doing anything special. Use the globalAgent + return this.httpModule.globalAgent + } + + // already generated an agent for this setting + if (this.pool[poolKey]) return this.pool[poolKey] + + return this.pool[poolKey] = new Agent(options) +} + +Request.prototype.start = function () { + var self = this + + if (self._aborted) return + + self._started = true + self.method = self.method || 'GET' + self.href = self.uri.href + if (log) log('%method %href', self) + + if (self.src && self.src.stat && self.src.stat.size) { + self.headers['content-length'] = self.src.stat.size + } + if (self._aws) { + self.aws(self._aws, true) + } + + self.req = self.httpModule.request(self, function (response) { + if (self._aborted) return + if (self._paused) response.pause() + + self.response = response + response.request = self + response.toJSON = toJSON + + if (self.httpModule === https && + self.strictSSL && + !response.client.authorized) { + var sslErr = response.client.authorizationError + self.emit('error', new Error('SSL Error: '+ sslErr)) + return + } + + if (self.setHost) delete self.headers.host + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + + var addCookie = function (cookie) { + if (self._jar) self._jar.add(new Cookie(cookie)) + else cookieJar.add(new Cookie(cookie)) + } + + if (response.headers['set-cookie'] && (!self._disableCookies)) { + if (Array.isArray(response.headers['set-cookie'])) response.headers['set-cookie'].forEach(addCookie) + else addCookie(response.headers['set-cookie']) + } + + if (response.statusCode >= 300 && response.statusCode < 400 && + (self.followAllRedirects || + (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST' && self.method !== 'DELETE'))) && + response.headers.location) { + if (self._redirectsFollowed >= self.maxRedirects) { + self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) + return + } + self._redirectsFollowed += 1 + + if (!isUrl.test(response.headers.location)) { + response.headers.location = url.resolve(self.uri.href, response.headers.location) + } + self.uri = response.headers.location + self.redirects.push( + { statusCode : response.statusCode + , redirectUri: response.headers.location + } + ) + if (self.followAllRedirects) self.method = 'GET' + // self.method = 'GET'; // Force all redirects to use GET || commented out fixes #215 + delete self.req + delete self.agent + delete self._started + delete self.body + if (self.headers) { + delete self.headers.host + } + if (log) log('Redirect to %uri', self) + self.init() + return // Ignore the rest of the response + } else { + self._redirectsFollowed = self._redirectsFollowed || 0 + // Be a good stream and emit end when the response is finished. + // Hack to emit end on close because of a core bug that never fires end + response.on('close', function () { + if (!self._ended) self.response.emit('end') + }) + + if (self.encoding) { + if (self.dests.length !== 0) { + console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") + } else { + response.setEncoding(self.encoding) + } + } + + self.dests.forEach(function (dest) { + self.pipeDest(dest) + }) + + response.on("data", function (chunk) { + self._destdata = true + self.emit("data", chunk) + }) + response.on("end", function (chunk) { + self._ended = true + self.emit("end", chunk) + }) + response.on("close", function () {self.emit("close")}) + + self.emit('response', response) + + if (self.callback) { + var buffer = [] + var bodyLen = 0 + self.on("data", function (chunk) { + buffer.push(chunk) + bodyLen += chunk.length + }) + self.on("end", function () { + if (self._aborted) return + + if (buffer.length && Buffer.isBuffer(buffer[0])) { + var body = new Buffer(bodyLen) + var i = 0 + buffer.forEach(function (chunk) { + chunk.copy(body, i, 0, chunk.length) + i += chunk.length + }) + if (self.encoding === null) { + response.body = body + } else { + response.body = body.toString() + } + } else if (buffer.length) { + response.body = buffer.join('') + } + + if (self._json) { + try { + response.body = JSON.parse(response.body) + } catch (e) {} + } + + self.emit('complete', response, response.body) + }) + } + } + }) + + if (self.timeout && !self.timeoutTimer) { + self.timeoutTimer = setTimeout(function () { + self.req.abort() + var e = new Error("ETIMEDOUT") + e.code = "ETIMEDOUT" + self.emit("error", e) + }, self.timeout) + + // Set additional timeout on socket - in case if remote + // server freeze after sending headers + if (self.req.setTimeout) { // only works on node 0.6+ + self.req.setTimeout(self.timeout, function () { + if (self.req) { + self.req.abort() + var e = new Error("ESOCKETTIMEDOUT") + e.code = "ESOCKETTIMEDOUT" + self.emit("error", e) + } + }) + } + } + + self.req.on('error', self.clientErrorHandler) + self.req.on('drain', function() { + self.emit('drain') + }) + + self.emit('request', self.req) +} + +Request.prototype.abort = function () { + this._aborted = true; + + if (this.req) { + this.req.abort() + } + else if (this.response) { + this.response.abort() + } + + this.emit("abort") +} + +Request.prototype.pipeDest = function (dest) { + var response = this.response + // Called after the response is received + if (dest.headers) { + dest.headers['content-type'] = response.headers['content-type'] + if (response.headers['content-length']) { + dest.headers['content-length'] = response.headers['content-length'] + } + } + if (dest.setHeader) { + for (var i in response.headers) { + dest.setHeader(i, response.headers[i]) + } + dest.statusCode = response.statusCode + } + if (this.pipefilter) this.pipefilter(response, dest) +} + +// Composable API +Request.prototype.setHeader = function (name, value, clobber) { + if (clobber === undefined) clobber = true + if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value + else this.headers[name] += ',' + value + return this +} +Request.prototype.setHeaders = function (headers) { + for (var i in headers) {this.setHeader(i, headers[i])} + return this +} +Request.prototype.qs = function (q, clobber) { + var base + if (!clobber && this.uri.query) base = qs.parse(this.uri.query) + else base = {} + + for (var i in q) { + base[i] = q[i] + } + + this.uri = url.parse(this.uri.href.split('?')[0] + '?' + qs.stringify(base)) + this.url = this.uri + + return this +} +Request.prototype.form = function (form) { + this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' + this.body = qs.stringify(form).toString('utf8') + return this +} +Request.prototype.multipart = function (multipart) { + var self = this + self.body = [] + + if (!self.headers['content-type']) { + self.headers['content-type'] = 'multipart/related; boundary=' + self.boundary; + } else { + self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary; + } + + console.log('boundary >> ' + self.boundary) + + if (!multipart.forEach) throw new Error('Argument error, options.multipart.') + + multipart.forEach(function (part) { + var body = part.body + if(body == null) throw Error('Body attribute missing in multipart.') + delete part.body + var preamble = '--' + self.boundary + '\r\n' + Object.keys(part).forEach(function (key) { + preamble += key + ': ' + part[key] + '\r\n' + }) + preamble += '\r\n' + self.body.push(new Buffer(preamble)) + self.body.push(new Buffer(body)) + self.body.push(new Buffer('\r\n')) + }) + self.body.push(new Buffer('--' + self.boundary + '--')) + return self +} +Request.prototype.json = function (val) { + this.setHeader('content-type', 'application/json') + this.setHeader('accept', 'application/json') + this._json = true + if (typeof val === 'boolean') { + if (typeof this.body === 'object') this.body = JSON.stringify(this.body) + } else { + this.body = JSON.stringify(val) + } + return this +} +Request.prototype.aws = function (opts, now) { + if (!now) { + this._aws = opts + return this + } + var date = new Date() + this.setHeader('date', date.toUTCString()) + this.setHeader('authorization', aws.authorization( + { key: opts.key + , secret: opts.secret + , verb: this.method + , date: date + , resource: aws.canonicalizeResource('/' + opts.bucket + this.path) + , contentType: this.headers['content-type'] || '' + , md5: this.headers['content-md5'] || '' + , amazonHeaders: aws.canonicalizeHeaders(this.headers) + } + )) + + return this +} + +Request.prototype.oauth = function (_oauth) { + var form + if (this.headers['content-type'] && + this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === + 'application/x-www-form-urlencoded' + ) { + form = qs.parse(this.body) + } + if (this.uri.query) { + form = qs.parse(this.uri.query) + } + if (!form) form = {} + var oa = {} + for (var i in form) oa[i] = form[i] + for (var i in _oauth) oa['oauth_'+i] = _oauth[i] + if (!oa.oauth_version) oa.oauth_version = '1.0' + if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString() + if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') + + oa.oauth_signature_method = 'HMAC-SHA1' + + var consumer_secret = oa.oauth_consumer_secret + delete oa.oauth_consumer_secret + var token_secret = oa.oauth_token_secret + delete oa.oauth_token_secret + + var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname + var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret) + + // oa.oauth_signature = signature + for (var i in form) { + if ( i.slice(0, 'oauth_') in _oauth) { + // skip + } else { + delete oa['oauth_'+i] + } + } + this.headers.Authorization = + 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') + this.headers.Authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"' + return this +} +Request.prototype.jar = function (jar) { + var cookies + + if (this._redirectsFollowed === 0) { + this.originalCookieHeader = this.headers.cookie + } + + if (jar === false) { + // disable cookies + cookies = false; + this._disableCookies = true; + } else if (jar) { + // fetch cookie from the user defined cookie jar + cookies = jar.get({ url: this.uri.href }) + } else { + // fetch cookie from the global cookie jar + cookies = cookieJar.get({ url: this.uri.href }) + } + + if (cookies && cookies.length) { + var cookieString = cookies.map(function (c) { + return c.name + "=" + c.value + }).join("; ") + + if (this.originalCookieHeader) { + // Don't overwrite existing Cookie header + this.headers.cookie = this.originalCookieHeader + '; ' + cookieString + } else { + this.headers.cookie = cookieString + } + } + this._jar = jar + return this +} + + +// Stream API +Request.prototype.pipe = function (dest, opts) { + if (this.response) { + if (this._destdata) { + throw new Error("You cannot pipe after data has been emitted from the response.") + } else if (this._ended) { + throw new Error("You cannot pipe after the response has been ended.") + } else { + stream.Stream.prototype.pipe.call(this, dest, opts) + this.pipeDest(dest) + return dest + } + } else { + this.dests.push(dest) + stream.Stream.prototype.pipe.call(this, dest, opts) + return dest + } +} +Request.prototype.write = function () { + if (!this._started) this.start() + return this.req.write.apply(this.req, arguments) +} +Request.prototype.end = function (chunk) { + if (chunk) this.write(chunk) + if (!this._started) this.start() + this.req.end() +} +Request.prototype.pause = function () { + if (!this.response) this._paused = true + else this.response.pause.apply(this.response, arguments) +} +Request.prototype.resume = function () { + if (!this.response) this._paused = false + else this.response.resume.apply(this.response, arguments) +} +Request.prototype.destroy = function () { + if (!this._ended) this.end() +} + +// organize params for post, put, head, del +function initParams(uri, options, callback) { + if ((typeof options === 'function') && !callback) callback = options; + if (options && typeof options === 'object') { + options.uri = uri; + } else if (typeof uri === 'string') { + options = {uri:uri}; + } else { + options = uri; + uri = options.uri; + } + return { uri: uri, options: options, callback: callback }; +} + +function request (uri, options, callback) { + if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.') + if ((typeof options === 'function') && !callback) callback = options; + if (options && typeof options === 'object') { + options.uri = uri; + } else if (typeof uri === 'string') { + options = {uri:uri}; + } else { + options = uri; + } + + if (callback) options.callback = callback; + var r = new Request(options) + return r +} + +module.exports = request + +request.defaults = function (options) { + var def = function (method) { + var d = function (uri, opts, callback) { + var params = initParams(uri, opts, callback); + for (var i in options) { + if (params.options[i] === undefined) params.options[i] = options[i] + } + return method(params.options, params.callback) + } + return d + } + var de = def(request) + de.get = def(request.get) + de.post = def(request.post) + de.put = def(request.put) + de.head = def(request.head) + de.del = def(request.del) + de.cookie = def(request.cookie) + de.jar = def(request.jar) + return de +} + +request.forever = function (agentOptions, optionsArg) { + var options = {} + if (optionsArg) { + for (option in optionsArg) { + options[option] = optionsArg[option] + } + } + if (agentOptions) options.agentOptions = agentOptions + options.forever = true + return request.defaults(options) +} + +request.get = request +request.post = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'POST'; + return request(params.uri || null, params.options, params.callback) +} +request.put = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'PUT' + return request(params.uri || null, params.options, params.callback) +} +request.head = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'HEAD' + if (params.options.body || + params.options.requestBodyStream || + (params.options.json && typeof params.options.json !== 'boolean') || + params.options.multipart) { + throw new Error("HTTP HEAD requests MUST NOT include a request body.") + } + return request(params.uri || null, params.options, params.callback) +} +request.del = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'DELETE' + return request(params.uri || null, params.options, params.callback) +} +request.jar = function () { + return new CookieJar +} +request.cookie = function (str) { + if (str && str.uri) str = str.uri + if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") + return new Cookie(str) +} + +// Safe toJSON + +function getSafe (self, uuid) { + if (typeof self === 'object' || typeof self === 'function') var safe = {} + if (Array.isArray(self)) var safe = [] + + var recurse = [] + + Object.defineProperty(self, uuid, {}) + + var attrs = Object.keys(self).filter(function (i) { + if (i === uuid) return false + if ( (typeof self[i] !== 'object' && typeof self[i] !== 'function') || self[i] === null) return true + return !(Object.getOwnPropertyDescriptor(self[i], uuid)) + }) + + + for (var i=0;i= 0.3.6" + ], + "main": "./main", + "scripts": { + "test": "node tests/run.js" + }, + "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n
\n  npm install request\n
\n\nOr from source:\n\n
\n  git clone git://github.com/mikeal/request.git \n  cd request\n  npm link\n
\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n if (!error && response.statusCode == 200) {\n console.log(body) // Print the google web page.\n }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n if (req.method === 'PUT') {\n req.pipe(request.put('http://mysite.com/doodle.png'))\n } else if (req.method === 'GET' || req.method === 'HEAD') {\n request.get('http://mysite.com/doodle.png').pipe(resp)\n } \n }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n var x = request('http://mysite.com/doodle.png')\n req.pipe(x)\n x.pipe(resp)\n }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n r.get('http://google.com/doodle.png').pipe(resp)\n }\n})\n```\n\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n , oauth =\n { callback: 'http://mysite.com/callback/'\n , consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n }\n , url = 'https://api.twitter.com/oauth/request_token'\n ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n // Assume by some stretch of magic you aquired the verifier\n var access_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: access_token.oauth_token\n , verifier: VERIFIER\n , token_secret: access_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/oauth/access_token'\n ;\n request.post({url:url, oauth:oauth}, function (e, r, body) {\n var perm_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: perm_token.oauth_token\n , token_secret: perm_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/1/users/show.json?'\n , params = \n { screen_name: perm_token.screen_name\n , user_id: perm_token.user_id\n }\n ;\n url += qs.stringify(params)\n request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n console.log(user)\n })\n })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for POST and PUT requests. Must be buffer or string.\n* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options) \n \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n var request = require('request')\n , rand = Math.floor(Math.random()*100000000).toString()\n ;\n request(\n { method: 'PUT'\n , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n , multipart: \n [ { 'content-type': 'application/json'\n , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n }\n , { body: 'I am an attachment' }\n ] \n }\n , function (error, response, body) {\n if(response.statusCode == 201){\n console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n } else {\n console.log('error: '+ response.statusCode)\n console.log(body)\n }\n }\n )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n request('http://images.google.com')\n})\n```\n", + "readmeFilename": "README.md", + "_id": "request@2.9.203", + "dist": { + "shasum": "141428406334b2bc7bbdf77f694321e57fb26db9" + }, + "_from": "request@2.9.x", + "_resolved": "https://registry.npmjs.org/request/-/request-2.9.203.tgz" +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/googledoodle.png b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/googledoodle.png new file mode 100644 index 0000000..f80c9c5 Binary files /dev/null and b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/googledoodle.png differ diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/run.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/run.js new file mode 100644 index 0000000..f3a30d3 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/run.js @@ -0,0 +1,39 @@ +var spawn = require('child_process').spawn + , exitCode = 0 + ; + +var tests = [ + 'test-body.js' + , 'test-cookie.js' + , 'test-cookiejar.js' + , 'test-defaults.js' + , 'test-errors.js' + , 'test-headers.js' + , 'test-httpModule.js' + , 'test-https.js' + , 'test-https-strict.js' + , 'test-oauth.js' + , 'test-pipes.js' + , 'test-pool.js' + , 'test-proxy.js' + , 'test-qs.js' + , 'test-redirect.js' + , 'test-timeout.js' + , 'test-toJSON.js' + , 'test-tunnel.js' +] + +var next = function () { + if (tests.length === 0) process.exit(exitCode); + + var file = tests.shift() + console.log(file) + var proc = spawn('node', [ 'tests/' + file ]) + proc.stdout.pipe(process.stdout) + proc.stderr.pipe(process.stderr) + proc.on('exit', function (code) { + exitCode += code || 0 + next() + }) +} +next() diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/server.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/server.js new file mode 100644 index 0000000..921f512 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/server.js @@ -0,0 +1,82 @@ +var fs = require('fs') + , http = require('http') + , path = require('path') + , https = require('https') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + ; + +exports.createServer = function (port) { + port = port || 6767 + var s = http.createServer(function (req, resp) { + s.emit(req.url, req, resp); + }) + s.port = port + s.url = 'http://localhost:'+port + return s; +} + +exports.createSSLServer = function(port, opts) { + port = port || 16767 + + var options = { 'key' : path.join(__dirname, 'ssl', 'test.key') + , 'cert': path.join(__dirname, 'ssl', 'test.crt') + } + if (opts) { + for (var i in opts) options[i] = opts[i] + } + + for (var i in options) { + options[i] = fs.readFileSync(options[i]) + } + + var s = https.createServer(options, function (req, resp) { + s.emit(req.url, req, resp); + }) + s.port = port + s.url = 'https://localhost:'+port + return s; +} + +exports.createPostStream = function (text) { + var postStream = new stream.Stream(); + postStream.writeable = true; + postStream.readable = true; + setTimeout(function () {postStream.emit('data', new Buffer(text)); postStream.emit('end')}, 0); + return postStream; +} +exports.createPostValidator = function (text) { + var l = function (req, resp) { + var r = ''; + req.on('data', function (chunk) {r += chunk}) + req.on('end', function () { + if (r !== text) console.log(r, text); + assert.equal(r, text) + resp.writeHead(200, {'content-type':'text/plain'}) + resp.write('OK') + resp.end() + }) + } + return l; +} +exports.createGetResponse = function (text, contentType) { + var l = function (req, resp) { + contentType = contentType || 'text/plain' + resp.writeHead(200, {'content-type':contentType}) + resp.write(text) + resp.end() + } + return l; +} +exports.createChunkResponse = function (chunks, contentType) { + var l = function (req, resp) { + contentType = contentType || 'text/plain' + resp.writeHead(200, {'content-type':contentType}) + chunks.forEach(function (chunk) { + resp.write(chunk) + }) + resp.end() + } + return l; +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/squid.conf b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/squid.conf new file mode 100644 index 0000000..0d4a3b6 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/squid.conf @@ -0,0 +1,77 @@ +# +# Recommended minimum configuration: +# +acl manager proto cache_object +acl localhost src 127.0.0.1/32 ::1 +acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1 + +# Example rule allowing access from your local networks. +# Adapt to list your (internal) IP networks from where browsing +# should be allowed +acl localnet src 10.0.0.0/8 # RFC1918 possible internal network +acl localnet src 172.16.0.0/12 # RFC1918 possible internal network +acl localnet src 192.168.0.0/16 # RFC1918 possible internal network +acl localnet src fc00::/7 # RFC 4193 local private network range +acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines + +acl SSL_ports port 443 +acl Safe_ports port 80 # http +acl Safe_ports port 21 # ftp +acl Safe_ports port 443 # https +acl Safe_ports port 70 # gopher +acl Safe_ports port 210 # wais +acl Safe_ports port 1025-65535 # unregistered ports +acl Safe_ports port 280 # http-mgmt +acl Safe_ports port 488 # gss-http +acl Safe_ports port 591 # filemaker +acl Safe_ports port 777 # multiling http +acl CONNECT method CONNECT + +# +# Recommended minimum Access Permission configuration: +# +# Only allow cachemgr access from localhost +http_access allow manager localhost +http_access deny manager + +# Deny requests to certain unsafe ports +http_access deny !Safe_ports + +# Deny CONNECT to other than secure SSL ports +#http_access deny CONNECT !SSL_ports + +# We strongly recommend the following be uncommented to protect innocent +# web applications running on the proxy server who think the only +# one who can access services on "localhost" is a local user +#http_access deny to_localhost + +# +# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS +# + +# Example rule allowing access from your local networks. +# Adapt localnet in the ACL section to list your (internal) IP networks +# from where browsing should be allowed +http_access allow localnet +http_access allow localhost + +# And finally deny all other access to this proxy +http_access deny all + +# Squid normally listens to port 3128 +http_port 3128 + +# We recommend you to use at least the following line. +hierarchy_stoplist cgi-bin ? + +# Uncomment and adjust the following to add a disk cache directory. +#cache_dir ufs /usr/local/var/cache 100 16 256 + +# Leave coredumps in the first cache dir +coredump_dir /usr/local/var/cache + +# Add any of your own refresh_pattern entries above these. +refresh_pattern ^ftp: 1440 20% 10080 +refresh_pattern ^gopher: 1440 0% 1440 +refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 +refresh_pattern . 0 20% 4320 diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf new file mode 100644 index 0000000..425a889 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf @@ -0,0 +1,20 @@ +[ req ] +default_bits = 1024 +days = 3650 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +output_password = password + +[ req_distinguished_name ] +C = US +ST = CA +L = Oakland +O = request +OU = request Certificate Authority +CN = requestCA +emailAddress = mikeal@mikealrogers.com + +[ req_attributes ] +challengePassword = password challenge + diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt new file mode 100644 index 0000000..b4524e4 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvTCCAiYCCQDn+P/MSbDsWjANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 +ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG +A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n +ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGiMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT +B3JlcXVlc3QxJjAkBgNVBAsTHXJlcXVlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MRIwEAYDVQQDEwlyZXF1ZXN0Q0ExJjAkBgkqhkiG9w0BCQEWF21pa2VhbEBtaWtl +YWxyb2dlcnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7t9pQUAK4 +5XJYTI6NrF0n3G2HZsfN+rPYSVzzL8SuVyb1tHXos+vbPm3NKI4E8X1yVAXU8CjJ +5SqXnp4DAypAhaseho81cbhk7LXUhFz78OvAa+OD+xTAEAnNQ8tGUr4VGyplEjfD +xsBVuqV2j8GPNTftr+drOCFlqfAgMrBn4wIDAQABMA0GCSqGSIb3DQEBBQUAA4GB +ADVdTlVAL45R+PACNS7Gs4o81CwSclukBu4FJbxrkd4xGQmurgfRrYYKjtqiopQm +D7ysRamS3HMN9/VKq2T7r3z1PMHPAy7zM4uoXbbaTKwlnX4j/8pGPn8Ca3qHXYlo +88L/OOPc6Di7i7qckS3HFbXQCTiULtxWmy97oEuTwrAj +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr new file mode 100644 index 0000000..e48c56e --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICBjCCAW8CAQAwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE +BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEmMCQGA1UECxMdcmVxdWVzdCBD +ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAMTCXJlcXVlc3RDQTEmMCQGCSqG +SIb3DQEJARYXbWlrZWFsQG1pa2VhbHJvZ2Vycy5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBALu32lBQArjlclhMjo2sXSfcbYdmx836s9hJXPMvxK5XJvW0 +deiz69s+bc0ojgTxfXJUBdTwKMnlKpeengMDKkCFqx6GjzVxuGTstdSEXPvw68Br +44P7FMAQCc1Dy0ZSvhUbKmUSN8PGwFW6pXaPwY81N+2v52s4IWWp8CAysGfjAgMB +AAGgIzAhBgkqhkiG9w0BCQcxFBMScGFzc3dvcmQgY2hhbGxlbmdlMA0GCSqGSIb3 +DQEBBQUAA4GBAGJO7grHeVHXetjHEK8urIxdnvfB2qeZeObz4GPKIkqUurjr0rfj +bA3EK1kDMR5aeQWR8RunixdM16Q6Ry0lEdLVWkdSwRN9dmirIHT9cypqnD/FYOia +SdezZ0lUzXgmJIwRYRwB1KSMMocIf52ll/xC2bEGg7/ZAEuAyAgcZV3X +-----END CERTIFICATE REQUEST----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key new file mode 100644 index 0000000..a53e7f7 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,C8B5887048377F02 + +nyD5ZH0Wup2uWsDvurq5mKDaDrf8lvNn9w0SH/ZkVnfR1/bkwqrFriqJWvZNUG+q +nS0iBYczsWLJnbub9a1zLOTENWUKVD5uqbC3aGHhnoUTNSa27DONgP8gHOn6JgR+ +GAKo01HCSTiVT4LjkwN337QKHnMP2fTzg+IoC/CigvMcq09hRLwU1/guq0GJKGwH +gTxYNuYmQC4Tjh8vdS4liF+Ve/P3qPR2CehZrIOkDT8PHJBGQJRo4xGUIB7Tpk38 +VCk+UZ0JCS2coY8VkY/9tqFJp/ZnnQQVmaNbdRqg7ECKL+bXnNo7yjzmazPZmPe3 +/ShbE0+CTt7LrjCaQAxWbeDzqfo1lQfgN1LulTm8MCXpQaJpv7v1VhIhQ7afjMYb +4thW/ypHPiYS2YJCAkAVlua9Oxzzh1qJoh8Df19iHtpd79Q77X/qf+1JvITlMu0U +gi7yEatmQcmYNws1mtTC1q2DXrO90c+NZ0LK/Alse6NRL/xiUdjug2iHeTf/idOR +Gg/5dSZbnnlj1E5zjSMDkzg6EHAFmHV4jYGSAFLEQgp4V3ZhMVoWZrvvSHgKV/Qh +FqrAK4INr1G2+/QTd09AIRzfy3/j6yD4A9iNaOsEf9Ua7Qh6RcALRCAZTWR5QtEf +dX+iSNJ4E85qXs0PqwkMDkoaxIJ+tmIRJY7y8oeylV8cfGAi8Soubt/i3SlR8IHC +uDMas/2OnwafK3N7ODeE1i7r7wkzQkSHaEz0TrF8XRnP25jAICCSLiMdAAjKfxVb +EvzsFSuAy3Jt6bU3hSLY9o4YVYKE+68ITMv9yNjvTsEiW+T+IbN34w== +-----END RSA PRIVATE KEY----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl new file mode 100644 index 0000000..17128db --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl @@ -0,0 +1 @@ +ADF62016AA40C9C3 diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf new file mode 100644 index 0000000..cd1fd1e --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf @@ -0,0 +1,19 @@ +[ req ] +default_bits = 1024 +days = 3650 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no + +[ req_distinguished_name ] +C = US +ST = CA +L = Oakland +O = request +OU = testing +CN = testing.request.mikealrogers.com +emailAddress = mikeal@mikealrogers.com + +[ req_attributes ] +challengePassword = password challenge + diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt new file mode 100644 index 0000000..efe96ce --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICejCCAeMCCQCt9iAWqkDJwzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 +ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG +A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n +ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGjMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT +B3JlcXVlc3QxEDAOBgNVBAsTB3Rlc3RpbmcxKTAnBgNVBAMTIHRlc3RpbmcucmVx +dWVzdC5taWtlYWxyb2dlcnMuY29tMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlr +ZWFscm9nZXJzLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDgVl0jMumvOpmM +20W5v9yhGgZj8hPhEQF/N7yCBVBn/rWGYm70IHC8T/pR5c0LkWc5gdnCJEvKWQjh +DBKxZD8FAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEABShRkNgFbgs4vUWW9R9deNJj +7HJoiTmvkmoOC7QzcYkjdgHbOxsSq3rBnwxsVjY9PAtPwBn0GRspOeG7KzKRgySB +kb22LyrCFKbEOfKO/+CJc80ioK9zEPVjGsFMyAB+ftYRqM+s/4cQlTg/m89l01wC +yapjN3RxZbInGhWR+jA= +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr new file mode 100644 index 0000000..a8e7595 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBgjCCASwCAQAwgaMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE +BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEQMA4GA1UECxMHdGVzdGluZzEp +MCcGA1UEAxMgdGVzdGluZy5yZXF1ZXN0Lm1pa2VhbHJvZ2Vycy5jb20xJjAkBgkq +hkiG9w0BCQEWF21pa2VhbEBtaWtlYWxyb2dlcnMuY29tMFwwDQYJKoZIhvcNAQEB +BQADSwAwSAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg +cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAaAjMCEGCSqGSIb3DQEJBzEU +ExJwYXNzd29yZCBjaGFsbGVuZ2UwDQYJKoZIhvcNAQEFBQADQQBD3E5WekQzCEJw +7yOcqvtPYIxGaX8gRKkYfLPoj3pm3GF5SGqtJKhylKfi89szHXgktnQgzff9FN+A +HidVJ/3u +-----END CERTIFICATE REQUEST----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.js new file mode 100644 index 0000000..05e21c1 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.js @@ -0,0 +1,28 @@ +var fs = require("fs") +var https = require("https") +var options = { key: fs.readFileSync("./server.key") + , cert: fs.readFileSync("./server.crt") } + +var server = https.createServer(options, function (req, res) { + res.writeHead(200) + res.end() + server.close() +}) +server.listen(1337) + +var ca = fs.readFileSync("./ca.crt") +var agent = new https.Agent({ host: "localhost", port: 1337, ca: ca }) + +https.request({ host: "localhost" + , method: "HEAD" + , port: 1337 + , headers: { host: "testing.request.mikealrogers.com" } + , agent: agent + , ca: [ ca ] + , path: "/" }, function (res) { + if (res.client.authorized) { + console.log("node test: OK") + } else { + throw new Error(res.client.authorizationError) + } +}).end() diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.key b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.key new file mode 100644 index 0000000..72d8698 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/ca/server.key @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg +cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAQJAK+r8ZM2sze8s7FRo/ApB +iRBtO9fCaIdJwbwJnXKo4RKwZDt1l2mm+fzZ+/QaQNjY1oTROkIIXmnwRvZWfYlW +gQIhAPKYsG+YSBN9o8Sdp1DMyZ/rUifKX3OE6q9tINkgajDVAiEA7Ltqh01+cnt0 +JEnud/8HHcuehUBLMofeg0G+gCnSbXECIQCqDvkXsWNNLnS/3lgsnvH0Baz4sbeJ +rjIpuVEeg8eM5QIgbu0+9JmOV6ybdmmiMV4yAncoF35R/iKGVHDZCAsQzDECIQDZ +0jGz22tlo5YMcYSqrdD3U4sds1pwiAaWFRbCunoUJw== +-----END RSA PRIVATE KEY----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt new file mode 100644 index 0000000..fde2fe9 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x +IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w +bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y +MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV +BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj +YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA +aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE +OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz +Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl +y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC +l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv +yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl +ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/test.crt b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/test.crt new file mode 100644 index 0000000..b357f86 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/test.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICQzCCAawCCQCO/XWtRFck1jANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJU +SDEQMA4GA1UECBMHQmFuZ2tvazEOMAwGA1UEBxMFU2lsb20xGzAZBgNVBAoTElRo +ZSBSZXF1ZXN0IE1vZHVsZTEYMBYGA1UEAxMPcmVxdWVzdC5leGFtcGxlMB4XDTEx +MTIwMzAyMjkyM1oXDTIxMTEzMDAyMjkyM1owZjELMAkGA1UEBhMCVEgxEDAOBgNV +BAgTB0Jhbmdrb2sxDjAMBgNVBAcTBVNpbG9tMRswGQYDVQQKExJUaGUgUmVxdWVz +dCBNb2R1bGUxGDAWBgNVBAMTD3JlcXVlc3QuZXhhbXBsZTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAwmctddZqlA48+NXs0yOy92DijcQV1jf87zMiYAIlNUto +wghVbTWgJU5r0pdKrD16AptnWJTzKanhItEX8XCCPgsNkq1afgTtJP7rNkwu3xcj +eIMkhJg/ay4ZnkbnhYdsii5VTU5prix6AqWRAhbkBgoA+iVyHyof8wvZyKBoFTMC +AwEAATANBgkqhkiG9w0BAQUFAAOBgQB6BybMJbpeiABgihDfEVBcAjDoQ8gUMgwV +l4NulugfKTDmArqnR9aPd4ET5jX5dkMP4bwCHYsvrcYDeWEQy7x5WWuylOdKhua4 +L4cEi2uDCjqEErIG3cc1MCOk6Cl6Ld6tkIzQSf953qfdEACRytOeUqLNQcrXrqeE +c7U8F6MWLQ== +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/test.key b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/test.key new file mode 100644 index 0000000..b85810d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/ssl/test.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDCZy111mqUDjz41ezTI7L3YOKNxBXWN/zvMyJgAiU1S2jCCFVt +NaAlTmvSl0qsPXoCm2dYlPMpqeEi0RfxcII+Cw2SrVp+BO0k/us2TC7fFyN4gySE +mD9rLhmeRueFh2yKLlVNTmmuLHoCpZECFuQGCgD6JXIfKh/zC9nIoGgVMwIDAQAB +AoGBALXFwfUf8vHTSmGlrdZS2AGFPvEtuvldyoxi9K5u8xmdFCvxnOcLsF2RsTHt +Mu5QYWhUpNJoG+IGLTPf7RJdj/kNtEs7xXqWy4jR36kt5z5MJzqiK+QIgiO9UFWZ +fjUb6oeDnTIJA9YFBdYi97MDuL89iU/UK3LkJN3hd4rciSbpAkEA+MCkowF5kSFb +rkOTBYBXZfiAG78itDXN6DXmqb9XYY+YBh3BiQM28oxCeQYyFy6pk/nstnd4TXk6 +V/ryA2g5NwJBAMgRKTY9KvxJWbESeMEFe2iBIV0c26/72Amgi7ZKUCLukLfD4tLF ++WSZdmTbbqI1079YtwaiOVfiLm45Q/3B0eUCQAaQ/0eWSGE+Yi8tdXoVszjr4GXb +G81qBi91DMu6U1It+jNfIba+MPsiHLcZJMVb4/oWBNukN7bD1nhwFWdlnu0CQQCf +Is9WHkdvz2RxbZDxb8verz/7kXXJQJhx5+rZf7jIYFxqX3yvTNv3wf2jcctJaWlZ +fVZwB193YSivcgt778xlAkEAprYUz3jczjF5r2hrgbizPzPDR94tM5BTO3ki2v3w +kbf+j2g7FNAx6kZiVN8XwfLc8xEeUGiPKwtq3ddPDFh17w== +-----END RSA PRIVATE KEY----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-body.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-body.js new file mode 100644 index 0000000..e3fc75d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-body.js @@ -0,0 +1,80 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetBuffer : + { resp : server.createGetResponse(new Buffer("TESTING!")) + , encoding: null + , expectBody: new Buffer("TESTING!") + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) + diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-cookie.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-cookie.js new file mode 100644 index 0000000..6c6a7a7 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-cookie.js @@ -0,0 +1,29 @@ +var Cookie = require('../vendor/cookie') + , assert = require('assert'); + +var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT'; +var cookie = new Cookie(str); + +// test .toString() +assert.equal(cookie.toString(), str); + +// test .path +assert.equal(cookie.path, '/'); + +// test .httpOnly +assert.equal(cookie.httpOnly, true); + +// test .name +assert.equal(cookie.name, 'Sid'); + +// test .value +assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="'); + +// test .expires +assert.equal(cookie.expires instanceof Date, true); + +// test .path default +var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' }); +assert.equal(cookie.path, '/bar'); + +console.log('All tests passed'); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-cookiejar.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-cookiejar.js new file mode 100644 index 0000000..76fcd71 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-cookiejar.js @@ -0,0 +1,90 @@ +var Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + , assert = require('assert'); + +function expires(ms) { + return new Date(Date.now() + ms).toUTCString(); +} + +// test .get() expiration +(function() { + var jar = new Jar; + var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000)); + jar.add(cookie); + setTimeout(function(){ + var cookies = jar.get({ url: 'http://foo.com/foo' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], cookie); + setTimeout(function(){ + var cookies = jar.get({ url: 'http://foo.com/foo' }); + assert.equal(cookies.length, 0); + }, 1000); + }, 5); +})(); + +// test .get() path support +(function() { + var jar = new Jar; + var a = new Cookie('sid=1234; path=/'); + var b = new Cookie('sid=1111; path=/foo/bar'); + var c = new Cookie('sid=2222; path=/'); + jar.add(a); + jar.add(b); + jar.add(c); + + // should remove the duplicates + assert.equal(jar.cookies.length, 2); + + // same name, same path, latter prevails + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], c); + + // same name, diff path, path specifity prevails, latter prevails + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], b); + + var jar = new Jar; + var a = new Cookie('sid=1111; path=/foo/bar'); + var b = new Cookie('sid=1234; path=/'); + jar.add(a); + jar.add(b); + + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], a); + + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], b); + + var jar = new Jar; + var a = new Cookie('sid=1111; path=/foo/bar'); + var b = new Cookie('sid=3333; path=/foo/bar'); + var c = new Cookie('pid=3333; path=/foo/bar'); + var d = new Cookie('sid=2222; path=/foo/'); + var e = new Cookie('sid=1234; path=/'); + jar.add(a); + jar.add(b); + jar.add(c); + jar.add(d); + jar.add(e); + + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 2); + assert.equal(cookies[0], b); + assert.equal(cookies[1], c); + + var cookies = jar.get({ url: 'http://foo.com/foo/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], d); + + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], e); +})(); + +setTimeout(function() { + console.log('All tests passed'); +}, 1200); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-defaults.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-defaults.js new file mode 100644 index 0000000..6c8b58f --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-defaults.js @@ -0,0 +1,68 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +s.listen(s.port, function () { + var counter = 0; + s.on('/get', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'GET') + resp.writeHead(200, {'Content-Type': 'text/plain'}); + resp.end('TESTING!'); + }); + + // test get(string, function) + request.defaults({headers:{foo:"bar"}})(s.url + '/get', function (e, r, b){ + if (e) throw e; + assert.deepEqual("TESTING!", b); + counter += 1; + }); + + s.on('/post', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.headers['content-type'], 'application/json'); + assert.equal(req.method, 'POST') + resp.writeHead(200, {'Content-Type': 'application/json'}); + resp.end(JSON.stringify({foo:'bar'})); + }); + + // test post(string, object, function) + request.defaults({headers:{foo:"bar"}}).post(s.url + '/post', {json: true}, function (e, r, b){ + if (e) throw e; + assert.deepEqual('bar', b.foo); + counter += 1; + }); + + s.on('/del', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'DELETE') + resp.writeHead(200, {'Content-Type': 'application/json'}); + resp.end(JSON.stringify({foo:'bar'})); + }); + + // test .del(string, function) + request.defaults({headers:{foo:"bar"}, json:true}).del(s.url + '/del', function (e, r, b){ + if (e) throw e; + assert.deepEqual('bar', b.foo); + counter += 1; + }); + + s.on('/head', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'HEAD') + resp.writeHead(200, {'Content-Type': 'text/plain'}); + resp.end(); + }); + + // test head.(object, function) + request.defaults({headers:{foo:"bar"}}).head({uri: s.url + '/head'}, function (e, r, b){ + if (e) throw e; + counter += 1; + console.log(counter.toString() + " tests passed.") + s.close() + }); + +}) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-errors.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-errors.js new file mode 100644 index 0000000..1986a59 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-errors.js @@ -0,0 +1,37 @@ +var server = require('./server') + , events = require('events') + , assert = require('assert') + , request = require('../main.js') + ; + +var local = 'http://localhost:8888/asdf' + +try { + request({uri:local, body:{}}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Argument error, options.body.') +} + +try { + request({uri:local, multipart: 'foo'}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Argument error, options.multipart.') +} + +try { + request({uri:local, multipart: [{}]}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Body attribute missing in multipart.') +} + +try { + request(local, {multipart: [{}]}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Body attribute missing in multipart.') +} + +console.log("All tests passed.") diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-headers.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-headers.js new file mode 100644 index 0000000..31fe3f4 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-headers.js @@ -0,0 +1,52 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + , s = server.createServer() + +s.listen(s.port, function () { + var serverUri = 'http://localhost:' + s.port + , numTests = 0 + , numOutstandingTests = 0 + + function createTest(requestObj, serverAssertFn) { + var testNumber = numTests; + numTests += 1; + numOutstandingTests += 1; + s.on('/' + testNumber, function (req, res) { + serverAssertFn(req, res); + res.writeHead(200); + res.end(); + }); + requestObj.url = serverUri + '/' + testNumber + request(requestObj, function (err, res, body) { + assert.ok(!err) + assert.equal(res.statusCode, 200) + numOutstandingTests -= 1 + if (numOutstandingTests === 0) { + console.log(numTests + ' tests passed.') + s.close() + } + }) + } + + // Issue #125: headers.cookie shouldn't be replaced when a cookie jar isn't specified + createTest({headers: {cookie: 'foo=bar'}}, function (req, res) { + assert.ok(req.headers.cookie) + assert.equal(req.headers.cookie, 'foo=bar') + }) + + // Issue #125: headers.cookie + cookie jar + var jar = new Jar() + jar.add(new Cookie('quux=baz')); + createTest({jar: jar, headers: {cookie: 'foo=bar'}}, function (req, res) { + assert.ok(req.headers.cookie) + assert.equal(req.headers.cookie, 'foo=bar; quux=baz') + }) + + // There should be no cookie header when neither headers.cookie nor a cookie jar is specified + createTest({}, function (req, res) { + assert.ok(!req.headers.cookie) + }) +}) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-httpModule.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-httpModule.js new file mode 100644 index 0000000..1866de2 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-httpModule.js @@ -0,0 +1,94 @@ +var http = require('http') + , https = require('https') + , server = require('./server') + , assert = require('assert') + , request = require('../main.js') + + +var faux_requests_made = {'http':0, 'https':0} +function wrap_request(name, module) { + // Just like the http or https module, but note when a request is made. + var wrapped = {} + Object.keys(module).forEach(function(key) { + var value = module[key]; + + if(key != 'request') + wrapped[key] = value; + else + wrapped[key] = function(options, callback) { + faux_requests_made[name] += 1 + return value.apply(this, arguments) + } + }) + + return wrapped; +} + + +var faux_http = wrap_request('http', http) + , faux_https = wrap_request('https', https) + , plain_server = server.createServer() + , https_server = server.createSSLServer() + + +plain_server.listen(plain_server.port, function() { + plain_server.on('/plain', function (req, res) { + res.writeHead(200) + res.end('plain') + }) + plain_server.on('/to_https', function (req, res) { + res.writeHead(301, {'location':'https://localhost:'+https_server.port + '/https'}) + res.end() + }) + + https_server.listen(https_server.port, function() { + https_server.on('/https', function (req, res) { + res.writeHead(200) + res.end('https') + }) + https_server.on('/to_plain', function (req, res) { + res.writeHead(302, {'location':'http://localhost:'+plain_server.port + '/plain'}) + res.end() + }) + + run_tests() + run_tests({}) + run_tests({'http:':faux_http}) + run_tests({'https:':faux_https}) + run_tests({'http:':faux_http, 'https:':faux_https}) + }) +}) + +function run_tests(httpModules) { + var to_https = 'http://localhost:'+plain_server.port+'/to_https' + var to_plain = 'https://localhost:'+https_server.port+'/to_plain' + + request(to_https, {'httpModules':httpModules}, function (er, res, body) { + assert.ok(!er, 'Bounce to SSL worked') + assert.equal(body, 'https', 'Received HTTPS server body') + done() + }) + + request(to_plain, {'httpModules':httpModules}, function (er, res, body) { + assert.ok(!er, 'Bounce to plaintext server worked') + assert.equal(body, 'plain', 'Received HTTPS server body') + done() + }) +} + + +var passed = 0; +function done() { + passed += 1 + var expected = 10 + + if(passed == expected) { + plain_server.close() + https_server.close() + + assert.equal(faux_requests_made.http, 4, 'Wrapped http module called appropriately') + assert.equal(faux_requests_made.https, 4, 'Wrapped https module called appropriately') + + console.log((expected+2) + ' tests passed.') + } +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-https-strict.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-https-strict.js new file mode 100644 index 0000000..f53fc14 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-https-strict.js @@ -0,0 +1,97 @@ +// a test where we validate the siguature of the keys +// otherwise exactly the same as the ssl test + +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , fs = require('fs') + , path = require('path') + , opts = { key: path.resolve(__dirname, 'ssl/ca/server.key') + , cert: path.resolve(__dirname, 'ssl/ca/server.crt') } + , s = server.createSSLServer(null, opts) + , caFile = path.resolve(__dirname, 'ssl/ca/ca.crt') + , ca = fs.readFileSync(caFile) + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + 'Oh hi.' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': 'Oh hi.'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + test.strictSSL = true + test.ca = ca + test.headers = { host: 'testing.request.mikealrogers.com' } + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-https.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-https.js new file mode 100644 index 0000000..df7330b --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-https.js @@ -0,0 +1,86 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + +var s = server.createSSLServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + 'Oh hi.' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': 'Oh hi.'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-oauth.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-oauth.js new file mode 100644 index 0000000..72ca923 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-oauth.js @@ -0,0 +1,117 @@ +var hmacsign = require('../oauth').hmacsign + , assert = require('assert') + , qs = require('querystring') + , request = require('../main') + ; + +function getsignature (r) { + var sign + r.headers.Authorization.slice('OAuth '.length).replace(/,\ /g, ',').split(',').forEach(function (v) { + if (v.slice(0, 'oauth_signature="'.length) === 'oauth_signature="') sign = v.slice('oauth_signature="'.length, -1) + }) + return decodeURIComponent(sign) +} + +// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth + +var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', + { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' + , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' + , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' + , oauth_signature_method: 'HMAC-SHA1' + , oauth_timestamp: '1272323042' + , oauth_version: '1.0' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98") + +console.log(reqsign) +console.log('8wUi7m5HFQy76nowoCThusfgB+Q=') +assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=') + +var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token', + { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' + , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' + , oauth_signature_method: 'HMAC-SHA1' + , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' + , oauth_timestamp: '1272323047' + , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' + , oauth_version: '1.0' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") + +console.log(accsign) +console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') +assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') + +var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', + { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" + , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" + , oauth_signature_method: "HMAC-SHA1" + , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" + , oauth_timestamp: "1272325550" + , oauth_version: "1.0" + , status: 'setting up my twitter 私のさえずりを設定する' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA") + +console.log(upsign) +console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') +assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') + + +var rsign = request.post( + { url: 'https://api.twitter.com/oauth/request_token' + , oauth: + { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' + , consumer_key: 'GDdmIQH6jhtmLUypg82g' + , nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' + , timestamp: '1272323042' + , version: '1.0' + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + } + }) + +setTimeout(function () { + console.log(getsignature(rsign)) + assert.equal(reqsign, getsignature(rsign)) +}) + +var raccsign = request.post( + { url: 'https://api.twitter.com/oauth/access_token' + , oauth: + { consumer_key: 'GDdmIQH6jhtmLUypg82g' + , nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' + , signature_method: 'HMAC-SHA1' + , token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' + , timestamp: '1272323047' + , verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' + , version: '1.0' + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + , token_secret: "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA" + } + }) + +setTimeout(function () { + console.log(getsignature(raccsign)) + assert.equal(accsign, getsignature(raccsign)) +}, 1) + +var rupsign = request.post( + { url: 'http://api.twitter.com/1/statuses/update.json' + , oauth: + { consumer_key: "GDdmIQH6jhtmLUypg82g" + , nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" + , signature_method: "HMAC-SHA1" + , token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" + , timestamp: "1272325550" + , version: "1.0" + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + , token_secret: "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA" + } + , form: {status: 'setting up my twitter 私のさえずりを設定する'} + }) +setTimeout(function () { + console.log(getsignature(rupsign)) + assert.equal(upsign, getsignature(rupsign)) +}, 1) + + + + diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-params.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-params.js new file mode 100644 index 0000000..8354f6d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-params.js @@ -0,0 +1,92 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetBuffer : + { resp : server.createGetResponse(new Buffer("TESTING!")) + , encoding: null + , expectBody: new Buffer("TESTING!") + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + 'Oh hi.' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': 'Oh hi.'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + //test.uri = s.url + '/' + i + request(s.url + '/' + i, test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-pipes.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-pipes.js new file mode 100644 index 0000000..1869874 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-pipes.js @@ -0,0 +1,202 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , fs = require('fs') + , request = require('../main.js') + , path = require('path') + , util = require('util') + ; + +var s = server.createServer(3453); + +function ValidationStream(str) { + this.str = str + this.buf = '' + this.on('data', function (data) { + this.buf += data + }) + this.on('end', function () { + assert.equal(this.str, this.buf) + }) + this.writable = true +} +util.inherits(ValidationStream, stream.Stream) +ValidationStream.prototype.write = function (chunk) { + this.emit('data', chunk) +} +ValidationStream.prototype.end = function (chunk) { + if (chunk) emit('data', chunk) + this.emit('end') +} + +s.listen(s.port, function () { + counter = 0; + + var check = function () { + counter = counter - 1 + if (counter === 0) { + console.log('All tests passed.') + setTimeout(function () { + process.exit(); + }, 500) + } + } + + // Test pipeing to a request object + s.once('/push', server.createPostValidator("mydata")); + + var mydata = new stream.Stream(); + mydata.readable = true + + counter++ + var r1 = request.put({url:'http://localhost:3453/push'}, function () { + check(); + }) + mydata.pipe(r1) + + mydata.emit('data', 'mydata'); + mydata.emit('end'); + + + // Test pipeing from a request object. + s.once('/pull', server.createGetResponse("mypulldata")); + + var mypulldata = new stream.Stream(); + mypulldata.writable = true + + counter++ + request({url:'http://localhost:3453/pull'}).pipe(mypulldata) + + var d = ''; + + mypulldata.write = function (chunk) { + d += chunk; + } + mypulldata.end = function () { + assert.equal(d, 'mypulldata'); + check(); + }; + + + s.on('/cat', function (req, resp) { + if (req.method === "GET") { + resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4}); + resp.end('asdf') + } else if (req.method === "PUT") { + assert.equal(req.headers['content-type'], 'text/plain-test'); + assert.equal(req.headers['content-length'], 4) + var validate = ''; + + req.on('data', function (chunk) {validate += chunk}) + req.on('end', function () { + resp.writeHead(201); + resp.end(); + assert.equal(validate, 'asdf'); + check(); + }) + } + }) + s.on('/pushjs', function (req, resp) { + if (req.method === "PUT") { + assert.equal(req.headers['content-type'], 'text/javascript'); + check(); + } + }) + s.on('/catresp', function (req, resp) { + request.get('http://localhost:3453/cat').pipe(resp) + }) + s.on('/doodle', function (req, resp) { + if (req.headers['x-oneline-proxy']) { + resp.setHeader('x-oneline-proxy', 'yup') + } + resp.writeHead('200', {'content-type':'image/png'}) + fs.createReadStream(path.join(__dirname, 'googledoodle.png')).pipe(resp) + }) + s.on('/onelineproxy', function (req, resp) { + var x = request('http://localhost:3453/doodle') + req.pipe(x) + x.pipe(resp) + }) + + counter++ + fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs')) + + counter++ + request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat')) + + counter++ + request.get('http://localhost:3453/catresp', function (e, resp, body) { + assert.equal(resp.headers['content-type'], 'text/plain-test'); + assert.equal(resp.headers['content-length'], 4) + check(); + }) + + var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.png')) + + counter++ + request.get('http://localhost:3453/doodle').pipe(doodleWrite) + + doodleWrite.on('close', function () { + assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.png')), fs.readFileSync(path.join(__dirname, 'test.png'))) + check() + }) + + process.on('exit', function () { + fs.unlinkSync(path.join(__dirname, 'test.png')) + }) + + counter++ + request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) { + assert.equal(resp.headers['x-oneline-proxy'], 'yup') + check() + }) + + s.on('/afterresponse', function (req, resp) { + resp.write('d') + resp.end() + }) + + counter++ + var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () { + var v = new ValidationStream('d') + afterresp.pipe(v) + v.on('end', check) + }) + + s.on('/forward1', function (req, resp) { + resp.writeHead(302, {location:'/forward2'}) + resp.end() + }) + s.on('/forward2', function (req, resp) { + resp.writeHead('200', {'content-type':'image/png'}) + resp.write('d') + resp.end() + }) + + counter++ + var validateForward = new ValidationStream('d') + validateForward.on('end', check) + request.get('http://localhost:3453/forward1').pipe(validateForward) + + // Test pipe options + s.once('/opts', server.createGetResponse('opts response')); + + var optsStream = new stream.Stream(); + optsStream.writable = true + + var optsData = ''; + optsStream.write = function (buf) { + optsData += buf; + if (optsData === 'opts response') { + setTimeout(check, 10); + } + } + + optsStream.end = function () { + assert.fail('end called') + }; + + counter++ + request({url:'http://localhost:3453/opts'}).pipe(optsStream, { end : false }) +}) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-pool.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-pool.js new file mode 100644 index 0000000..1e7d578 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-pool.js @@ -0,0 +1,16 @@ +var request = require('../main') + , http = require('http') + , assert = require('assert') + ; + +var s = http.createServer(function (req, resp) { + resp.statusCode = 200; + resp.end('asdf'); +}).listen(8080, function () { + request({'url': 'http://localhost:8080', 'pool': false}, function (e, resp) { + var agent = resp.request.agent; + assert.strictEqual(typeof agent, 'boolean'); + assert.strictEqual(agent, false); + s.close(); + }); +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-proxy.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-proxy.js new file mode 100644 index 0000000..647157c --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-proxy.js @@ -0,0 +1,39 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , fs = require('fs') + , request = require('../main.js') + , path = require('path') + , util = require('util') + ; + +var port = 6768 + , called = false + , proxiedHost = 'google.com' + ; + +var s = server.createServer(port) +s.listen(port, function () { + s.on('http://google.com/', function (req, res) { + called = true + assert.equal(req.headers.host, proxiedHost) + res.writeHeader(200) + res.end() + }) + request ({ + url: 'http://'+proxiedHost, + proxy: 'http://localhost:'+port + /* + //should behave as if these arguments where passed: + url: 'http://localhost:'+port, + headers: {host: proxiedHost} + //*/ + }, function (err, res, body) { + s.close() + }) +}) + +process.on('exit', function () { + assert.ok(called, 'the request must be made to the proxy server') +}) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-qs.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-qs.js new file mode 100644 index 0000000..1aac22b --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-qs.js @@ -0,0 +1,28 @@ +var request = request = require('../main.js') + , assert = require('assert') + ; + + +// Test adding a querystring +var req1 = request.get({ uri: 'http://www.google.com', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?q=search', req1.path) +}, 1) + +// Test replacing a querystring value +var req2 = request.get({ uri: 'http://www.google.com?q=abc', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?q=search', req2.path) +}, 1) + +// Test appending a querystring value to the ones present in the uri +var req3 = request.get({ uri: 'http://www.google.com?x=y', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?x=y&q=search', req3.path) +}, 1) + +// Test leaving a querystring alone +var req4 = request.get({ uri: 'http://www.google.com?x=y'}) +setTimeout(function() { + assert.equal('/?x=y', req4.path) +}, 1) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-redirect.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-redirect.js new file mode 100644 index 0000000..b84844a --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-redirect.js @@ -0,0 +1,154 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + +var s = server.createServer() + +s.listen(s.port, function () { + var server = 'http://localhost:' + s.port; + var hits = {} + var passed = 0; + + bouncer(301, 'temp') + bouncer(302, 'perm') + bouncer(302, 'nope') + + function bouncer(code, label) { + var landing = label+'_landing'; + + s.on('/'+label, function (req, res) { + hits[label] = true; + res.writeHead(code, { + 'location':server + '/'+landing, + 'set-cookie': 'ham=eggs' + }) + res.end() + }) + + s.on('/'+landing, function (req, res) { + if (req.method !== 'GET') { // We should only accept GET redirects + console.error("Got a non-GET request to the redirect destination URL"); + res.writeHead(400); + res.end(); + return; + } + // Make sure the cookie doesn't get included twice, see #139: + // Make sure cookies are set properly after redirect + assert.equal(req.headers.cookie, 'foo=bar; quux=baz; ham=eggs'); + hits[landing] = true; + res.writeHead(200) + res.end(landing) + }) + } + + // Permanent bounce + var jar = new Jar() + jar.add(new Cookie('quux=baz')) + request({uri: server+'/perm', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.perm, 'Original request is to /perm') + assert.ok(hits.perm_landing, 'Forward to permanent landing URL') + assert.equal(body, 'perm_landing', 'Got permanent landing content') + passed += 1 + done() + }) + + // Temporary bounce + request({uri: server+'/temp', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + // Prevent bouncing. + request({uri:server+'/nope', jar: jar, headers: {cookie: 'foo=bar'}, followRedirect:false}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 302) throw new Error('Status is not 302: '+res.statusCode) + assert.ok(hits.nope, 'Original request to /nope') + assert.ok(!hits.nope_landing, 'No chasing the redirect') + assert.equal(res.statusCode, 302, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow post redirects by default + request.post(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when post') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should follow post redirects when followAllRedirects true + request.post({uri:server+'/temp', followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + request.post({uri:server+'/temp', followAllRedirects:false, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow delete redirects by default + request.del(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode < 301) throw new Error('Status is not a redirect.') + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow delete redirects even if followRedirect is set to true + request.del(server+'/temp', { followRedirect: true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should follow delete redirects when followAllRedirects true + request.del(server+'/temp', {followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + var reqs_done = 0; + function done() { + reqs_done += 1; + if(reqs_done == 9) { + console.log(passed + ' tests passed.') + s.close() + } + } +}) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-s3.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-s3.js new file mode 100644 index 0000000..5f59c4a --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-s3.js @@ -0,0 +1,13 @@ +var request = require('../main') + +var r = request.get('https://log.curlybracecast.com.s3.amazonaws.com/', + { aws: + { key: 'AKIAI6KIQRRVMGK3WK5Q' + , secret: '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' + , bucket: 'log.curlybracecast.com' + } + }, function (e, resp, body) { + console.log(r.headers) + console.log(body) + } +) \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-timeout.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-timeout.js new file mode 100644 index 0000000..673f8ad --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-timeout.js @@ -0,0 +1,87 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); +var expectedBody = "waited"; +var remainingTests = 5; + +s.listen(s.port, function () { + // Request that waits for 200ms + s.on('/timeout', function (req, resp) { + setTimeout(function(){ + resp.writeHead(200, {'content-type':'text/plain'}) + resp.write(expectedBody) + resp.end() + }, 200); + }); + + // Scenario that should timeout + var shouldTimeout = { + url: s.url + "/timeout", + timeout:100 + } + + + request(shouldTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + + // Scenario that shouldn't timeout + var shouldntTimeout = { + url: s.url + "/timeout", + timeout:300 + } + + request(shouldntTimeout, function (err, resp, body) { + assert.equal(err, null); + assert.equal(expectedBody, body) + checkDone(); + }) + + // Scenario with no timeout set, so shouldn't timeout + var noTimeout = { + url: s.url + "/timeout" + } + + request(noTimeout, function (err, resp, body) { + assert.equal(err); + assert.equal(expectedBody, body) + checkDone(); + }) + + // Scenario with a negative timeout value, should be treated a zero or the minimum delay + var negativeTimeout = { + url: s.url + "/timeout", + timeout:-1000 + } + + request(negativeTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + // Scenario with a float timeout value, should be rounded by setTimeout anyway + var floatTimeout = { + url: s.url + "/timeout", + timeout: 100.76 + } + + request(floatTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + function checkDone() { + if(--remainingTests == 0) { + s.close(); + console.log("All tests passed."); + } + } +}) + diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-toJSON.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-toJSON.js new file mode 100644 index 0000000..b7c67ef --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-toJSON.js @@ -0,0 +1,14 @@ +var request = require('../main') + , http = require('http') + , assert = require('assert') + ; + +var s = http.createServer(function (req, resp) { + resp.statusCode = 200 + resp.end('asdf') +}).listen(8080, function () { + var r = request('http://localhost:8080', function (e, resp) { + assert.equal(JSON.parse(JSON.stringify(r)).response.statusCode, 200) + s.close() + }) +}) \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-tunnel.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-tunnel.js new file mode 100644 index 0000000..58131b9 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tests/test-tunnel.js @@ -0,0 +1,61 @@ +// test that we can tunnel a https request over an http proxy +// keeping all the CA and whatnot intact. +// +// Note: this requires that squid is installed. +// If the proxy fails to start, we'll just log a warning and assume success. + +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , fs = require('fs') + , path = require('path') + , caFile = path.resolve(__dirname, 'ssl/npm-ca.crt') + , ca = fs.readFileSync(caFile) + , child_process = require('child_process') + , sqConf = path.resolve(__dirname, 'squid.conf') + , sqArgs = ['-f', sqConf, '-N', '-d', '5'] + , proxy = 'http://localhost:3128' + , hadError = null + +var squid = child_process.spawn('squid', sqArgs); +var ready = false + +squid.stderr.on('data', function (c) { + console.error('SQUIDERR ' + c.toString().trim().split('\n') + .join('\nSQUIDERR ')) + ready = c.toString().match(/ready to serve requests/i) +}) + +squid.stdout.on('data', function (c) { + console.error('SQUIDOUT ' + c.toString().trim().split('\n') + .join('\nSQUIDOUT ')) +}) + +squid.on('exit', function (c) { + console.error('exit '+c) + if (c && !ready) { + console.error('squid must be installed to run this test.') + c = null + hadError = null + process.exit(0) + return + } + + if (c) { + hadError = hadError || new Error('Squid exited with '+c) + } + if (hadError) throw hadError +}) + +setTimeout(function F () { + if (!ready) return setTimeout(F, 100) + request({ uri: 'https://registry.npmjs.org/request/' + , proxy: 'http://localhost:3128' + , ca: ca + , json: true }, function (er, body) { + hadError = er + console.log(er || typeof body) + if (!er) console.log("ok") + squid.kill('SIGKILL') + }) +}, 100) diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tunnel.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tunnel.js new file mode 100644 index 0000000..453786c --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/tunnel.js @@ -0,0 +1,229 @@ +'use strict'; + +var net = require('net'); +var tls = require('tls'); +var http = require('http'); +var https = require('https'); +var events = require('events'); +var assert = require('assert'); +var util = require('util'); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port) { + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === host && pending.port === port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port) { + var self = this; + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push({host: host, port: port, request: req}); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket({host: host, port: port, request: req}, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, host, port); + } + + function onCloseOrRemove(err) { + self.removeSocket(); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false + }); + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode === 200) { + assert.equal(head.length, 0); + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + cb(socket); + } else { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + var error = new Error('tunneling socket could not be established, ' + + 'sutatusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, mergeOptions({}, self.options, { + socket: socket + })); + cb(secureSocket); + }); +} + + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/uuid.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/uuid.js new file mode 100644 index 0000000..1d83bd5 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/uuid.js @@ -0,0 +1,19 @@ +module.exports = function () { + var s = [], itoh = '0123456789ABCDEF'; + + // Make array of random hex digits. The UUID only has 32 digits in it, but we + // allocate an extra items to make room for the '-'s we'll be inserting. + for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10); + + // Conform to RFC-4122, section 4.4 + s[14] = 4; // Set 4 high bits of time_high field to version + s[19] = (s[19] & 0x3) | 0x8; // Specify 2 high bits of clock sequence + + // Convert to hex chars + for (var i = 0; i <36; i++) s[i] = itoh[s[i]]; + + // Insert '-'s + s[8] = s[13] = s[18] = s[23] = '-'; + + return s.join(''); +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/vendor/cookie/index.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/vendor/cookie/index.js new file mode 100644 index 0000000..ff44b3e --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/vendor/cookie/index.js @@ -0,0 +1,65 @@ +/*! + * Tobi - Cookie + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var url = require('url'); + +/** + * Initialize a new `Cookie` with the given cookie `str` and `req`. + * + * @param {String} str + * @param {IncomingRequest} req + * @api private + */ + +var Cookie = exports = module.exports = function Cookie(str, req) { + this.str = str; + + // Map the key/val pairs + str.split(/ *; */).reduce(function(obj, pair){ + var p = pair.indexOf('='); + var key = p > 0 ? pair.substring(0, p).trim() : pair.trim(); + var lowerCasedKey = key.toLowerCase(); + var value = p > 0 ? pair.substring(p + 1).trim() : true; + + if (!obj.name) { + // First key is the name + obj.name = key; + obj.value = value; + } + else if (lowerCasedKey === 'httponly') { + obj.httpOnly = value; + } + else { + obj[lowerCasedKey] = value; + } + return obj; + }, this); + + // Expires + this.expires = this.expires + ? new Date(this.expires) + : Infinity; + + // Default or trim path + this.path = this.path + ? this.path.trim(): req + ? url.parse(req.url).pathname: '/'; +}; + +/** + * Return the original cookie string. + * + * @return {String} + * @api public + */ + +Cookie.prototype.toString = function(){ + return this.str; +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/vendor/cookie/jar.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/vendor/cookie/jar.js new file mode 100644 index 0000000..34920e0 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/request/vendor/cookie/jar.js @@ -0,0 +1,72 @@ +/*! +* Tobi - CookieJar +* Copyright(c) 2010 LearnBoost +* MIT Licensed +*/ + +/** +* Module dependencies. +*/ + +var url = require('url'); + +/** +* Initialize a new `CookieJar`. +* +* @api private +*/ + +var CookieJar = exports = module.exports = function CookieJar() { + this.cookies = []; +}; + +/** +* Add the given `cookie` to the jar. +* +* @param {Cookie} cookie +* @api private +*/ + +CookieJar.prototype.add = function(cookie){ + this.cookies = this.cookies.filter(function(c){ + // Avoid duplication (same path, same name) + return !(c.name == cookie.name && c.path == cookie.path); + }); + this.cookies.push(cookie); +}; + +/** +* Get cookies for the given `req`. +* +* @param {IncomingRequest} req +* @return {Array} +* @api private +*/ + +CookieJar.prototype.get = function(req){ + var path = url.parse(req.url).pathname + , now = new Date + , specificity = {}; + return this.cookies.filter(function(cookie){ + if (0 == path.indexOf(cookie.path) && now < cookie.expires + && cookie.path.length > (specificity[cookie.name] || 0)) + return specificity[cookie.name] = cookie.path.length; + }); +}; + +/** +* Return Cookie string for the given `req`. +* +* @param {IncomingRequest} req +* @return {String} +* @api private +*/ + +CookieJar.prototype.cookieString = function(req){ + var cookies = this.get(req); + if (cookies.length) { + return cookies.map(function(cookie){ + return cookie.name + '=' + cookie.value; + }).join('; '); + } +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/.npmignore b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/.npmignore new file mode 100644 index 0000000..b59f7e3 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/.npmignore @@ -0,0 +1 @@ +test/ \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/License b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/License new file mode 100644 index 0000000..11ec094 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Felix Geisendörfer (felix@debuggable.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/Makefile b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/Makefile new file mode 100644 index 0000000..a7ce31d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/Makefile @@ -0,0 +1,11 @@ +SHELL := /bin/bash + +test: + @./test/run.js + +release: + git push + git push --tags + npm publish . + +.PHONY: test diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/Readme.md b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/Readme.md new file mode 100644 index 0000000..fcd1b97 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/Readme.md @@ -0,0 +1,98 @@ +# stack-trace + +Get v8 stack traces as an array of CallSite objects. + +## Install + +``` bash +npm install stack-trace +``` + +## Usage + +The stack-trace module makes it easy for you to capture the current stack: + +``` javascript +var stackTrace = require('stack-trace'); +var trace = stackTrace.get(); + +require('assert').strictEqual(trace[0].getFileName(), __filename); +``` + +However, sometimes you have already popped the stack you are interested in, +and all you have left is an `Error` object. This module can help: + +``` javascript +var stackTrace = require('stack-trace'); +var err = new Error('something went wrong'); +var trace = stackTrace.parse(err); + +require('assert').strictEqual(trace[0].getFileName(), __filename); +``` + +Please note that parsing the `Error#stack` property is not perfect, only +certain properties can be retrieved with it as noted in the API docs below. + +## Long stack traces + +stack-trace works great with [long-stack-traces][], when parsing an `err.stack` +that has crossed the event loop boundary, a `CallSite` object returning +`'----------------------------------------'` for `getFileName()` is created. +All other methods of the event loop boundary call site return `null`. + +[long-stack-traces]: https://github.com/tlrobinson/long-stack-traces + +## API + +### stackTrace.get([belowFn]) + +Returns an array of `CallSite` objects, where element `0` is the current call +site. + +When passing a function on the current stack as the `belowFn` parameter, the +returned array will only include `CallSite` objects below this function. + +### stackTrace.parse(err) + +Parses the `err.stack` property of an `Error` object into an array compatible +with those returned by `stackTrace.get()`. However, only the following methods +are implemented on the returned `CallSite` objects. + +* getTypeName +* getFunctionName +* getMethodName +* getFileName +* getLineNumber +* getColumnNumber +* isNative + +Note: Except `getFunctionName()`, all of the above methods return exactly the +same values as you would get from `stackTrace.get()`. `getFunctionName()` +is sometimes a little different, but still useful. + +### CallSite + +The official v8 CallSite object API can be found [here][v8stackapi]. A quick +excerpt: + +> A CallSite object defines the following methods: +> +> * **getThis**: returns the value of this +> * **getTypeName**: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property. +> * **getFunction**: returns the current function +> * **getFunctionName**: returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context. +> * **getMethodName**: returns the name of the property of this or one of its prototypes that holds the current function +> * **getFileName**: if this function was defined in a script returns the name of the script +> * **getLineNumber**: if this function was defined in a script returns the current line number +> * **getColumnNumber**: if this function was defined in a script returns the current column number +> * **getEvalOrigin**: if this function was created using a call to eval returns a CallSite object representing the location where eval was called +> * **isToplevel**: is this a toplevel invocation, that is, is this the global object? +> * **isEval**: does this call take place in code defined by a call to eval? +> * **isNative**: is this call in native V8 code? +> * **isConstructor**: is this a constructor call? + +[v8stackapi]: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + +## License + +stack-trace is licensed under the MIT license. diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js new file mode 100644 index 0000000..583002b --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js @@ -0,0 +1,111 @@ +exports.get = function(belowFn) { + var oldLimit = Error.stackTraceLimit; + Error.stackTraceLimit = Infinity; + + var dummyObject = {}; + + var v8Handler = Error.prepareStackTrace; + Error.prepareStackTrace = function(dummyObject, v8StackTrace) { + return v8StackTrace; + }; + Error.captureStackTrace(dummyObject, belowFn || exports.get); + + var v8StackTrace = dummyObject.stack; + Error.prepareStackTrace = v8Handler; + Error.stackTraceLimit = oldLimit; + + return v8StackTrace; +}; + +exports.parse = function(err) { + if (!err.stack) { + return []; + } + + var self = this; + var lines = err.stack.split('\n').slice(1); + + return lines + .map(function(line) { + if (line.match(/^\s*[-]{4,}$/)) { + return self._createParsedCallSite({ + fileName: line, + lineNumber: null, + functionName: null, + typeName: null, + methodName: null, + columnNumber: null, + 'native': null, + }); + } + + var lineMatch = line.match(/at (?:([^\s]+)\s+)?\(?(?:(.+?):(\d+):(\d+)|([^)]+))\)?/); + if (!lineMatch) { + return; + } + + var object = null; + var method = null; + var functionName = null; + var typeName = null; + var methodName = null; + var isNative = (lineMatch[5] === 'native'); + + if (lineMatch[1]) { + var methodMatch = lineMatch[1].match(/([^\.]+)(?:\.(.+))?/); + object = methodMatch[1]; + method = methodMatch[2]; + functionName = lineMatch[1]; + typeName = 'Object'; + } + + if (method) { + typeName = object; + methodName = method; + } + + if (method === '') { + methodName = null; + functionName = ''; + } + + var properties = { + fileName: lineMatch[2] || null, + lineNumber: parseInt(lineMatch[3], 10) || null, + functionName: functionName, + typeName: typeName, + methodName: methodName, + columnNumber: parseInt(lineMatch[4], 10) || null, + 'native': isNative, + }; + + return self._createParsedCallSite(properties); + }) + .filter(function(callSite) { + return !!callSite; + }); +}; + +exports._createParsedCallSite = function(properties) { + var methods = {}; + for (var property in properties) { + var prefix = 'get'; + if (property === 'native') { + prefix = 'is'; + } + var method = prefix + property.substr(0, 1).toUpperCase() + property.substr(1); + + (function(property) { + methods[method] = function() { + return properties[property]; + } + })(property); + } + + var callSite = Object.create(methods); + for (var property in properties) { + callSite[property] = properties[property]; + } + + return callSite; +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/package.json b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/package.json new file mode 100644 index 0000000..3b1e6fa --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/node_modules/stack-trace/package.json @@ -0,0 +1,36 @@ +{ + "author": { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com", + "url": "http://debuggable.com/" + }, + "name": "stack-trace", + "description": "Get v8 stack traces as an array of CallSite objects.", + "version": "0.0.7", + "homepage": "https://github.com/felixge/node-stack-trace", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-stack-trace.git" + }, + "main": "./lib/stack-trace", + "engines": { + "node": "*" + }, + "dependencies": {}, + "devDependencies": { + "far": "0.0.3", + "long-stack-traces": "0.1.2" + }, + "readme": "# stack-trace\n\nGet v8 stack traces as an array of CallSite objects.\n\n## Install\n\n``` bash\nnpm install stack-trace\n```\n\n## Usage\n\nThe stack-trace module makes it easy for you to capture the current stack:\n\n``` javascript\nvar stackTrace = require('stack-trace');\nvar trace = stackTrace.get();\n\nrequire('assert').strictEqual(trace[0].getFileName(), __filename);\n```\n\nHowever, sometimes you have already popped the stack you are interested in,\nand all you have left is an `Error` object. This module can help:\n\n``` javascript\nvar stackTrace = require('stack-trace');\nvar err = new Error('something went wrong');\nvar trace = stackTrace.parse(err);\n\nrequire('assert').strictEqual(trace[0].getFileName(), __filename);\n```\n\nPlease note that parsing the `Error#stack` property is not perfect, only\ncertain properties can be retrieved with it as noted in the API docs below.\n\n## Long stack traces\n\nstack-trace works great with [long-stack-traces][], when parsing an `err.stack`\nthat has crossed the event loop boundary, a `CallSite` object returning\n`'----------------------------------------'` for `getFileName()` is created.\nAll other methods of the event loop boundary call site return `null`.\n\n[long-stack-traces]: https://github.com/tlrobinson/long-stack-traces\n\n## API\n\n### stackTrace.get([belowFn])\n\nReturns an array of `CallSite` objects, where element `0` is the current call\nsite.\n\nWhen passing a function on the current stack as the `belowFn` parameter, the\nreturned array will only include `CallSite` objects below this function.\n\n### stackTrace.parse(err)\n\nParses the `err.stack` property of an `Error` object into an array compatible\nwith those returned by `stackTrace.get()`. However, only the following methods\nare implemented on the returned `CallSite` objects.\n\n* getTypeName\n* getFunctionName\n* getMethodName\n* getFileName\n* getLineNumber\n* getColumnNumber\n* isNative\n\nNote: Except `getFunctionName()`, all of the above methods return exactly the\nsame values as you would get from `stackTrace.get()`. `getFunctionName()`\nis sometimes a little different, but still useful.\n\n### CallSite\n\nThe official v8 CallSite object API can be found [here][v8stackapi]. A quick\nexcerpt:\n\n> A CallSite object defines the following methods:\n>\n> * **getThis**: returns the value of this\n> * **getTypeName**: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.\n> * **getFunction**: returns the current function\n> * **getFunctionName**: returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context.\n> * **getMethodName**: returns the name of the property of this or one of its prototypes that holds the current function\n> * **getFileName**: if this function was defined in a script returns the name of the script\n> * **getLineNumber**: if this function was defined in a script returns the current line number\n> * **getColumnNumber**: if this function was defined in a script returns the current column number\n> * **getEvalOrigin**: if this function was created using a call to eval returns a CallSite object representing the location where eval was called\n> * **isToplevel**: is this a toplevel invocation, that is, is this the global object?\n> * **isEval**: does this call take place in code defined by a call to eval?\n> * **isNative**: is this call in native V8 code?\n> * **isConstructor**: is this a constructor call?\n\n[v8stackapi]: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi\n\n## License\n\nstack-trace is licensed under the MIT license.\n", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/felixge/node-stack-trace/issues" + }, + "_id": "stack-trace@0.0.7", + "dist": { + "shasum": "c6fda71bb9f0d2906613235299fb973f94b1b0fc" + }, + "_from": "stack-trace@0.0.x", + "_resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.7.tgz", + "scripts": {} +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/package.json b/node_modules/forever/node_modules/cliff/node_modules/winston/package.json new file mode 100644 index 0000000..a38e693 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/package.json @@ -0,0 +1,54 @@ +{ + "name": "winston", + "description": "A multi-transport async logging library for Node.js", + "version": "0.6.2", + "author": { + "name": "Nodejitsu Inc.", + "email": "info@nodejitsu.com" + }, + "maintainers": [ + { + "name": "indexzero", + "email": "charlie@nodejitsu.com" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/flatiron/winston.git" + }, + "keywords": [ + "logging", + "sysadmin", + "tools" + ], + "dependencies": { + "async": "0.1.x", + "colors": "0.x.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "pkginfo": "0.2.x", + "request": "2.9.x", + "stack-trace": "0.0.x" + }, + "devDependencies": { + "vows": "0.6.x" + }, + "main": "./lib/winston", + "scripts": { + "test": "vows --spec --isolate" + }, + "engines": { + "node": ">= 0.4.0" + }, + "readme": "# winston [![Build Status](https://secure.travis-ci.org/flatiron/winston.png)](http://travis-ci.org/flatiron/winston)\n\nA multi-transport async logging library for node.js. "CHILL WINSTON! ... I put it in the logs."\n\n## Motivation\nWinston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file.\n\nThere also seemed to be a lot of logging libraries out there that coupled their implementation of logging (i.e. how the logs are stored / indexed) to the API that they exposed to the programmer. This library aims to decouple those parts of the process to make it more flexible and extensible.\n\n## Usage\nThere are two different ways to use winston: directly via the default logger, or by instantiating your own Logger. The former is merely intended to be a convenient shared logger to use throughout your application if you so choose.\n\n* [Logging](#logging)\n * [Using the Default Logger](#using-the-default-logger)\n * [Instantiating your own Logger](#instantiating-your-own-logger)\n * [Logging with Metadata](#logging-with-metadata)\n* [Transports](https://github.com/flatiron/winston/blob/master/docs/transports.md)\n* [Profiling](#profiling)\n* [Streaming Logs](#streaming-logs)\n* [Querying Logs](#querying-logs) \n* [Exceptions](#exceptions)\n * [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston)\n * [To Exit or Not to Exit](#to-exit-or-not-to-exit)\n* [Logging Levels](#logging-levels)\n * [Using Logging Levels](#using-logging-levels)\n * [Using Custom Logging Levels](#using-custom-logging-levels)\n* [Further Reading](#further-reading)\n * [Events and Callbacks in Winston](#events-and-callbacks-in-winston)\n * [Working with multiple Loggers in winston](#working-with-multiple-loggers-in-winston)\n * [Using winston in a CLI tool](#using-winston-in-a-cli-tool)\n * [Extending another object with Logging](#extending-another-object-with-logging)\n * [Adding Custom Transports](#adding-custom-transports)\n\n## Logging\n\n### Using the Default Logger\nThe default logger is accessible through the winston module directly. Any method that you could call on an instance of a logger is available on the default logger:\n\n``` js\n var winston = require('winston');\n\n winston.log('info', 'Hello distributed log files!');\n winston.info('Hello again distributed logs');\n```\n\nBy default, only the Console transport is set on the default logger. You can add or remove transports via the add() and remove() methods:\n\n``` js\n winston.add(winston.transports.File, { filename: 'somefile.log' });\n winston.remove(winston.transports.Console);\n```\n\nFor more documenation about working with each individual transport supported by Winston see the \"Working with Transports\" section below.\n\n### Instantiating your own Logger\nIf you would prefer to manage the object lifetime of loggers you are free to instantiate them yourself:\n\n``` js\n var logger = new (winston.Logger)({\n transports: [\n new (winston.transports.Console)(),\n new (winston.transports.File)({ filename: 'somefile.log' })\n ]\n });\n```\n\nYou can work with this logger in the same way that you work with the default logger:\n\n``` js\n //\n // Logging\n //\n logger.log('info', 'Hello distributed log files!');\n logger.info('Hello again distributed logs');\n\n //\n // Adding / Removing Transports\n // (Yes It's chainable)\n //\n logger.add(winston.transports.File)\n .remove(winston.transports.Console);\n```\n\n### Logging with Metadata\nIn addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple:\n\n``` js\n winston.log('info', 'Test Log Message', { anything: 'This is metadata' });\n```\n\nThe way these objects is stored varies from transport to transport (to best support the storage mechanisms offered). Here's a quick summary of how each transports handles metadata:\n\n1. __Console:__ Logged via util.inspect(meta)\n2. __File:__ Logged via util.inspect(meta)\n\n## Profiling\nIn addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger:\n\n``` js\n //\n // Start profile of 'test'\n // Remark: Consider using Date.now() with async operations\n //\n winston.profile('test');\n\n setTimeout(function () {\n //\n // Stop profile of 'test'. Logging will now take place:\n // \"17 Jan 21:00:00 - info: test duration=1000ms\"\n //\n winston.profile('test');\n }, 1000);\n```\n\nAll profile messages are set to the 'info' by default and both message and metadata are optional There are no plans in the Roadmap to make this configurable, but I'm open to suggestions / issues.\n\n\n## Querying Logs\nWinston supports querying of logs with Loggly-like options.\nSpecifically: `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`.\n\n``` js\n var options = {\n from: new Date - 24 * 60 * 60 * 1000,\n until: new Date\n };\n\n //\n // Find items logged between today and yesterday.\n //\n winston.query(options, function (err, results) {\n if (err) {\n throw err;\n }\n \n console.log(results);\n });\n```\n\n## Streaming Logs\nStreaming allows you to stream your logs back from your chosen transport.\n\n``` js\n //\n // Start at the end.\n //\n winston.stream({ start: -1 }).on('log', function(log) {\n console.log(log);\n });\n```\n\n## Exceptions\n\n### Handling Uncaught Exceptions with winston\n\nWith `winston`, it is possible to catch and log `uncaughtException` events from your process. There are two distinct ways of enabling this functionality either through the default winston logger or your own logger instance.\n\nIf you want to use this feature with the default logger simply call `.handleExceptions()` with a transport instance.\n\n``` js\n //\n // You can add a separate exception logger by passing it to `.handleExceptions`\n //\n winston.handleExceptions(new winston.transports.File({ filename: 'path/to/exceptions.log' }))\n\n //\n // Alternatively you can set `.handleExceptions` to true when adding transports to winston\n //\n winston.add(winston.transports.File, {\n filename: 'path/to/all-logs.log',\n handleExceptions: true\n });\n```\n\n### To Exit or Not to Exit\n\nby default, winston will exit after logging an uncaughtException. if this is not the behavior you want,\nset `exitOnError = false`\n\n``` js\n var logger = new (winston.Logger)({ exitOnError: false });\n\n //\n // or, like this:\n //\n logger.exitOnError = false;\n```\n\nWhen working with custom logger instances, you can pass in separate transports to the `exceptionHandlers` property or set `.handleExceptions` on any transport.\n\nExample 1\n\n``` js\n var logger = new (winston.Logger)({\n transports: [\n new winston.transports.File({ filename: 'path/to/all-logs.log' })\n ]\n exceptionHandlers: [\n new winston.transports.File({ filename: 'path/to/exceptions.log' })\n ]\n });\n```\n\nExample 2\n\n```\nvar logger = new winston.Logger({\n transports: [\n new winston.transports.Console({\n handleExceptions: true,\n json: true\n })\n ],\n exitOnError: false\n});\n```\n\nThe `exitOnError` option can also be a function to prevent exit on only certain types of errors:\n\n``` js\n function ignoreEpipe(err) {\n return err.code !== 'EPIPE';\n }\n\n var logger = new (winston.Logger)({ exitOnError: ignoreEpipe });\n\n //\n // or, like this:\n //\n logger.exitOnError = ignoreEpipe;\n```\n\n## Logging Levels\n\n### Using Logging Levels\nSetting the level for your logging message can be accomplished in one of two ways. You can pass a string representing the logging level to the log() method or use the level specified methods defined on every winston Logger.\n\n``` js\n //\n // Any logger instance\n //\n logger.log('info', \"127.0.0.1 - there's no place like home\");\n logger.log('warn', \"127.0.0.1 - there's no place like home\");\n logger.log('error', \"127.0.0.1 - there's no place like home\");\n logger.info(\"127.0.0.1 - there's no place like home\");\n logger.warn(\"127.0.0.1 - there's no place like home\");\n logger.error(\"127.0.0.1 - there's no place like home\");\n\n //\n // Default logger\n //\n winston.log('info', \"127.0.0.1 - there's no place like home\");\n winston.info(\"127.0.0.1 - there's no place like home\");\n```\n\nWinston allows you to set a `level` on each transport that specifies the level of messages this transport should log. For example, you could log only errors to the console, with the full logs in a file:\n\n``` js\n var logger = new (winston.Logger)({\n transports: [\n new (winston.transports.Console)({ level: 'error' }),\n new (winston.transports.File)({ filename: 'somefile.log' })\n ]\n });\n```\n\nAs of 0.2.0, winston supports customizable logging levels, defaulting to [npm][0] style logging levels. Changing logging levels is easy:\n\n``` js\n //\n // Change levels on the default winston logger\n //\n winston.setLevels(winston.config.syslog.levels);\n\n //\n // Change levels on an instance of a logger\n //\n logger.setLevels(winston.config.syslog.levels);\n```\n\nCalling `.setLevels` on a logger will remove all of the previous helper methods for the old levels and define helper methods for the new levels. Thus, you should be careful about the logging statements you use when changing levels. For example, if you ran this code after changing to the syslog levels:\n\n``` js\n //\n // Logger does not have 'silly' defined since that level is not in the syslog levels\n //\n logger.silly('some silly message');\n```\n\n### Using Custom Logging Levels\nIn addition to the predefined `npm` and `syslog` levels available in Winston, you can also choose to define your own:\n\n``` js\n var myCustomLevels = {\n levels: {\n foo: 0,\n bar: 1,\n baz: 2,\n foobar: 3\n },\n colors: {\n foo: 'blue',\n bar: 'green',\n baz: 'yellow',\n foobar: 'red'\n }\n };\n\n var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels });\n customLevelLogger.foobar('some foobar level-ed message');\n```\n\nAlthough there is slight repetition in this data structure, it enables simple encapsulation if you not to have colors. If you do wish to have colors, in addition to passing the levels to the Logger itself, you must make winston aware of them:\n\n``` js\n //\n // Make winston aware of these colors\n //\n winston.addColors(myCustomLevels.colors);\n```\n\nThis enables transports with the 'colorize' option set to appropriately color the output of custom levels.\n\n## Further Reading\n\n### Events and Callbacks in Winston\nEach instance of winston.Logger is also an instance of an [EventEmitter][1]. A log event will be raised each time a transport successfully logs a message:\n\n``` js\n logger.on('logging', function (transport, level, msg, meta) {\n // [msg] and [meta] have now been logged at [level] to [transport]\n });\n\n logger.info('CHILL WINSTON!', { seriously: true });\n```\n\nIt is also worth mentioning that the logger also emits an 'error' event which you should handle or suppress if you don't want unhandled exceptions:\n\n``` js\n //\n // Handle errors\n //\n logger.on('error', function (err) { /* Do Something */ });\n\n //\n // Or just suppress them.\n //\n logger.emitErrs = false;\n```\n\nEvery logging method described in the previous section also takes an optional callback which will be called only when all of the transports have logged the specified message.\n\n``` js\n logger.info('CHILL WINSTON!', { seriously: true }, function (err, level, msg, meta) {\n // [msg] and [meta] have now been logged at [level] to **every** transport.\n });\n```\n\n### Working with multiple Loggers in winston\n\nOften in larger, more complex applications it is necessary to have multiple logger instances with different settings. Each logger is responsible for a different feature area (or category). This is exposed in `winston` in two ways: through `winston.loggers` and instances of `winston.Container`. In fact, `winston.loggers` is just a predefined instance of `winston.Container`:\n\n``` js\n var winston = require('winston');\n\n //\n // Configure the logger for `category1`\n //\n winston.loggers.add('category1', {\n console: {\n level: 'silly',\n colorize: 'true'\n },\n file: {\n filename: '/path/to/some/file'\n }\n });\n\n //\n // Configure the logger for `category2`\n //\n winston.loggers.add('category2', {\n couchdb: {\n host: '127.0.0.1',\n port: 5984\n }\n });\n```\n\nNow that your loggers are setup you can require winston _in any file in your application_ and access these pre-configured loggers:\n\n``` js\n var winston = require('winston');\n\n //\n // Grab your preconfigured logger\n //\n var category1 = winston.loggers.get('category1');\n\n category1.info('logging from your IoC container-based logger');\n```\n\nIf you prefer to manage the `Container` yourself you can simply instantiate one:\n\n``` js\n var winston = require('winston'),\n container = new winston.Container();\n\n container.add('category1', {\n console: {\n level: 'silly',\n colorize: 'true'\n },\n file: {\n filename: '/path/to/some/file'\n }\n });\n```\n\n### Sharing transports between Loggers in winston\n\n``` js\n var winston = require('winston');\n\n //\n // Setup transports to be shared across all loggers\n // in three ways:\n //\n // 1. By setting it on the default Container\n // 2. By passing `transports` into the constructor function of winston.Container\n // 3. By passing `transports` into the `.get()` or `.add()` methods\n //\n\n //\n // 1. By setting it on the default Container\n //\n winston.loggers.options.transports = [\n // Setup your shared transports here\n ];\n\n //\n // 2. By passing `transports` into the constructor function of winston.Container\n //\n var container = new winston.Container({\n transports: [\n // Setup your shared transports here\n ]\n });\n\n //\n // 3. By passing `transports` into the `.get()` or `.add()` methods\n //\n winston.loggers.add('some-category', {\n transports: [\n // Setup your shared transports here\n ]\n });\n\n container.add('some-category', {\n transports: [\n // Setup your shared transports here\n ]\n });\n```\n\n### Using winston in a CLI tool\nA common use-case for logging is output to a CLI tool. Winston has a special helper method which will pretty print output from your CLI tool. Here's an example from the [require-analyzer][2] written by [Nodejitsu][3]:\n\n```\n info: require-analyzer starting in /Users/Charlie/Nodejitsu/require-analyzer\n info: Found existing dependencies\n data: {\n data: colors: '0.x.x',\n data: eyes: '0.1.x',\n data: findit: '0.0.x',\n data: npm: '1.0.x',\n data: optimist: '0.2.x',\n data: semver: '1.0.x',\n data: winston: '0.2.x'\n data: }\n info: Analyzing dependencies...\n info: Done analyzing raw dependencies\n info: Retrieved packages from npm\n warn: No additional dependencies found\n```\n\nConfiguring output for this style is easy, just use the `.cli()` method on `winston` or an instance of `winston.Logger`:\n\n``` js\n var winston = require('winston');\n\n //\n // Configure CLI output on the default logger\n //\n winston.cli();\n\n //\n // Configure CLI on an instance of winston.Logger\n //\n var logger = new winston.Logger({\n transports: [\n new (winston.transports.Console)()\n ]\n });\n\n logger.cli();\n```\n\n### Extending another object with Logging\nOften in a given code base with lots of Loggers it is useful to add logging methods a different object so that these methods can be called with less syntax. Winston exposes this functionality via the 'extend' method:\n\n``` js\n var myObject = {};\n\n logger.extend(myObject);\n\n //\n // You can now call logger methods on 'myObject'\n //\n myObject.info('127.0.0.1 - there's no place like home');\n```\n\n## Working with Transports\nRight now there are four transports supported by winston core. If you have a transport you would like to add either open an issue or fork and submit a pull request. Commits are welcome, but I'll give you extra street cred if you __add tests too :D__\n \n1. __Console:__ Output to the terminal\n2. __Files:__ Append to a file\n3. __Loggly:__ Log to Logging-as-a-Service platform Loggly\n\n### Console Transport\n``` js\n winston.add(winston.transports.Console, options)\n```\n\nThe Console transport takes two simple options:\n\n* __level:__ Level of messages that this transport should log (default 'info').\n* __silent:__ Boolean flag indicating whether to suppress output (default false).\n* __colorize:__ Boolean flag indicating if we should colorize output (default false).\n* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps.\n\n*Metadata:* Logged via util.inspect(meta);\n\n### File Transport\n``` js\n winston.add(winston.transports.File, options)\n```\n\nThe File transport should really be the 'Stream' transport since it will accept any [WritableStream][14]. It is named such because it will also accept filenames via the 'filename' option:\n\n* __level:__ Level of messages that this transport should log.\n* __silent:__ Boolean flag indicating whether to suppress output.\n* __colorize:__ Boolean flag indicating if we should colorize output.\n* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default true). If function is specified, its return value will be used instead of timestamps.\n* __filename:__ The filename of the logfile to write output to.\n* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created.\n* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded.\n* __stream:__ The WriteableStream to write output to.\n* __json:__ If true, messages will be logged as JSON (default true).\n\n*Metadata:* Logged via util.inspect(meta);\n\n### Loggly Transport\n``` js\n var Loggly = require('winston-loggly').Loggly\n winston.add(Loggly, options);\n```\n\nThe Loggly transport is based on [Nodejitsu's][5] [node-loggly][6] implementation of the [Loggly][7] API. If you haven't heard of Loggly before, you should probably read their [value proposition][8]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required:\n\n* __level:__ Level of messages that this transport should log. \n* __subdomain:__ The subdomain of your Loggly account. *[required]*\n* __auth__: The authentication information for your Loggly account. *[required with inputName]*\n* __inputName:__ The name of the input this instance should log to.\n* __inputToken:__ The input token of the input this instance should log to.\n* __json:__ If true, messages will be sent to Loggly as JSON.\n\n*Metadata:* Logged in suggested [Loggly format][2]\n\n### Riak Transport\nAs of `0.3.0` the Riak transport has been broken out into a new module: [winston-riak][17]. Using it is just as easy:\n\n``` js\n var Riak = require('winston-riak').Riak;\n winston.add(Riak, options);\n```\n\nIn addition to the options accepted by the [riak-js][3] [client][4], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default:\n\n* __level:__ Level of messages that this transport should log.\n* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically.\n\n``` js\n // Use a single bucket for all your logs\n var singleBucketTransport = new (Riak)({ bucket: 'some-logs-go-here' });\n \n // Generate a dynamic bucket based on the date and level\n var dynamicBucketTransport = new (Riak)({\n bucket: function (level, msg, meta, now) {\n var d = new Date(now);\n return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-');\n }\n });\n```\n\n*Metadata:* Logged as JSON literal in Riak\n\n### MongoDB Transport\nAs of `0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][16]. Using it is just as easy:\n\n``` js\n var MongoDB = require('winston-mongodb').MongoDB;\n winston.add(MongoDB, options);\n```\n\nThe MongoDB transport takes the following options. 'db' is required:\n\n* __level:__ Level of messages that this transport should log. \n* __silent:__ Boolean flag indicating whether to suppress output.\n* __db:__ The name of the database you want to log to. *[required]*\n* __collection__: The name of the collection you want to store log messages in, defaults to 'log'.\n* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true.\n* __host:__ The host running MongoDB, defaults to localhost.\n* __port:__ The port on the host that MongoDB is running on, defaults to MongoDB's default port.\n\n*Metadata:* Logged as a native JSON object.\n\n### SimpleDB Transport\n\nThe [winston-simpledb][18] transport is just as easy:\n\n``` js\n var SimpleDB = require('winston-simpledb').SimpleDB;\n winston.add(SimpleDB, options);\n```\n\nThe SimpleDB transport takes the following options. All items marked with an asterisk are required:\n\n* __awsAccessKey__:* your AWS Access Key\n* __secretAccessKey__:* your AWS Secret Access Key\n* __awsAccountId__:* your AWS Account Id\n* __domainName__:* a string or function that returns the domain name to log to\n* __region__:* the region your domain resides in\n* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log\n\n*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item.\n\n### Mail Transport\n\nThe [winston-mail][19] is an email transport:\n\n``` js\n var Mail = require('winston-mail').Mail;\n winston.add(Mail, options);\n```\n\nThe Mail transport uses [emailjs](https://github.com/eleith/emailjs) behind the scenes. Options are the following:\n\n* __to:__ The address(es) you want to send to. *[required]*\n* __from:__ The address you want to send from. (default: `winston@[server-host-name]`)\n* __host:__ SMTP server hostname (default: localhost)\n* __port:__ SMTP port (default: 587 or 25)\n* __username__ User for server auth\n* __password__ Password for server auth\n* __ssl:__ Use SSL (boolean or object { key, ca, cert })\n* __tls:__ Boolean (if true, use starttls)\n* __level:__ Level of messages that this transport should log. \n* __silent:__ Boolean flag indicating whether to suppress output.\n\n*Metadata:* Stringified as JSON in email.\n\n### Amazon SNS (Simple Notification System) Transport\n\nThe [winston-sns][21] transport uses amazon SNS to send emails, texts, or a bunch of other notifications.\n\n``` js\n require('winston-sns').SNS;\n winston.add(winston.transports.SNS, options);\n```\n\nOptions:\n\n* __aws_key:__ Your Amazon Web Services Key. *[required]*\n* __aws_secret:__ Your Amazon Web Services Secret. *[required]*\n* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]*\n* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]*\n* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`)\n* __subject:__ Subject for notifications. (default: \"Winston Error Report\")\n* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: \"Level '%l' Error:\\n%e\\n\\nMetadata:\\n%m\")\n* __level:__ lowest level this transport will log. (default: `info`)\n\n### Graylog2 Transport\n\n[winston-graylog2][22] is a Graylog2 transport:\n\n``` js\n var Graylog2 = require('winston-graylog2').Graylog2;\n winston.add(Graylog2, options);\n```\n\nThe Graylog2 transport connects to a Graylog2 server over UDP using the following options:\n\n* __level:__ Level of messages this transport should log. (default: info)\n* __silent:__ Boolean flag indicating whether to suppress output. (default: false)\n\n* __graylogHost:__ IP address or hostname of the graylog2 server. (default: localhost)\n* __graylogPort:__ Port to send messages to on the graylog2 server. (default: 12201)\n* __graylogHostname:__ The hostname associated with graylog2 messages. (default: require('os').hostname())\n* __graylogFacility:__ The graylog2 facility to send log messages.. (default: nodejs)\n\n*Metadata:* Stringified as JSON in the full message GELF field.\n\n### Adding Custom Transports\nAdding a custom transport (say for one of the datastore on the Roadmap) is actually pretty easy. All you need to do is accept a couple of options, set a name, implement a log() method, and add it to the set of transports exposed by winston.\n\n``` js\n var util = require('util'),\n winston = require('winston');\n\n var CustomLogger = winston.transports.CustomerLogger = function (options) {\n //\n // Name this logger\n //\n this.name = 'customLogger';\n\n //\n // Set the level from your options\n //\n this.level = options.level || 'info';\n\n //\n // Configure your storage backing as you see fit\n //\n };\n\n //\n // Inherit from `winston.Transport` so you can take advantage\n // of the base functionality and `.handleExceptions()`.\n //\n util.inherits(CustomLogger, winston.Transport);\n\n CustomLogger.prototype.log = function (level, msg, meta, callback) {\n //\n // Store this message and metadata, maybe use some custom logic\n // then callback indicating success.\n //\n callback(null, true);\n };\n```\n\n### Inspirations\n1. [npm][0]\n2. [log.js][4]\n3. [socket.io][5]\n4. [node-rlog][6]\n5. [BigBrother][7]\n6. [Loggly][8]\n\n## Installation\n\n### Installing npm (node package manager)\n```\n curl http://npmjs.org/install.sh | sh\n```\n\n### Installing winston\n```\n [sudo] npm install winston\n```\n\n## Run Tests\nAll of the winston tests are written in [vows][9], and designed to be run with npm. \n\n``` bash\n $ npm test\n```\n\n#### Author: [Charlie Robbins](http://twitter.com/indexzero)\n#### Contributors: [Matthew Bergman](http://github.com/fotoverite), [Marak Squires](http://github.com/marak)\n\n[0]: https://github.com/isaacs/npm/blob/master/lib/utils/log.js\n[1]: http://nodejs.org/docs/v0.3.5/api/events.html#events.EventEmitter\n[2]: http://github.com/nodejitsu/require-analyzer\n[3]: http://nodejitsu.com\n[4]: https://github.com/visionmedia/log.js\n[5]: http://socket.io\n[6]: https://github.com/jbrisbin/node-rlog\n[7]: https://github.com/feisty/BigBrother\n[8]: http://loggly.com\n[9]: http://vowsjs.org\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/flatiron/winston/issues" + }, + "_id": "winston@0.6.2", + "dist": { + "shasum": "e54f5c026ccc82d252686e35d7630bea289fc23b" + }, + "_from": "winston@0.6.x", + "_resolved": "https://registry.npmjs.org/winston/-/winston-0.6.2.tgz" +} diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/cli-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/cli-test.js new file mode 100644 index 0000000..365fba3 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/cli-test.js @@ -0,0 +1,40 @@ +/* + * cli-test.js: Tests for the cli levels available in winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston/logger/cli').addBatch({ + "When an instance of winston.Logger": { + topic: function () { + return new winston.Logger({ + transports: [ + new winston.transports.Console() + ] + }) + }, + "the cli() method": { + "should set the appropriate values on the logger": function (logger) { + logger.cli(); + assert.isTrue(logger.padLevels); + assert.isTrue(logger.transports.console.colorize); + assert.isFalse(logger.transports.console.timestamp); + Object.keys(winston.config.cli.levels).forEach(function (level) { + assert.isNumber(logger.levels[level]); + }); + + Object.keys(winston.config.cli.colors).forEach(function (color) { + assert.isString(winston.config.allColors[color]); + }); + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/container-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/container-test.js new file mode 100644 index 0000000..2fcc26a --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/container-test.js @@ -0,0 +1,99 @@ +/* + * container-test.js: Tests for the Container object + * + * (C) 2011 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + http = require('http'), + path = require('path'), + vows = require('vows'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston/container').addBatch({ + "An instance of winston.Container": { + topic: new winston.Container(), + "the add() method": { + topic: function (container) { + return container.add('default-test'); + }, + "should correctly instantiate a Logger": function (logger) { + assert.instanceOf(logger, winston.Logger); + }, + "the get() method": { + topic: function (logger, container) { + this.callback.apply(this, arguments); + }, + "should respond with the logger previously created": function (existing, container) { + var logger = container.get('default-test'); + assert.isTrue(existing === logger); + } + }, + "the has() method": { + topic: function (logger, container) { + this.callback.apply(this, arguments); + }, + "should indicate `default-test` logger exists": function (existing, container) { + assert.isTrue(container.has('default-test')); + }, + "should indicate `not-has` logger doesnt exists": function (existing, container) { + assert.isFalse(container.has('not-has')); + } + }, + "the close() method": { + topic: function (logger, container) { + this.callback.apply(this, arguments); + }, + "should remove the specified logger": function (logger, container) { + container.close('default-test'); + assert.isTrue(!container.loggers['default-test']); + } + } + } + }, + "An instance of winston.Container with explicit transports": { + topic: function () { + this.port = 9412; + this.transports = [ + new winston.transports.Webhook({ + port: this.port + }) + ]; + + this.container = new winston.Container({ + transports: this.transports + }); + + return null; + }, + "the get() method": { + topic: function (container) { + var server = http.createServer(function (req, res) { + res.end(); + }); + + server.listen(this.port, this.callback.bind(this, null)); + }, + "should add the logger correctly": function () { + this.someLogger = this.container.get('some-logger'); + assert.isObject(this.someLogger.transports); + assert.instanceOf(this.someLogger.transports['webhook'], winston.transports.Webhook); + assert.strictEqual(this.someLogger.transports['webhook'], this.transports[0]); + }, + "a second call to get()": { + "should respond with the same transport object": function () { + this.someOtherLogger = this.container.get('some-other-logger'); + + assert.isObject(this.someOtherLogger.transports); + assert.instanceOf(this.someOtherLogger.transports['webhook'], winston.transports.Webhook); + assert.strictEqual(this.someOtherLogger.transports['webhook'], this.transports[0]); + assert.strictEqual(this.someOtherLogger.transports['webhook'], this.someLogger.transports['webhook']); + } + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/custom-timestamp-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/custom-timestamp-test.js new file mode 100644 index 0000000..efdc40f --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/custom-timestamp-test.js @@ -0,0 +1,62 @@ +/* + * custom-timestamp-test.js: Test function as timestamp option for transport `{ timestamp: function () {} }` + * + * (C) 2011 Charlie Robbins, Tom Shinnick + * MIT LICENSE + * + */ + +var assert = require('assert'), + events = require('events'), + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +function assertTimestamp (basename, options) { + var filename = path.join(__dirname, 'fixtures', 'logs', basename + '.log'); + + try { fs.unlinkSync(filename) } + catch (ex) { } + + return { + topic: function () { + options.filename = filename; + var transport = new (winston.transports.File)(options); + + // We must wait until transport file has emitted the 'flush' + // event to be sure the file has been created and written + transport.once('flush', this.callback.bind(this, null, filename)); + transport.log('info', 'When a fake tree falls in the forest...', null, function () {}); + }, + "should log with the appropriate timestamp": function (_, filename) { + var data = fs.readFileSync(filename, 'utf8'); + assert.isNotNull(data.match(options.pattern)); + } + } +} + +vows.describe('winston/transport/timestamp').addBatch({ + "When timestamp option is used": { + "with file transport": { + "with value set to false": assertTimestamp('noTimestamp', { + pattern: /^info\:/, + json: false, + timestamp: false + }), + "with value set to true ": assertTimestamp('defaultTimestamp', { + pattern: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/, + json: false, + timestamp: true + }), + "and function value": assertTimestamp('customTimestamp', { + pattern: /^\d{8}\./, + json: false, + timestamp: function () { + return '20110803.171657'; + } + }) + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/exception-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/exception-test.js new file mode 100644 index 0000000..3c3178e --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/exception-test.js @@ -0,0 +1,47 @@ +/* + * exception-test.js: Tests for exception data gathering in winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston/exception').addBatch({ + "When using the winston exception module": { + "the getProcessInfo() method": { + topic: winston.exception.getProcessInfo(), + "should respond with the appropriate data": function (info) { + helpers.assertProcessInfo(info); + } + }, + "the getOsInfo() method": { + topic: winston.exception.getOsInfo(), + "should respond with the appropriate data": function (info) { + helpers.assertOsInfo(info); + } + }, + "the getTrace() method": { + topic: winston.exception.getTrace(new Error()), + "should have the appropriate info": function (trace) { + helpers.assertTrace(trace); + } + }, + "the getAllInfo() method": { + topic: winston.exception.getAllInfo(new Error()), + "should have the appropriate info": function (info) { + assert.isObject(info); + assert.isArray(info.stack); + helpers.assertDateInfo(info.date); + helpers.assertProcessInfo(info.process); + helpers.assertOsInfo(info.os); + helpers.assertTrace(info.trace); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/.gitkeep b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/keys/agent2-cert.pem b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/keys/agent2-cert.pem new file mode 100644 index 0000000..8e4354d --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/keys/agent2-cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB7DCCAZYCCQC7gs0MDNn6MTANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJV +UzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZKb3llbnQxEDAO +BgNVBAsTB05vZGUuanMxDzANBgNVBAMTBmFnZW50MjEgMB4GCSqGSIb3DQEJARYR +cnlAdGlueWNsb3Vkcy5vcmcwHhcNMTEwMzE0MTgyOTEyWhcNMzgwNzI5MTgyOTEy +WjB9MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYD +VQQKEwZKb3llbnQxEDAOBgNVBAsTB05vZGUuanMxDzANBgNVBAMTBmFnZW50MjEg +MB4GCSqGSIb3DQEJARYRcnlAdGlueWNsb3Vkcy5vcmcwXDANBgkqhkiG9w0BAQEF +AANLADBIAkEAyXb8FrRdKbhrKLgLSsn61i1C7w7fVVVd7OQsmV/7p9WB2lWFiDlC +WKGU9SiIz/A6wNZDUAuc2E+VwtpCT561AQIDAQABMA0GCSqGSIb3DQEBBQUAA0EA +C8HzpuNhFLCI3A5KkBS5zHAQax6TFUOhbpBCR0aTDbJ6F1liDTK1lmU/BjvPoj+9 +1LHwrmh29rK8kBPEjmymCQ== +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/keys/agent2-key.pem b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/keys/agent2-key.pem new file mode 100644 index 0000000..522903c --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/keys/agent2-key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOgIBAAJBAMl2/Ba0XSm4ayi4C0rJ+tYtQu8O31VVXezkLJlf+6fVgdpVhYg5 +QlihlPUoiM/wOsDWQ1ALnNhPlcLaQk+etQECAwEAAQJBAMT6Bf34+UHKY1ObpsbH +9u2jsVblFq1rWvs8GPMY6oertzvwm3DpuSUp7PTgOB1nLTLYtCERbQ4ovtN8tn3p +OHUCIQDzIEGsoCr5vlxXvy2zJwu+fxYuhTZWMVuo1397L0VyhwIhANQh+yzqUgaf +WRtSB4T2W7ADtJI35ET61jKBty3CqJY3AiAIwju7dVW3A5WeD6Qc1SZGKZvp9yCb +AFI2BfVwwaY11wIgXF3PeGcvACMyMWsuSv7aPXHfliswAbkWuzcwA4TW01ECIGWa +cgsDvVFxmfM5NPSuT/UDTa6R5BFISB5ea0N0AR3I +-----END RSA PRIVATE KEY----- diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/logs/.gitkeep b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/default-exceptions.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/default-exceptions.js new file mode 100644 index 0000000..ab26aa5 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/default-exceptions.js @@ -0,0 +1,21 @@ +/* + * default-exceptions.js: A test fixture for logging exceptions with the default winston logger. + * + * (C) 2011 Charlie Robbins + * MIT LICENCE + * + */ + +var path = require('path'), + winston = require('../../../lib/winston'); + +winston.handleExceptions([ + new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'logs', 'default-exception.log'), + handleExceptions: true + }) +]); + +setTimeout(function () { + throw new Error('OH NOES! It failed!'); +}, 1000); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/exit-on-error.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/exit-on-error.js new file mode 100644 index 0000000..fa3dd65 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/exit-on-error.js @@ -0,0 +1,25 @@ +/* + * default-exceptions.js: A test fixture for logging exceptions with the default winston logger. + * + * (C) 2011 Charlie Robbins + * MIT LICENCE + * + */ + +var path = require('path'), + winston = require('../../../lib/winston'); + +winston.exitOnError = function (err) { + return err.message !== 'Ignore this error'; +}; + +winston.handleExceptions([ + new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'logs', 'exit-on-error.log'), + handleExceptions: true + }) +]); + +setTimeout(function () { + throw new Error('Ignore this error'); +}, 1000); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/log-exceptions.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/log-exceptions.js new file mode 100644 index 0000000..43ce7eb --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/log-exceptions.js @@ -0,0 +1,25 @@ +/* + * log-exceptions.js: A test fixture for logging exceptions in winston. + * + * (C) 2011 Charlie Robbins + * MIT LICENCE + * + */ + +var path = require('path'), + winston = require('../../../lib/winston'); + +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'logs', 'exception.log'), + handleExceptions: true + }) + ] +}); + +logger.handleExceptions(); + +setTimeout(function () { + throw new Error('OH NOES! It failed!'); +}, 1000); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js new file mode 100644 index 0000000..5d722a7 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js @@ -0,0 +1,26 @@ +/* + * unhandle-exceptions.js: A test fixture for using `.unhandleExceptions()` winston. + * + * (C) 2011 Charlie Robbins + * MIT LICENCE + * + */ + +var path = require('path'), + winston = require('../../../lib/winston'); + +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'logs', 'unhandle-exception.log'), + handleExceptions: true + }) + ] +}); + +logger.handleExceptions(); +logger.unhandleExceptions(); + +setTimeout(function () { + throw new Error('OH NOES! It failed!'); +}, 1000); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/helpers.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/helpers.js new file mode 100644 index 0000000..2564f79 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/helpers.js @@ -0,0 +1,173 @@ +/* + * helpers.js: Test helpers for winston + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + spawn = require('child_process').spawn, + util = require('util'), + vows = require('vows'), + winston = require('../lib/winston'); + +var helpers = exports; + +helpers.size = function (obj) { + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + size++; + } + } + + return size; +}; + +helpers.tryUnlink = function (file) { + try { fs.unlinkSync(file) } + catch (ex) { } +}; + +helpers.assertDateInfo = function (info) { + assert.isNumber(Date.parse(info)); +}; + +helpers.assertProcessInfo = function (info) { + assert.isNumber(info.pid); + assert.isNumber(info.uid); + assert.isNumber(info.gid); + assert.isString(info.cwd); + assert.isString(info.execPath); + assert.isString(info.version); + assert.isArray(info.argv); + assert.isObject(info.memoryUsage); +}; + +helpers.assertOsInfo = function (info) { + assert.isArray(info.loadavg); + assert.isNumber(info.uptime); +}; + +helpers.assertTrace = function (trace) { + trace.forEach(function (site) { + assert.isTrue(!site.column || typeof site.column === 'number'); + assert.isTrue(!site.line || typeof site.line === 'number'); + assert.isTrue(!site.file || typeof site.file === 'string'); + assert.isTrue(!site.method || typeof site.method === 'string'); + assert.isTrue(!site.function || typeof site.function === 'string'); + assert.isTrue(typeof site.native === 'boolean'); + }); +}; + +helpers.assertLogger = function (logger, level) { + assert.instanceOf(logger, winston.Logger); + assert.isFunction(logger.log); + assert.isFunction(logger.add); + assert.isFunction(logger.remove); + assert.equal(logger.level, level || "info"); + Object.keys(logger.levels).forEach(function (method) { + assert.isFunction(logger[method]); + }); +}; + +helpers.assertConsole = function (transport) { + assert.instanceOf(transport, winston.transports.Console); + assert.isFunction(transport.log); +}; + +helpers.assertFile = function (transport) { + assert.instanceOf(transport, winston.transports.File); + assert.isFunction(transport.log); +} + +helpers.assertWebhook = function (transport) { + assert.instanceOf(transport, winston.transports.Webhook); + assert.isFunction(transport.log); +}; + +helpers.assertCouchdb = function (transport) { + assert.instanceOf(transport, winston.transports.Couchdb); + assert.isFunction(transport.log); +}; + +helpers.assertHandleExceptions = function (options) { + return { + topic: function () { + var that = this, + child = spawn('node', [options.script]); + + helpers.tryUnlink(options.logfile); + child.on('exit', function () { + fs.readFile(options.logfile, that.callback); + }); + }, + "should save the error information to the specified file": function (err, data) { + assert.isTrue(!err); + data = JSON.parse(data); + + assert.isObject(data); + helpers.assertProcessInfo(data.process); + helpers.assertOsInfo(data.os); + helpers.assertTrace(data.trace); + } + } +} + +helpers.testNpmLevels = function (transport, assertMsg, assertFn) { + return helpers.testLevels(winston.config.npm.levels, transport, assertMsg, assertFn); +}; + +helpers.testSyslogLevels = function (transport, assertMsg, assertFn) { + return helpers.testLevels(winston.config.syslog.levels, transport, assertMsg, assertFn); +}; + +helpers.testLevels = function (levels, transport, assertMsg, assertFn) { + var tests = {}; + + Object.keys(levels).forEach(function (level) { + var test = { + topic: function () { + transport.log(level, 'test message', {}, this.callback.bind(this, null)); + } + }; + + test[assertMsg] = assertFn; + tests['with the ' + level + ' level'] = test; + }); + + var metadatatest = { + topic: function () { + transport.log('info', 'test message', { metadata: true }, this.callback.bind(this, null)); + } + }; + + metadatatest[assertMsg] = assertFn; + tests['when passed metadata'] = metadatatest; + + var primmetadatatest = { + topic: function () { + transport.log('info', 'test message', 'metadata', this.callback.bind(this, null)); + } + }; + + primmetadatatest[assertMsg] = assertFn; + tests['when passed primitive metadata'] = primmetadatatest; + + var circmetadata = { }; + circmetadata['metadata'] = circmetadata; + + var circmetadatatest = { + topic: function () { + transport.log('info', 'test message', circmetadata, this.callback.bind(this, null)); + } + }; + + circmetadatatest[assertMsg] = assertFn; + tests['when passed circular metadata'] = circmetadatatest; + + return tests; +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/log-exception-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/log-exception-test.js new file mode 100644 index 0000000..164dcdf --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/log-exception-test.js @@ -0,0 +1,60 @@ +/* + * exception-test.js: Tests for exception data gathering in winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + path = require('path'), + fs = require('fs'), + spawn = require('child_process').spawn, + vows = require('vows'), + winston = require('../lib/winston'), + helpers = require('./helpers'), + exists = (fs.exists || path.exists); + +vows.describe('winston/logger/exceptions').addBatch({ + "When using winston": { + "the handleException() method": { + "with a custom winston.Logger instance": helpers.assertHandleExceptions({ + script: path.join(__dirname, 'fixtures', 'scripts', 'log-exceptions.js'), + logfile: path.join(__dirname, 'fixtures', 'logs', 'exception.log') + }), + "with the default winston logger": helpers.assertHandleExceptions({ + script: path.join(__dirname, 'fixtures', 'scripts', 'default-exceptions.js'), + logfile: path.join(__dirname, 'fixtures', 'logs', 'default-exception.log') + }), + "when a custom exitOnError function is set": { + topic: function () { + var that = this, + scriptDir = path.join(__dirname, 'fixtures', 'scripts'); + + that.child = spawn('node', [path.join(scriptDir, 'exit-on-error.js')]); + setTimeout(this.callback.bind(this), 1500); + }, + "should not exit the process": function () { + assert.isFalse(this.child.killed); + this.child.kill(); + } + } + }, + "the unhandleException() method": { + topic: function () { + var that = this, + child = spawn('node', [path.join(__dirname, 'fixtures', 'scripts', 'unhandle-exceptions.js')]), + exception = path.join(__dirname, 'fixtures', 'logs', 'unhandle-exception.log'); + + helpers.tryUnlink(exception); + child.on('exit', function () { + exists(exception, that.callback.bind(this, null)); + }); + }, + "should not write to the specified error file": function (err, exists) { + assert.isTrue(!err); + assert.isFalse(exists); + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/log-rewriter-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/log-rewriter-test.js new file mode 100644 index 0000000..f1deeba --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/log-rewriter-test.js @@ -0,0 +1,98 @@ +/* + * log-rewriter-test.js: Tests for rewriting metadata in winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston/logger/rewriter').addBatch({ + "An instance of winston.Logger": { + topic: new (winston.Logger)({transports: [ + new (winston.transports.Console)({ level: 'info' }) + ]}), + "the addRewriter() method": { + topic: function (logger) { + logger.addRewriter(function (level, msg, meta) { + meta.level = level; + meta.msg = msg; + meta.foo = 'bar'; + return meta; + }); + return logger; + }, + "should add the rewriter": function (logger) { + assert.equal(helpers.size(logger.rewriters), 1); + }, + "the log() method": { + topic: function (logger) { + logger.once('logging', this.callback); + logger.log('info', 'test message', {"a": "b"}); + }, + "should run the rewriter": function (transport, level, msg, meta) { + assert.equal(meta.a, 'b'); + assert.equal(meta.level, 'info'); + assert.equal(meta.msg, 'test message'); + assert.equal(meta.foo, 'bar'); + } + } + } + } +}).addBatch({ + "An instance of winston.Logger with explicit rewriter": { + topic: new (winston.Logger)({transports: [ + new (winston.transports.Console)({ level: 'info'}) + ], rewriters: [ + function (level, msg, meta) { + meta.level = level; + meta.msg = msg; + meta.foo = 'bar'; + return meta; + } + ]}), + "should add the rewriter": function (logger) { + assert.equal(helpers.size(logger.rewriters), 1); + }, + "the log() method": { + topic: function (logger) { + logger.once('logging', this.callback); + logger.log('info', 'test message', {"a": "b"}); + }, + "should run the rewriter": function (transport, level, msg, meta) { + assert.equal(meta.a, 'b'); + assert.equal(meta.level, 'info'); + assert.equal(meta.msg, 'test message'); + assert.equal(meta.foo, 'bar'); + } + } + } +}).addBatch({ + "An instance of winston.Logger with rewriters": { + topic: new (winston.Logger)({transports: [ + new (winston.transports.Console)({ level: 'info' }) + ], rewriters: [ + function (level, msg, meta) { + meta.numbers.push(1); + return meta; + }, + function (level, msg, meta) { + meta.numbers.push(2); + return meta; + } + ]}), + "the log() method": { + topic: function (logger) { + logger.once('logging', this.callback); + logger.log('info', 'test message', {"numbers": [0]}); + }, + "should run the rewriters in correct order": function (transport, level, msg, meta) { + assert.deepEqual(meta.numbers, [0, 1, 2]); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/logger-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/logger-test.js new file mode 100644 index 0000000..0074f20 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/logger-test.js @@ -0,0 +1,200 @@ +/* + * logger-test.js: Tests for instances of the winston Logger + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../lib/winston'), + helpers = require('./helpers'), + transport = require('./transports/transport'); + +vows.describe('winton/logger').addBatch({ + "An instance of winston.Logger": { + topic: new (winston.Logger)({ transports: [new (winston.transports.Console)({ level: 'info' })] }), + "should have the correct methods / properties defined": function (logger) { + helpers.assertLogger(logger); + }, + "the add() with an unsupported transport": { + "should throw an error": function () { + assert.throws(function () { logger.add('unsupported') }, Error); + } + } + } +}).addBatch({ + "An instance of winston.Logger with no transports": { + topic: new (winston.Logger)({ emitErrs: true }), + "the log() method should throw an error": function (logger) { + assert.throws(function () { logger.log('anything') }, Error); + }, + "the extend() method called on an empty object": { + topic: function (logger) { + var empty = {}; + logger.extend(empty); + return empty; + }, + "should define the appropriate methods": function (extended) { + ['log', 'profile', 'startTimer'].concat(Object.keys(winston.config.npm.levels)).forEach(function (method) { + assert.isFunction(extended[method]); + }); + } + }, + "the add() method with a supported transport": { + topic: function (logger) { + return logger.add(winston.transports.Console); + }, + "should add the console Transport onto transports": function (logger) { + assert.equal(helpers.size(logger.transports), 1); + helpers.assertConsole(logger.transports.console); + }, + "should throw an error when the same Transport is added": function (logger) { + assert.throws(function () { logger.add(winston.transports.Console) }, Error); + }, + "the log() method": { + topic: function (logger) { + logger.once('logging', this.callback); + logger.log('info', 'test message'); + }, + "should emit the 'log' event with the appropriate transport": function (transport, ign) { + helpers.assertConsole(transport); + } + }, + "the profile() method": { + "when passed a callback": { + topic: function (logger) { + var that = this; + logger.profile('test1'); + setTimeout(function () { + logger.profile('test1', function (err, level, msg, meta) { + that.callback(err, level, msg, meta, logger); + }); + }, 1000); + }, + "should respond with the appropriate profile message": function (err, level, msg, meta, logger) { + assert.isNull(err); + assert.equal(level, 'info'); + assert.match(meta.duration, /(\d+)ms/); + assert.isTrue(typeof logger.profilers['test'] === 'undefined'); + } + }, + "when not passed a callback": { + topic: function (logger) { + var that = this; + logger.profile('test2'); + logger.once('logging', that.callback.bind(null, null)); + setTimeout(function () { + logger.profile('test2'); + }, 1000); + }, + "should respond with the appropriate profile message": function (err, transport, level, msg, meta) { + assert.isNull(err); + assert.equal(level, 'info'); + assert.match(meta.duration, /(\d+)ms/); + } + } + }, + "the startTimer() method": { + "when passed a callback": { + topic: function (logger) { + var that = this; + var timer = logger.startTimer() + setTimeout(function () { + timer.done('test', function (err, level, msg, meta) { + that.callback(err, level, msg, meta, logger); + }); + }, 1000); + }, + "should respond with the appropriate message": function (err, level, msg, meta, logger) { + assert.isNull(err); + assert.equal(level, 'info'); + assert.match(meta.duration, /(\d+)ms/); + } + }, + "when not passed a callback": { + topic: function (logger) { + var that = this; + var timer = logger.startTimer() + logger.once('logging', that.callback.bind(null, null)); + setTimeout(function () { + timer.done(); + }, 1000); + }, + "should respond with the appropriate message": function (err, transport, level, msg, meta) { + assert.isNull(err); + assert.equal(level, 'info'); + assert.match(meta.duration, /(\d+)ms/); + + var duration = parseInt(meta.duration); + assert.isNumber(duration); + assert.isTrue(duration > 900 && duration < 1100); + } + } + }, + "and adding an additional transport": { + topic: function (logger) { + return logger.add(winston.transports.File, { + filename: path.join(__dirname, 'fixtures', 'logs', 'testfile2.log') + }); + }, + "should be able to add multiple transports": function (logger) { + assert.equal(helpers.size(logger.transports), 2); + helpers.assertConsole(logger.transports.console); + helpers.assertFile(logger.transports.file); + } + } + } + } +}).addBatch({ + "The winston logger": { + topic: new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.File)({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log' )}) + ] + }), + "should return have two transports": function (logger) { + assert.equal(helpers.size(logger.transports), 2); + }, + "the remove() with an unadded transport": { + "should throw an Error": function (logger) { + assert.throws(function () { logger.remove(winston.transports.Webhook) }, Error); + } + }, + "the remove() method with an added transport": { + topic: function (logger) { + return logger.remove(winston.transports.Console); + }, + "should remove the Console transport from transports": function (logger) { + assert.equal(helpers.size(logger.transports), 1); + helpers.assertFile(logger.transports.file); + }, + "and removing an additional transport": { + topic: function (logger) { + return logger.remove(winston.transports.File); + }, + "should remove File transport from transports": function (logger) { + assert.equal(helpers.size(logger.transports), 0); + } + } + } + } +}).addBatch({ + "The winston logger": { + topic: new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.File)({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log' )}) + ] + }), + "the clear() method": { + "should remove all transports": function (logger) { + logger.clear(); + assert.equal(helpers.size(logger.transports), 0); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/console-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/console-test.js new file mode 100644 index 0000000..07f5a6e --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/console-test.js @@ -0,0 +1,39 @@ +/* + * console-test.js: Tests for instances of the Console transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var npmTransport = new (winston.transports.Console)(), + syslogTransport = new (winston.transports.Console)({ levels: winston.config.syslog.levels }); + +vows.describe('winston/transports/console').addBatch({ + "An instance of the Console Transport": { + "with npm levels": { + "should have the proper methods defined": function () { + helpers.assertConsole(npmTransport); + }, + "the log() method": helpers.testNpmLevels(npmTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "with syslog levels": { + "should have the proper methods defined": function () { + helpers.assertConsole(syslogTransport); + }, + "the log() method": helpers.testSyslogLevels(syslogTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-maxfiles-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-maxfiles-test.js new file mode 100644 index 0000000..a9fa89e --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-maxfiles-test.js @@ -0,0 +1,102 @@ +/* + * file-maxfiles-test.js: Tests for instances of the File transport setting the max file size, + * and setting a number for max files created. + * maxSize * maxFiles = total storage used by winston. + * + * (C) 2011 Daniel Aristizabal + * MIT LICENSE + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var maxfilesTransport = new winston.transports.File({ + timestamp: false, + json: false, + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles.log'), + maxsize: 4096, + maxFiles: 3 +}); + +vows.describe('winston/transports/file/maxfiles').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + topic: maxfilesTransport, + "should be a valid transporter": function (transportTest) { + helpers.assertFile(transportTest); + }, + "should set the maxFiles option correctly": function (transportTest) { + assert.isNumber(transportTest.maxFiles); + } + }, + "when delete old test files": { + topic: function () { + exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles*'), this.callback); + }, + "and when passed more files than the maxFiles": { + topic: function () { + var that = this, + created = 0; + + function data(ch) { + return new Array(1018).join(String.fromCharCode(65 + ch)); + }; + + function logKbytes(kbytes, txt) { + // + // With no timestamp and at the info level, + // winston adds exactly 7 characters: + // [info](4)[ :](2)[\n](1) + // + for (var i = 0; i < kbytes; i++) { + maxfilesTransport.log('info', data(txt), null, function () { }); + } + } + + maxfilesTransport.on('logged', function () { + if (++created === 6) { + return that.callback(); + } + + logKbytes(4, created); + }); + + logKbytes(4, created); + }, + "should be only 3 files called 5.log, 4.log and 3.log": function () { + for (var num = 0; num < 6; num++) { + var file = !num ? 'testmaxfiles.log' : 'testmaxfiles' + num + '.log', + fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file); + + // There should be no files with that name + if (num >= 0 && num < 3) { + return assert.throws(function () { + fs.statSync(file); + }, Error); + } + + // The other files should be exist + assert.doesNotThrow(function () { + fs.statSync(file); + }, Error); + } + }, + "should have the correct content": function () { + ['D', 'E', 'F'].forEach(function (name, inx) { + var counter = inx + 3, + logsDir = path.join(__dirname, '..', 'fixtures', 'logs'), + content = fs.readFileSync(path.join(logsDir, 'testmaxfiles' + counter + '.log'), 'utf-8'); + // The content minus the 7 characters added by winston + assert.lengthOf(content.match(new RegExp(name, 'g')), 4068); + }); + } + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-maxsize-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-maxsize-test.js new file mode 100644 index 0000000..7d20e08 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-maxsize-test.js @@ -0,0 +1,82 @@ +/* + * file-test.js: Tests for instances of the File transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var maxsizeTransport = new winston.transports.File({ + timestamp: false, + json: false, + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize.log'), + maxsize: 4096 +}); + +vows.describe('winston/transports/file/maxsize').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + "the log() method": { + topic: function () { + exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize*'), this.callback); + }, + "when passed more than the maxsize": { + topic: function () { + var that = this, + data = new Array(1018).join('-'); + + // + // Setup a list of files which we will later stat. + // + that.files = []; + + function logKbytes (kbytes) { + // + // With no timestamp and at the info level, + // winston adds exactly 7 characters: + // [info](4)[ :](2)[\n](1) + // + for (var i = 0; i < kbytes; i++) { + maxsizeTransport.log('info', data, null, function () { }); + } + } + + maxsizeTransport.on('open', function (file) { + var match = file.match(/(\d+)\.log$/), + count = match ? match[1] : 0; + + that.files.push(file); + + if (that.files.length === 5) { + return that.callback(); + } + + logKbytes(4); + }); + + logKbytes(4); + }, + "should create multiple files correctly": function () { + this.files.forEach(function (file) { + try { + var stats = fs.statSync(file); + assert.equal(stats.size, 4096); + } + catch (ex) { + assert.isNull(ex); + } + }); + } + } + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-test.js new file mode 100644 index 0000000..2039b03 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/file-test.js @@ -0,0 +1,60 @@ +/* + * file-test.js: Tests for instances of the File transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + fs = require('fs'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var transport = require('./transport'); + +var stream = fs.createWriteStream( + path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log') + ), + fileTransport = new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfilename.log') + }), + streamTransport = new (winston.transports.File)({ stream: stream }); + +vows.describe('winston/transports/file').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + "should have the proper methods defined": function () { + helpers.assertFile(fileTransport); + }, + "the log() method": helpers.testNpmLevels(fileTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "when passed a valid file stream": { + "should have the proper methods defined": function () { + helpers.assertFile(streamTransport); + }, + "the log() method": helpers.testNpmLevels(streamTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + } +}).addBatch({ + "These tests have a non-deterministic end": { + topic: function () { + setTimeout(this.callback, 200); + }, + "and this should be fixed before releasing": function () { + assert.isTrue(true); + } + } +}).addBatch({ + "An instance of the File Transport": transport(winston.transports.File, { + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log') + }) +}).export(module); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/transport.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/transport.js new file mode 100644 index 0000000..89b1eab --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/transport.js @@ -0,0 +1,212 @@ +var assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +module.exports = function (transport, options) { + var logger = transport instanceof winston.Logger + ? transport + : new winston.Logger({ + transports: [ + new transport(options) + ] + }); + + // hack to fix transports that don't log + // any unit of time smaller than seconds + var common = require('../../lib/winston/common'); + common.timestamp = function() { + return new Date().toISOString(); + }; + + var transport = logger.transports[logger._names[0]]; + + var out = { + 'topic': logger, + 'when passed valid options': { + 'should have the proper methods defined': function () { + switch (transport.name) { + case 'console': + helpers.assertConsole(transport); + break; + case 'file': + helpers.assertFile(transport); + break; + case 'webhook': + helpers.assertWebhook(transport); + break; + case 'couchdb': + helpers.assertCouchdb(transport); + break; + } + assert.isFunction(transport.log); + } + }, + 'the log() method': helpers.testNpmLevels(transport, + 'should respond with true', function (ign, err, logged) { + assert.isNull(err); + assert.isNotNull(logged); + } + ), + 'the stream() method': { + 'using no options': { + 'topic': function () { + if (!transport.stream) return; + + logger.log('info', 'hello world', {}); + + var cb = this.callback, + j = 10, + i = 10, + results = [], + stream = logger.stream(); + + stream.on('log', function (log) { + results.push(log); + results.stream = stream; + if (!--j) cb(null, results); + }); + + stream.on('error', function () {}); + + while (i--) logger.log('info', 'hello world ' + i, {}); + }, + 'should stream logs': function (err, results) { + if (!transport.stream) return; + assert.isNull(err); + results.forEach(function (log) { + assert.ok(log.message.indexOf('hello world') === 0 + || log.message.indexOf('test message') === 0); + }); + results.stream.destroy(); + } + }, + 'using the `start` option': { + 'topic': function () { + if (!transport.stream) return; + + var cb = this.callback, + stream = logger.stream({ start: 0 }); + + stream.on('log', function (log) { + log.stream = stream; + if (cb) cb(null, log); + cb = null; + }); + }, + 'should stream logs': function (err, log) { + if (!transport.stream) return; + assert.isNull(err); + assert.isNotNull(log.message); + log.stream.destroy(); + } + } + }, + 'after the logs have flushed': { + topic: function () { + setTimeout(this.callback, 1000); + }, + 'the query() method': { + 'using basic querying': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query(cb); + }); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + var log = results.pop(); + assert.ok(log.message.indexOf('hello world') === 0 + || log.message.indexOf('test message') === 0); + } + }, + 'using the `rows` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query({ rows: 1 }, cb); + }); + }, + 'should return one result': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.equal(results.length, 1); + } + }, + 'using `fields` and `order` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query({ order: 'asc', fields: ['timestamp'] }, cb); + }); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.equal(Object.keys(results[0]).length, 1); + assert.ok(new Date(results.shift().timestamp) + < new Date(results.pop().timestamp)); + } + }, + 'using the `from` and `until` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + var start = new Date - 100 * 1000; + var end = new Date + 100 * 1000; + logger.query({ from: start, until: end }, cb); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.ok(results.length >= 1); + } + }, + 'using a bad `from` and `until` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'bad from and until', {}, function () { + var now = new Date + 1000000; + logger.query({ from: now, until: now }, cb); + }); + }, + 'should return no results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + results = [results.filter(function(log) { + return log.message === 'bad from and until'; + }).pop()]; + assert.isUndefined(results[0]); + } + } + } + } + }; + + return out; +}; diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/webhook-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/webhook-test.js new file mode 100644 index 0000000..8d40c00 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/transports/webhook-test.js @@ -0,0 +1,125 @@ +/* + * webhook-test.js: Tests for instances of the Webhook transport + * + * (C) 2011 Marak Squires + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + fs = require('fs'), + http = require('http'), + https = require('https'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var webhookTransport = new (winston.transports.Webhook)({ + "host": "localhost", + "port": 8080, + "path": "/winston-test" +}); + +var httpsWebhookTransport = new (winston.transports.Webhook)({ + "host": "localhost", + "port": 8081, + "path": "/winston-test", + "ssl": true +}); + +var authWebhookTransport = new (winston.transports.Webhook)({ + "host": "localhost", + "port": 8080, + "path": "/winston-auth-test", + "auth": { + "username": "winston", + "password": "churchill" + } +}); + +var requestsAuthenticated = true; + +var server = http.createServer(function (req, res) { + if (req.url == '/winston-auth-test') { + // + // Test if request has been correctly authenticated + // + // Strip 'Basic' from Authorization header + var signature = req.headers['authorization'].substr(6); + requestsAuthenticated = requestsAuthenticated && + new Buffer(signature, 'base64').toString('utf8') == 'winston:churchill'; + } + res.end(); +}); + +server.listen(8080); + + +var httpsServer = https.createServer({ + cert: fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'keys', 'agent2-cert.pem')), + key: fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'keys', 'agent2-key.pem')) +}, function (req, res) { + res.end(); +}); + +httpsServer.listen(8081); + +vows.describe('winston/transports/webhook').addBatch({ + "An instance of the Webhook Transport": { + "when passed valid options": { + "should have the proper methods defined": function () { + helpers.assertWebhook(webhookTransport); + }, + "the log() method": helpers.testNpmLevels(webhookTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + }, + "An https instance of the Webhook Transport": { + "when passed valid options": { + "should have the proper methods defined": function () { + helpers.assertWebhook(httpsWebhookTransport); + }, + "the log() method": helpers.testNpmLevels(httpsWebhookTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + }, + "An http Basic Auth instance of the Webhook Transport": { + "when passed valid options": { + "should have the proper methods defined": function () { + helpers.assertWebhook(authWebhookTransport); + }, + "the log() method": helpers.testNpmLevels(authWebhookTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + } +}).addBatch({ + "When the tests are over": { + topic: function () { + // + // Delay destruction of the server since the + // WebHook transport responds before the request + // has actually be completed. + // + setTimeout(this.callback, 1000); + }, + "the server should cleanup": function () { + server.close(); + }, + "requests have been correctly authenticated": function () { + assert.ok(requestsAuthenticated); + } + } +}).addBatch({ + // "An instance of the Webhook Transport": transport(winston.transports.Webhook, { + // "host": "localhost", + // "port": 8080, + // "path": "/winston-test" + // }) +}).export(module); diff --git a/node_modules/forever/node_modules/cliff/node_modules/winston/test/winston-test.js b/node_modules/forever/node_modules/cliff/node_modules/winston/test/winston-test.js new file mode 100644 index 0000000..7105329 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/node_modules/winston/test/winston-test.js @@ -0,0 +1,98 @@ +/* + * logger-test.js: Tests for instances of the winston Logger + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var fs = require('fs'), + path = require('path'), + vows = require('vows'), + http = require('http'), + assert = require('assert'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston').addBatch({ + "The winston module": { + topic: function () { + winston.default.transports.console.level = 'silly'; + return null; + }, + "should have the correct methods defined": function () { + assert.isObject(winston.transports); + assert.isFunction(winston.Transport); + assert.isTrue(!winston.transports.Transport); + assert.isFunction(winston.transports.Console); + assert.isFunction(winston.transports.File); + assert.isFunction(winston.transports.Webhook); + assert.isObject(winston.default.transports.console); + assert.isFalse(winston.emitErrs); + assert.isObject(winston.config); + ['Logger', 'add', 'remove', 'extend'] + .concat(Object.keys(winston.config.npm.levels)) + .forEach(function (key) { + assert.isFunction(winston[key]); + }); + }, + "it should": { + topic: function () { + fs.readFile(path.join(__dirname, '..', 'package.json'), this.callback); + }, + "have the correct version set": function (err, data) { + assert.isNull(err); + data = JSON.parse(data.toString()); + assert.equal(winston.version, data.version); + } + }, + "the log() method": helpers.testNpmLevels(winston, "should respond without an error", function (err) { + assert.isNull(err); + }), + "the extend() method called on an empty object": { + topic: function (logger) { + var empty = {}; + winston.extend(empty); + return empty; + }, + "should define the appropriate methods": function (extended) { + ['log', 'profile', 'startTimer'].concat(Object.keys(winston.config.npm.levels)).forEach(function (method) { + assert.isFunction(extended[method]); + }); + } + } + } +}).addBatch({ + "The winston module": { + "the setLevels() method": { + topic: function () { + winston.setLevels(winston.config.syslog.levels); + return null; + }, + "should have the proper methods defined": function () { + assert.isObject(winston.transports); + assert.isFunction(winston.transports.Console); + assert.isFunction(winston.transports.Webhook); + assert.isObject(winston.default.transports.console); + assert.isFalse(winston.emitErrs); + assert.isObject(winston.config); + + var newLevels = Object.keys(winston.config.syslog.levels); + ['Logger', 'add', 'remove', 'extend'] + .concat(newLevels) + .forEach(function (key) { + assert.isFunction(winston[key]); + }); + + + Object.keys(winston.config.npm.levels) + .filter(function (key) { + return newLevels.indexOf(key) === -1; + }) + .forEach(function (key) { + assert.isTrue(typeof winston[key] === 'undefined'); + }); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/cliff/package.json b/node_modules/forever/node_modules/cliff/package.json new file mode 100644 index 0000000..0987a86 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/package.json @@ -0,0 +1,51 @@ +{ + "name": "cliff", + "description": "Your CLI formatting friend.", + "version": "0.1.8", + "author": { + "name": "Nodejitsu Inc.", + "email": "info@nodejitsu.com" + }, + "repository": { + "type": "git", + "url": "http://github.com/flatiron/cliff.git" + }, + "maintainers": [ + { + "name": "indexzero", + "email": "charlie@nodejitsu.com" + } + ], + "keywords": [ + "cli", + "logging", + "tools", + "winston" + ], + "dependencies": { + "colors": "0.x.x", + "eyes": "0.1.x", + "winston": "0.6.x" + }, + "devDependencies": { + "vows": "0.5.x" + }, + "main": "./lib/cliff", + "scripts": { + "test": "vows test/*-test.js --spec" + }, + "engines": { + "node": ">= 0.4.0" + }, + "readme": "# cliff\n\nCLI output formatting tools: \"Your CLI Formatting Friend\".\n\n## Installation\n\n### Installing npm (node package manager)\n```\n curl http://npmjs.org/install.sh | sh\n```\n\n### Installing cliff\n```\n [sudo] npm install cliff\n```\n\n## Usage\nThere are a number of methods available in Cliff for common logging tasks in command-line tools. If you're looking for more usage, checkout the [examples in this repository][3]:\n\n1. Logging rows of data\n2. Inspecting Objects\n\n### Logging rows of data\n\n**cliff.stringifyRows(rows[, colors])**\n\nTakes a set of Arrays and row headers and returns properly formatted and padded rows. Here's a sample:\n\n``` js\n var cliff = require('../lib/cliff');\n\n var rows = [\n ['Name', 'Flavor', 'Dessert'],\n ['Alice', 'cherry', 'yogurt'],\n ['Bob', 'carmel', 'apples'],\n ['Joe', 'chocolate', 'cake'],\n ['Nick', 'vanilla', 'ice cream']\n ];\n\n console.log(cliff.stringifyRows(rows, ['red', 'blue', 'green']));\n```\n\n![output from string-rows.js][string-rows]\n\n**cliff.putRows(level, rows[, colors])**\n\nThe `putRows` method is a simple helper that takes a set of Arrays and row headers and logs properly formatted and padded rows (logs `stringifyRows` to [winston][0]). Here's a quick sample:\n\n``` js\n var cliff = require('../lib/cliff');\n\n var rows = [\n ['Name', 'Flavor', 'Dessert'],\n ['Alice', 'cherry', 'yogurt'],\n ['Bob', 'carmel', 'apples'],\n ['Joe', 'chocolate', 'cake'],\n ['Nick', 'vanilla', 'ice cream']\n ];\n\n cliff.putRows('data', rows, ['red', 'blue', 'green']);\n```\n\nThe resulting output on the command-line would be:\n\n![output from put-rows.js][put-rows]\n\n**cliff.stringifyObjectRows(objs, properties[, colors])**\n*used to be: cliff.rowifyObjects(objs, properties, colors)*\n\nTakes a set of Objects and the properties to extract from them and returns properly formatted and padded rows. Here's a sample:\n\n``` js\n var cliff = require('../lib/cliff');\n\n var objs = [], obj = {\n name: \"bazz\",\n address: \"1234 Nowhere Dr.\",\n };\n\n for (var i = 0; i < 10; i++) {\n objs.push({\n name: obj.name,\n address: obj.address,\n id: Math.random().toString()\n });\n }\n\n console.log(cliff.stringifyObjectRows(objs, ['id', 'name', 'address'], ['red', 'blue', 'green']));\n```\n\n![output from string-object-rows.js][string-object-rows]\n\n**cliff.putObjectRows(level, objs, properties[, colors])**\n\nTakes a set of Objects and the properties to extract from them and it will log to the console. (it prints `stringifyObjectRows` with [winston][0]). Here's a sample:\n\n``` js\n var cliff = require('../lib/cliff');\n\n var objs = [], obj = {\n name: \"bazz\",\n address: \"1234 Nowhere Dr.\",\n };\n\n for (var i = 0; i < 10; i++) {\n objs.push({\n name: obj.name,\n address: obj.address,\n id: Math.random().toString()\n });\n }\n\n cliff.putObjectRows('data', objs, ['id', 'name', 'address']);\n```\n\n![output from string-object-rows.js][string-object-rows]\n\n**Colors Parameter**\n\nThe `colors` parameter is an array that colors the first row. It uses the [colors.js][2]. You can use any of those.\n\n``` js\n var cliff = require('../lib/cliff');\n\n var rows = [\n ['Name', 'Flavor', 'Dessert'],\n ['Alice'.grey, 'cherry'.cyan, 'yogurt'.yellow],\n ['Bob'.magenta, 'carmel'.rainbow, 'apples'.white],\n ['Joe'.italic, 'chocolate'.underline, 'cake'.inverse],\n ['Nick'.bold, 'vanilla', 'ice cream']\n ];\n\n cliff.putRows('data', rows, ['red', 'blue', 'green']);\n```\n\nThe resulting output on the command-line would be:\n\n![output from puts-rows-colors.js][put-rows-colors]\n\n### Inspecting Objects\n\n**cliff.inspect(obj)**\n\nThe `inspect` method is a lightweight wrapper to a pre-configured [eyes][1] inspector. If you wish to change the coloring of objects that are logged using `cliff` you only need to override `cliff.inspect` with a new [eyes][1] inspector. Here is how to use it:\n\n``` js\n var cliff = require('../lib/cliff');\n\n console.log(cliff.inspect({\n literal: \"bazz\",\n arr: [\n \"one\",\n 2,\n ],\n obj: {\n host: \"localhost\",\n port: 5984,\n auth: {\n username: \"admin\",\n password: \"password\"\n }\n }\n }));\n```\n\n![output from inspect.js][inspect]\n\n**cliff.putObject(obj, [rewriters, padding])**\n\nThe `putObject` method is a simple helper function for prefixing and styling inspected object output from [eyes][1]. Here's a quick sample:\n\n``` js\nvar cliff = require('cliff');\n\ncliff.putObject({\n literal: \"bazz\",\n arr: [\n \"one\",\n 2,\n ],\n obj: {\n host: \"localhost\",\n port: 5984,\n auth: {\n username: \"admin\",\n password: \"password\"\n }\n }\n});\n```\n\nThe resulting output on the command-line would be: \n\n![output from put-object.js][put-object]\n\n## Run Tests\n\nAll of the cliff tests are written in [vows][4], and cover all of the use cases described above.\n\n```\n npm test\n```\n\n## Motivation\n\nCliff is the swiss army knife of CLI formatting tools. It is based on highly flexible and powerful libraries: \n\n* [winston][0]: A multi-transport async logging library for node.js\n* [eyes][1]: A customizable value inspector for node.js\n* [colors][2]: Get colors in your node.js console like what \n\n\n#### Author: [Charlie Robbins](http://twitter.com/indexzero)\n\n[0]: http://github.com/indexzero/winston\n[1]: http://github.com/cloudhead/eyes.js\n[2]: http://github.com/marak/colors.js\n[3]: http://github.com/flatiron/cliff/tree/master/examples\n[4]: http://vowsjs.org\n\n[inspect]: https://github.com/flatiron/cliff/raw/master/assets/inspect.png\n[put-object-rows]: https://github.com/flatiron/cliff/raw/master/assets/put-object-rows.png\n[put-object]: https://github.com/flatiron/cliff/raw/master/assets/put-object.png\n[put-rows-colors]: https://github.com/flatiron/cliff/raw/master/assets/put-rows-colors.png\n[put-rows]: https://github.com/flatiron/cliff/raw/master/assets/put-rows.png\n[string-object-rows]: https://github.com/flatiron/cliff/raw/master/assets/string-object-rows.png\n[string-rows]: https://github.com/flatiron/cliff/raw/master/assets/string-rows.png", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/flatiron/cliff/issues" + }, + "_id": "cliff@0.1.8", + "dist": { + "shasum": "f4ba28f6ca479afdcfb21794390b9dae177a1767" + }, + "_from": "cliff@0.1.8", + "_resolved": "https://registry.npmjs.org/cliff/-/cliff-0.1.8.tgz" +} diff --git a/node_modules/forever/node_modules/cliff/test/cliff-test.js b/node_modules/forever/node_modules/cliff/test/cliff-test.js new file mode 100644 index 0000000..17c5952 --- /dev/null +++ b/node_modules/forever/node_modules/cliff/test/cliff-test.js @@ -0,0 +1,79 @@ +/* + * log-test.js: Tests for cliff. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var assert = require('assert'), + vows = require('vows'), + eyes = require('eyes'), + cliff = require('../lib/cliff'); + +vows.describe('cliff').addBatch({ + "When using cliff module": { + "the columnMajor() method": { + "should respond with rows in column major form": function () { + var columns, rows = [ + ["1a", "2a", "3a", "4a"], + ["1b", "2b", "3b", "4b"], + ["1c", "2c", "3c", "4c"] + ]; + + columns = cliff.columnMajor(rows); + for (var i = 0; i < columns.length; i++) { + columns[i].forEach(function (val) { + assert.isTrue(val.indexOf(i + 1) !== -1); + }); + } + } + }, + "the arrayLengths() method": { + "with a set of strings": { + "should respond with a list of the longest elements": function () { + var lengths, rows = [ + ["1a", "2a", "3a", "4a"], + ["1b", "2bb", "3b", "4b"], + ["1c", "2c", "3ccc", "4c"], + ["1d", "2d", "3dd", "4dddd"] + ]; + + lengths = cliff.arrayLengths(rows); + assert.equal(lengths[0], 2); + assert.equal(lengths[1], 3); + assert.equal(lengths[2], 4); + assert.equal(lengths[3], 5); + } + }, + "with a set of numbers and strings": { + "should respond with a list of the longest elements": function () { + var lengths, rows = [ + [11, "2a", "3a", "4a"], + ["1b", 222, "3b", "4b"], + ["1c", "2c", 3333, "4c"], + ["1d", "2d", "3dd", 44444] + ]; + + lengths = cliff.arrayLengths(rows); + assert.equal(lengths[0], 2); + assert.equal(lengths[1], 3); + assert.equal(lengths[2], 4); + assert.equal(lengths[3], 5); + } + } + }, + "the stringifyRows() method": { + "should calculate padding correctly for numbers": function() { + var rows = [ + ['a', 'b'], + [12345, 1] + ]; + + assert.equal( + cliff.stringifyRows(rows), + 'a b \n12345 1 ' + ); + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/colors/MIT-LICENSE.txt b/node_modules/forever/node_modules/colors/MIT-LICENSE.txt new file mode 100644 index 0000000..7dca107 --- /dev/null +++ b/node_modules/forever/node_modules/colors/MIT-LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2010 + +Marak Squires +Alexis Sellier (cloudhead) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/node_modules/colors/ReadMe.md b/node_modules/forever/node_modules/colors/ReadMe.md new file mode 100644 index 0000000..1c6b0d0 --- /dev/null +++ b/node_modules/forever/node_modules/colors/ReadMe.md @@ -0,0 +1,77 @@ +# colors.js - get color and style in your node.js console ( and browser ) like what + + + + +## Installation + + npm install colors + +## colors and styles! + +- bold +- italic +- underline +- inverse +- yellow +- cyan +- white +- magenta +- green +- red +- grey +- blue +- rainbow +- zebra +- random + +## Usage + +``` js +var colors = require('./colors'); + +console.log('hello'.green); // outputs green text +console.log('i like cake and pies'.underline.red) // outputs red underlined text +console.log('inverse the color'.inverse); // inverses the color +console.log('OMG Rainbows!'.rainbow); // rainbow (ignores spaces) +``` + +# Creating Custom themes + +```js + +var require('colors'); + +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}); + +// outputs red text +console.log("this is an error".error); + +// outputs yellow text +console.log("this is a warning".warn); +``` + + +### Contributors + +Marak (Marak Squires) +Alexis Sellier (cloudhead) +mmalecki (Maciej Małecki) +nicoreed (Nico Reed) +morganrallen (Morgan Allen) +JustinCampbell (Justin Campbell) +ded (Dustin Diaz) + + +#### , Marak Squires , Justin Campbell, Dustin Diaz (@ded) diff --git a/node_modules/forever/node_modules/colors/colors.js b/node_modules/forever/node_modules/colors/colors.js new file mode 100644 index 0000000..a7198f1 --- /dev/null +++ b/node_modules/forever/node_modules/colors/colors.js @@ -0,0 +1,269 @@ +/* +colors.js + +Copyright (c) 2010 + +Marak Squires +Alexis Sellier (cloudhead) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +var isHeadless = false; + +if (typeof module !== 'undefined') { + isHeadless = true; +} + +if (!isHeadless) { + var exports = {}; + var module = {}; + var colors = exports; + exports.mode = "browser"; +} else { + exports.mode = "console"; +} + +// +// Prototypes the string object to have additional method calls that add terminal colors +// +var addProperty = function (color, func) { + var allowOverride = ['bold']; + exports[color] = function(str) { + return func.apply(str); + }; + String.prototype.__defineGetter__(color, func); +} + +// +// Iterate through all default styles and colors +// + +var x = ['bold', 'underline', 'italic', 'inverse', 'grey', 'black', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta']; +x.forEach(function (style) { + + // __defineGetter__ at the least works in more browsers + // http://robertnyman.com/javascript/javascript-getters-setters.html + // Object.defineProperty only works in Chrome + addProperty(style, function () { + return stylize(this, style); + }); +}); + +function sequencer(map) { + return function () { + if (!isHeadless) { + return this.replace(/( )/, '$1'); + } + var exploded = this.split(""); + var i = 0; + exploded = exploded.map(map); + return exploded.join(""); + } +} + +var rainbowMap = (function () { + var rainbowColors = ['red','yellow','green','blue','magenta']; //RoY G BiV + return function (letter, i, exploded) { + if (letter == " ") { + return letter; + } else { + return stylize(letter, rainbowColors[i++ % rainbowColors.length]); + } + } +})(); + +exports.addSequencer = function (name, map) { + addProperty(name, sequencer(map)); +} + +exports.addSequencer('rainbow', rainbowMap); +exports.addSequencer('zebra', function (letter, i, exploded) { + return i % 2 === 0 ? letter : letter.inverse; +}); + +exports.setTheme = function (theme) { + Object.keys(theme).forEach(function(prop){ + addProperty(prop, function(){ + return exports[theme[prop]](this); + }); + }); +} + +function stylize(str, style) { + + if (exports.mode == 'console') { + var styles = { + //styles + 'bold' : ['\033[1m', '\033[22m'], + 'italic' : ['\033[3m', '\033[23m'], + 'underline' : ['\033[4m', '\033[24m'], + 'inverse' : ['\033[7m', '\033[27m'], + //grayscale + 'white' : ['\033[37m', '\033[39m'], + 'grey' : ['\033[90m', '\033[39m'], + 'black' : ['\033[30m', '\033[39m'], + //colors + 'blue' : ['\033[34m', '\033[39m'], + 'cyan' : ['\033[36m', '\033[39m'], + 'green' : ['\033[32m', '\033[39m'], + 'magenta' : ['\033[35m', '\033[39m'], + 'red' : ['\033[31m', '\033[39m'], + 'yellow' : ['\033[33m', '\033[39m'] + }; + } else if (exports.mode == 'browser') { + var styles = { + //styles + 'bold' : ['', ''], + 'italic' : ['', ''], + 'underline' : ['', ''], + 'inverse' : ['', ''], + //grayscale + 'white' : ['', ''], + 'grey' : ['', ''], + 'black' : ['', ''], + //colors + 'blue' : ['', ''], + 'cyan' : ['', ''], + 'green' : ['', ''], + 'magenta' : ['', ''], + 'red' : ['', ''], + 'yellow' : ['', ''] + }; + } else if (exports.mode == 'none') { + return str; + } else { + console.log('unsupported mode, try "browser", "console" or "none"'); + } + return styles[style][0] + str + styles[style][1]; +}; + +// don't summon zalgo +addProperty('zalgo', function () { + return zalgo(this); +}); + +// please no +function zalgo(text, options) { + var soul = { + "up" : [ + '̍','̎','̄','̅', + '̿','̑','̆','̐', + '͒','͗','͑','̇', + '̈','̊','͂','̓', + '̈','͊','͋','͌', + '̃','̂','̌','͐', + '̀','́','̋','̏', + '̒','̓','̔','̽', + '̉','ͣ','ͤ','ͥ', + 'ͦ','ͧ','ͨ','ͩ', + 'ͪ','ͫ','ͬ','ͭ', + 'ͮ','ͯ','̾','͛', + '͆','̚' + ], + "down" : [ + '̖','̗','̘','̙', + '̜','̝','̞','̟', + '̠','̤','̥','̦', + '̩','̪','̫','̬', + '̭','̮','̯','̰', + '̱','̲','̳','̹', + '̺','̻','̼','ͅ', + '͇','͈','͉','͍', + '͎','͓','͔','͕', + '͖','͙','͚','̣' + ], + "mid" : [ + '̕','̛','̀','́', + '͘','̡','̢','̧', + '̨','̴','̵','̶', + '͜','͝','͞', + '͟','͠','͢','̸', + '̷','͡',' ҉' + ] + }, + all = [].concat(soul.up, soul.down, soul.mid), + zalgo = {}; + + function randomNumber(range) { + r = Math.floor(Math.random()*range); + return r; + }; + + function is_char(character) { + var bool = false; + all.filter(function(i){ + bool = (i == character); + }); + return bool; + } + + function heComes(text, options){ + result = ''; + options = options || {}; + options["up"] = options["up"] || true; + options["mid"] = options["mid"] || true; + options["down"] = options["down"] || true; + options["size"] = options["size"] || "maxi"; + var counts; + text = text.split(''); + for(var l in text){ + if(is_char(l)) { continue; } + result = result + text[l]; + + counts = {"up" : 0, "down" : 0, "mid" : 0}; + + switch(options.size) { + case 'mini': + counts.up = randomNumber(8); + counts.min= randomNumber(2); + counts.down = randomNumber(8); + break; + case 'maxi': + counts.up = randomNumber(16) + 3; + counts.min = randomNumber(4) + 1; + counts.down = randomNumber(64) + 3; + break; + default: + counts.up = randomNumber(8) + 1; + counts.mid = randomNumber(6) / 2; + counts.down= randomNumber(8) + 1; + break; + } + + var arr = ["up", "mid", "down"]; + for(var d in arr){ + var index = arr[d]; + for (var i = 0 ; i <= counts[index]; i++) + { + if(options[index]) { + result = result + soul[index][randomNumber(soul[index].length)]; + } + } + } + } + return result; + }; + return heComes(text); +} + +addProperty('stripColors', function() { + return ("" + this).replace(/\u001b\[\d+m/g,''); +}); diff --git a/node_modules/forever/node_modules/colors/example.html b/node_modules/forever/node_modules/colors/example.html new file mode 100644 index 0000000..ab95649 --- /dev/null +++ b/node_modules/forever/node_modules/colors/example.html @@ -0,0 +1,74 @@ + + + + + Colors Example + + + + + + \ No newline at end of file diff --git a/node_modules/forever/node_modules/colors/example.js b/node_modules/forever/node_modules/colors/example.js new file mode 100644 index 0000000..3da2986 --- /dev/null +++ b/node_modules/forever/node_modules/colors/example.js @@ -0,0 +1,65 @@ +var colors = require('./colors'); + +//colors.mode = "browser"; + +var test = colors.red("hopefully colorless output"); +console.log('Rainbows are fun!'.rainbow); +console.log('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported +console.log('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported +//console.log('zalgo time!'.zalgo); +console.log(test.stripColors); +console.log("a".grey + " b".black); + +console.log("Zebras are so fun!".zebra); + +console.log(colors.rainbow('Rainbows are fun!')); +console.log(colors.italic('So ') + colors.underline('are') + colors.bold(' styles! ') + colors.inverse('inverse')); // styles not widely supported +console.log(colors.bold(colors.italic(colors.underline(colors.red('Chains are also cool.'))))); // styles not widely supported +//console.log(colors.zalgo('zalgo time!')); +console.log(colors.stripColors(test)); +console.log(colors.grey("a") + colors.black(" b")); + +colors.addSequencer("america", function(letter, i, exploded) { + if(letter === " ") return letter; + switch(i%3) { + case 0: return letter.red; + case 1: return letter.white; + case 2: return letter.blue; + } +}); + +colors.addSequencer("random", (function() { + var available = ['bold', 'underline', 'italic', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta']; + + return function(letter, i, exploded) { + return letter === " " ? letter : letter[available[Math.round(Math.random() * (available.length - 1))]]; + }; +})()); + +console.log("AMERICA! F--K YEAH!".america); +console.log("So apparently I've been to Mars, with all the little green men. But you know, I don't recall.".random); + +// +// Custom themes +// + +colors.setTheme({ + silly: 'rainbow', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}); + +// outputs red text +console.log("this is an error".error); + +// outputs yellow text +console.log("this is a warning".warn); + + diff --git a/node_modules/forever/node_modules/colors/package.json b/node_modules/forever/node_modules/colors/package.json new file mode 100644 index 0000000..2e9ab12 --- /dev/null +++ b/node_modules/forever/node_modules/colors/package.json @@ -0,0 +1,27 @@ +{ + "name": "colors", + "description": "get colors in your node.js console like what", + "version": "0.6.0-1", + "author": { + "name": "Marak Squires" + }, + "repository": { + "type": "git", + "url": "http://github.com/Marak/colors.js.git" + }, + "engines": { + "node": ">=0.1.90" + }, + "main": "colors", + "readme": "# colors.js - get color and style in your node.js console ( and browser ) like what\n\n\n\n\n## Installation\n\n npm install colors\n\n## colors and styles!\n\n- bold\n- italic\n- underline\n- inverse\n- yellow\n- cyan\n- white\n- magenta\n- green\n- red\n- grey\n- blue\n- rainbow\n- zebra\n- random\n\n## Usage\n\n``` js\nvar colors = require('./colors');\n\nconsole.log('hello'.green); // outputs green text\nconsole.log('i like cake and pies'.underline.red) // outputs red underlined text\nconsole.log('inverse the color'.inverse); // inverses the color\nconsole.log('OMG Rainbows!'.rainbow); // rainbow (ignores spaces)\n```\n\n# Creating Custom themes\n\n```js\n\nvar require('colors');\n\ncolors.setTheme({\n silly: 'rainbow',\n input: 'grey',\n verbose: 'cyan',\n prompt: 'grey',\n info: 'green',\n data: 'grey',\n help: 'cyan',\n warn: 'yellow',\n debug: 'blue',\n error: 'red'\n});\n\n// outputs red text\nconsole.log(\"this is an error\".error);\n\n// outputs yellow text\nconsole.log(\"this is a warning\".warn);\n```\n\n\n### Contributors \n\nMarak (Marak Squires)\nAlexis Sellier (cloudhead)\nmmalecki (Maciej Małecki)\nnicoreed (Nico Reed)\nmorganrallen (Morgan Allen)\nJustinCampbell (Justin Campbell)\nded (Dustin Diaz)\n\n\n#### , Marak Squires , Justin Campbell, Dustin Diaz (@ded)\n", + "readmeFilename": "ReadMe.md", + "bugs": { + "url": "https://github.com/Marak/colors.js/issues" + }, + "_id": "colors@0.6.0-1", + "dist": { + "shasum": "18e91ff914a2f70ca8953b7dd969644edcd08bef" + }, + "_from": "colors@0.6.0-1", + "_resolved": "https://registry.npmjs.org/colors/-/colors-0.6.0-1.tgz" +} diff --git a/node_modules/forever/node_modules/colors/test.js b/node_modules/forever/node_modules/colors/test.js new file mode 100644 index 0000000..1c03d65 --- /dev/null +++ b/node_modules/forever/node_modules/colors/test.js @@ -0,0 +1,65 @@ +var assert = require('assert'), + colors = require('./colors'); + +// +// This is a pretty nice example on how tests shouldn't be written. However, +// it's more about API stability than about really testing it (although it's +// a pretty complete test suite). +// + +var s = 'string'; + +function a(s, code) { + return '\033[' + code.toString() + 'm' + s + '\033[39m'; +} + +function aE(s, color, code) { + assert.equal(s[color], a(s, code)); + assert.equal(colors[color](s), a(s, code)); + assert.equal(s[color], colors[color](s)); + assert.equal(s[color].stripColors, s); + assert.equal(s[color].stripColors, colors.stripColors(s)); +} + +function h(s, color) { + return '' + s + ''; + // that's pretty dumb approach to testing it +} + +var stylesColors = ['white', 'grey', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow']; +var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']); + +colors.mode = 'console'; +assert.equal(s.bold, '\033[1m' + s + '\033[22m'); +assert.equal(s.italic, '\033[3m' + s + '\033[23m'); +assert.equal(s.underline, '\033[4m' + s + '\033[24m'); +assert.equal(s.inverse, '\033[7m' + s + '\033[27m'); +assert.ok(s.rainbow); +aE(s, 'white', 37); +aE(s, 'grey', 90); +aE(s, 'black', 30); +aE(s, 'blue', 34); +aE(s, 'cyan', 36); +aE(s, 'green', 32); +aE(s, 'magenta', 35); +aE(s, 'red', 31); +aE(s, 'yellow', 33); +assert.equal(s, 'string'); + +colors.mode = 'browser'; +assert.equal(s.bold, '' + s + ''); +assert.equal(s.italic, '' + s + ''); +assert.equal(s.underline, '' + s + ''); +assert.equal(s.inverse, '' + s + ''); +assert.ok(s.rainbow); +stylesColors.forEach(function (color) { + assert.equal(s[color], h(s, color)); + assert.equal(colors[color](s), h(s, color)); +}); + +colors.mode = 'none'; +stylesAll.forEach(function (style) { + assert.equal(s[style], s); + assert.equal(colors[style](s), s); +}); + diff --git a/node_modules/forever/node_modules/flatiron/.npmignore b/node_modules/forever/node_modules/flatiron/.npmignore new file mode 100644 index 0000000..5171c54 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/.npmignore @@ -0,0 +1,2 @@ +node_modules +npm-debug.log \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/.travis.yml b/node_modules/forever/node_modules/flatiron/.travis.yml new file mode 100644 index 0000000..2f2ef03 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +branches: + only: + - master +node_js: + - 0.8 + +notifications: + email: + - travis@nodejitsu.com + irc: "irc.freenode.org#nodejitsu" + diff --git a/node_modules/forever/node_modules/flatiron/LICENSE b/node_modules/forever/node_modules/flatiron/LICENSE new file mode 100644 index 0000000..1f01e2b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Nodejitsu Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/README.md b/node_modules/forever/node_modules/flatiron/README.md new file mode 100644 index 0000000..7d7af77 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/README.md @@ -0,0 +1,482 @@ +# [flatiron](http://flatironjs.org) [![Build Status](https://secure.travis-ci.org/flatiron/flatiron.png)](http://travis-ci.org/flatiron/flatiron) + +*Framework components for node.js and the browser* + +![](http://flatironjs.org/img/flatiron.png) + +# Example HTTP Server: + +```js +var flatiron = require('flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.http); + +app.router.get('/', function () { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }); + this.res.end('Hello world!\n'); +}); + +app.start(8080); +``` + +# Example HTTPS Server: + +```js +var flatiron = require('flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.http, { + https: { + cert: 'path/to/cert.pem', + key: 'path/to/key.pem', + ca: 'path/to/ca.pem' + } +}); + +app.router.get('/', function () { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }); + this.res.end('Hello world!\n'); +}); + +app.start(8080); +``` + +# Example CLI Application: + +```js +// example.js + +var flatiron = require('flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.cli, { + dir: __dirname, + usage: [ + 'This is a basic flatiron cli application example!', + '', + 'hello - say hello to somebody.' + ] +}); + +app.cmd('hello', function () { + app.prompt.get('name', function (err, result) { + app.log.info('hello '+result.name+'!'); + }) +}) + +app.start(); +``` + +## Run It: + +``` +% node example.js hello +prompt: name: world +info: hello world! +``` + +## Installation + +### Installing NPM (Node Package Manager) +``` + curl http://npmjs.org/install.sh | sh +``` + +### Installing Flatiron +``` + [sudo] npm install flatiron +``` + +### Installing Union (Required for `flatiron.plugins.http`) +``` + npm install union +``` + +# Usage: + +## Start With `flatiron.app`: + +`flatiron.app` is a [broadway injection container](https://github.com/flatiron/broadway). To be brief, what it does is allow plugins to modify the `app` object directly: + +```js +var flatiron = require('flatiron'), + app = require('app'); + +var hello = { + attach: function (options) { + this.hello = options.message || 'Why hello!'; + } +}; + +app.use(hello, { + message: "Hi! How are you?" +}); + +// Will print, "Hi! How are you?" +console.log(app.hello); +``` + +Virtually all additional functionality in flatiron comes from broadway plugins, such as `flatiron.plugins.http` and `flatiron.plugins.cli`. + +### `app.config` + +`flatiron.app` comes with a [`config`](https://github.com/flatiron/broadway/blob/master/lib/broadway/plugins/config.js) plugin pre-loaded, which adds configuration management courtesy [nconf](https://github.com/flatiron/nconf). `app.config` has the same api as the `nconf` object. + +The `literal` store is configured by default. If you want to use different stores you can easily attach them to the `app.config` instance. + +```js +// add the `env` store to the config +app.config.use('env'); + +// add the `file` store the the config +app.config.use('file', { file: 'path/to/config.json' }); + +// or using an alternate syntax +app.config.env().file({ file: 'path/to/config.json' }); + +// and removing stores +app.config.remove('literal'); +``` + +### `app.log` + +`flatiron.app` will also load a [`log`](https://github.com/flatiron/broadway/blob/master/lib/broadway/plugins/log.js) plugin during the init phase, which attaches a [winston container](https://github.com/flatiron/winston) to `app.log`. This logger is configured by combining the `app.options.log` property with the configuration retrieved from `app.config.get('log')`. + +## Create An HTTP Server with `flatiron.plugins.http(options)`: + +This plugin adds http serving functionality to your flatiron app by attaching the following properties and methods: + +### Define Routes with `app.router`: + +This is a [director](https://github.com/flatiron/director) router configured to route http requests after the middlewares in `app.http.before` are applied. Example routes include: + +```js + +// GET / +app.router.get('/', function () { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }); + this.res.end('Hello world!\n'); +}); + +// POST to / +app.router.post('/', function () { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }); + this.res.write('Hey, you posted some cool data!\n'); + this.res.end(util.inspect(this.req.body, true, 2, true) + '\n'); +}); + +// Parameterized routes +app.router.get('/sandwich/:type', function (type) { + if (~['bacon', 'burger'].indexOf(type)) { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }); + this.res.end('Serving ' + type + ' sandwich!\n'); + } + else { + this.res.writeHead(404, { 'Content-Type': 'text/plain' }); + this.res.end('No such sandwich, sorry!\n'); + } +}); +``` + +`app.router` can also route against regular expressions and more! To learn more about director's advanced functionality, visit director's [project page](https://github.com/flatiron/director#readme). + + +### Access The Server with `app.server`: + +This is a [union](https://github.com/flatiron/union) middleware kernel. + +### Modify the Server Options with `app.http`: + +This object contains options that are passed to the union server, including `app.http.before`, `app.http.after` and `app.http.headers`. + +These properties may be set by passing them through as options: + +```js +app.use(flatiron.plugins.http, { + before: [], + after: [] +}); +``` + +You can read more about these options on the [union project page](https://github.com/flatiron/union#readme). + +### Start The Server with `app.start(port, , )` + +This method will both call `app.init` (which will call any asynchronous initialization steps on loaded plugins) and start the http server with the given arguments. For example, the following will start your flatiron http server on port 8080: + +```js +app.start(8080); +``` + +## Create a CLI Application with `flatiron.plugins.cli(options)` + +This plugin turns your app into a cli application framework. For example, [jitsu] +(https://github.com/nodejitsu/jitsu) uses flatiron and the cli plugin. + +Valid options include: + +```js +{ + "argvOptions": {}, // A configuration hash passed to the cli argv parser. + "usage": [ "foo", "bar" ], // A message to show for cli usage. Joins arrays with `\n`. + "dir": require('path').join(__dirname, 'lib', 'commands'), // A directory with commands to lazy-load + "notFoundUsage": false // Disable help messages when command not found +} +``` + +### Add lazy-loaded CLI commands with `options.dir` and `app.commands`: + + Flatiron CLI will automatically lazy-load modules defining commands in the directory specified by `options.dir`. For example: + +```js +// example2.js +var path = require('path'), + flatiron = require('./lib/flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.cli, { + dir: path.join(__dirname, 'cmds') +}); + +app.start(); +``` + +```js +// cmd/highfive.js +var highfive = module.exports = function highfive (person, cb) { + this.log.info('High five to ' + person + '!'); + cb(null); +}; +``` + +In the command, you expose a function of arguments and a callback. `this` is set to `app`, and the routing is taken care of automatically. + +Here it is in action: + +``` +% node example2.js highfive Flatiron +info: High five to Flatiron! +``` + +You can also define these commands by adding them directly to `app.commands` yourself: + +``` +// example2b.js +var flatiron = require('./lib/flatiron'), + app = flatiron.app; + +var path = require('path'), + flatiron = require('./lib/flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.cli); + +app.commands.highfive = function (person, cb) { + this.log.info('High five to ' + person + '!'); + cb(null); +}; + +app.start(); +``` + +``` +% node example2b.js highfive Flatiron +info: High five to Flatiron! +``` + +Callback will always be the last argument provided to a function assigned to command + +```js +app.commands.highfive = function (person, cb) { + this.log.info('High five to ' + person + '!'); + console.log(arguments); +} +``` + +``` +% node example2b.js highfive Flatiron lol haha +info: High five to Flatiron! +{ + '0': 'Flatiron', + '1': 'lol', + '2': 'haha', + '3': [Function] +} +``` + +### Define Ad-Hoc Commands With `app.cmd(path, handler)`: + +This adds the cli routing path `path` to the app's CLI router, using the [director](https://github.com/flatiron/director) route handler `handler`, aliasing `app.router.on`. `cmd` routes are defined the same way as http routes, except that it uses ` ` (a space) for a delimiter instead of `/`. + +For example: + +```js +// example.js +var flatiron = require('./lib/flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.cli, { + usage: [ + 'usage: node test.js hello ', + '', + ' This will print "hello "' + ] +}); + +app.cmd('hello :person', function (person) { + app.log.info('hello ' + person + '!'); +}); + +app.start() +``` + +When you run this program correctly, it will say hello: + +``` +% node example.js hello person +info: hello person! +``` + +If not, you get a friendly usage message: + +``` +% node test.js hello +help: usage: node test.js hello +help: +help: This will print "hello " +``` + +### Check CLI Arguments with `app.argv`: + +Once your app is started, `app.argv` will contain the [optimist](http://github.com/substack/node-optimist)-parsed argv options hash, ready to go! + +Here's an example: + +```js +// example3.js +var flatiron = require('./lib/flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.cli); + +app.start(); + +app.log.info(JSON.stringify(app.argv)); +``` + +This prints: + +``` +% node example3.js +info: {"_":[], "$0": "node ./example3.js"} +``` + +Awesome! + +### Add a Default Help Command with `options.usage`: + +When attaching the CLI plugin, just specify options.usage to get a friendly default message for when there aren't any matching routes: + +```js +// example4.js +var flatiron = require('./lib/flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.cli, { + usage: [ + 'Welcome to my app!', + 'Your command didn\'t do anything.', + 'This is expected.' + ] +}); + +app.start(); +``` + +``` +% node example4.js +help: Welcome to my app! +help: Your command didn't do anything. +help: This is expected. +``` + +### Start The Application with `app.start(callback)`: + +As seen in these examples, starting your app is as easy as `app.start`! this method takes a callback, which is called when an `app.command` completes. Here's a complete example demonstrating this behavior and how it integrates with `options.usage`: + +```js +// example5.js +var path = require('path'), + flatiron = require('./lib/flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.cli, { + usage: [ + '`node example5.js error`: Throws an error.', + '`node example5.js friendly`: Does not throw an error.' + ] +}); + +app.commands.error = function (cb) { + cb(new Error('I\'m an error!')); +}; + +app.commands.friendly = function (cb) { + cb(null); +} + +app.start(function (err) { + if (err) { + app.log.error(err.message || 'You didn\'t call any commands!'); + app.log.warn('NOT OK.'); + return process.exit(1); + } + app.log.info('OK.'); +}); +``` + +Here's how our app behaves: + +``` +% node example5.js friendly +info: OK. + +% node example5.js error +error: I'm an error! +warn: NOT OK. + +% node example5.js +help: `node example2b.js error`: Throws an error. +help: `node example2b.js friendly`: Does not throw an error. +error: You didn't call any commands! +warn: NOT OK. +``` + +# Read More About Flatiron! + +## Articles + +* [Scaling Isomorphic Javascript Code](http://blog.nodejitsu.com/scaling-isomorphic-javascript-code) +* [Introducing Flatiron](http://blog.nodejitsu.com/introducing-flatiron) +* [Writing CLI Apps with Flatiron](http://blog.jit.su/writing-cli-apps-with-flatiron) + +## Sub-Projects + +* [Broadway](https://github.com/flatiron/broadway) +* [Union](https://github.com/flatiron/union) +* [Director](https://github.com/flatiron/director) +* [Plates](https://github.com/flatiron/plates) +* [Resourceful](https://github.com/flatiron/resourceful) +* [And More](https://github.com/flatiron)! + +# Tests + +Tests are written in vows: + +``` bash + $ npm test +``` + +#### Author: [Nodejitsu Inc.](http://nodejitsu.com) +#### License: MIT diff --git a/node_modules/forever/node_modules/flatiron/bin/flatiron b/node_modules/forever/node_modules/flatiron/bin/flatiron new file mode 100755 index 0000000..760f978 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/bin/flatiron @@ -0,0 +1,30 @@ +#!/usr/bin/env node + +var flatiron = require('../lib/flatiron'), + path = require('path'), + app = flatiron.app; + +var actions = { + create: 'Creates an empty template for a flatiron application' +}; + +app.version = flatiron.version; + +app.use(flatiron.plugins.cli, { + version: true, + dir: path.join(__dirname, '..', 'lib', 'flatiron', 'cli'), + usage: [ + 'flatiron', + '', + 'Commands:' + ].concat(Object.keys(actions).map(function(key){ + return ' ' + key + ' - ' + actions[key]; + })) +}); + +// +// Alias `flatiron create` to `flatiron new`. +// +app.alias('new', 'create'); + +app.start(); diff --git a/node_modules/forever/node_modules/flatiron/examples/cli-sample/index.js b/node_modules/forever/node_modules/flatiron/examples/cli-sample/index.js new file mode 100644 index 0000000..cd8bc8a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/cli-sample/index.js @@ -0,0 +1,28 @@ +console.time('start'); +var flatiron = require('../../lib/flatiron'), + app = flatiron.app; + +require('pkginfo')(module, 'version'); + +app.version = exports.version; + +app.use(flatiron.plugins.cli, { + dir: __dirname, + usage: [ + 'Simple app example for flatiron!', + '', + 'app start - print a prompt and arguments', + 'print - echo a message' + ], + version: true +}); + +app.cmd('app start', function () { + console.timeEnd('start'); + console.dir('it works!!!'); + app.prompt.get('name', function (err, name) { + console.dir(arguments); + }) +}) + +app.start(); diff --git a/node_modules/forever/node_modules/flatiron/examples/cli-sample/print.js b/node_modules/forever/node_modules/flatiron/examples/cli-sample/print.js new file mode 100644 index 0000000..ea2d2be --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/cli-sample/print.js @@ -0,0 +1,5 @@ +var print = module.exports = function print(msg) { + console.log(msg); +} +print.usage = 'Print out a '; + diff --git a/node_modules/forever/node_modules/flatiron/examples/http-sample.js b/node_modules/forever/node_modules/flatiron/examples/http-sample.js new file mode 100644 index 0000000..be752e0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/http-sample.js @@ -0,0 +1,30 @@ +var util = require('util'), + flatiron = require('../lib/flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.http); + +app.router.get('/', function () { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }); + this.res.end('Hello world!\n'); +}); + +app.router.post('/', function () { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }); + this.res.write('Hey, you posted some cool data!\n'); + this.res.end(util.inspect(this.req.body, true, 2, true) + '\n'); +}); + +app.router.get('/sandwich/:type', function (type) { + if (~['bacon', 'burger'].indexOf(type)) { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }); + this.res.end('Serving ' + type + ' sandwich!\n'); + } + else { + this.res.writeHead(404, { 'Content-Type': 'text/plain' }); + this.res.end('No such sandwich, sorry!\n'); + } +}); + +app.start(8080); + diff --git a/node_modules/forever/node_modules/flatiron/examples/resourceful-app/app.js b/node_modules/forever/node_modules/flatiron/examples/resourceful-app/app.js new file mode 100644 index 0000000..5c47e0c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/resourceful-app/app.js @@ -0,0 +1,8 @@ + +var flatiron = require('../../lib/flatiron'), + app = module.exports = flatiron.app; + +app.use(flatiron.plugins.resourceful, { + root: __dirname, + engine: 'memory' +}); diff --git a/node_modules/forever/node_modules/flatiron/examples/resourceful-app/app/resources/creature.js b/node_modules/forever/node_modules/flatiron/examples/resourceful-app/app/resources/creature.js new file mode 100644 index 0000000..ca919be --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/resourceful-app/app/resources/creature.js @@ -0,0 +1,13 @@ +var resourceful = require('resourceful'); + +var Creature = module.exports = resourceful.define('creature', function () { + this.string('diet'); + this.bool('vertebrate'); + this.array('belly'); + + this.timestamps(); +}); + +Creature.prototype.feed = function (food) { + this.belly.push(food); +}; diff --git a/node_modules/forever/node_modules/flatiron/examples/resourceful-app/package.json b/node_modules/forever/node_modules/flatiron/examples/resourceful-app/package.json new file mode 100644 index 0000000..c739af3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/resourceful-app/package.json @@ -0,0 +1,15 @@ +{ + "name": "resourceful-app", + "description": "An example flatiron app using resourceful", + "version": "0.1.0", + "author": "Nodejitsu Inc. ", + "dependencies": { + "flatiron": "0.3.x", + "resourceful": "0.3.x" + }, + "main": "./app", + "engines": { + "node": ">= 0.6.4" + } +} + diff --git a/node_modules/forever/node_modules/flatiron/examples/socket.io/index.html b/node_modules/forever/node_modules/flatiron/examples/socket.io/index.html new file mode 100644 index 0000000..9798bb0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/socket.io/index.html @@ -0,0 +1,8 @@ + + diff --git a/node_modules/forever/node_modules/flatiron/examples/socket.io/server.js b/node_modules/forever/node_modules/flatiron/examples/socket.io/server.js new file mode 100644 index 0000000..b119013 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/socket.io/server.js @@ -0,0 +1,38 @@ +// Socket.io configuration for Flatiron +// -------------------------------------------------- // + +var flatiron = require('../../lib/flatiron'), + fs = require("fs"), + app = flatiron.app; + +app.use(flatiron.plugins.http, { + before: [function (req, res) { + fs.readFile(__dirname + '/index.html', function (err, data) { + if (err) { + res.writeHead(500); + return res.end('Error loading index.html'); + } + res.writeHead(200); + res.end(data); + }); + + }] +}); + + +// Set the server to listen on port `8080`. +// It is important to do this first, as app.server +// isn't actually created until you start() +app.start(8080); + +// Socket.io +// -------------------------------------------------- // + +var io = require('socket.io').listen(app.server); + +io.sockets.on('connection', function(socket) { + socket.emit('news', { hello: 'world' }); + socket.on('my other event', function(data) { + console.log(data); + }); +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/examples/static-app/app.js b/node_modules/forever/node_modules/flatiron/examples/static-app/app.js new file mode 100644 index 0000000..9c17ad9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/static-app/app.js @@ -0,0 +1,12 @@ + +var flatiron = require('../../lib/flatiron'), + app = flatiron.app; + +app.use(flatiron.plugins.http); +app.use(flatiron.plugins.static, { root: __dirname }); + +app.router.get('/headers', function () { + this.res.json(this.req.headers); +}); + +module.exports = app; diff --git a/node_modules/forever/node_modules/flatiron/examples/static-app/app/assets/style.css b/node_modules/forever/node_modules/flatiron/examples/static-app/app/assets/style.css new file mode 100644 index 0000000..6d64cfc --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/static-app/app/assets/style.css @@ -0,0 +1 @@ +body { color: lime; background-color: black; } diff --git a/node_modules/forever/node_modules/flatiron/examples/static-app/app/assets/style.js b/node_modules/forever/node_modules/flatiron/examples/static-app/app/assets/style.js new file mode 100644 index 0000000..371d5db --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/static-app/app/assets/style.js @@ -0,0 +1 @@ +document.write('Hello World!'); diff --git a/node_modules/forever/node_modules/flatiron/examples/static-app/package.json b/node_modules/forever/node_modules/flatiron/examples/static-app/package.json new file mode 100644 index 0000000..573743d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/examples/static-app/package.json @@ -0,0 +1,15 @@ +{ + "name": "static-app", + "description": "An example flatiron app using static plugin", + "version": "0.1.0", + "author": "Nodejitsu Inc. ", + "dependencies": { + "flatiron": "0.3.x", + "st": "0.1.0" + }, + "main": "./app", + "engines": { + "node": ">= 0.6.4" + } +} + diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron.js b/node_modules/forever/node_modules/flatiron/lib/flatiron.js new file mode 100644 index 0000000..1dc2cd7 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron.js @@ -0,0 +1,75 @@ +/* + * flatiron.js: An elegant blend of convention and configuration for building apps in Node.js and the browser. + * + * Copyright(c) 2011 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var fs = require('fs'), + path = require('path'), + broadway = require('broadway'); + +var flatiron = exports, + _app; + +// +// Expose version through `pkginfo` +// +require('pkginfo')(module, 'version'); + +// +// ### Export core `flatiron` modules +// +flatiron.common = require('./flatiron/common'); +flatiron.constants = require('./flatiron/constants'); +flatiron.formats = broadway.formats; +flatiron.App = require('./flatiron/app').App; + +// +// ### Expose core `flatiron` plugins +// Hoist those up from `broadway` and define each of +// the `flatiron` plugins as a lazy loaded `require` statement +// +flatiron.plugins = broadway.common.mixin( + {}, + broadway.plugins, + broadway.common.requireDirLazy(path.join(__dirname, 'flatiron', 'plugins')) +); + + +Object.defineProperty(flatiron, 'app', { + + // Don't allow another `.defineProperty` on 'app' + configurable: false, + + // + // ### getter @app {flatiron.App} + // Gets the default top-level Application for `flatiron` + // + get: function() { + return _app = _app || flatiron.createApp(); + }, + + // + // #### setter @app {flatiron.App} + // Options for the application to create or the application to set + // + set: function(value) { + if (value instanceof flatiron.App) return _app = value; + return _app = flatiron.createApp(value); + } + +}); + + +// +// ### function createApp (options) +// #### @options {Object} Options for the application to create +// Creates a new instance of `flatiron.App` with the +// specified `options`. +// +flatiron.createApp = function (options) { + return new flatiron.App(options); +}; + diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron/app.js b/node_modules/forever/node_modules/flatiron/lib/flatiron/app.js new file mode 100644 index 0000000..5bf2467 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron/app.js @@ -0,0 +1,32 @@ +/* + * app.js: Core Application object for managing plugins and features in broadway + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var fs = require('fs'), + path = require('path'), + util = require('util'), + broadway = require('broadway'), + directories = broadway.common.directories, + constants = require('./constants'); + +var App = exports.App = function (options) { + broadway.App.call(this, options); +}; + +// +// Inherit from `broadway.App`. +// +util.inherits(App, broadway.App); + +// +// ### function init (callback) +// #### @callback {function} Continuation to respond to when complete. +// Initializes this instance of `flatiron.App` +// +App.prototype.init = function () { + broadway.App.prototype.init.apply(this, Array.prototype.slice.call(arguments)); +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron/cli/create.js b/node_modules/forever/node_modules/flatiron/lib/flatiron/cli/create.js new file mode 100644 index 0000000..caf8567 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron/cli/create.js @@ -0,0 +1,97 @@ +var fs = require('fs'), + path = require('path'), + flatiron = require('../../flatiron'), + common = flatiron.common, + app = flatiron.app; + +module.exports = function create(name, type, callback) { + type = type || 'http'; + + var existsSync = fs.existsSync || path.existsSync, + root = path.join(process.cwd(), name), + scaffold = path.join(__dirname, '..', '..', '..', 'scaffolds', type), + info = {}; + + if (!existsSync(scaffold)) { + app.log.error('Scaffold named ' + type.yellow + ' does not exist'); + return callback(); + } + + // + // Prompts user for details about their app to put in `package.json`. + // + function prompt (next) { + var fields = ['name', 'author', 'description', 'homepage']; + app.prompt.override = {name: name}; + app.prompt.start(); + app.prompt.addProperties(info, fields, next); + } + + // + // Creates directories specified in `/scaffolds/:type/directories.json`. + // + function createDirs(next) { + var dirs = common.directories.normalize( + common.mixin({}, flatiron.constants.DIRECTORIES, { '#ROOT': root }), + JSON.parse(fs.readFileSync(path.join(scaffold, 'directories.json'), 'utf8')) + ); + + Object.keys(dirs).forEach(function (name) { + app.log.info('Creating directory ' + name.grey); + }); + + common.directories.create(dirs, next); + } + + // + // Creates files specified in `/scaffolds/:type/files.json`. + // + function createFiles(next) { + var files = common.directories.normalize( + common.mixin({}, flatiron.constants.DIRECTORIES, { '#ROOT': root }), + JSON.parse(fs.readFileSync(path.join(scaffold, 'files.json'), 'utf8')) + ); + + function copyFile(file, nextFile) { + app.log.info('Writing file ' + file.grey); + common.cpr(path.join(scaffold, file), files[file], nextFile); + } + + common.async.mapSeries(Object.keys(files), copyFile, next); + } + + // + // Creates a templated package.json from `/scaffolds/:type/package.json`. + // + function createPackage(next) { + var pkg = JSON.parse(fs.readFileSync(path.join(scaffold, 'package.json'), 'utf8')); + + pkg.dependencies.flatiron = flatiron.version; + + flatiron.common.mixin(pkg, info); + + app.log.info('Writing ' + 'package.json'.grey); + fs.writeFile(path.join(root, 'package.json'), JSON.stringify(pkg, null, 2) + '\n', next); + } + + app.log.info('Creating application ' + (name ? name.magenta : '')); + app.log.info('Using ' + type.yellow + ' scaffold.'); + common.async.series([ + prompt, + createDirs, + createPackage, + createFiles + ], function onComplete(next) { + app.log.info('Application ' + info.name.magenta + ' is now ready'); + callback(); + } + ); +} + +module.exports.usage = [ + 'Generates a flatiron skeleton application. If no ', + 'is specified an HTTP application will be created.', + ' can currently be either cli or http', + '', + 'create ', +]; diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron/common.js b/node_modules/forever/node_modules/flatiron/lib/flatiron/common.js new file mode 100644 index 0000000..dbaf012 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron/common.js @@ -0,0 +1,52 @@ +/* + * common.js: Common utility functions for flatiron. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var fs = require('fs'), + broadway = require('broadway'); + +// +// Hoist `broadway.common` to `flatiron.common`. +// +var common = module.exports = broadway.common.mixin({}, broadway.common); + +// +// ### function templateUsage (app, commands) +// Updates the references to `` to `app.name` in usage for the +// specified `commands`. +// +common.templateUsage = function (app, commands) { + if (!app.name) { + return commands; + } + + function templateUsage(usage) { + return usage.map(function (line) { + return line.replace(/\/ig, app.name); + }); + } + + Object.keys(commands).forEach(function (command) { + if (command === 'usage') { + commands.usage = templateUsage(commands.usage); + } + else if (commands[command].usage) { + commands[command].usage = templateUsage(commands[command].usage); + } + }); +}; + +// +// ### function tryReaddirSync (dir) +// #### @dir {string} Directory to attempt to list +// +// Attempts to call `fs.readdirSync` but ignores errors. +// +common.tryReaddirSync = function (dir) { + try { return fs.readdirSync(dir) } + catch (err) { return [] } +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron/constants.js b/node_modules/forever/node_modules/flatiron/lib/flatiron/constants.js new file mode 100644 index 0000000..0dc1584 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron/constants.js @@ -0,0 +1,19 @@ +/* + * constants.js: Constants within the Flatiron framework. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var constants = exports; + +constants.DIRECTORIES = { + "#ENV": "#CONFIG/env", + "#APP": "#ROOT/app", + "#CONFIG": "#ROOT/config", + "#DOCS": "#ROOT/docs", + "#LOG": "#ROOT/log", + "#LIB": "#ROOT/lib", + "#TEST": "#ROOT/test" +}; diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/cli.js b/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/cli.js new file mode 100644 index 0000000..00d7e38 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/cli.js @@ -0,0 +1,453 @@ +/* + * index.js: Top-level plugin exposing CLI features in flatiron + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var fs = require('fs'), + path = require('path'), + flatiron = require('../../flatiron'), + common = flatiron.common, + director = require('director'); + +// +// ### Name this plugin +// +exports.name = 'cli'; + +// +// ### function attach (options, done) +// #### @options {Object} Options for this plugin +// Initializes `this` (the application) with the core `cli` plugins consisting of: +// `argv`, `prompt`, `routing`, `commands` in that order. +// +exports.attach = function (options) { + var app = this; + options = options || {}; + + // + // Define the `cli` namespace on the app for later use + // + app.cli = app.cli || {}; + + // + // Mixin some keys properly so that plugins can also set them + // + options.argv = common.mixin({}, app.cli.argv || {}, options.argv || {}); + options.prompt = common.mixin({}, app.cli.prompt || {}, options.prompt || {}); + + app.cli = common.mixin({}, app.cli, options); + + if (app.cli.notFoundUsage == undefined) { + app.cli.notFoundUsage = true; + } + + // + // Setup `this.argv` to use `optimist`. + // + exports.argv.call(this, app.cli.argv); + app.use(flatiron.plugins.inspect); + + // + // If `options.version` is truthy, `app.version` is defined and `-v` or + // `--version` command line parameters were passed, print out `app.version` + // and exit. + // + if (app.cli.version && app.version && (this.argv.v || this.argv.version)) { + console.log(app.version); + process.exit(0); + } + + // + // Setup `this.prompt`. + // + exports.prompt.call(this, app.cli.prompt); + + // + // Setup `app.router` and associated core routing method. + // + app.router = new director.cli.Router().configure({ + async: app.async || app.cli.async + }); + + app.start = function (options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + callback = callback || function () {}; + app.init(options, function (err) { + if (err) { + return callback(err); + } + + app.router.dispatch('on', app.argv._.join(' '), app.log, callback); + }); + }; + + app.cmd = function (path, handler) { + app.router.on(path, handler); + }; + + exports.commands.call(this); +}; + +// +// ### function init (done) +// #### @done {function} Continuation to respond to when complete +// Initializes this plugin by setting `winston.cli` (i.e. `app.log.cli`) +// to enable colors and padded levels. +// +exports.init = function (done) { + var app = this, + logger; + + if (!app.log.help) { + logger = app.log.get('default'); + logger.cli().extend(app.log); + } + + if (app.config) { + // + // Create a literal store for argv to + // avoid re-parsing CLI options. + // + app.config.use('argv', { + type: 'literal', + store: app.argv + }); + + app.config.env(); + } + + done(); +}; + +// +// ### function argv (options) +// #### @options {Object} Pass-thru options for optimist +// Sets up `app.argv` using `optimist` and the specified options. +// +exports.argv = function (options) { + var optimist = require('optimist').string('_'); + + if (options && Object.keys(options).length) { + optimist = optimist.options(options); + this.showOptions = optimist.help; + this.argv = optimist.argv; + } + else { + this.showOptions = optimist.help; + this.argv = optimist.argv; + } +}; + +// +// ### function commands (options) +// #### @options {Object} Options for the application commands +// Configures the `app.commands` object which is lazy-loaded from disk +// along with some default logic for: `help` and `alias`. +// +exports.commands = function (options) { + var app = this; + + function showUsage(target) { + target = Array.isArray(target) ? target : target.split('\n'); + target.forEach(function (line) { + app.log.help(line); + }); + + var lines = app.showOptions().split('\n').filter(Boolean); + + if (lines.length) { + app.log.help(''); + lines.forEach(function (line) { + app.log.help(line); + }); + } + } + + // + // Setup any pass-thru options to the + // application instance but make them lazy + // + app.usage = app.cli.usage; + app.cli.source = app.cli.dir || app.cli.source; + app.commands = app.commands || {}; + + // + // Helper function which loads the file for the + // specified `name` into `app.commands`. + // + function loadCommand(name, command, silent) { + var resource = app.commands[name]; + + if (resource && (!command || resource[command])) { + return true; + } + + if (app.cli.source) { + if (!app.cli.sourceDir) { + try { + var stats = fs.statSync(app.cli.source); + app.cli.sourceDir = stats.isDirectory(); + } + catch (ex) { + if (app.cli.notFoundUsage) { + showUsage(app.usage || [ + 'Cannot find commands for ' + name.magenta + ]); + } + + return false; + } + } + + try { + if (app.cli.sourceDir) { + app.commands[name] = require(path.join(app.cli.source, name || '')); + } + else { + app.commands = common.mixin(app.commands, require(app.cli.source)); + } + return true; + } + catch (err) { + // If that file could not be found, error message should start with + // "Cannot find module" and contain the name of the file we tried requiring. + if (!err.message.match(/^Cannot find module/) || (name && err.message.indexOf(name) === -1)) { + throw err; + } + + if (!silent) { + if (app.cli.notFoundUsage) { + showUsage(app.usage || [ + 'Cannot find commands for ' + name.magenta + ]); + } + } + + return false; + } + } + } + + // + // Helper function to ensure the user wishes to execute + // a destructive command. + // + function ensureDestroy(callback) { + app.prompt.get(['destroy'], function (err, result) { + if (result.destroy !== 'yes' && result.destroy !== 'y') { + app.log.warn('Destructive operation cancelled'); + return callback(true); + } + + callback(); + }); + } + + // + // Helper function which executes the command + // represented by the Array of `parts` passing + // control to the `callback`. + // + function executeCommand(parts, callback) { + var name, + shouldLoad = true, + command, + usage; + + if (typeof parts === 'undefined' || typeof parts === 'function') { + throw(new Error('parts is a required argument of type Array')); + } + + name = parts.shift(); + + if (app.cli.source || app.commands[name]) { + if (app.commands[name]) { + shouldLoad = false; + if (typeof app.commands[name] != 'function' && !app.commands[name][parts[0]]) { + shouldLoad = true; + } + } + + if (shouldLoad && !loadCommand(name, parts[0])) { + return callback(); + } + + command = app.commands[name]; + while (command) { + usage = command.usage; + + if (!app.argv.h && !app.argv.help && typeof command === 'function') { + while (parts.length + 1 < command.length) { + parts.push(null); + } + + if (command.destructive) { + return ensureDestroy(function (err) { + return err ? callback() : command.apply(app, parts.concat(callback)); + }) + } + + command.apply(app, parts.concat(callback)); + return; + } + + command = command[parts.shift()]; + } + + // + // Since we have not resolved a needle, try and print out a usage message + // + if (usage || app.cli.usage) { + showUsage(usage || app.cli.usage); + callback(false); + } + } + else if (app.usage) { + // + // If there's no directory we're supposed to search for modules, simply + // print out usage notice if it's provided. + // + showUsage(app.cli.usage); + callback(true); + } + } + + // + // Expose the executeCommand method + // + exports.executeCommand = executeCommand; + + // + // Allow commands to be aliased to subcomponents. e.g. + // + // app.alias('list', { resource: 'apps', command: 'list' }); + // app.alias('new', { command: 'create' }); + // app.alias('new', 'create'); + // + app.alias = function (target, source) { + app.commands.__defineGetter__(target, function () { + + var resource = source.resource || source.command || source, + command = source.resource ? source.command : null; + + loadCommand(resource, command, true); + resource = app.commands[resource]; + + if (resource) { + return source.resource && source.command + ? resource[source.command] + : resource; + } + }); + }; + + // + // Set the `loadCommand` function to run + // whenever the router has not matched + // the CLI arguments, `process.argv`. + // + app.router.notfound = function (callback) { + executeCommand(app.argv._.slice(), callback); + }; + + // + // Setup default help command + // + app.cmd(/help ([^\s]+)?\s?([^\s]+)?/, app.showHelp = function showHelp() { + var args = Array.prototype.slice.call(arguments).filter(Boolean), + callback = typeof args[args.length - 1] === 'function' && args.pop(), + resource, + usage; + + function displayAndRespond(found) { + showUsage(usage || app.usage); + if (!found) { + app.log.warn('Cannot find help for ' + args.join(' ').magenta); + } + + if (callback) { + callback(); + } + } + + if (!loadCommand(args[0], args[1], true)) { + return displayAndRespond(false); + } + + resource = app.commands[args[0]]; + usage = resource.usage; + + for (var i = 1; i < args.length; i++) { + if (!resource[args[i]]) { + return displayAndRespond(false); + } + else if (resource[args[i]].usage) { + resource = resource[args[i]]; + usage = resource.usage; + } + } + + displayAndRespond(true); + }); +}; + +// +// ### function prompt (options) +// #### @options {Object} Options for the prompt. +// Sets up the application `prompt` property to be a lazy +// setting which loads the `prompt` module. +// +exports.prompt = function (options) { + options = options || {}; + + this.__defineGetter__('prompt', function () { + if (!this._prompt) { + // + // Pass-thru any prompt specific options that are supplied. + // + var prompt = require('prompt'), + self = this; + + prompt.allowEmpty = options.allowEmpty || prompt.allowEmpty; + prompt.message = options.message || prompt.message; + prompt.delimiter = options.delimiter || prompt.delimiter; + prompt.properties = options.properties || prompt.properties; + + // + // Setup `destroy` property for destructive commands + // + prompt.properties.destroy = { + name: 'destroy', + message: 'This operation cannot be undone, Would you like to proceed?', + default: 'yes' + }; + + // + // Hoist up any prompt specific events and re-emit them as + // `prompt::*` events. + // + ['start', 'pause', 'resume', 'prompt', 'invalid'].forEach(function (ev) { + prompt.on(ev, function () { + var args = Array.prototype.slice.call(arguments); + self.emit.apply(self, [['prompt', ev]].concat(args)); + }); + }); + + // + // Extend `this` (the application) with prompt functionality + // and open `stdin`. + // + this._prompt = prompt; + this._prompt.start().pause(); + } + + return this._prompt; + }); +}; diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/http.js b/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/http.js new file mode 100644 index 0000000..a50a596 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/http.js @@ -0,0 +1,103 @@ +/* + * http.js: Top-level plugin exposing HTTP features in flatiron + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var director = require('director'), + flatiron = require('../../flatiron'), + union; + +try { + // + // Attempt to require union. + // + union = require('union'); +} +catch (ex) { + // + // Do nothing since this is a progressive enhancement + // + console.warn('flatiron.plugins.http requires the `union` module from npm'); + console.warn('install using `npm install union`.'); + console.trace(); + process.exit(1); +} + +// +// Name this plugin. +// +exports.name = 'http'; + +exports.attach = function (options) { + var app = this; + + // + // Define the `http` namespace on the app for later use + // + app.http = app.http || {}; + + app.http = flatiron.common.mixin({}, app.http, options || {}); + + app.http.route = flatiron.common.mixin({ async: true }, app.http.route || {}); + + app.http.buffer = (app.http.buffer !== false); + app.http.before = app.http.before || []; + app.http.after = app.http.after || []; + app.http.headers = app.http.headers || { + 'x-powered-by': 'flatiron ' + flatiron.version + }; + + app.router = new director.http.Router().configure(app.http.route); + + app.start = function (port, host, callback) { + if (!callback && typeof host === 'function') { + callback = host; + host = null; + } + + app.createServer(); + + app.init(function (err) { + if (err) { + if (callback) { + return callback(err); + } + + throw err; + } + + app.listen(port, host, callback); + }); + }; + + app.createServer = function(){ + app.server = union.createServer({ + buffer: app.http.buffer, + after: app.http.after, + before: app.http.before.concat(function (req, res) { + if (!app.router.dispatch(req, res, app.http.onError || union.errorHandler)) { + if (!app.http.onError) res.emit('next'); + } + }), + headers: app.http.headers, + limit: app.http.limit, + https: app.http.https + }); + }; + + app.listen = function (port, host, callback) { + if (!callback && typeof host === 'function') { + callback = host; + host = null; + } + + if (!app.server) app.createServer(); + + return host + ? app.server.listen(port, host, callback) + : app.server.listen(port, callback); + }; +}; diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/resourceful.js b/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/resourceful.js new file mode 100644 index 0000000..1ae8c83 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/resourceful.js @@ -0,0 +1,125 @@ +/* + * resourceful.js: Top-level plugin exposing resourceful to flatiron app + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ +var path = require('path'), + fs = require('fs'), + flatiron = require('../../flatiron'), + common = flatiron.common, + resourceful, + existsSync = fs.existsSync || path.existsSync; + +try { + // + // Attempt to require resourceful. + // + resourceful = require('resourceful'); +} +catch (ex) { + // + // Do nothing since this is a progressive enhancement + // + console.warn('flatiron.plugins.resourceful requires the `resourceful` module from npm'); + console.warn('install using `npm install resourceful`.'); + console.trace(); + process.exit(1); +} + +exports.name = 'resourceful'; + +exports.attach = function (options) { + var app = this; + options = options || {}; + + // + // Accept string `options`. + // + if (typeof options === 'string') { + options = { root: options }; + } + + // + // Create `app.resources` if it does not exist already. + // + app.resources = app.resources || {}; + + // + // Expose a couple of resourceful helpers + // + app.define = resourceful.define; + + // + // Lazy-load the resources directory based on a few intelligent defaults: + // + // * `options.dir`: Explicit path to resources directory + // * `options.root`: Relative root to the resources directory ('/app/resources') + // * `app.root`: Relative root to the resources directory ('/app/resources') + // + if (options.dir || options.root || app.root) { + app._resourceDir = options.dir + || path.join(options.root || app.root, 'app', 'resources'); + + try { + existsSync(app._resourceDir) + } + catch (err) { + // + // If an invalid path has been provided, don't attempt to load it + // + console.error('invalid resource path: ' + app._resourceDir); + return; + } + + var files = common.tryReaddirSync(app._resourceDir); + + if (files.length === 0) { + // + // If no resources were found in the path, warn, but don't error + // + console.warn('no resources found at: ' + app._resourceDir); + } + + files.forEach(function (file) { + file = file.replace('.js', ''); + app.resources.__defineGetter__(common.capitalize(file), function () { + delete app.resources[common.capitalize(file)]; + return app.resources[common.capitalize(file)] = require( + path.resolve(app._resourceDir, file) + ); + }); + }); + + } + // + // TODO: Determine how best to integrate `restful` here. + // +}; + +exports.init = function (done) { + var app = this, + options; + + // + // Attempt to merge defaults passed to `app.use(flatiron.plugins.resourceful)` + // with any additional configuration that may have been loaded. + // + options = common.mixin( + {}, + app.options['resourceful'], + app.config.get('resourceful') || {} + ); + + app.config.set('resourceful', options); + + // + // Remark: Should we accept the autoMigrate option? + // + if (options.engine) { + resourceful.use(options.engine, options); + } + + done(); +}; diff --git a/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/static.js b/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/static.js new file mode 100644 index 0000000..01e282a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/lib/flatiron/plugins/static.js @@ -0,0 +1,87 @@ +/* + * static.js: Top-level plugin exposing st's static server to flatiron app + * + * (C) 2012, Nodejitsu, Inc. + * MIT LICENSE + * + */ + +var path = require('path'), + flatiron = require('../../flatiron'), + common = flatiron.common, st; + +try { + // + // Attempt to require st. + // + st = require('st'); +} +catch (ex) { + // + // Do nothing since this is a progressive enhancement + // + console.warn('flatiron.plugins.static requires the `st` module from npm'); + console.warn('install using `npm install st`.'); + console.trace(); + process.exit(1); +} + +exports.name = 'static'; + +exports.attach = function (options) { + var app = this; + + options = options || {}; + + // + // Accept string `options` + // + if (typeof options === 'string') { + options = { root: options }; + } + + // + // Default overrides + // + options.passthrough = true; + + // + // Url for static server + // + options.index = options.index || false; + options.dot = options.dot || false; + options.url = options.url || '/'; + + // + // Attempt to merge defaults passed to `app.use(flatiron.plugins.static)` + // with any additional configuration that may have been loaded + options = common.mixin( + {}, + options, + app.config.get('static') || {} + ); + + app.config.set('static', options); + + // + // `app.static` api to be used by other plugins + // to server static files + // + app.static = function (dir) { + options.path = dir; + app.http.before = app.http.before.concat(st(options)); + } + + // * `options.dir`: Explicit path to assets directory + // * `options.root`: Relative root to the assets directory ('/app/assets') + // * `app.root`: Relative root to the assets directory ('/app/assets') + if (options.dir || options.root || app.root) { + app._staticDir = options.dir + || path.join(options.root || app.root, 'app', 'assets'); + + // + // Serve staticDir using middleware in union + // + app.static(app._staticDir); + } +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/broadway/.npmignore new file mode 100644 index 0000000..d567f61 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/.npmignore @@ -0,0 +1,4 @@ +node_modules +npm-debug.log +.DS_Store + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/.travis.yml b/node_modules/forever/node_modules/flatiron/node_modules/broadway/.travis.yml new file mode 100644 index 0000000..389329f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/.travis.yml @@ -0,0 +1,11 @@ +language: node_js + +node_js: + - 0.6 + - 0.8 + +notifications: + email: + - travis@nodejitsu.com + irc: "irc.freenode.org#nodejitsu" + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/LICENSE b/node_modules/forever/node_modules/flatiron/node_modules/broadway/LICENSE new file mode 100644 index 0000000..1f01e2b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Nodejitsu Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/README.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/README.md new file mode 100644 index 0000000..959ebe1 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/README.md @@ -0,0 +1,124 @@ +# broadway [![Build Status](https://secure.travis-ci.org/flatiron/broadway.png)](http://travis-ci.org/flatiron/broadway) + +*Lightweight application extensibility and composition with a twist of feature +reflection.* + +## Example + +### app.js +```js +var broadway = require("broadway"); + +var app = new broadway.App(); + +// Passes the second argument to `helloworld.attach`. +app.use(require("./plugins/helloworld"), { "delimiter": "!" } ); + +app.init(function (err) { + if (err) { + console.log(err); + } +}); + +app.hello("world"); +``` + +### plugins/helloworld.js + +```js +// `exports.attach` gets called by broadway on `app.use` +exports.attach = function (options) { + + this.hello = function (world) { + console.log("Hello "+ world + options.delimiter || "."); + }; + +}; + +// `exports.init` gets called by broadway on `app.init`. +exports.init = function (done) { + + // This plugin doesn't require any initialization step. + return done(); + +}; +``` + +### run it! + +```bash +josh@onix:~/dev/broadway/examples$ node simple/app.js +Hello world! +josh@onix:~/dev/broadway/examples$ +``` + +## Installation + +### Installing npm (node package manager) +``` bash + $ curl http://npmjs.org/install.sh | sh +``` + +### Installing broadway +``` bash + $ [sudo] npm install broadway +``` + +## API + +### App#init(callback) + +Initialize application and it's plugins, `callback` will be called with null or +initialization error as first argument. + +### App#use(plugin, options) + +Attach plugin to application. `plugin` should conform to following interface: + +```javascript +var plugin = { + "name": "example-plugin", // Plugin's name + + "attach": function attach(options) { + // Called with plugin options once plugin attached to application + // `this` - is a reference to application + }, + + "detach": function detach() { + // Called when plugin detached from application + // (Only if plugin with same name was attached) + // `this` - is a reference to application + }, + + "init": function init(callback) { + // Called on application initialization + // App#init(callback) will be called once every plugin will call `callback` + // `this` - is a reference to application + } +}; +``` + +### App#on(event, callback) and App#emit(event, data) + +App inherits from [EventEmitter2][2], and many plugins build on this +functionality. + +#### Built-In Events: + +* `error:init`: Broadway emits this event when it throws an error while attempting to initialize. + +Read the [EventEmitter2][2] documentation for more information. + +## Tests +All tests are written with [vows][0] and should be run with [npm][1]: + +``` bash + $ npm test +``` + +#### [Charlie Robbins](http://nodejitsu.com) +#### License: MIT + +[0]: http://vowsjs.org +[1]: http://npmjs.org +[2]: https://github.com/hij1nx/EventEmitter2 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/bin/build b/node_modules/forever/node_modules/flatiron/node_modules/broadway/bin/build new file mode 100755 index 0000000..ca128ba --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/bin/build @@ -0,0 +1,66 @@ +#!/usr/bin/env node + +var Codesurgeon = require('codesurgeon').Codesurgeon; +var surgeon = new Codesurgeon; + +var path = require('path'); + +var root = path.join(__dirname, '..'); +var lib = path.join(root, 'lib', 'broadway'); + +// +// Distill and package the browser version. +// +surgeon + // + .configure({ + package: root + '/package.json', + owner: 'Nodejitsu, Inc (Using Codesurgeon).' + }) + .read( + path.join(root, 'node_modules', 'eventemitter2', 'lib', 'eventemitter2.js'), + path.join(lib, 'browser.js') + ) + // + // we want everything so far. specify extract with no + // parameters to get everything into the output buffer. + // + .extract() + // + // clear the input so far, but don't clear the output. + // + .clear('inputs') + // + // read the `app.js` file + // + .read( + path.join(lib, 'app.js') + ) + // + // the current input buffer contains stuff that we dont + // want in the browser build, so let's cherry pick from + // the buffer. + // + .extract( + 'App.prototype.init', + 'App.prototype.use', + 'App.prototype.remove', + 'App.prototype.inspect' + ) + // + // wrap everything that is in the current buffer with a + // closure so that we dont get any collisions with other + // libraries + // + .wrap() + // + // write the debuggable version of the file. This file will + // get renamed to include the version from the package.json + // + .write(root + '/build/broadway.js') + // + // now lets make a minified version for production use. + // + .uglify() + .write(root + '/build/broadway.min.js') +; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/app.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/app.js new file mode 100644 index 0000000..7851df3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/app.js @@ -0,0 +1,12 @@ + +var app = new App(); + +app.use(HelloWorld, { "delimiter": "!" } ); + +app.init(function (err) { + if (err) { + console.log(err); + } +}); + +app.hello("world"); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/index.html b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/index.html new file mode 100644 index 0000000..4a88d9a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/index.html @@ -0,0 +1,11 @@ + + + Example + + + + + + + + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/plugins/helloworld.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/plugins/helloworld.js new file mode 100644 index 0000000..7c9afbe --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/browser/plugins/helloworld.js @@ -0,0 +1,23 @@ + +window.HelloWorld = {}; + +// +// `exports.attach` gets called by broadway on `app.use` +// +HelloWorld.attach = function (options) { + + this.hello = function (world) { + console.log("Hello "+ world + options.delimiter || "."); + } +}; + +// +// `exports.init` gets called by broadway on `app.init`. +// +HelloWorld.init = function (done) { + + // + // This plugin doesn't require any initialization step. + // + return done(); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/nodejs/app.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/nodejs/app.js new file mode 100644 index 0000000..ce89a59 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/nodejs/app.js @@ -0,0 +1,17 @@ +var broadway = require('../../'), + app = new broadway.App(); + +// Passes the second argument to `helloworld.attach`. +app.use(require("./plugins/helloworld"), { "delimiter": "!" } ); +app.use(broadway.plugins.log, { + logAll: true +}); + +app.init(function (err) { + if (err) { + console.log(err); + } +}); + +app.hello("world"); +app.emit('world:hello', { meta: 'is here' }); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/nodejs/plugins/helloworld.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/nodejs/plugins/helloworld.js new file mode 100644 index 0000000..ed0738d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/examples/nodejs/plugins/helloworld.js @@ -0,0 +1,23 @@ + +var HelloWorld = exports; + +// +// `exports.attach` gets called by broadway on `app.use` +// +HelloWorld.attach = function (options) { + + this.hello = function (world) { + console.log("Hello "+ world + options.delimiter || "."); + } +}; + +// +// `exports.init` gets called by broadway on `app.init`. +// +HelloWorld.init = function (done) { + + // + // This plugin doesn't require any initialization step. + // + return done(); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway.js new file mode 100644 index 0000000..fc614e4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway.js @@ -0,0 +1,19 @@ +/* + * broadway.js: Top-level include for the broadway module. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var path = require('path'), + utile = require('utile'); + +var broadway = exports; + +broadway.App = require('./broadway/app').App; +broadway.common = require('./broadway/common'); +broadway.features = require('./broadway/features'); +broadway.formats = require('nconf').formats; +broadway.plugins = utile.requireDirLazy(path.join(__dirname, 'broadway', 'plugins')); + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/app.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/app.js new file mode 100644 index 0000000..4f9d218 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/app.js @@ -0,0 +1,225 @@ +/* + * app.js: Core Application object for managing plugins and features in broadway + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var utile = require('utile'), + async = utile.async, + events = require('eventemitter2'), + bootstrapper = require('./bootstrapper'), + common = require('./common'), + features = require('./features'); + +var App = exports.App = function (options) { + // + // Setup options and `App` constants. + // + options = options || {}; + this.root = options.root; + this.delimiter = options.delimiter || '::'; + + // + // Inherit from `EventEmitter2` + // + events.EventEmitter2.call(this, { + delimiter: this.delimiter, + wildcard: true + }); + + // + // Setup other relevant options such as the plugins + // for this instance. + // + this.options = options; + this.env = options.env || process.env['NODE_ENV'] || 'development' + this.plugins = options.plugins || {}; + this.initialized = false; + this.bootstrapper = options.bootstrapper || bootstrapper; + this.initializers = {}; + this.initlist = []; + + // + // Bootstrap this instance + // + this.bootstrapper.bootstrap(this); +}; + +// +// Inherit from `EventEmitter2`. +// +utile.inherits(App, events.EventEmitter2); + +// +// ### function init (options, callback) +// #### @options {Object} **Optional** Additional options to initialize with. +// #### @callback {function} Continuation to respond to when complete. +// Initializes this instance by the following procedure: +// +// 1. Initializes all plugins (starting with `core`). +// 2. Creates all directories in `this.config.directories` (if any). +// 3. Ensures the files in the core directory structure conform to the +// features required by this application. +// +App.prototype.init = function (options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + if (this.initialized) { + return callback(); + } + + var self = this; + options = options || {}; + callback = callback || function () {}; + this.env = options.env || this.env; + this.options = common.mixin({}, this.options, options); + + function onComplete() { + self.initialized = true; + self.emit('init'); + callback(); + } + + function ensureFeatures (err) { + return err + ? onError(err) + : features.ensure(this, onComplete); + } + + function initPlugin(plugin, next) { + if (typeof self.initializers[plugin] === 'function') { + return self.initializers[plugin].call(self, function (err) { + if (err) { + return next(err); + } + + self.emit(['plugin', plugin, 'init']); + self.initializers[plugin] = true; + next(); + }); + } + + next(); + } + + function initPlugins() { + async.forEach(self.initlist, initPlugin, ensureFeatures); + } + + // + // Emit and respond with any errors that may short + // circuit the process. + // + function onError(err) { + self.emit(['error', 'init'], err); + callback(err); + } + + // + // Run the bootstrapper, initialize plugins, and + // ensure features for this instance. + // + this.bootstrapper.init(this, initPlugins); +}; + +// +// ### function use(plugin, callback) +// Attachs the plugin with the specific name to this `App` instance. +// +App.prototype.use = function (plugin, options, callback) { + options = options || {}; + + if (typeof plugin === 'undefined') { + console.log('Cannot load invalid plugin!'); + return callback && callback(new Error('Invalid plugin')); + } + + var name = plugin.name, + self = this; + + // If the plugin doesn't have a name, use itself as an identifier for the plugins hash. + if (!name) { + name = common.uuid(); + } + + if (this.plugins[name]) { + return callback && callback(); + } + + // + // Setup state on this instance for the specified plugin + // + this.plugins[name] = plugin; + this.options[name] = common.mixin({}, options, this.options[name] || {}); + + // + // Attach the specified plugin to this instance, extending + // the `App` with new functionality. + // + if (this.plugins[name].attach && options.attach !== false) { + this.plugins[name].attach.call(this, options); + } + + // + // Setup the initializer only if `options.init` is + // not false. This allows for some plugins to be lazy-loaded + // + if (options.init === false) { + return callback && callback(); + } + + if (!this.initialized) { + this.initializers[name] = plugin.init || true; + this.initlist.push(name); + return callback && callback(); + } + else if (plugin.init) { + plugin.init.call(this, function (err) { + var args = err + ? [['plugin', name, 'error'], err] + : [['plugin', name, 'init']]; + + self.emit.apply(self, args); + return callback && (err ? callback(err) : callback()); + }); + } +}; + +// +// ### function remove(name) +// Detaches the plugin with the specific name from this `App` instance. +// +App.prototype.remove = function (name) { + // if this is a plugin object set the name to the plugins name + if (name.name) { + name = name.name; + } + + if (this.plugins[name] && this.plugins[name].detach) { + this.plugins[name].detach.call(this); + } + + delete this.plugins[name]; + delete this.options[name]; + delete this.initializers[name]; + + var init = this.initlist.indexOf(name); + + if (init !== -1) { + this.initlist.splice(1, init); + } +} + +// +// ### function inspect () +// Inspects the modules and features used by the current +// application directory structure +// +App.prototype.inspect = function () { + +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/bootstrapper.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/bootstrapper.js new file mode 100644 index 0000000..f27dae8 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/bootstrapper.js @@ -0,0 +1,65 @@ +/* + * bootstrapper.js: Default logic for bootstrapping broadway applications. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var broadway = require('../broadway'); + +// +// ### bootstrap (app, callback) +// #### @app {broadway.App} Application to bootstrap +// #### @callback {function} Continuation to respond to when complete. +// Bootstraps the specified `app`. +// +exports.bootstrap = function (app) { + app.options['config'] = app.options['config'] || {}; + app.options['config'].init = false; + app.use(broadway.plugins.config); + + // + // Remove initializers run by the bootstrapper. + // + delete app.initializers['config']; + app.initlist.pop(); + + // + // Set the current environment in the config + // + app.config.set('env', app.env); +}; + +// +// ### bootstrap (app, callback) +// #### @app {broadway.App} Application to bootstrap +// #### @callback {function} Continuation to respond to when complete. +// Runs the initialization step of the bootstrapping process +// for the specified `app`. +// +exports.init = function (app, callback) { + broadway.plugins.config.init.call(app, function (err) { + if (err) { + return callback(err); + } + + if (app.config.get('handleExceptions')) { + app.use(broadway.plugins.exceptions, app.options['exceptions'] || {}); + } + + app.use(broadway.plugins.directories, app.options['directories'] || {}); + app.use(broadway.plugins.log, app.options['log'] || {}); + + // + // Ensure the `directories` and `log` plugins initialize before + // any other plugins. + // + app.initlist.unshift.apply( + app.initlist, + app.initlist.splice(-2, 2) + ); + + callback(); + }); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/browser.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/browser.js new file mode 100644 index 0000000..9ea14cf --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/browser.js @@ -0,0 +1,75 @@ + +/* + * browser.js: Browser specific functionality for broadway. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var id = 0; + +var common = { + mixin: function (target) { + var objs = Array.prototype.slice.call(arguments, 1); + objs.forEach(function (o) { + Object.keys(o).forEach(function (attr) { + var getter = o.__lookupGetter__(attr); + if (!getter) { + target[attr] = o[attr]; + } + else { + target.__defineGetter__(attr, getter); + } + }); + }); + + return target; + }, + uuid: function () { + return String(id++); + } +}; + +var App = exports.App = function (options) { + // + // Setup options and `App` constants. + // + var self = this; + options = options || {}; + this.root = options.root; + this.delimiter = options.delimiter || '::'; + + // + // Inherit from `EventEmitter2` + // + exports.EventEmitter2.call(this, { + delimiter: this.delimiter, + wildcard: true + }); + + // + // Setup other relevant options such as the plugins + // for this instance. + // + this.options = options; + this.plugins = options.plugins || {}; + this.initialized = false; + this.bootstrapper = { init: function (app, func) {} }; + this.initializers = {}; +}; + +var inherit = function (ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); +} + +inherit(exports.App, exports.EventEmitter2); + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/common/directories.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/common/directories.js new file mode 100644 index 0000000..46a437f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/common/directories.js @@ -0,0 +1,78 @@ +/* + * app.js: Common utility functions for working with directories + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var utile = require('utile'), + async = utile.async, + mkdirp = utile.mkdirp, + rimraf = utile.rimraf; + +var directories = exports; + +// +// ### function create (dirs, callback) +// #### @dirs {Object} Directories to create +// #### @callback {function} Continuation to respond to when complete +// Creates all of the specified `directories` in the current environment. +// +directories.create = function (dirs, callback) { + function createDir(dir, next) { + mkdirp(dir, 0755, function () { + next(null, dir); + }); + } + + if (!dirs) { + return callback(); + } + + async.mapSeries(Object.keys(dirs).map(function (key) { + return dirs[key] + }), createDir, callback); +}; + +// +// ### function remove (dirs, callback) +// #### @dirs {Object} Directories to remove +// #### @callback {function} Continuation to respond to when complete +// Removes all of the specified `directories` in the current environment. +// +directories.remove = function (dirs, callback) { + function removeDir (dir, next) { + rimraf(dir, function () { + next(null, dir); + }); + } + + if (!dirs) { + return callback(); + } + + async.mapSeries(Object.keys(dirs).map(function (key) { + return dirs[key] + }), removeDir, callback); +}; + +// +// ### function normalize (root, dirs) +// #### @keys {Object} Set of keys to normalize upon. +// #### @dirs {Object} Set of directories to normalize. +// Normalizes the specified `dirs` against the relative +// `root` of the application. +// +directories.normalize = function (keys, dirs) { + var normalized = {}; + + Object.keys(dirs).forEach(function (key) { + normalized[key] = dirs[key]; + Object.keys(keys).forEach(function (constant) { + normalized[key] = normalized[key].replace(constant, keys[constant]); + }); + }); + + return normalized; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/common/index.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/common/index.js new file mode 100644 index 0000000..81d38d9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/common/index.js @@ -0,0 +1,18 @@ +/* + * common.js: Top-level include for the `common` module. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var common = module.exports = require('utile'); + +common.directories = require('./directories'); + +// A naive shared "unique ID" generator for cases where `plugin.name` is +// undefined. +var id = 0; +common.uuid = function () { + return String(id++); +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/features/index.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/features/index.js new file mode 100644 index 0000000..ae50e4a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/features/index.js @@ -0,0 +1,48 @@ +/* + * index.js: Top-level include for the features module. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +exports.ensure = function (app, callback) { + return callback(); +} + +exports.all = [ + { + name: 'Entry Point', + test: function (target, name) { + return typeof target.start === 'function' || + typeof target.createServer === 'function'; + }, + allExports: ['start', 'createServer', 'init', 'getRoutes'] + }, + { + name: 'Resource', + test: function (target, name) { + var methods = ['create', 'get', 'update', 'destroy'], + resource = target[capitalize(name)]; + + if (typeof resource !== 'function') { + return false; + } + + for (var i = 0; i < methods.length; i++) { + if (typeof resource[method] !== 'function') { + return false; + } + } + }, + allExports: ['addRoutes', 'init'] + }, + { + name: 'Configurator', + exports: ['config'], + }, + { + name: 'Serve Files', + exports: 'serve' + } +]; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/config.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/config.js new file mode 100644 index 0000000..9f9e0c4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/config.js @@ -0,0 +1,46 @@ +/* + * config.js: Default configuration management plugin which attachs nconf to App instances + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var nconf = require('nconf'); + +// +// ### Name this plugin +// +exports.name = 'config'; + +// +// ### function attach (options) +// #### @options {Object} Options for this plugin +// Extends `this` (the application) with configuration functionality +// from `nconf`. +// +exports.attach = function (options) { + options = options || {}; + this.config = new nconf.Provider(options); + + // + // Setup a default store + // + this.config.use('literal'); + this.config.stores.literal.readOnly = false; +}; + +// +// ### function init (done) +// #### @done {function} Continuation to respond to when complete. +// Initalizes the `nconf.Provider` associated with this instance. +// +exports.init = function (done) { + // + // Remark: There should be code here for automated remote + // seeding and loading + // + this.config.load(function (err) { + return err ? done(err) : done(); + }); +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/directories.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/directories.js new file mode 100644 index 0000000..331f8b2 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/directories.js @@ -0,0 +1,49 @@ +/* + * directories.js: Plugin for creating directories for a required for a broadway App. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var common = require('../common'); + +// +// ### Name this plugin +// +exports.name = 'directories'; + +// +// ### function attach (options) +// #### @options {Object} Options for this plugin +// #### @done {function} Continuation to respond to when complete. +// Prepopulates the directory structure of `this` (the application). +// +exports.attach = function (options) { + options = options || {}; + + if (this.config) { + // + // Merge options with any pre-existing application config. + // + options = common.mixin({}, options, this.config.get('directories') || {}); + } + + options = common.directories.normalize({'#ROOT': this.root}, options); + this.options['directories'] = options; + + if (this.config) { + this.config.merge('directories', options); + } +}; + +// +// ### function init (done) +// #### @done {function} Continuation to respond to when complete. +// Creates the directories associated with this instance. +// +exports.init = function (done) { + common.directories.create(this.options['directories'], function (err) { + return err ? done(err) : done(); + }); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/exceptions.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/exceptions.js new file mode 100644 index 0000000..883d394 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/exceptions.js @@ -0,0 +1,70 @@ +/* + * exceptions.js: Plugin responsible for logging all uncaughtExceptions in a flatiron App. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var winston = require('winston'), + common = require('../common'); + +var exceptions = exports; + +// +// ### Setup default state for the exceptions plugin +// +exceptions.name = 'exceptions'; +exceptions.initalized = false; + +var defaultConfig = exceptions.defaultConfig = { + console: { + colorize: false, + json: true, + level: 'silly' + } +}; + +// +// ### function attach (options) +// #### @options {Object} Options for this plugin +// Extends `this` the application with exception handling +// functionality from `winston`. +// +exceptions.attach = function (options) { + options = options || {}; + + if (this.config) { + options = common.mixin({}, options, this.config.get('exceptions') || {}); + } + + if (exceptions.initalized) { + return; + } + + var exceptionHandlers = []; + + // + // Create the exceptionHandlers defaulting to Console and Loggly. + // + exceptionHandlers.push(new winston.transports.Console(options.console || defaultConfig.console)); + + Object.keys(options).forEach(function (name) { + if (name === 'console') { + return; + } + + exceptionHandlers.push(new (winston.transports[common.capitalize(name)])(options[name])); + }); + + // + // Update the state of the plugin with the logger. + // + exceptions.logger = new winston.Logger({ exceptionHandlers: exceptionHandlers }); + exceptions.initalized = true; + + // + // Have the logger handle uncaught exceptions. + // + exceptions.logger.handleExceptions(); +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/inspect.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/inspect.js new file mode 100644 index 0000000..47bf803 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/inspect.js @@ -0,0 +1,40 @@ +/* + * inspect.js: Plugin responsible for attaching inspection behavior using `cliff` and `eyes`. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +// +// ### Name this plugin +// +exports.name = 'inspect'; + +// +// ### function init (done) +// #### @done {function} Continuation to respond to when complete. +// Attaches inspection behavior through `cliff` and `eyes`. +// +exports.init = function (done) { + var namespace = 'default', + app = this; + + if (app.options['inspect'] && app.options['inspect'].namespace) { + namespace = app.options['inspect'].namespace; + } + + app.inspect = require('cliff'); + app.inspect.logger = app.log.get('namespace'); + done(); +}; + +// +// ### function detact() +// Removes inspection behavior exposed by this plugin. +// +exports.detach = function () { + if (this.inspect) { + delete this.inspect; + } +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/log.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/log.js new file mode 100644 index 0000000..bca7dba --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/lib/broadway/plugins/log.js @@ -0,0 +1,195 @@ +/* + * log.js: Default logging plugin which attachs winston to App instances + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var winston = require('winston'), + common = require('../common'); + +var log = exports; + +// +// ### Setup default state for the exceptions plugin +// +log.name = 'log'; +log.ignore = ['broadway']; + +// +// ### function attach (options) +// #### @options {Object} Options for this plugin +// Extends `this` (the application) with logging functionality from `winston`. +// +log.attach = function (options) { + options = options || {}; + + var app = this, + namespaces, + logAll; + + if (this.config) { + // + // Merge options with any pre-existing application config. + // + options = common.mixin({}, options, this.config.get('log') || {}); + } + + // + // Setup namespaces and then remove them from + // `options` so they are not caught by `winston`. + // + namespaces = options.namespaces || {}; + delete options.namespaces; + + logAll = options.logAll || false; + if (options.logAll) { + delete options.logAll; + } + + // + // Hoist up relelvant logging functions onto the app + // if requested. + // + this.log = new winston.Container(options); + this.log.namespaces = namespaces; + this.log.get('default').extend(this.log); + + // + // Set the default console loglevel to options.level + // + this.log.get('default').transports.console.level = options.level || 'info'; + + Object.defineProperty(this.log, 'logAll', { + get: function () { + return this._logAll; + }, + set: function (val) { + if (val === this._logAll) { + // + // If the value is identical return + // + return; + } + + if (val) { + app.onAny(log.logEvent); + app.off(['log'], log.logEvent); + app.off(['log', '*'], log.logEvent); + app.off(['log', '*', '*'], log.logEvent); + } + else { + app.offAny(log.logEvent); + app.on(['log'], log.logEvent); + app.on(['log', '*'], log.logEvent); + app.on(['log', '*', '*'], log.logEvent); + } + + this._logAll = val; + } + }); + + // + // Listen to relevant `app` events and + // log them appropriately. + // + this.log.logAll = logAll; + + // + // Add any namespaced containers to this App instance. + // + Object.keys(this.log.namespaces).forEach(function (namespace) { + app.log.add(app.log.namespaces[namespace]); + }); +}; + +// +// ### function logEvent ([level], msg, meta) +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Metadata to log +// Logs the specified `msg` and `meta` according to +// the following conditions: +// +// #### `log` events +// 1. `log` - Logs to the default logger and level. +// 2. `log::[level]` - Logs to the default logger. +// 3. `log::[level]::[namespace]` - Logs to a namespaced logger. +// +// ### `[namespaced]` events +// If `app.log.logAll` is set, then find a logger at `namespace`, +// otherwise the default logger is used. +// +// 1. `[namespace]::**(level, msg, meta)` - Logs the event as the +// message to the logger for the specified namespace and level. +// 2. `[namespace]::[level]::**(msg, meta)` - Logs the event and +// the message to the logger for the specified namespace and level. +// +log.logEvent = function (/* level, msg, meta */) { + var parts = Array.isArray(this.event) ? this.event : this.event.split(this.delimiter), + ev = parts[0], + namespace, + logger, + level, + meta, + msg; + + if (log.ignore.indexOf(ev) !== -1) { + return; + } + + // + // Determine the `namespace` to log the event to + // + if (ev === 'log') { + namespace = parts[2] || 'default'; + logger = this.log.get('default'); + } + else if (this.log.logAll) { + namespace = this.log.namespaces[ev] ? this.log.namespaces[ev] : 'default'; + logger = this.log.get(namespace); + } + else { + return; + } + + // + // Parse arguments now that we have the logger. + // + Array.prototype.slice.call(arguments).forEach(function (a) { + switch (typeof a) { + case 'object': { + meta = a; + break; + } + case 'string': { + if (logger[a]) { + level = a; + } + else { + msg = a; + } + } + } + }); + + if (ev === 'log') { + level = parts[1] || level || 'info'; + } + else if (this.log.logAll) { + if (logger[parts[1]]) { + level = parts[1]; + parts.splice(1, 1); + } + } + + if (level in logger.levels === false) { + level = 'info'; + } + + parts = parts.join(this.delimiter); + meta = meta || {}; + msg = msg || parts; + logger.log(level, msg, meta); + this.emit(['broadway', 'logged'], level, msg, meta, parts); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/.npmignore new file mode 100644 index 0000000..dbed671 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/.npmignore @@ -0,0 +1,13 @@ +#ignore these files +*.swp +*~ +*.lock +*.DS_Store +node_modules +npm-debug.log +*.out +*.o +*.tmp + + + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/README.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/README.md new file mode 100644 index 0000000..e0c2aa8 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/README.md @@ -0,0 +1,212 @@ +# EventEmitter2 + +EventEmitter2 is a an implementation of the EventEmitter found in Node.js + +## Features + + - Namespaces/Wildcards. + - Times To Listen (TTL), extends the `once` concept with `many`. + - Browser environment compatibility. + - Demonstrates good performance in benchmarks + +``` +EventEmitterHeatUp x 3,728,965 ops/sec \302\2610.68% (60 runs sampled) +EventEmitter x 2,822,904 ops/sec \302\2610.74% (63 runs sampled) +EventEmitter2 x 7,251,227 ops/sec \302\2610.55% (58 runs sampled) +EventEmitter2 (wild) x 3,220,268 ops/sec \302\2610.44% (65 runs sampled) +Fastest is EventEmitter2 +``` + +## Differences (Non breaking, compatible with existing EventEmitter) + + - The constructor takes a configuration object. + +```javascript + var EventEmitter2 = require('eventemitter2').EventEmitter2; + var server = new EventEmitter2({ + wildcard: true, // should the event emitter use wildcards. + delimiter: '::', // the delimiter used to segment namespaces, defaults to `.`. + newListener: false, // if you want to emit the newListener event set to true. + maxListeners: 20, // the max number of listeners that can be assigned to an event, defaults to 10. + }); +``` + + - Getting the actual event that fired. + +```javascript + server.on('foo.*', function(value1, value2) { + console.log(this.event, value1, value2); + }); +``` + + - Fire an event N times and then remove it, an extension of the `once` concept. + +```javascript + server.many('foo', 4, function() { + console.log('hello'); + }); +``` + + - Pass in a namespaced event as an array rather than a delimited string. + +```javascript + server.many(['foo', 'bar', 'bazz'], function() { + console.log('hello'); + }); +``` + + +## API + +When an `EventEmitter` instance experiences an error, the typical action is +to emit an `error` event. Error events are treated as a special case. +If there is no listener for it, then the default action is to print a stack +trace and exit the program. + +All EventEmitters emit the event `newListener` when new listeners are +added. + + +**Namespaces** with **Wildcards** +To use namespaces/wildcards, pass the `wildcard` option into the EventEmitter constructor. +When namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated +by a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a +constructor option. + +An event name passed to any event emitter method can contain a wild card (the `*` character). +If the event name is a string, a wildcard may appear as `foo.*`. If the event name is an array, +the wildcard may appear as `['foo', '*']`. + +If either of the above described events were passed to the `on` method, subsequent emits such +as the following would be observed... + +```javascript + emitter.emit('foo.bazz'); + emitter.emit(['foo', 'bar']); +``` + + +#### emitter.addListener(event, listener) +#### emitter.on(event, listener) + +Adds a listener to the end of the listeners array for the specified event. + +```javascript + server.on('data', function(value1, value2, value3 /* accepts any number of expected values... */) { + console.log('The event was raised!'); + }); +``` + +```javascript + server.on('data', function(value) { + console.log('The event was raised!'); + }); +``` + +#### emitter.onAny(listener) + +Adds a listener that will be fired when any event is emitted. + +```javascript + server.onAny(function(value) { + console.log('All events trigger this.'); + }); +``` + +#### emitter.offAny(listener) + +Removes the listener that will be fired when any event is emitted. + +```javascript + server.offAny(function(value) { + console.log('The event was raised!'); + }); +``` + +#### emitter.once(event, listener) + +Adds a **one time** listener for the event. The listener is invoked only the first time the event is fired, after which it is removed. + +```javascript + server.once('get', function (value) { + console.log('Ah, we have our first value!'); + }); +``` + +#### emitter.many(event, timesToListen, listener) + +Adds a listener that will execute **n times** for the event before being removed. The listener is invoked only the first time the event is fired, after which it is removed. + +```javascript + server.many('get', 4, function (value) { + console.log('This event will be listened to exactly four times.'); + }); +``` + + +#### emitter.removeListener(event, listener) +#### emitter.off(event, listener) + +Remove a listener from the listener array for the specified event. **Caution**: changes array indices in the listener array behind the listener. + +```javascript + var callback = function(value) { + console.log('someone connected!'); + }; + server.on('get', callback); + // ... + server.removeListener('get', callback); +``` + + +#### emitter.removeAllListeners([event]) + +Removes all listeners, or those of the specified event. + + +#### emitter.setMaxListeners(n) + +By default EventEmitters will print a warning if more than 10 listeners are added to it. This is a useful default which helps finding memory leaks. Obviously not all Emitters should be limited to 10. This function allows that to be increased. Set to zero for unlimited. + + +#### emitter.listeners(event) + +Returns an array of listeners for the specified event. This array can be manipulated, e.g. to remove listeners. + +```javascript + server.on('get', function(value) { + console.log('someone connected!'); + }); + console.log(console.log(server.listeners('get')); // [ [Function] ] +``` + +#### emitter.listenersAny() + +Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, e.g. to remove listeners. + +```javascript + server.onAny(function(value) { + console.log('someone connected!'); + }); + console.log(console.log(server.listenersAny()[0]); // [ [Function] ] // someone connected! +``` + +#### emitter.emit(event, [arg1], [arg2], [...]) + +Execute each of the listeners that may be listening for the specified event name in order with the list of arguments. + +## Test coverage + +There is a test suite that tries to cover each use case, it can be found
here. + +## Licence + +(The MIT License) + +Copyright (c) 2011 hij1nx + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/index.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/index.js new file mode 100644 index 0000000..6f583b5 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/eventemitter2'); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/lib/eventemitter2.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/lib/eventemitter2.js new file mode 100644 index 0000000..ba83369 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/lib/eventemitter2.js @@ -0,0 +1,560 @@ +;!function(exports, undefined) { + + var isArray = Array.isArray ? Array.isArray : function _isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + var defaultMaxListeners = 10; + + function init() { + this._events = {}; + if (this._conf) { + configure.call(this, this._conf); + } + } + + function configure(conf) { + if (conf) { + + this._conf = conf; + + conf.delimiter && (this.delimiter = conf.delimiter); + conf.maxListeners && (this._events.maxListeners = conf.maxListeners); + conf.wildcard && (this.wildcard = conf.wildcard); + conf.newListener && (this.newListener = conf.newListener); + + if (this.wildcard) { + this.listenerTree = {}; + } + } + } + + function EventEmitter(conf) { + this._events = {}; + this.newListener = false; + configure.call(this, conf); + } + + // + // Attention, function return type now is array, always ! + // It has zero elements if no any matches found and one or more + // elements (leafs) if there are matches + // + function searchListenerTree(handlers, type, tree, i) { + if (!tree) { + return []; + } + var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, + typeLength = type.length, currentType = type[i], nextType = type[i+1]; + if (i === typeLength && tree._listeners) { + // + // If at the end of the event(s) list and the tree has listeners + // invoke those listeners. + // + if (typeof tree._listeners === 'function') { + handlers && handlers.push(tree._listeners); + return [tree]; + } else { + for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { + handlers && handlers.push(tree._listeners[leaf]); + } + return [tree]; + } + } + + if ((currentType === '*' || currentType === '**') || tree[currentType]) { + // + // If the event emitted is '*' at this part + // or there is a concrete match at this patch + // + if (currentType === '*') { + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); + } + } + return listeners; + } else if(currentType === '**') { + endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); + if(endReached && tree._listeners) { + // The next element has a _listeners, add it to the handlers. + listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); + } + + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + if(branch === '*' || branch === '**') { + if(tree[branch]._listeners && !endReached) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); + } + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } else if(branch === nextType) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); + } else { + // No match on this one, shift into the tree but not in the type array. + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } + } + } + return listeners; + } + + listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); + } + + xTree = tree['*']; + if (xTree) { + // + // If the listener tree will allow any match for this part, + // then recursively explore all branches of the tree + // + searchListenerTree(handlers, type, xTree, i+1); + } + + xxTree = tree['**']; + if(xxTree) { + if(i < typeLength) { + if(xxTree._listeners) { + // If we have a listener on a '**', it will catch all, so add its handler. + searchListenerTree(handlers, type, xxTree, typeLength); + } + + // Build arrays of matching next branches and others. + for(branch in xxTree) { + if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { + if(branch === nextType) { + // We know the next element will match, so jump twice. + searchListenerTree(handlers, type, xxTree[branch], i+2); + } else if(branch === currentType) { + // Current node matches, move into the tree. + searchListenerTree(handlers, type, xxTree[branch], i+1); + } else { + isolatedBranch = {}; + isolatedBranch[branch] = xxTree[branch]; + searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); + } + } + } + } else if(xxTree._listeners) { + // We have reached the end and still on a '**' + searchListenerTree(handlers, type, xxTree, typeLength); + } else if(xxTree['*'] && xxTree['*']._listeners) { + searchListenerTree(handlers, type, xxTree['*'], typeLength); + } + } + + return listeners; + } + + function growListenerTree(type, listener) { + + type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + + // + // Looks for two consecutive '**', if so, don't add the event at all. + // + for(var i = 0, len = type.length; i+1 < len; i++) { + if(type[i] === '**' && type[i+1] === '**') { + return; + } + } + + var tree = this.listenerTree; + var name = type.shift(); + + while (name) { + + if (!tree[name]) { + tree[name] = {}; + } + + tree = tree[name]; + + if (type.length === 0) { + + if (!tree._listeners) { + tree._listeners = listener; + } + else if(typeof tree._listeners === 'function') { + tree._listeners = [tree._listeners, listener]; + } + else if (isArray(tree._listeners)) { + + tree._listeners.push(listener); + + if (!tree._listeners.warned) { + + var m = defaultMaxListeners; + + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } + + if (m > 0 && tree._listeners.length > m) { + + tree._listeners.warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + tree._listeners.length); + console.trace(); + } + } + } + return true; + } + name = type.shift(); + } + return true; + }; + + // By default EventEmitters will print a warning if more than + // 10 listeners are added to it. This is a useful default which + // helps finding memory leaks. + // + // Obviously not all Emitters should be limited to 10. This function allows + // that to be increased. Set to zero for unlimited. + + EventEmitter.prototype.delimiter = '.'; + + EventEmitter.prototype.setMaxListeners = function(n) { + this._events || init.call(this); + this._events.maxListeners = n; + if (!this._conf) this._conf = {}; + this._conf.maxListeners = n; + }; + + EventEmitter.prototype.event = ''; + + EventEmitter.prototype.once = function(event, fn) { + this.many(event, 1, fn); + return this; + }; + + EventEmitter.prototype.many = function(event, ttl, fn) { + var self = this; + + if (typeof fn !== 'function') { + throw new Error('many only accepts instances of Function'); + } + + function listener() { + if (--ttl === 0) { + self.off(event, listener); + } + fn.apply(this, arguments); + }; + + listener._origin = fn; + + this.on(event, listener); + + return self; + }; + + EventEmitter.prototype.emit = function() { + + this._events || init.call(this); + + var type = arguments[0]; + + if (type === 'newListener' && !this.newListener) { + if (!this._events.newListener) { return false; } + } + + // Loop through the *_all* functions and invoke them. + if (this._all) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + for (i = 0, l = this._all.length; i < l; i++) { + this.event = type; + this._all[i].apply(this, args); + } + } + + // If there is no 'error' event listener then throw. + if (type === 'error') { + + if (!this._all && + !this._events.error && + !(this.wildcard && this.listenerTree.error)) { + + if (arguments[1] instanceof Error) { + throw arguments[1]; // Unhandled 'error' event + } else { + throw new Error("Uncaught, unspecified 'error' event."); + } + return false; + } + } + + var handler; + + if(this.wildcard) { + handler = []; + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + searchListenerTree.call(this, handler, ns, this.listenerTree, 0); + } + else { + handler = this._events[type]; + } + + if (typeof handler === 'function') { + this.event = type; + if (arguments.length === 1) { + handler.call(this); + } + else if (arguments.length > 1) + switch (arguments.length) { + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + handler.apply(this, args); + } + return true; + } + else if (handler) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + + var listeners = handler.slice(); + for (var i = 0, l = listeners.length; i < l; i++) { + this.event = type; + listeners[i].apply(this, args); + } + return (listeners.length > 0) || this._all; + } + else { + return this._all; + } + + }; + + EventEmitter.prototype.on = function(type, listener) { + + if (typeof type === 'function') { + this.onAny(type); + return this; + } + + if (typeof listener !== 'function') { + throw new Error('on only accepts instances of Function'); + } + this._events || init.call(this); + + // To avoid recursion in the case that type == "newListeners"! Before + // adding it to the listeners, first emit "newListeners". + this.emit('newListener', type, listener); + + if(this.wildcard) { + growListenerTree.call(this, type, listener); + return this; + } + + if (!this._events[type]) { + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + } + else if(typeof this._events[type] === 'function') { + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + } + else if (isArray(this._events[type])) { + // If we've already got an array, just append. + this._events[type].push(listener); + + // Check for listener leak + if (!this._events[type].warned) { + + var m = defaultMaxListeners; + + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } + + if (m > 0 && this._events[type].length > m) { + + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + } + return this; + }; + + EventEmitter.prototype.onAny = function(fn) { + + if(!this._all) { + this._all = []; + } + + if (typeof fn !== 'function') { + throw new Error('onAny only accepts instances of Function'); + } + + // Add the function to the event listener collection. + this._all.push(fn); + return this; + }; + + EventEmitter.prototype.addListener = EventEmitter.prototype.on; + + EventEmitter.prototype.off = function(type, listener) { + if (typeof listener !== 'function') { + throw new Error('removeListener only takes instances of Function'); + } + + var handlers,leafs=[]; + + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); + } + else { + // does not use listeners(), so no side effect of creating _events[type] + if (!this._events[type]) return this; + handlers = this._events[type]; + leafs.push({_listeners:handlers}); + } + + for (var iLeaf=0; iLeaf 0) { + fns = this._all; + for(i = 0, l = fns.length; i < l; i++) { + if(fn === fns[i]) { + fns.splice(i, 1); + return this; + } + } + } else { + this._all = []; + } + return this; + }; + + EventEmitter.prototype.removeListener = EventEmitter.prototype.off; + + EventEmitter.prototype.removeAllListeners = function(type) { + if (arguments.length === 0) { + !this._events || init.call(this); + return this; + } + + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); + + for (var iLeaf=0; iLeaf= 0.2.2" + }, + "engines": [ + "node" + ], + "main": "./lib/eventemitter2.js", + "scripts": { + "test": "nodeunit test/simple/* && nodeunit test/wildcardEvents/*", + "benchmark": "node test/perf/benchmark.js" + }, + "readme": "# EventEmitter2\n\nEventEmitter2 is a an implementation of the EventEmitter found in Node.js\n\n## Features\n\n - Namespaces/Wildcards.\n - Times To Listen (TTL), extends the `once` concept with `many`.\n - Browser environment compatibility.\n - Demonstrates good performance in benchmarks\n\n```\nEventEmitterHeatUp x 3,728,965 ops/sec \\302\\2610.68% (60 runs sampled)\nEventEmitter x 2,822,904 ops/sec \\302\\2610.74% (63 runs sampled)\nEventEmitter2 x 7,251,227 ops/sec \\302\\2610.55% (58 runs sampled)\nEventEmitter2 (wild) x 3,220,268 ops/sec \\302\\2610.44% (65 runs sampled)\nFastest is EventEmitter2\n```\n\n## Differences (Non breaking, compatible with existing EventEmitter)\n\n - The constructor takes a configuration object.\n \n```javascript\n var EventEmitter2 = require('eventemitter2').EventEmitter2;\n var server = new EventEmitter2({\n wildcard: true, // should the event emitter use wildcards.\n delimiter: '::', // the delimiter used to segment namespaces, defaults to `.`.\n newListener: false, // if you want to emit the newListener event set to true.\n maxListeners: 20, // the max number of listeners that can be assigned to an event, defaults to 10.\n });\n```\n\n - Getting the actual event that fired.\n\n```javascript\n server.on('foo.*', function(value1, value2) {\n console.log(this.event, value1, value2);\n });\n```\n\n - Fire an event N times and then remove it, an extension of the `once` concept.\n\n```javascript\n server.many('foo', 4, function() {\n console.log('hello');\n });\n```\n\n - Pass in a namespaced event as an array rather than a delimited string.\n\n```javascript\n server.many(['foo', 'bar', 'bazz'], function() {\n console.log('hello');\n });\n```\n\n\n## API\n\nWhen an `EventEmitter` instance experiences an error, the typical action is\nto emit an `error` event. Error events are treated as a special case.\nIf there is no listener for it, then the default action is to print a stack\ntrace and exit the program.\n\nAll EventEmitters emit the event `newListener` when new listeners are\nadded.\n\n\n**Namespaces** with **Wildcards**\nTo use namespaces/wildcards, pass the `wildcard` option into the EventEmitter constructor.\nWhen namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated\nby a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a \nconstructor option.\n\nAn event name passed to any event emitter method can contain a wild card (the `*` character).\nIf the event name is a string, a wildcard may appear as `foo.*`. If the event name is an array, \nthe wildcard may appear as `['foo', '*']`.\n\nIf either of the above described events were passed to the `on` method, subsequent emits such \nas the following would be observed...\n\n```javascript\n emitter.emit('foo.bazz');\n emitter.emit(['foo', 'bar']);\n```\n\n\n#### emitter.addListener(event, listener)\n#### emitter.on(event, listener)\n\nAdds a listener to the end of the listeners array for the specified event.\n\n```javascript\n server.on('data', function(value1, value2, value3 /* accepts any number of expected values... */) {\n console.log('The event was raised!');\n });\n```\n\n```javascript\n server.on('data', function(value) {\n console.log('The event was raised!');\n });\n```\n\n#### emitter.onAny(listener)\n\nAdds a listener that will be fired when any event is emitted.\n\n```javascript\n server.onAny(function(value) {\n console.log('All events trigger this.');\n });\n```\n\n#### emitter.offAny(listener)\n\nRemoves the listener that will be fired when any event is emitted.\n\n```javascript\n server.offAny(function(value) {\n console.log('The event was raised!');\n });\n```\n\n#### emitter.once(event, listener)\n\nAdds a **one time** listener for the event. The listener is invoked only the first time the event is fired, after which it is removed.\n\n```javascript\n server.once('get', function (value) {\n console.log('Ah, we have our first value!');\n });\n```\n\n#### emitter.many(event, timesToListen, listener)\n\nAdds a listener that will execute **n times** for the event before being removed. The listener is invoked only the first time the event is fired, after which it is removed.\n\n```javascript\n server.many('get', 4, function (value) {\n console.log('This event will be listened to exactly four times.');\n });\n```\n\n\n#### emitter.removeListener(event, listener)\n#### emitter.off(event, listener)\n\nRemove a listener from the listener array for the specified event. **Caution**: changes array indices in the listener array behind the listener.\n\n```javascript\n var callback = function(value) {\n console.log('someone connected!');\n };\n server.on('get', callback);\n // ...\n server.removeListener('get', callback);\n```\n\n\n#### emitter.removeAllListeners([event])\n\nRemoves all listeners, or those of the specified event.\n\n\n#### emitter.setMaxListeners(n)\n\nBy default EventEmitters will print a warning if more than 10 listeners are added to it. This is a useful default which helps finding memory leaks. Obviously not all Emitters should be limited to 10. This function allows that to be increased. Set to zero for unlimited.\n\n\n#### emitter.listeners(event)\n\nReturns an array of listeners for the specified event. This array can be manipulated, e.g. to remove listeners.\n\n```javascript\n server.on('get', function(value) {\n console.log('someone connected!');\n });\n console.log(console.log(server.listeners('get')); // [ [Function] ]\n```\n\n#### emitter.listenersAny()\n\nReturns an array of listeners that are listening for any event that is specified. This array can be manipulated, e.g. to remove listeners.\n\n```javascript\n server.onAny(function(value) {\n console.log('someone connected!');\n });\n console.log(console.log(server.listenersAny()[0]); // [ [Function] ] // someone connected!\n```\n\n#### emitter.emit(event, [arg1], [arg2], [...])\n\nExecute each of the listeners that may be listening for the specified event name in order with the list of arguments.\n\n## Test coverage\n\nThere is a test suite that tries to cover each use case, it can be found here.\n\n## Licence\n\n(The MIT License)\n\nCopyright (c) 2011 hij1nx \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "readmeFilename": "README.md", + "repository": { + "type": "git", + "url": "git://github.com/hij1nx/EventEmitter2.git" + }, + "bugs": { + "url": "https://github.com/hij1nx/EventEmitter2/issues" + }, + "_id": "eventemitter2@0.4.11", + "dist": { + "shasum": "44bec41c8e04576c4e6bec0eca6a0990a79245dd" + }, + "_from": "eventemitter2@0.4.11", + "_resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.11.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/common.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/common.js new file mode 100644 index 0000000..415cdb0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/common.js @@ -0,0 +1,122 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var path = require('path'); +var assert = require('assert'); + +exports.testDir = path.dirname(__filename); +exports.fixturesDir = path.join(exports.testDir, 'fixtures'); +exports.libDir = path.join(exports.testDir, '../lib'); +exports.tmpDir = path.join(exports.testDir, 'tmp'); +exports.PORT = 12346; + +if (process.platform == 'win32') { + exports.PIPE = '\\\\.\\pipe\\libuv-test'; +} else { + exports.PIPE = exports.tmpDir + '/test.sock'; +} + +var util = require('util'); +for (var i in util) exports[i] = util[i]; +//for (var i in exports) global[i] = exports[i]; + +function protoCtrChain(o) { + var result = []; + for (; o; o = o.__proto__) { result.push(o.constructor); } + return result.join(); +} + +exports.indirectInstanceOf = function(obj, cls) { + if (obj instanceof cls) { return true; } + var clsChain = protoCtrChain(cls.prototype); + var objChain = protoCtrChain(obj); + return objChain.slice(-clsChain.length) === clsChain; +}; + + +// Turn this off if the test should not check for global leaks. +exports.globalCheck = true; + +process.on('exit', function() { + if (!exports.globalCheck) return; + var knownGlobals = [setTimeout, + setInterval, + clearTimeout, + clearInterval, + console, + Buffer, + process, + global.ArrayBuffer!==undefined?ArrayBuffer:null, + global.Int8Array!==undefined?Int8Array:null, + global.Uint8Array!==undefined?Uint8Array:null, + global.Int16Array!==undefined?Int16Array:null, + global.Uint16Array!==undefined?Uint16Array:null, + global.Int32Array!==undefined?Int32Array:null, + global.Uint32Array!==undefined?Uint32Array:null, + global.Float32Array!==undefined?Float32Array:null, + global.Float64Array!==undefined?Float64Array:null, + global.DataView!==undefined?DataView:null, + global.Uint8ClampedArray!==undefined?Uint8ClampedArray:null, + AssertionError, + global + ]; + + if (global.errno) { + knownGlobals.push(errno); + } + + if (global.gc) { + knownGlobals.push(gc); + } + + if (global.DTRACE_HTTP_SERVER_RESPONSE) { + knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE); + knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST); + knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE); + knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST); + knownGlobals.push(DTRACE_NET_STREAM_END); + knownGlobals.push(DTRACE_NET_SERVER_CONNECTION); + knownGlobals.push(DTRACE_NET_SOCKET_READ); + knownGlobals.push(DTRACE_NET_SOCKET_WRITE); + } + + for (var x in global) { + var found = false; + + for (var y in knownGlobals) { + if (global[x] === knownGlobals[y]) { + found = true; + break; + } + } + + if (!found) { + console.error('Unknown global: %s', x); + assert.ok(false, 'Unknown global founded'); + } + } +}); + + +// This function allows one two run an HTTP test agaist both HTTPS and +// normal HTTP modules. This ensures they fit the same API. +exports.httpTest = function httpTest(cb) { +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/perf/benchmark.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/perf/benchmark.js new file mode 100644 index 0000000..5383654 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/perf/benchmark.js @@ -0,0 +1,53 @@ + +var Benchmark = require('benchmark'); +var suite = new Benchmark.Suite(); + +var EventEmitter = require('events').EventEmitter; +var emitter = new EventEmitter; + +var EventEmitter2 = require('../../lib/eventemitter2').EventEmitter2; +var emitter2 = new EventEmitter2; + +var EventEmitter3 = require('events').EventEmitter; +var emitter3 = new EventEmitter3; + +suite + + .add('EventEmitterHeatUp', function() { + + emitter3.on('test3', function () { 1==1; }); + emitter3.emit('test3'); + emitter3.removeAllListeners('test3'); + + }) + .add('EventEmitter', function() { + + emitter.on('test1', function () { 1==1; }); + emitter.emit('test1'); + emitter.removeAllListeners('test1'); + + }) + .add('EventEmitter2', function() { + + emitter2.on('test2', function () { 1==1; }); + emitter2.emit('test2'); + emitter2.removeAllListeners('test2'); + + }) + + .add('EventEmitter2 (wild)', function() { + + emitter2.on('test2.foo', function () { 1==1; }); + emitter2.emit('test2.foo'); + emitter2.removeAllListeners('test2.foo'); + + }) + + .on('cycle', function(event, bench) { + console.log(String(bench)); + }) + .on('complete', function() { + console.log('Fastest is ' + this.filter('fastest').pluck('name')); + }) + + .run(true); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/addListener.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/addListener.js new file mode 100644 index 0000000..2bc675a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/addListener.js @@ -0,0 +1,179 @@ + +var simpleEvents = require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + '1. Add a single listener on a single event.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners('test1').length, 1, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + '2. Add two listeners on a single event.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners('test1').length, 2, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + '3. Add three listeners on a single event.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners('test1').length, 3, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + '4. Add two listeners to two different events.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test2', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test2', function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners('test1').length, 2, 'There are two emitters'); + test.equal(emitter.listeners('test2').length, 2, 'There are two emitters'); + + test.expect(2); + test.done(); + + }, + '5. Never adding any listeners should yield a listeners array with the length of 0.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + emitter.on('test1', function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners('test2').length, 0, 'There are no emitters'); + + test.expect(1); + test.done(); + }, + + '6. the listener added should be the right listener.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + var type = 'somelistenerbar'; + var f = function () {}; + + emitter.on(type, f); + test.equal(emitter.listeners(type).length, 1, 'There are is one emitters'); + test.equal(emitter.listeners(type)[0], f, 'The function should be f'); + + test.expect(2); + test.done(); + + }, + + '7. should be able to listen on any event' : function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + var f = function () { + test.ok(true, 'the event was fired'); + }; + + emitter.onAny(f); + emitter.emit('test23.ns5.ns5', 'someData'); //1 + emitter.offAny(f); + emitter.emit('test21'); //0 + emitter.onAny(f); + emitter.onAny(f); + emitter.emit('test23.ns5.ns5', 'someData'); //3 + + test.expect(3); + test.done(); + + }, + + '8. should be able to listen on any event (should cause an error)' : function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + var f = function () { + test.ok(true, 'the event was fired'); + }; + emitter.onAny(f); + + emitter.emit('error'); + + test.expect(1); + test.done(); + + }, + + '9. onAny alias' : function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + var f = function () { + test.ok(true, 'the event was fired'); + }; + + emitter.on(f); + + emitter.emit('foo'); + emitter.emit('bar'); + + test.expect(2); + test.done(); + + } +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/emit.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/emit.js new file mode 100644 index 0000000..c52c567 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/emit.js @@ -0,0 +1,142 @@ + +var simpleEvents = require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + '1. Add two listeners on a single event and emit the event.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + function functionA() { test.ok(true, 'The event was raised'); } + function functionB() { test.ok(true, 'The event was raised'); } + + emitter.on('test2', functionA); + emitter.on('test2', functionB); + + emitter.emit('test2'); + + test.expect(2); + test.done(); + + }, + '2. Add two listeners on a single event and emit the event twice.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + function functionA() { test.ok(true, 'The event was raised'); } + function functionB() { test.ok(true, 'The event was raised'); } + + emitter.on('test2', functionA); + emitter.on('test2', functionB); + + emitter.emit('test2'); + emitter.emit('test2'); + + test.expect(4); + test.done(); + + }, + '3. Add two listeners on a single event and emit the event with a parameter.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + function functionA(value1) { + test.ok(true, 'The event was raised'); + test.equal(typeof value1, 'string', 'The event was raised'); + } + + function functionB(value1) { + test.ok(true, 'The event was raised'); + test.equal(typeof value1, 'string', 'The event was raised'); + } + + emitter.on('test2', functionA); + emitter.on('test2', functionB); + + emitter.emit('test2', 'Hello, Node'); + + test.expect(4); + test.done(); + + }, + '4. Add two listeners on an single event and emit the event twice with a parameter.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + function functionA(value1) { + test.ok(true, 'The event was raised'); + test.equal(typeof value1, 'string', 'The event was raised'); + } + + function functionB(value1) { + test.ok(true, 'The event was raised'); + test.equal(typeof value1, 'string', 'The event was raised'); + } + + emitter.on('test2', functionA); + emitter.on('test2', functionB); + + emitter.emit('test2', 'Hello, Node1'); + emitter.emit('test2', 'Hello, Node2'); + + test.expect(8); + test.done(); + + }, + '5. Add two listeners on an single event and emit the event twice with multiple parameters.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + function functionA(value1, value2, value3) { + test.ok(true, 'The event was raised'); + test.equal(typeof value1, 'string', 'The value named "value1" is OK'); + test.equal(typeof value2, 'string', 'The value named "value2" is OK'); + test.equal(typeof value3, 'string', 'The value named "value3" is OK'); + } + + function functionB(value1, value2, value3) { + test.ok(true, 'The event was raised'); + test.equal(typeof value1, 'string', 'The value named "value1" is OK'); + test.equal(typeof value2, 'string', 'The value named "value2" is OK'); + test.equal(typeof value3, 'string', 'The value named "value3" is OK'); + } + + emitter.on('test2', functionA); + emitter.on('test2', functionB); + + emitter.emit('test2', 'Hello, Node1', 'Hello, Node2', 'Hello, Node3'); + emitter.emit('test2', 'Hello, Node1', 'Hello, Node2', 'Hello, Node3'); + + test.expect(16); + test.done(); + + }, + '6. Check return values of emit.': function (test) { + + var emitter = new EventEmitter2({ verbose: true }); + + function functionA() { test.ok(true, 'The event was raised'); } + + emitter.on('test6', functionA); + + test.ok(emitter.emit('test6'), 'emit should return true after calling a listener'); + test.ok(!emitter.emit('other'), 'emit should return false when no listener was called'); + + emitter.onAny(functionA); + test.ok(emitter.emit('other'), 'emit should return true after calling an onAny() listener'); + + test.expect(5); + test.done(); + }, + +}); + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/reconfigure.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/reconfigure.js new file mode 100644 index 0000000..a944fd9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/reconfigure.js @@ -0,0 +1,55 @@ +var simpleEvents = require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + 'reconfigure1. initialize, removeAllListeners' : function (test) { + + var emitter, + config = { + wildcard: true, // should the event emitter use wildcards. + delimiter: '::::', // the delimiter used to segment namespaces, defaults to `.`. + maxListeners: 20 // the max number of listeners that can be assigned to an event, defaults to 10. + }; + + emitter = new EventEmitter2(config); + + emitter.removeAllListeners(); + + test.equal(emitter._events.maxListeners, config.maxListeners, 'should be ' + config.maxListeners); + + test.equal(emitter._conf.maxListeners, config.maxListeners, 'should be ' + config.maxListeners); + test.equal(emitter._conf.delimiter, config.delimiter, 'should be ' + config.delimiter); + test.equal(emitter._conf.wildcard, config.wildcard, 'should be ' + config.wildcard); + + test.expect(4); + test.done(); + }, + + 'reconfigure1. setMaxListeners, removeAllListeners' : function (test) { + var emitter, + amount = 99; + + emitter = new EventEmitter2(); + + emitter.setMaxListeners(amount); + + emitter.removeAllListeners(); + + test.equal(emitter._events.maxListeners, amount, 'should be ' + amount); + + test.equal(emitter._conf.maxListeners, amount, 'should be ' + amount); + + test.expect(2); + test.done(); + } + +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/removeListener.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/removeListener.js new file mode 100644 index 0000000..0aedafe --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/removeListener.js @@ -0,0 +1,196 @@ + +var simpleEvents= require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + 'removeListener1. adding 1, removing 1' : function (test) { + + var emitter = new EventEmitter2; + + var type = 'remove', + listeners; + + var f = function f() { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should only have 1'); + + //remove + emitter.removeListener(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(2); + test.done(); + }, + + 'removeListener2. adding 2, removing 1' : function (test) { + + var emitter = new EventEmitter2; + + var type = 'remove', + listeners; + + var f = function f() { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 2, 'should only have 2'); + + //remove + emitter.removeListener(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should be 1'); + + test.expect(2); + test.done(); + }, + + 'removeListener3. adding 3, removing 1' : function (test) { + + var emitter = new EventEmitter2; + + var type = 'remove', + listeners; + + var f = function f() { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + emitter.on(type, f); + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 3, 'should only have 3'); + + //remove + emitter.removeListener(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 2, 'should be 2'); + + test.expect(2); + test.done(); + }, + + 'removeListener4. should error if we don\'t pass in a function' : function (test) { + + var emitter = new EventEmitter2; + var type = 'remove', + listeners; + + var f = function f() { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should only have 1'); + + //remove + test.throws(function () {emitter.removeListener(type, type)}, Error, 'should throw an Error'); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should be 1'); + + test.expect(3); + test.done(); + }, + + 'removeListener5. removing a different function, should not remove' : function (test) { + + var emitter = new EventEmitter2; + var type = 'remove', + listeners; + + var f = function f() { + test.ok(true, 'event was raised'); + }; + var g = function g() { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should only have 1'); + + //remove + emitter.removeListener(type, g); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should be 1'); + + test.expect(2); + test.done(); + }, + + 'removeListener6. removing all functions' : function (test) { + + var emitter = new EventEmitter2; + var type = 'remove', + listeners; + + var f = function f() { + test.ok(true, 'event was raised'); + }; + for (var i = 0; i < 10; i++) { + emitter.on(type, f); + } + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should only have 10'); + + emitter.removeListener(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 9, 'should be 9'); + emitter.removeAllListeners(type); + listeners = emitter.listeners(type); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(3); + test.done(); + }, + + 'removeListener7. removing different event, should not remove' : function (test) { + + var emitter = new EventEmitter2; + var type = 'remove', + listeners; + + var f = function f() { + test.ok(true, 'event was raised'); + }; + + for (var i = 0; i < 10; i++) { + emitter.on(type, f); + } + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should only have 10'); + + emitter.removeListener(type+type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should be 10'); + + emitter.removeAllListeners(type+type); + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should be 10'); + + emitter.removeAllListeners(type); + listeners = emitter.listeners(type); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(4); + test.done(); + } +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/setMax.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/setMax.js new file mode 100644 index 0000000..531862d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/setMax.js @@ -0,0 +1,135 @@ + +var simpleEvents= require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + 'setMaxListener1. default behavior of 10 listeners.' : function (test) { + + var emitter = new EventEmitter2; + + for (var i = 0; i < 10; i++) { + emitter.on('foobar', function () { + test.ok(true, 'event was raised'); + }); + } + + var listeners = emitter.listeners('foobar'); + test.equal(listeners.length, 10, 'should only have 10'); + + test.expect(1); + test.done(); + }, + + 'setMaxListener2. If we added more than 10, should not see them' : function (test) { + + var emitter = new EventEmitter2; + + for (var i = 0; i < 10 ; i++) { + emitter.on('foobar2', function () { + test.ok(true, 'event was raised'); + }); + } + console.log('should see EE2 complaining:'); + emitter.on('foobar2', function () { + test.ok(true, 'event was raised'); + }); + + var listeners = emitter.listeners('foobar2'); + test.equal(listeners.length, 11, 'should have 11'); + test.ok(emitter._events['foobar2'].warned, 'should have been warned'); + + test.expect(2); + test.done(); + }, + + 'setMaxListener3. if we set maxListener to be greater before adding' : function (test) { + + var emitter = new EventEmitter2; + var type = 'foobar3'; + + // set to 20 + emitter.setMaxListeners(20); + + for (var i = 0; i < 15 ; i++) { + emitter.on(type, function () { + test.ok(true, 'event was raised'); + }); + } + + var listeners = emitter.listeners(type); + test.equal(listeners.length, 15, 'should have 15'); + test.ok(!(emitter._events[type].warned), 'should not have been set'); + + test.expect(2); + test.done(); + }, + + 'setMaxListener4. should be able to change it right at 10' : function (test) { + + var emitter = new EventEmitter2; + var type = 'foobar4'; + + for (var i = 0; i < 10 ; i++) { + emitter.on(type, function () { + test.ok(true, 'event was raised'); + }); + } + + emitter.setMaxListeners(9001); + emitter.on(type, function () { + test.ok(true, 'event was raised'); + }); + + var listeners = emitter.listeners(type); + test.equal(listeners.length, 11, 'should have 11'); + test.ok(!(emitter._events[type].warned), 'should not have been set'); + + test.expect(2); + test.done(); + }, + + 'setMaxListener5. if we set maxListener to be 0 should add endlessly' : function (test) { + + var emitter = new EventEmitter2; + var type = 'foobar'; + + // set to 0 + emitter.setMaxListeners(0); + + for (var i = 0; i < 25 ; i++) { + emitter.on(type, function () { + test.ok(true, 'event was raised'); + }); + } + + var listeners = emitter.listeners(type); + test.equal(listeners.length, 25, 'should have 25'); + test.ok(!(emitter._events[type].warned), 'should not have been set'); + + test.expect(2); + test.done(); + }, + 'maxListeners parameter. Passing maxListeners as a parameter should override default.' : function (test) { + + var emitter = new EventEmitter2({ + maxListeners: 2 + }); + + console.log(emitter, test.equal, test.ok); + emitter.on('a', function () {}); + emitter.on('a', function () {}); + emitter.on('a', function () {}); + test.ok(emitter._events.a.warned, + '.on() should warn when maxListeners is exceeded.'); + test.done(); + } +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/ttl.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/ttl.js new file mode 100644 index 0000000..332e8a7 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/simple/ttl.js @@ -0,0 +1,115 @@ + +var simpleEvents = require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + '1. A listener added with `once` should only listen once and then be removed.': function (test) { + + var emitter = new EventEmitter2(); + + emitter.once('test1', function () { + test.ok(true, 'The event was raised once'); + }); + + emitter.emit('test1'); + emitter.emit('test1'); + + test.expect(1); + test.done(); + + }, + '2. A listener with a TTL of 4 should only listen 4 times.': function (test) { + + var emitter = new EventEmitter2(); + + emitter.many('test1', 4, function (value1) { + test.ok(true, 'The event was raised 4 times.'); + }); + + emitter.emit('test1', 1); + emitter.emit('test1', 2); + emitter.emit('test1', 3); + emitter.emit('test1', 4); + emitter.emit('test1', 5); + + test.expect(4); + test.done(); + + }, + '3. A listener with a TTL of 4 should only listen 4 times and pass parameters.': function (test) { + + var emitter = new EventEmitter2(); + + emitter.many('test1', 4, function (value1, value2, value3) { + test.ok(typeof value1 !== 'undefined', 'got value 1'); + test.ok(typeof value2 !== 'undefined', 'got value 2'); + test.ok(typeof value3 !== 'undefined', 'got value 3'); + }); + + emitter.emit('test1', 1, 'A', false); + emitter.emit('test1', 2, 'A', false); + emitter.emit('test1', 3, 'A', false); + emitter.emit('test1', 4, 'A', false); + emitter.emit('test1', 5, 'A', false); + + test.done(); + + }, + '4. Remove an event listener by signature.': function (test) { + + var emitter = new EventEmitter2(); + var count = 0; + + function f1(event) { + "event A"; + test.ok(true, 'The event was raised less than 3 times.'); + } + + emitter.on('test1', f1); + + function f2(event) { + "event B"; + test.ok(true, 'The event was raised less than 3 times.'); + } + + emitter.on('test1', f2); + + function f3(event) { + "event C"; + test.ok(true, 'The event was raised less than 3 times.'); + } + + emitter.on('test1', f3); + + emitter.removeListener('test1', f2); + + emitter.emit('test1'); + + test.expect(2); + test.done(); + + }, + '5. `removeListener` and `once`': function(test) { + + var emitter = new EventEmitter2(); + var functionA = function() { test.ok(true, 'Event was fired'); }; + + emitter.once('testA', functionA); + emitter.removeListener('testA', functionA); + + emitter.emit('testA'); + + test.expect(0); + test.done(); + } + +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/addListener.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/addListener.js new file mode 100644 index 0000000..308093a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/addListener.js @@ -0,0 +1,338 @@ + +var simpleEvents = require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; + +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + '1. Add a single listener on a single event.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var type = 'some.listener.bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 1, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + + '1a. Add a single listener on a single event (using an array).': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var type = ['some', 'listener', 'bar']; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 1, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + + '2. Add two listeners on a single event.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var type = 'some.listener.bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 2, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + + '2a. Add two listeners on a single event (using an array).': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var type = ['some', 'listener', 'bar']; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 2, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + + '3. Add three listeners on a single event.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var type = 'some.listener.bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 3, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + + '4. Add two listeners to two different events.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var type = 'some.listener.bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test2', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test2', function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 2, 'There are two emitters'); + test.equal(emitter.listeners('test2').length, 2, 'There are two emitters'); + + test.expect(2); + test.done(); + }, + + '5. Never adding any listeners should yield a listeners array with the length of 0.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var type = 'some.listener.bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners('test2').length, 0, 'There are no emitters'); + + test.expect(1); + test.done(); + }, + + '6. the listener added should be the right listener.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var type = 'some.listener.bar'; + var f = function () {}; + + emitter.on(type, f); + test.equal(emitter.listeners(type).length, 1, 'There are is one emitters'); + test.equal(emitter.listeners(type)[0], f, 'The function should be f'); + + test.expect(2); + test.done(); + + }, + + '7. Listeners on `*`, `*.*`, `*.test` with emissions from `foo.test` and `other.emit`': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var f = function () { + test.ok(true, 'the event was fired') + }; + + emitter.on('*.test', f); + emitter.on('*.*', f); + emitter.on('*', f); + + emitter.emit('other.emit'); + emitter.emit('foo.test'); + + test.expect(3); + test.done(); + }, + + '8. Listeners on `*`, `*.*`, foo.test with emissions from `*`, `*.*` and `foo.test`': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var f = function () { + test.ok(true, 'the event was fired') + }; + + emitter.on('foo.test', f); + emitter.on('*.*', f); + emitter.on('*', f); + + emitter.emit('*.*'); + emitter.emit('foo.test'); + emitter.emit('*') + + test.expect(5); + test.done(); + }, + + '9. Listeners on `*`. (using an array)': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var f = function () { + test.ok(true, 'the event was fired') + }; + + emitter.on(['*'], f); + emitter.emit('*') + + test.expect(1); + test.done(); + }, + + '10. actual event name': function(test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + emitter.on('foo', function() { + emitter.emit('bar'); // changes the current event, passes the old one in as a parameter. + }); + + emitter.on('*', function() { + console.log(this.event); + }); + + emitter.emit('foo'); + + test.done(); + }, + + '11. Listeners with multi-level wildcards': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + var i = 0; + var f = function (n) { + return function() { + //console.log('Event', n, 'fired by', this.event); + test.ok(true, 'the event was fired'); + }; + }; + + emitter.on('**.test', f(i++)); // 0: 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + emitter.on('**.bar.**', f(i++)); // 1: 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + emitter.on('**.*', f(i++)); // 2: 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + emitter.on('*.**', f(i++)); // 3: 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + emitter.on('**', f(i++)); // 4: 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + emitter.on('other.**', f(i++)); // 5: 1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 1 + emitter.on('foo.**.test', f(i++)); // 6: 0 + 1 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + emitter.on('test.**', f(i++)); // 7: 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + // Add forbidden patterns for safety purpose. + emitter.on('**.**', f(i++)); + emitter.on('a.b.**.**', f(i++)); + emitter.on('**.**.a.b', f(i++)); + emitter.on('a.b.**.**.a.b', f(i++)); + + emitter.emit('other.emit'); // 4 + emitter.emit('foo.bar.test'); // 6 + emitter.emit('foo.bar.test.bar.foo.test.foo'); // 4 + emitter.emit('bar.bar.bar.bar.bar.bar'); // 4 + emitter.emit('**.*'); // 8 + emitter.emit('test'); // 5 + emitter.emit('foo.test'); // 5 + emitter.emit('foo.**.*'); // 6 + emitter.emit('**.test'); // 8 + emitter.emit('**.test.**'); // 8 + //emitter.emit('*.**.test.**.a'); // 0 + + test.expect(58); + test.done(); + }, + + '12. Check return values of emit for wildcard emitter.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true + }); + + emitter.on('foo.*', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.onAny(function () { + test.ok(true, 'The event was raised'); + }); + + test.ok(emitter.emit('foo.blah'), 'emit should return true after calling a listener'); + test.ok(emitter.emit('bar'), 'emit should return true after calling a listener'); + + test.expect(5); + test.done(); + } + +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/all.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/all.js new file mode 100644 index 0000000..63bf8fb --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/all.js @@ -0,0 +1,248 @@ +var basicEvents = require('nodeunit').testCase; + +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require('../../lib/eventemitter2').EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +function setHelper (emitter, test, testName){ + var eventNames = [ + testName, + testName + '.*', + testName + '.ns1', + testName + '.ns1.ns2', + testName + '.ns2.*' + ]; + + for (var i = 0; i < eventNames.length; i++) { + emitter.on(eventNames[i], function () { + test.ok(true, eventNames[i] + 'has fired'); + }); + } + + return eventNames; +}; + +module.exports = basicEvents({ + + '1. An event can be namespaced.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test1.ns1', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.emit('test1.ns1'); + + test.expect(1); + test.done(); + + }, + '2. An event can be namespaced and accept values.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test2.ns1', function(value1) { + test.ok(true, 'The event was raised'); + test.ok(typeof value1 !== 'undefined', 'The event was raised with the value `' + value1 + '`.'); + }); + + emitter.emit('test2.ns1', 1); + + test.expect(2); + test.done(); + + }, + '3. A namespaced event can be raised multiple times and accept values.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test3.ns1', function (value1, value2, value3) { + test.ok(true, 'The event was raised'); + test.ok(arguments.length === 3, 'The event was raised with the correct number of arguments'); + test.ok(value1 === 1 || value1 === 4, 'The event was raised with the value `' + value1 + '`.'); + test.ok(value2 === 2 || value2 === 5, 'The event was raised with the value `' + value2 + '`.'); + test.ok(value3 === 3 || value3 === 6, 'The event was raised with the value `' + value3 + '`.'); + }); + + emitter.emit('test3.ns1', 1, 2, 3); + emitter.emit('test3.ns1', 4, 5, 6); + + test.expect(10); + test.done(); + }, + '4. A listener should support wild cards.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test4.*', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.emit('test4.ns1'); + + test.expect(1); + test.done(); + + }, + '5. Emitting an event should support wildcards.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test5A.test5B', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.emit('test5A.*'); + + test.expect(1); + test.done(); + + }, + '6. A listener should support complex wild cards.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test10.*.foo', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.emit('test10.ns1.foo'); + + test.expect(1); + test.done(); + + }, + '7. Emitting an event should support complex wildcards.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test11.ns1.foo', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.emit('test11.*.foo'); + + test.expect(1); + test.done(); + + }, + '8. Emitting an event should support complex wildcards multiple times, a valid listener should accept values.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test12.ns1.ns2', function (value1, value2, value3) { + test.ok(true, 'The event was raised'); + test.ok(arguments.length === 3, 'The event was raised with the correct number of arguments'); + test.ok(value1 === 1 || value1 === 4, 'The event was raised with the value `' + value1 + '`.'); + test.ok(value2 === 2 || value2 === 5, 'The event was raised with the value `' + value1 + '`.'); + test.ok(value3 === 3 || value3 === 6, 'The event was raised with the value `' + value1 + '`.'); + }); + + emitter.emit('test12.*.ns2', 1, 2, 3); + emitter.emit('test12.*.ns2', 4, 5, 6); + + test.expect(10); + test.done(); + + }, + '9. List all the listeners for a particular event.': function(test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + emitter.on('test13', function (event) { + test.ok(true,'raised one'); + }); + + emitter.on('test13', function (event) { + test.ok(true,'raised two'); + }); + + var listeners = emitter.listeners('test13'); + + test.ok(listeners.length === 2, 'The event `test13` should have 2 listeners'); + test.expect(1); + test.done(); + + }, + '10. should be able to listen on any event' : function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + var fn = function (foo, bar) { + test.equal(this.event, 'test23.ns5.ns5') + test.equal(foo, 'foo'); + test.equal(bar, 1); + test.ok(true, 'raised test23.ns5.ns5'); + } + + emitter.onAny(fn); + emitter.emit('test23.ns5.ns5', 'foo', 1); + test.expect(4); + test.done(); + + }, + + '11. No warning should be raised if we set maxListener to be greater before adding' : function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + var type = 'test29.*'; + + // set to 20 + emitter.setMaxListeners(20); + + for (var i = 0; i < 15 ; i++) { + emitter.on(type, function () { + test.ok(true, 'event was raised'); + }); + } + + var listeners = emitter.listeners(type); + test.equal(listeners.length, 15, 'should have 15'); + test.ok(!(emitter.listenerTree[ 'test29' ]['*']._listeners.warned), 'should not have been set'); + + test.expect(2); + test.done(); + } + + +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/customDelimiter.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/customDelimiter.js new file mode 100644 index 0000000..ee0c6f1 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/customDelimiter.js @@ -0,0 +1,250 @@ + +var simpleEvents = require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; + +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + '1. Add a single listener on a single event.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var type = 'some::listener::bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 1, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + + '2. Add two listeners on a single event.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var type = 'some::listener::bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 2, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + '3. Add three listeners on a single event.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var type = 'some::listener::bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 3, 'There are three emitters'); + + test.expect(1); + test.done(); + + }, + '4. Add two listeners to two different events.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var type = 'some::listener::bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test2', function () { + test.ok(true, 'The event was raised'); + }); + + emitter.on('test2', function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners(type).length, 2, 'There are two emitters'); + test.equal(emitter.listeners('test2').length, 2, 'There are two emitters'); + + test.expect(2); + test.done(); + }, + + '5. Never adding any listeners should yield a listeners array with the length of 0.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var type = 'some::listener::bar'; + + emitter.on(type, function () { + test.ok(true, 'The event was raised'); + }); + + test.equal(emitter.listeners('test2').length, 0, 'There are no emitters'); + + test.expect(1); + test.done(); + }, + + '6. the listener added should be the right listener.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var type = 'some::listener::bar'; + var f = function () {}; + + emitter.on(type, f); + test.equal(emitter.listeners(type).length, 1, 'There are is one emitters'); + test.equal(emitter.listeners(type)[0], f, 'The function should be f'); + + test.expect(2); + test.done(); + + }, + + '7. Listeners on *, *::*, *::test with emissions from foo::test and other::emit': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var f = function () { + test.ok(true, 'the event was fired') + }; + + emitter.on('*::test', f); + emitter.on('*::*', f); + emitter.on('*', f); + + emitter.emit('other::emit'); + emitter.emit('foo::test'); + + test.expect(3); + test.done(); + }, + + '8. Listeners on *, *::*, foo.test with emissions from *, *::* and foo.test': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var f = function () { + test.ok(true, 'the event was fired') + }; + + emitter.on('foo::test', f); + emitter.on('*::*', f); + emitter.on('*', f); + + emitter.emit('*::*'); + emitter.emit('foo::test'); + emitter.emit('*') + + test.expect(5); + test.done(); + }, + + '9. Listeners on **, **::*, **::test with emissions from foo::test and other::emit': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var f = function () { + test.ok(true, 'the event was fired'); + }; + + emitter.on('**::test', f); + emitter.on('**::*', f); + emitter.on('**', f); + + emitter.emit('other::emit'); // 2 + emitter.emit('foo::test'); // 3 + + test.expect(5); + test.done(); + }, + + '10. Listeners on **, **::*, foo.test with emissions from **, **::* and foo.test': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + delimiter: '::' + }); + + var i = 0; + var f = function (n) { + return function() { + //console.log(n, this.event); + test.ok(true, 'the event was fired'); + }; + }; + + emitter.on('foo::test', f(i++)); + emitter.on('**::*', f(i++)); + emitter.on('**', f(i++)); + + emitter.emit('**::*'); // 3 + emitter.emit('foo::test'); // 3 + emitter.emit('**'); // 3 + + test.expect(9); + test.done(); + } + +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/k1.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/k1.js new file mode 100644 index 0000000..5b6ef8c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/k1.js @@ -0,0 +1,56 @@ + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var EventEmitter = require('../../lib/eventemitter2').EventEmitter2; + +var e = new EventEmitter({wildcard: true}); +var countWildcard = 0; +var counMultiLevelWildcard = 0; +var countAny = 0; + +e.on('foo', function() { + e.emit('bar', 'bar'); +}); +e.on('*', function(name) { + ++countWildcard; + console.log(this.event, name); + assert.equal(this.event, name); +}); +e.on('**', function(name) { + ++counMultiLevelWildcard; + console.log(this.event, name); + assert.equal(this.event, name); +}); +e.onAny(function(name) { + ++countAny; + assert.equal(this.event, name); +}); + +e.emit('foo', 'foo'); + +process.on('exit', function() { + assert.equal(countWildcard, 2); + assert.equal(counMultiLevelWildcard, 2); + assert.equal(countAny, 2); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/options.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/options.js new file mode 100644 index 0000000..445aa4b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/options.js @@ -0,0 +1,72 @@ +var basicEvents = require('nodeunit').testCase; +var lib = '../../lib/eventemitter2'; + +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(lib).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +function setHelper (emitter, test, testName){ + var eventNames = [ + testName, + testName + '.*', + testName + '.ns1', + testName + '.ns1.ns2', + testName + '.ns2.*', + testName + '.**', + testName = '.ns2.**' + ]; + + for (var i = 0; i < eventNames.length; i++) { + emitter.on(eventNames[i], function () { + test.ok(true, eventNames[i] + 'has fired'); + }); + } + + return eventNames; +} + +module.exports = basicEvents({ + + 'intialize 1. Configuration Flags Test.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + var emitterDefault = new EventEmitter2({ + }); + + test.ok(!emitterDefault.wildcard, 'default .wildcard should be false'); + test.ok(emitter.wildcard, '.wildcard should be true when set'); + + test.expect(2); + test.done(); + + }, + 'initialize 2. creating a wildcard EE should have listenerTree.': function (test) { + + var emitter = new EventEmitter2({ + wildcard: true, + verbose: true + }); + + var emitterDefault = new EventEmitter2({ + }); + + test.ok(emitter.listenerTree, 'listenerTree should exist'); + test.equal(typeof emitter.listenerTree, 'object', 'listenerTree should be an Object'); + + test.ok(!emitterDefault.listenerTree, 'listenerTree should not exist'); + // check the tree to be empty? + + test.expect(3); + test.done(); + + }, +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/removeListener.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/removeListener.js new file mode 100644 index 0000000..1099c8a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/removeListener.js @@ -0,0 +1,317 @@ +var simpleEvents= require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; + +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + '1. add a single event and then remove the event.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'remove.foo.bar', + listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should only have 1'); + + //remove + emitter.removeListener(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(2); + test.done(); + }, + + '2. Add two events and then remove only one of those events.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'remove.foo.bar', + listeners; + + var f = function f() { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + emitter.on(type, f); + + listeners = emitter.listeners(type); + test.equal(listeners.length, 2, 'should only have 2'); + + emitter.removeListener(type, f); + + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should be 1'); + + test.expect(2); + test.done(); + }, + + '3. Add three events and remove only one of the events that was added.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'remove.foo.bar', + listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + emitter.on(type, f); + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 3, 'should only have 3'); + + //remove + emitter.removeListener(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 2, 'should be 2'); + + test.expect(2); + test.done(); + }, + + '4. Should error if we don\'t pass a function to the emit method.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'remove.foo.bar', + listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should only have 1'); + + //remove + test.throws(function () {emitter.removeListener(type, type)}, Error, 'should throw an Error'); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should be 1'); + + test.expect(3); + test.done(); + }, + + '5. Removing one listener should not affect another listener.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'remove.foo.bar', + listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + var g = function () { + test.ok(true, 'event was raised'); + }; + + emitter.on(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should only have 1'); + + //remove + emitter.removeListener(type, g); + listeners = emitter.listeners(type); + test.equal(listeners.length, 1, 'should be 1'); + + test.expect(2); + test.done(); + }, + + '6. Remove all listener functions.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'remove.foo.bar', + listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + for (var i = 0; i < 10; i++) { + emitter.on(type, f); + } + + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should only have 10'); + + emitter.removeListener(type, f); + listeners = emitter.listeners(type); + test.equal(listeners.length, 9, 'should be 9'); + emitter.removeAllListeners(type); + listeners = emitter.listeners(type); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(3); + test.done(); + }, + + '7. Removing listeners for one event should not affect another event\'s listeners.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'remove.foo.bar'; + + var listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + + for (var i = 0; i < 10; i++) { + emitter.on(type, f); + } + + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should only have 10'); + + emitter.removeListener(type+type, f); + + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should be 10'); + + emitter.removeAllListeners(type+type); + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should be 10'); + + emitter.removeAllListeners(type+'.'+type); + listeners = emitter.listeners(type); + test.equal(listeners.length, 10, 'should be 10'); + + emitter.removeAllListeners(type); + listeners = emitter.listeners(type); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(5); + test.done(); + }, + + '8. Its ok to listen on wildcard, so it is ok to remove it.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type1 = '*.wild.card', + type2 = 'just.another.event', + listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + + emitter.on(type2, f); + emitter.on(type1, f); + + //remove + emitter.removeListener(type1, f); + listeners = emitter.listeners(type1); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(1); + test.done(); + }, + + '9. And (8) should not depend on order of listening.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type1 = '*.wild.card', + type2 = 'just.another.event', + listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + + emitter.on(type1, f); + emitter.on(type2, f); + + //remove + emitter.removeListener(type1, f); + listeners = emitter.listeners(type1); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(1); + test.done(); + }, + + '10. Reporting many listeners on wildcard all should removed.' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type1 = '*.wild.card', + type2 = 'exact.wild.card', + listeners; + + var f = function () { + test.ok(true, 'event was raised'); + }; + + emitter.on(type1, f); + emitter.on(type2, f); + + // check number of listeners by wild card + listeners = emitter.listeners(type1); + test.equal(listeners.length, 2, 'should only have 2'); + + // remove by wild card should remove both + emitter.removeListener(type1, f); + listeners = emitter.listeners(type1); + test.equal(listeners.length, 0, 'should be 0'); + + test.expect(2); + test.done(); + } + + +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/ttl.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/ttl.js new file mode 100644 index 0000000..11205dc --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2/test/wildcardEvents/ttl.js @@ -0,0 +1,223 @@ +var simpleEvents = require('nodeunit').testCase; +var file = '../../lib/eventemitter2'; + +var EventEmitter2; + +if(typeof require !== 'undefined') { + EventEmitter2 = require(file).EventEmitter2; +} +else { + EventEmitter2 = window.EventEmitter2; +} + +module.exports = simpleEvents({ + + '1. A listener added with `once` should only listen once and then be removed.': function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'test1.foo.bar'; + + emitter.once(type, function () { + test.ok(true, 'The event was raised once'); + }); + + emitter.emit(type); + emitter.emit(type); + + test.expect(1); + test.done(); + + }, + '2. A listener with a TTL of 4 should only listen 4 times.': function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'test1.foo.bar'; + + emitter.many(type, 4, function (value1) { + test.ok(true, 'The event was raised 4 times.'); + }); + + emitter.emit(type, 1); + emitter.emit(type, 2); + emitter.emit(type, 3); + emitter.emit(type, 4); + emitter.emit(type, 5); + + test.expect(4); + test.done(); + + }, + '3. A listener with a TTL of 4 should only listen 4 times and pass parameters.': function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'test1.foo.bar'; + + emitter.many(type, 4, function (value1, value2, value3) { + test.ok(typeof value1 !== 'undefined', 'got value 1'); + test.ok(typeof value2 !== 'undefined', 'got value 2'); + test.ok(typeof value3 !== 'undefined', 'got value 3'); + }); + + emitter.emit(type, 1, 'A', false); + emitter.emit(type, 2, 'A', false); + emitter.emit(type, 3, 'A', false); + emitter.emit(type, 4, 'A', false); + emitter.emit(type, 5, 'A', false); + + test.done(); + + }, + '4. Remove an event listener by signature.': function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'test1.foo.bar'; + var count = 0; + + function f1(event) { + "event A"; + test.ok(true, 'The event was raised less than 3 times.'); + } + + emitter.on(type, f1); + + function f2(event) { + "event B"; + test.ok(true, 'The event was raised less than 3 times.'); + } + + emitter.on(type, f2); + + function f3(event) { + "event C"; + test.ok(true, 'The event was raised less than 3 times.'); + } + + emitter.on(type, f3); + + emitter.removeListener(type, f2); + + emitter.emit(type); + + test.expect(2); + test.done(); + + }, + '5. `removeListener` and `once`': function(test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'test1.foo.bar'; + var functionA = function() { test.ok(true, 'Event was fired'); }; + + emitter.once(type, functionA); + emitter.removeListener(type, functionA); + + emitter.emit(type); + + test.expect(0); + test.done(); + }, + + '6. Listening with a wildcard on once' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'test1.foo.*'; + var functionA = function() { test.ok(true, 'Event was fired'); }; + + emitter.once(type, functionA); + emitter.on(type,functionA); + + emitter.emit(type); //2 + emitter.emit(type); //1 + + test.expect(3); + test.done(); + }, + + '7. Emitting with a wildcard targeted at once' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'test1.foo.bar'; + var type2 = 'test1.foo.*'; + var functionA = function() { test.ok(true, 'Event was fired'); }; + + emitter.once(type, functionA); + emitter.emit(type2); + emitter.emit(type2); + + test.expect(1); + test.done(); + }, + + '8. Emitting with a multi-level wildcard on once': function(test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var i = 0; + var type = 'test1.**'; + var functionA = function(n) { + return function() { + console.log(n, this.event); + test.ok(true, 'Event was fired'); + }; + } + + emitter.once(type, functionA(i++)); + emitter.on(type, functionA(i++)); + emitter.emit(type); //2 + emitter.emit(type); //1 + + test.expect(3); + test.done(); + }, + + '9. Emitting with a multi-level wildcard targeted at once' : function (test) { + + var emitter = new EventEmitter2({ + wildcard : true, + verbose : true + }); + + var type = 'test1.foo.bar'; + var type2 = 'test1.**'; + var functionA = function() { test.ok(true, 'Event was fired'); }; + + emitter.once(type, functionA); + emitter.emit(type2); + emitter.emit(type2); + + test.expect(1); + test.done(); + } + +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/.npmignore new file mode 100644 index 0000000..2c5c40a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/.npmignore @@ -0,0 +1,6 @@ +test/*.log +test/fixtures/*.json +test/fixtures/logs/*.log +node_modules/ +node_modules/* +npm-debug.log \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/.travis.yml b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/.travis.yml new file mode 100644 index 0000000..b250521 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - 0.4 + - 0.6 +branches: + only: + - master +notifications: + email: + - travis@nodejitsu.com + irc: "irc.freenode.org#nodejitsu" + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/LICENSE b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/LICENSE new file mode 100644 index 0000000..948d80d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Charlie Robbins + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/README.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/README.md new file mode 100644 index 0000000..2fc4798 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/README.md @@ -0,0 +1,790 @@ +# winston [![Build Status](https://secure.travis-ci.org/flatiron/winston.png)](http://travis-ci.org/flatiron/winston) + +A multi-transport async logging library for node.js. "CHILL WINSTON! ... I put it in the logs." + +## Motivation +Winston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file. + +There also seemed to be a lot of logging libraries out there that coupled their implementation of logging (i.e. how the logs are stored / indexed) to the API that they exposed to the programmer. This library aims to decouple those parts of the process to make it more flexible and extensible. + +## Usage +There are two different ways to use winston: directly via the default logger, or by instantiating your own Logger. The former is merely intended to be a convenient shared logger to use throughout your application if you so choose. + +* [Logging](#logging) + * [Using the Default Logger](#using-the-default-logger) + * [Instantiating your own Logger](#instantiating-your-own-logger) + * [Logging with Metadata](#logging-with-metadata) +* [Transports](https://github.com/flatiron/winston/blob/master/docs/transports.md) +* [Profiling](#profiling) +* [Streaming Logs](#streaming-logs) +* [Querying Logs](#querying-logs) +* [Exceptions](#exceptions) + * [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston) + * [To Exit or Not to Exit](#to-exit-or-not-to-exit) +* [Logging Levels](#logging-levels) + * [Using Logging Levels](#using-logging-levels) + * [Using Custom Logging Levels](#using-custom-logging-levels) +* [Further Reading](#further-reading) + * [Events and Callbacks in Winston](#events-and-callbacks-in-winston) + * [Working with multiple Loggers in winston](#working-with-multiple-loggers-in-winston) + * [Using winston in a CLI tool](#using-winston-in-a-cli-tool) + * [Extending another object with Logging](#extending-another-object-with-logging) + * [Adding Custom Transports](#adding-custom-transports) + +## Logging + +### Using the Default Logger +The default logger is accessible through the winston module directly. Any method that you could call on an instance of a logger is available on the default logger: + +``` js + var winston = require('winston'); + + winston.log('info', 'Hello distributed log files!'); + winston.info('Hello again distributed logs'); +``` + +By default, only the Console transport is set on the default logger. You can add or remove transports via the add() and remove() methods: + +``` js + winston.add(winston.transports.File, { filename: 'somefile.log' }); + winston.remove(winston.transports.Console); +``` + +For more documenation about working with each individual transport supported by Winston see the "Working with Transports" section below. + +### Instantiating your own Logger +If you would prefer to manage the object lifetime of loggers you are free to instantiate them yourself: + +``` js + var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.File)({ filename: 'somefile.log' }) + ] + }); +``` + +You can work with this logger in the same way that you work with the default logger: + +``` js + // + // Logging + // + logger.log('info', 'Hello distributed log files!'); + logger.info('Hello again distributed logs'); + + // + // Adding / Removing Transports + // (Yes It's chainable) + // + logger.add(winston.transports.File) + .remove(winston.transports.Console); +``` + +### Logging with Metadata +In addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple: + +``` js + winston.log('info', 'Test Log Message', { anything: 'This is metadata' }); +``` + +The way these objects is stored varies from transport to transport (to best support the storage mechanisms offered). Here's a quick summary of how each transports handles metadata: + +1. __Console:__ Logged via util.inspect(meta) +2. __File:__ Logged via util.inspect(meta) + +## Profiling +In addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger: + +``` js + // + // Start profile of 'test' + // Remark: Consider using Date.now() with async operations + // + winston.profile('test'); + + setTimeout(function () { + // + // Stop profile of 'test'. Logging will now take place: + // "17 Jan 21:00:00 - info: test duration=1000ms" + // + winston.profile('test'); + }, 1000); +``` + +All profile messages are set to the 'info' by default and both message and metadata are optional There are no plans in the Roadmap to make this configurable, but I'm open to suggestions / issues. + + +## Querying Logs +Winston supports querying of logs with Loggly-like options. +Specifically: `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`. + +``` js + var options = { + from: new Date - 24 * 60 * 60 * 1000, + until: new Date + }; + + // + // Find items logged between today and yesterday. + // + winston.query(options, function (err, results) { + if (err) { + throw err; + } + + console.log(results); + }); +``` + +## Streaming Logs +Streaming allows you to stream your logs back from your chosen transport. + +``` js + // + // Start at the end. + // + winston.stream({ start: -1 }).on('log', function(log) { + console.log(log); + }); +``` + +## Exceptions + +### Handling Uncaught Exceptions with winston + +With `winston`, it is possible to catch and log `uncaughtException` events from your process. There are two distinct ways of enabling this functionality either through the default winston logger or your own logger instance. + +If you want to use this feature with the default logger simply call `.handleExceptions()` with a transport instance. + +``` js + // + // You can add a separate exception logger by passing it to `.handleExceptions` + // + winston.handleExceptions(new winston.transports.File({ filename: 'path/to/exceptions.log' })) + + // + // Alternatively you can set `.handleExceptions` to true when adding transports to winston + // + winston.add(winston.transports.File, { + filename: 'path/to/all-logs.log', + handleExceptions: true + }); +``` + +### To Exit or Not to Exit + +by default, winston will exit after logging an uncaughtException. if this is not the behavior you want, +set `exitOnError = false` + +``` js + var logger = new (winston.Logger)({ exitOnError: false }); + + // + // or, like this: + // + logger.exitOnError = false; +``` + +When working with custom logger instances, you can pass in separate transports to the `exceptionHandlers` property or set `.handleExceptions` on any transport. + +Example 1 + +``` js + var logger = new (winston.Logger)({ + transports: [ + new winston.transports.File({ filename: 'path/to/all-logs.log' }) + ] + exceptionHandlers: [ + new winston.transports.File({ filename: 'path/to/exceptions.log' }) + ] + }); +``` + +Example 2 + +``` +var logger = new winston.Logger({ + transports: [ + new winston.transports.Console({ + handleExceptions: true, + json: true + }) + ], + exitOnError: false +}); +``` + +The `exitOnError` option can also be a function to prevent exit on only certain types of errors: + +``` js + function ignoreEpipe(err) { + return err.code !== 'EPIPE'; + } + + var logger = new (winston.Logger)({ exitOnError: ignoreEpipe }); + + // + // or, like this: + // + logger.exitOnError = ignoreEpipe; +``` + +## Logging Levels + +### Using Logging Levels +Setting the level for your logging message can be accomplished in one of two ways. You can pass a string representing the logging level to the log() method or use the level specified methods defined on every winston Logger. + +``` js + // + // Any logger instance + // + logger.log('info', "127.0.0.1 - there's no place like home"); + logger.log('warn', "127.0.0.1 - there's no place like home"); + logger.log('error', "127.0.0.1 - there's no place like home"); + logger.info("127.0.0.1 - there's no place like home"); + logger.warn("127.0.0.1 - there's no place like home"); + logger.error("127.0.0.1 - there's no place like home"); + + // + // Default logger + // + winston.log('info', "127.0.0.1 - there's no place like home"); + winston.info("127.0.0.1 - there's no place like home"); +``` + +Winston allows you to set a `level` on each transport that specifies the level of messages this transport should log. For example, you could log only errors to the console, with the full logs in a file: + +``` js + var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)({ level: 'error' }), + new (winston.transports.File)({ filename: 'somefile.log' }) + ] + }); +``` + +As of 0.2.0, winston supports customizable logging levels, defaulting to [npm][0] style logging levels. Changing logging levels is easy: + +``` js + // + // Change levels on the default winston logger + // + winston.setLevels(winston.config.syslog.levels); + + // + // Change levels on an instance of a logger + // + logger.setLevels(winston.config.syslog.levels); +``` + +Calling `.setLevels` on a logger will remove all of the previous helper methods for the old levels and define helper methods for the new levels. Thus, you should be careful about the logging statements you use when changing levels. For example, if you ran this code after changing to the syslog levels: + +``` js + // + // Logger does not have 'silly' defined since that level is not in the syslog levels + // + logger.silly('some silly message'); +``` + +### Using Custom Logging Levels +In addition to the predefined `npm` and `syslog` levels available in Winston, you can also choose to define your own: + +``` js + var myCustomLevels = { + levels: { + foo: 0, + bar: 1, + baz: 2, + foobar: 3 + }, + colors: { + foo: 'blue', + bar: 'green', + baz: 'yellow', + foobar: 'red' + } + }; + + var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels }); + customLevelLogger.foobar('some foobar level-ed message'); +``` + +Although there is slight repetition in this data structure, it enables simple encapsulation if you not to have colors. If you do wish to have colors, in addition to passing the levels to the Logger itself, you must make winston aware of them: + +``` js + // + // Make winston aware of these colors + // + winston.addColors(myCustomLevels.colors); +``` + +This enables transports with the 'colorize' option set to appropriately color the output of custom levels. + +## Further Reading + +### Events and Callbacks in Winston +Each instance of winston.Logger is also an instance of an [EventEmitter][1]. A log event will be raised each time a transport successfully logs a message: + +``` js + logger.on('logging', function (transport, level, msg, meta) { + // [msg] and [meta] have now been logged at [level] to [transport] + }); + + logger.info('CHILL WINSTON!', { seriously: true }); +``` + +It is also worth mentioning that the logger also emits an 'error' event which you should handle or suppress if you don't want unhandled exceptions: + +``` js + // + // Handle errors + // + logger.on('error', function (err) { /* Do Something */ }); + + // + // Or just suppress them. + // + logger.emitErrs = false; +``` + +Every logging method described in the previous section also takes an optional callback which will be called only when all of the transports have logged the specified message. + +``` js + logger.info('CHILL WINSTON!', { seriously: true }, function (err, level, msg, meta) { + // [msg] and [meta] have now been logged at [level] to **every** transport. + }); +``` + +### Working with multiple Loggers in winston + +Often in larger, more complex applications it is necessary to have multiple logger instances with different settings. Each logger is responsible for a different feature area (or category). This is exposed in `winston` in two ways: through `winston.loggers` and instances of `winston.Container`. In fact, `winston.loggers` is just a predefined instance of `winston.Container`: + +``` js + var winston = require('winston'); + + // + // Configure the logger for `category1` + // + winston.loggers.add('category1', { + console: { + level: 'silly', + colorize: 'true' + }, + file: { + filename: '/path/to/some/file' + } + }); + + // + // Configure the logger for `category2` + // + winston.loggers.add('category2', { + couchdb: { + host: '127.0.0.1', + port: 5984 + } + }); +``` + +Now that your loggers are setup you can require winston _in any file in your application_ and access these pre-configured loggers: + +``` js + var winston = require('winston'); + + // + // Grab your preconfigured logger + // + var category1 = winston.loggers.get('category1'); + + category1.info('logging from your IoC container-based logger'); +``` + +If you prefer to manage the `Container` yourself you can simply instantiate one: + +``` js + var winston = require('winston'), + container = new winston.Container(); + + container.add('category1', { + console: { + level: 'silly', + colorize: 'true' + }, + file: { + filename: '/path/to/some/file' + } + }); +``` + +### Sharing transports between Loggers in winston + +``` js + var winston = require('winston'); + + // + // Setup transports to be shared across all loggers + // in three ways: + // + // 1. By setting it on the default Container + // 2. By passing `transports` into the constructor function of winston.Container + // 3. By passing `transports` into the `.get()` or `.add()` methods + // + + // + // 1. By setting it on the default Container + // + winston.loggers.options.transports = [ + // Setup your shared transports here + ]; + + // + // 2. By passing `transports` into the constructor function of winston.Container + // + var container = new winston.Container({ + transports: [ + // Setup your shared transports here + ] + }); + + // + // 3. By passing `transports` into the `.get()` or `.add()` methods + // + winston.loggers.add('some-category', { + transports: [ + // Setup your shared transports here + ] + }); + + container.add('some-category', { + transports: [ + // Setup your shared transports here + ] + }); +``` + +### Using winston in a CLI tool +A common use-case for logging is output to a CLI tool. Winston has a special helper method which will pretty print output from your CLI tool. Here's an example from the [require-analyzer][2] written by [Nodejitsu][3]: + +``` + info: require-analyzer starting in /Users/Charlie/Nodejitsu/require-analyzer + info: Found existing dependencies + data: { + data: colors: '0.x.x', + data: eyes: '0.1.x', + data: findit: '0.0.x', + data: npm: '1.0.x', + data: optimist: '0.2.x', + data: semver: '1.0.x', + data: winston: '0.2.x' + data: } + info: Analyzing dependencies... + info: Done analyzing raw dependencies + info: Retrieved packages from npm + warn: No additional dependencies found +``` + +Configuring output for this style is easy, just use the `.cli()` method on `winston` or an instance of `winston.Logger`: + +``` js + var winston = require('winston'); + + // + // Configure CLI output on the default logger + // + winston.cli(); + + // + // Configure CLI on an instance of winston.Logger + // + var logger = new winston.Logger({ + transports: [ + new (winston.transports.Console)() + ] + }); + + logger.cli(); +``` + +### Extending another object with Logging +Often in a given code base with lots of Loggers it is useful to add logging methods a different object so that these methods can be called with less syntax. Winston exposes this functionality via the 'extend' method: + +``` js + var myObject = {}; + + logger.extend(myObject); + + // + // You can now call logger methods on 'myObject' + // + myObject.info('127.0.0.1 - there's no place like home'); +``` + +## Working with Transports +Right now there are four transports supported by winston core. If you have a transport you would like to add either open an issue or fork and submit a pull request. Commits are welcome, but I'll give you extra street cred if you __add tests too :D__ + +1. __Console:__ Output to the terminal +2. __Files:__ Append to a file +3. __Loggly:__ Log to Logging-as-a-Service platform Loggly + +### Console Transport +``` js + winston.add(winston.transports.Console, options) +``` + +The Console transport takes two simple options: + +* __level:__ Level of messages that this transport should log (default 'info'). +* __silent:__ Boolean flag indicating whether to suppress output (default false). +* __colorize:__ Boolean flag indicating if we should colorize output (default false). +* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps. + +*Metadata:* Logged via util.inspect(meta); + +### File Transport +``` js + winston.add(winston.transports.File, options) +``` + +The File transport should really be the 'Stream' transport since it will accept any [WritableStream][14]. It is named such because it will also accept filenames via the 'filename' option: + +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. +* __colorize:__ Boolean flag indicating if we should colorize output. +* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default true). If function is specified, its return value will be used instead of timestamps. +* __filename:__ The filename of the logfile to write output to. +* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created. +* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded. +* __stream:__ The WriteableStream to write output to. +* __json:__ If true, messages will be logged as JSON (default true). + +*Metadata:* Logged via util.inspect(meta); + +### Loggly Transport +``` js + var Loggly = require('winston-loggly').Loggly + winston.add(Loggly, options); +``` + +The Loggly transport is based on [Nodejitsu's][5] [node-loggly][6] implementation of the [Loggly][7] API. If you haven't heard of Loggly before, you should probably read their [value proposition][8]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required: + +* __level:__ Level of messages that this transport should log. +* __subdomain:__ The subdomain of your Loggly account. *[required]* +* __auth__: The authentication information for your Loggly account. *[required with inputName]* +* __inputName:__ The name of the input this instance should log to. +* __inputToken:__ The input token of the input this instance should log to. +* __json:__ If true, messages will be sent to Loggly as JSON. + +*Metadata:* Logged in suggested [Loggly format][2] + +### Riak Transport +As of `0.3.0` the Riak transport has been broken out into a new module: [winston-riak][17]. Using it is just as easy: + +``` js + var Riak = require('winston-riak').Riak; + winston.add(Riak, options); +``` + +In addition to the options accepted by the [riak-js][3] [client][4], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default: + +* __level:__ Level of messages that this transport should log. +* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically. + +``` js + // Use a single bucket for all your logs + var singleBucketTransport = new (Riak)({ bucket: 'some-logs-go-here' }); + + // Generate a dynamic bucket based on the date and level + var dynamicBucketTransport = new (Riak)({ + bucket: function (level, msg, meta, now) { + var d = new Date(now); + return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-'); + } + }); +``` + +*Metadata:* Logged as JSON literal in Riak + +### MongoDB Transport +As of `0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][16]. Using it is just as easy: + +``` js + var MongoDB = require('winston-mongodb').MongoDB; + winston.add(MongoDB, options); +``` + +The MongoDB transport takes the following options. 'db' is required: + +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. +* __db:__ The name of the database you want to log to. *[required]* +* __collection__: The name of the collection you want to store log messages in, defaults to 'log'. +* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true. +* __host:__ The host running MongoDB, defaults to localhost. +* __port:__ The port on the host that MongoDB is running on, defaults to MongoDB's default port. + +*Metadata:* Logged as a native JSON object. + +### SimpleDB Transport + +The [winston-simpledb][18] transport is just as easy: + +``` js + var SimpleDB = require('winston-simpledb').SimpleDB; + winston.add(SimpleDB, options); +``` + +The SimpleDB transport takes the following options. All items marked with an asterisk are required: + +* __awsAccessKey__:* your AWS Access Key +* __secretAccessKey__:* your AWS Secret Access Key +* __awsAccountId__:* your AWS Account Id +* __domainName__:* a string or function that returns the domain name to log to +* __region__:* the region your domain resides in +* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log + +*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item. + +### Mail Transport + +The [winston-mail][19] is an email transport: + +``` js + var Mail = require('winston-mail').Mail; + winston.add(Mail, options); +``` + +The Mail transport uses [emailjs](https://github.com/eleith/emailjs) behind the scenes. Options are the following: + +* __to:__ The address(es) you want to send to. *[required]* +* __from:__ The address you want to send from. (default: `winston@[server-host-name]`) +* __host:__ SMTP server hostname (default: localhost) +* __port:__ SMTP port (default: 587 or 25) +* __username__ User for server auth +* __password__ Password for server auth +* __ssl:__ Use SSL (boolean or object { key, ca, cert }) +* __tls:__ Boolean (if true, use starttls) +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. + +*Metadata:* Stringified as JSON in email. + +### Amazon SNS (Simple Notification System) Transport + +The [winston-sns][21] transport uses amazon SNS to send emails, texts, or a bunch of other notifications. + +``` js + require('winston-sns').SNS; + winston.add(winston.transports.SNS, options); +``` + +Options: + +* __aws_key:__ Your Amazon Web Services Key. *[required]* +* __aws_secret:__ Your Amazon Web Services Secret. *[required]* +* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]* +* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]* +* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`) +* __subject:__ Subject for notifications. (default: "Winston Error Report") +* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Level '%l' Error:\n%e\n\nMetadata:\n%m") +* __level:__ lowest level this transport will log. (default: `info`) + +### Graylog2 Transport + +[winston-graylog2][22] is a Graylog2 transport: + +``` js + var Graylog2 = require('winston-graylog2').Graylog2; + winston.add(Graylog2, options); +``` + +The Graylog2 transport connects to a Graylog2 server over UDP using the following options: + +* __level:__ Level of messages this transport should log. (default: info) +* __silent:__ Boolean flag indicating whether to suppress output. (default: false) + +* __graylogHost:__ IP address or hostname of the graylog2 server. (default: localhost) +* __graylogPort:__ Port to send messages to on the graylog2 server. (default: 12201) +* __graylogHostname:__ The hostname associated with graylog2 messages. (default: require('os').hostname()) +* __graylogFacility:__ The graylog2 facility to send log messages.. (default: nodejs) + +*Metadata:* Stringified as JSON in the full message GELF field. + +### Adding Custom Transports +Adding a custom transport (say for one of the datastore on the Roadmap) is actually pretty easy. All you need to do is accept a couple of options, set a name, implement a log() method, and add it to the set of transports exposed by winston. + +``` js + var util = require('util'), + winston = require('winston'); + + var CustomLogger = winston.transports.CustomerLogger = function (options) { + // + // Name this logger + // + this.name = 'customLogger'; + + // + // Set the level from your options + // + this.level = options.level || 'info'; + + // + // Configure your storage backing as you see fit + // + }; + + // + // Inherit from `winston.Transport` so you can take advantage + // of the base functionality and `.handleExceptions()`. + // + util.inherits(CustomLogger, winston.Transport); + + CustomLogger.prototype.log = function (level, msg, meta, callback) { + // + // Store this message and metadata, maybe use some custom logic + // then callback indicating success. + // + callback(null, true); + }; +``` + +### Inspirations +1. [npm][0] +2. [log.js][4] +3. [socket.io][5] +4. [node-rlog][6] +5. [BigBrother][7] +6. [Loggly][8] + +## Installation + +### Installing npm (node package manager) +``` + curl http://npmjs.org/install.sh | sh +``` + +### Installing winston +``` + [sudo] npm install winston +``` + +## Run Tests +All of the winston tests are written in [vows][9], and designed to be run with npm. + +``` bash + $ npm test +``` + +#### Author: [Charlie Robbins](http://twitter.com/indexzero) +#### Contributors: [Matthew Bergman](http://github.com/fotoverite), [Marak Squires](http://github.com/marak) + +[0]: https://github.com/isaacs/npm/blob/master/lib/utils/log.js +[1]: http://nodejs.org/docs/v0.3.5/api/events.html#events.EventEmitter +[2]: http://github.com/nodejitsu/require-analyzer +[3]: http://nodejitsu.com +[4]: https://github.com/visionmedia/log.js +[5]: http://socket.io +[6]: https://github.com/jbrisbin/node-rlog +[7]: https://github.com/feisty/BigBrother +[8]: http://loggly.com +[9]: http://vowsjs.org diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/docs/transports.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/docs/transports.md new file mode 100644 index 0000000..5930ad4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/docs/transports.md @@ -0,0 +1,342 @@ +# Winston Transports + +In `winston` a transport a transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file. + +There are several [core transports](#winston-core) included in `winston`, which leverage the built-in networking and file I/O offered by node.js core. In addition, there are [third-party transports which are supported by the winston core team](#winston-more). And last (but not least) there are [additional transports written by members of the community](#additional-transports). + +* **[Winston Core](#winston-core)** + * [Console](#console-transport) + * [File](#file-transport) + * [Http](#http-transport) + * [Webhook](#webhook-transport) + +* **[Winston More](#winston-more)** + * [CouchDB](#couchdb-transport) + * [Loggly](#loggly-transport) + * [MongoDB](#mongodb-transport) + * [Redis](#redis-transport) + * [Riak](#riak-transport) + +* **[Additional Transports](#additional-transports)** + * [SimpleDB](#simpledb-transport) + * [Mail](#mail-transport) + * [Amazon SNS](#amazon-sns-simple-notification-system-transport) + * [Graylog2](#graylog2-transport) + +## Winston Core + +There are several core transports included in `winston`, which leverage the built-in networking and file I/O offered by node.js core. + +* [Console](#console-transport) +* [File](#file-transport) +* [Http](#http-transport) +* [Webhook](#webhook-transport) + +### Console Transport + +``` js + winston.add(winston.transports.Console, options) +``` + +The Console transport takes two simple options: + +* __level:__ Level of messages that this transport should log (default 'debug'). +* __silent:__ Boolean flag indicating whether to suppress output (default false). +* __colorize:__ Boolean flag indicating if we should colorize output (default false). +* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps. + +*Metadata:* Logged via util.inspect(meta); + +### File Transport + +``` js + winston.add(winston.transports.File, options) +``` + +The File transport should really be the 'Stream' transport since it will accept any [WritableStream][0]. It is named such because it will also accept filenames via the 'filename' option: + +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. +* __colorize:__ Boolean flag indicating if we should colorize output. +* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps. +* __filename:__ The filename of the logfile to write output to. +* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created. +* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded. +* __stream:__ The WriteableStream to write output to. +* __json:__ If true, messages will be logged as JSON (default true). + +*Metadata:* Logged via util.inspect(meta); + +### Http Transport + +``` js + winston.add(winston.transports.Http, options) +``` + +The `Http` transport is a generic way to log, query, and stream logs from an arbitrary Http endpoint, preferably [winstond][1]. It takes options that are passed to the node.js `http` or `https` request: + +* __host:__ (Default: **localhost**) Remote host of the HTTP logging endpoint +* __port:__ (Default: **80 or 443**) Remote port of the HTTP logging endpoint +* __path:__ (Default: **/**) Remote URI of the HTTP logging endpoint +* __auth:__ (Default: **None**) An object representing the `username` and `password` for HTTP Basic Auth +* __ssl:__ (Default: **false**) Value indicating if we should us HTTPS + +## Winston More + +Starting with `winston@0.3.0` an effort was made to remove any transport which added additional dependencies to `winston`. At the time there were several transports already in `winston` which will **always be supported by the winston core team.** + +* [CouchDB](#couchdb-transport) +* [Redis](#redis-transport) +* [MongoDB](#mongodb-transport) +* [Riak](#riak-transport) +* [Loggly](#loggly-transport) + +### CouchDB Transport + +_As of `winston@0.6.0` the CouchDB transport has been broken out into a new module: [winston-couchdb][2]._ + +``` js + winston.add(winston.transports.Couchdb, options) +``` + +The `Couchdb` will place your logs in a remote CouchDB database. It will also create a [Design Document][3], `_design/Logs` for later querying and streaming your logs from CouchDB. The transport takes the following options: + +* __host:__ (Default: **localhost**) Remote host of the HTTP logging endpoint +* __port:__ (Default: **5984**) Remote port of the HTTP logging endpoint +* __db:__ (Default: **winston**) Remote URI of the HTTP logging endpoint +* __auth:__ (Default: **None**) An object representing the `username` and `password` for HTTP Basic Auth +* __ssl:__ (Default: **false**) Value indicating if we should us HTTPS + +### Redis Transport + +``` js + winston.add(winston.transports.Redis, options) +``` + +This transport accepts the options accepted by the [node-redis][4] client: + +* __host:__ (Default **localhost**) Remote host of the Redis server +* __port:__ (Default **6379**) Port the Redis server is running on. +* __auth:__ (Default **None**) Password set on the Redis server + +In addition to these, the Redis transport also accepts the following options. + +* __length:__ (Default **200**) Number of log messages to store. +* __container:__ (Default **winston**) Name of the Redis container you wish your logs to be in. +* __channel:__ (Default **None**) Name of the Redis channel to stream logs from. + +*Metadata:* Logged as JSON literal in Redis + +### Loggly Transport + +_As of `winston@0.6.0` the Loggly transport has been broken out into a new module: [winston-loggly][5]._ + +``` js + winston.add(winston.transports.Loggly, options); +``` + +The Loggly transport is based on [Nodejitsu's][6] [node-loggly][7] implementation of the [Loggly][8] API. If you haven't heard of Loggly before, you should probably read their [value proposition][9]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required: + +* __level:__ Level of messages that this transport should log. +* __subdomain:__ The subdomain of your Loggly account. *[required]* +* __auth__: The authentication information for your Loggly account. *[required with inputName]* +* __inputName:__ The name of the input this instance should log to. +* __inputToken:__ The input token of the input this instance should log to. +* __json:__ If true, messages will be sent to Loggly as JSON. + +*Metadata:* Logged in suggested [Loggly format][10] + +### Riak Transport + +_As of `winston@0.3.0` the Riak transport has been broken out into a new module: [winston-riak][11]._ Using it is just as easy: + +``` js + var Riak = require('winston-riak').Riak; + winston.add(Riak, options); +``` + +In addition to the options accepted by the [riak-js][12] [client][13], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default: + +* __level:__ Level of messages that this transport should log. +* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically. + +``` js + // Use a single bucket for all your logs + var singleBucketTransport = new (Riak)({ bucket: 'some-logs-go-here' }); + + // Generate a dynamic bucket based on the date and level + var dynamicBucketTransport = new (Riak)({ + bucket: function (level, msg, meta, now) { + var d = new Date(now); + return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-'); + } + }); +``` + +*Metadata:* Logged as JSON literal in Riak + +### MongoDB Transport + +As of `winston@0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][14]. Using it is just as easy: + +``` js + var MongoDB = require('winston-mongodb').MongoDB; + winston.add(MongoDB, options); +``` + +The MongoDB transport takes the following options. 'db' is required: + +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. +* __db:__ The name of the database you want to log to. *[required]* +* __collection__: The name of the collection you want to store log messages in, defaults to 'log'. +* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true. +* __host:__ The host running MongoDB, defaults to localhost. +* __port:__ The port on the host that MongoDB is running on, defaults to MongoDB's default port. + +*Metadata:* Logged as a native JSON object. + +## Additional Transports + +The community has truly embraced `winston`; there are over **23** winston transports and over half of them are maintained by authors external to the winston core team. If you want to check them all out, just search `npm`: + +``` bash + $ npm search winston +``` + +**If you have an issue using one of these modules you should contact the module author directly** + +### SimpleDB Transport + +The [winston-simpledb][15] transport is just as easy: + +``` js + var SimpleDB = require('winston-simpledb').SimpleDB; + winston.add(SimpleDB, options); +``` + +The SimpleDB transport takes the following options. All items marked with an asterisk are required: + +* __awsAccessKey__:* your AWS Access Key +* __secretAccessKey__:* your AWS Secret Access Key +* __awsAccountId__:* your AWS Account Id +* __domainName__:* a string or function that returns the domain name to log to +* __region__:* the region your domain resides in +* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log + +*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item. + +### Mail Transport + +The [winston-mail][16] is an email transport: + +``` js + var Mail = require('winston-mail').Mail; + winston.add(Mail, options); +``` + +The Mail transport uses [node-mail][17] behind the scenes. Options are the following, `to` and `host` are required: + +* __to:__ The address(es) you want to send to. *[required]* +* __from:__ The address you want to send from. (default: `winston@[server-host-name]`) +* __host:__ SMTP server hostname +* __port:__ SMTP port (default: 587 or 25) +* __secure:__ Use secure +* __username__ User for server auth +* __password__ Password for server auth +* __level:__ Level of messages that this transport should log. +* __silent:__ Boolean flag indicating whether to suppress output. + +*Metadata:* Stringified as JSON in email. + +### Amazon SNS (Simple Notification System) Transport + +The [winston-sns][18] transport uses amazon SNS to send emails, texts, or a bunch of other notifications. + +``` js + require('winston-sns').SNS; + winston.add(winston.transports.SNS, options); +``` + +Options: + +* __aws_key:__ Your Amazon Web Services Key. *[required]* +* __aws_secret:__ Your Amazon Web Services Secret. *[required]* +* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]* +* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]* +* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`) +* __subject:__ Subject for notifications. (default: "Winston Error Report") +* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Level '%l' Error:\n%e\n\nMetadata:\n%m") +* __level:__ lowest level this transport will log. (default: `info`) + +### Graylog2 Transport + +[winston-graylog2][19] is a Graylog2 transport: + +``` js + var Graylog2 = require('winston-graylog2').Graylog2; + winston.add(Graylog2, options); +``` + +The Graylog2 transport connects to a Graylog2 server over UDP using the following options: + +* __level:__ Level of messages this transport should log. (default: info) +* __silent:__ Boolean flag indicating whether to suppress output. (default: false) + +* __graylogHost:__ IP address or hostname of the graylog2 server. (default: localhost) +* __graylogPort:__ Port to send messages to on the graylog2 server. (default: 12201) +* __graylogHostname:__ The hostname associated with graylog2 messages. (default: require('os').hostname()) +* __graylogFacility:__ The graylog2 facility to send log messages.. (default: nodejs) + +*Metadata:* Stringified as JSON in the full message GELF field. + +## Find more Transports + +``` bash + $ npm search winston + (...) + winston-amon Winston transport for Amon logging =zoramite + winston-amqp An AMQP transport for winston =kr1sp1n + winston-couchdb a couchdb transport for winston =alz + winston-express Express middleware to let you use winston from the browser. =regality + winston-graylog2 A graylog2 transport for winston =smithclay + winston-hbase A HBase transport for winston =ddude + winston-loggly A Loggly transport for winston =indexzero + winston-mail A mail transport for winston =wavded + winston-mail2 A mail transport for winston =ivolo + winston-mongodb A MongoDB transport for winston =indexzero + winston-nodemail A mail transport for winston =reinpk + winston-nssocket nssocket transport for winston =mmalecki + winston-papertrail A Papertrail transport for winston =kenperkins + winston-redis A fixed-length Redis transport for winston =indexzero + winston-riak A Riak transport for winston =indexzero + winston-scribe A scribe transport for winston =wnoronha + winston-simpledb A Winston transport for Amazon SimpleDB =chilts + winston-skywriter A Windows Azure table storage transport for winston =pofallon + winston-sns A Simple Notification System Transport for winston =jesseditson + winston-syslog A syslog transport for winston =indexzero + winston-syslog-ain2 An ain2 based syslog transport for winston =lamtha + winston-winlog Windows Event Log logger for Winston =jfromaniello + winston-zmq A 0MQ transport for winston =dhendo +``` + +[0]: http://nodejs.org/docs/v0.3.5/api/streams.html#writable_Stream +[1]: https://github.com/flatiron/winstond +[2]: https://github.com/indexzero/winston-couchdb +[3]: http://guide.couchdb.org/draft/design.html +[4]: https://github.com/mranney/node_redis +[5]: https://github.com/indexzero/winston-loggly +[6]: http://nodejitsu.com +[7]: https://github.com/nodejitsu/node-loggly +[8]: http://loggly.com +[9]: http://www.loggly.com/product/ +[10]: http://wiki.loggly.com/loggingfromcode +[11]: https://github.com/indexzero/winston-riak +[12]: http://riakjs.org +[13]: https://github.com/frank06/riak-js/blob/master/src/http_client.coffee#L10 +[14]: http://github.com/indexzero/winston-mongodb +[15]: http://github.com/appsattic/winston-simpledb +[16]: http://github.com/wavded/winston-mail +[17]: https://github.com/weaver/node-mail +[18]: https://github.com/jesseditson/winston-sns +[19]: https://github.com/flite/winston-graylog2 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/couchdb.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/couchdb.js new file mode 100644 index 0000000..ce2d960 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/couchdb.js @@ -0,0 +1,18 @@ +var winston = require('../lib/winston'); + +// +// Create a new winston logger instance with two tranports: Console, and Couchdb +// +// +// The Console transport will simply output to the console screen +// The Couchdb tranport will perform an HTTP POST request to the specified CouchDB instance +// +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.Couchdb)({ 'host': 'localhost', 'db': 'logs' }) + // if you need auth do this: new (winston.transports.Couchdb)({ 'user': 'admin', 'pass': 'admin', 'host': 'localhost', 'db': 'logs' }) + ] +}); + +logger.log('info', 'Hello webhook log files!', { 'foo': 'bar' }); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/exception.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/exception.js new file mode 100644 index 0000000..99f605b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/exception.js @@ -0,0 +1,4 @@ +var winston = require('../'); +winston.handleExceptions(new winston.transports.Console({ colorize: true, json: true })); + +throw new Error('Hello, winston!'); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/raw-mode.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/raw-mode.js new file mode 100644 index 0000000..89e070d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/raw-mode.js @@ -0,0 +1,10 @@ +var winston = require('../lib/winston'); + +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)({ raw: true }), + ] +}); + +logger.log('info', 'Hello, this is a raw logging event', { 'foo': 'bar' }); +logger.log('info', 'Hello, this is a raw logging event 2', { 'foo': 'bar' }); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/webhook-post.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/webhook-post.js new file mode 100644 index 0000000..0fa1c8d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/examples/webhook-post.js @@ -0,0 +1,17 @@ +var winston = require('../lib/winston'); + +// +// Create a new winston logger instance with two tranports: Console, and Webhook +// +// +// The Console transport will simply output to the console screen +// The Webhook tranports will perform an HTTP POST request to an abritrary end-point ( for post/recieve webhooks ) +// +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.Webhook)({ 'host': 'localhost', 'port': 8080, 'path': '/collectdata' }) + ] +}); + +logger.log('info', 'Hello webhook log files!', { 'foo': 'bar' }); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston.js new file mode 100644 index 0000000..b8fea28 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston.js @@ -0,0 +1,145 @@ +/* + * winston.js: Top-level include defining Winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var winston = exports; + +// +// Expose version using `pkginfo` +// +require('pkginfo')(module, 'version'); + +// +// Include transports defined by default by winston +// +winston.transports = require('./winston/transports'); + +// +// Expose utility methods +// +var common = require('./winston/common'); +winston.hash = common.hash; +winston.clone = common.clone; +winston.longestElement = common.longestElement; +winston.exception = require('./winston/exception'); +winston.config = require('./winston/config'); +winston.addColors = winston.config.addColors; + +// +// Expose core Logging-related prototypes. +// +winston.Container = require('./winston/container').Container; +winston.Logger = require('./winston/logger').Logger; +winston.Transport = require('./winston/transports/transport').Transport; + +// +// We create and expose a default `Container` to `winston.loggers` so that the +// programmer may manage multiple `winston.Logger` instances without any additional overhead. +// +// ### some-file1.js +// +// var logger = require('winston').loggers.get('something'); +// +// ### some-file2.js +// +// var logger = require('winston').loggers.get('something'); +// +winston.loggers = new winston.Container(); + +// +// We create and expose a 'defaultLogger' so that the programmer may do the +// following without the need to create an instance of winston.Logger directly: +// +// var winston = require('winston'); +// winston.log('info', 'some message'); +// winston.error('some error'); +// +var defaultLogger = new winston.Logger({ + transports: [new winston.transports.Console()] +}); + +// +// Pass through the target methods onto `winston. +// +var methods = [ + 'log', + 'query', + 'stream', + 'add', + 'remove', + 'profile', + 'startTimer', + 'extend', + 'cli', + 'handleExceptions', + 'unhandleExceptions' +]; +common.setLevels(winston, null, defaultLogger.levels); +methods.forEach(function (method) { + winston[method] = function () { + return defaultLogger[method].apply(defaultLogger, arguments); + }; +}); + +// +// ### function cli () +// Configures the default winston logger to have the +// settings for command-line interfaces: no timestamp, +// colors enabled, padded output, and additional levels. +// +winston.cli = function () { + winston.padLevels = true; + common.setLevels(winston, defaultLogger.levels, winston.config.cli.levels); + defaultLogger.setLevels(winston.config.cli.levels); + winston.config.addColors(winston.config.cli.colors); + + if (defaultLogger.transports.console) { + defaultLogger.transports.console.colorize = true; + defaultLogger.transports.console.timestamp = false; + } + + return winston; +}; + +// +// ### function setLevels (target) +// #### @target {Object} Target levels to use +// Sets the `target` levels specified on the default winston logger. +// +winston.setLevels = function (target) { + common.setLevels(winston, defaultLogger.levels, target); + defaultLogger.setLevels(target); +}; + +// +// Define getters / setters for appropriate properties of the +// default logger which need to be exposed by winston. +// +['emitErrs', 'exitOnError', 'padLevels', 'level', 'levelLength', 'stripColors'].forEach(function (prop) { + Object.defineProperty(winston, prop, { + get: function () { + return defaultLogger[prop]; + }, + set: function (val) { + defaultLogger[prop] = val; + } + }); +}); + +// +// @default {Object} +// The default transports and exceptionHandlers for +// the default winston logger. +// +Object.defineProperty(winston, 'default', { + get: function () { + return { + transports: defaultLogger.transports, + exceptionHandlers: defaultLogger.exceptionHandlers + }; + } +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/common.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/common.js new file mode 100644 index 0000000..c67a878 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/common.js @@ -0,0 +1,259 @@ +/* + * common.js: Internal helper and utility functions for winston + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var util = require('util'), + crypto = require('crypto'), + cycle = require('cycle'), + config = require('./config'); + +// +// ### function setLevels (target, past, current) +// #### @target {Object} Object on which to set levels. +// #### @past {Object} Previous levels set on target. +// #### @current {Object} Current levels to set on target. +// Create functions on the target objects for each level +// in current.levels. If past is defined, remove functions +// for each of those levels. +// +exports.setLevels = function (target, past, current, isDefault) { + if (past) { + Object.keys(past).forEach(function (level) { + delete target[level]; + }); + } + + target.levels = current || config.npm.levels; + if (target.padLevels) { + target.levelLength = exports.longestElement(Object.keys(target.levels)); + } + + // + // Define prototype methods for each log level + // e.g. target.log('info', msg) <=> target.info(msg) + // + Object.keys(target.levels).forEach(function (level) { + target[level] = function (msg) { + var args = Array.prototype.slice.call(arguments), + callback = typeof args[args.length - 1] === 'function' || !args[args.length - 1] ? args.pop() : null, + meta = args.length === 2 ? args.pop() : null; + + return target.log(level, msg, meta, callback); + }; + }); + + return target; +}; + +// +// ### function longestElement +// #### @xs {Array} Array to calculate against +// Returns the longest element in the `xs` array. +// +exports.longestElement = function (xs) { + return Math.max.apply( + null, + xs.map(function (x) { return x.length; }) + ); +}; + +// +// ### function clone (obj) +// #### @obj {Object} Object to clone. +// Helper method for deep cloning pure JSON objects +// i.e. JSON objects that are either literals or objects (no Arrays, etc) +// +exports.clone = function (obj) { + // we only need to clone refrence types (Object) + if (!(obj instanceof Object)) { + return obj; + } + else if (obj instanceof Date) { + return obj; + } + + var copy = {}; + for (var i in obj) { + if (Array.isArray(obj[i])) { + copy[i] = obj[i].slice(0); + } + else if (obj[i] instanceof Buffer) { + copy[i] = obj[i].slice(0); + } + else if (typeof obj[i] != 'function') { + copy[i] = obj[i] instanceof Object ? exports.clone(obj[i]) : obj[i]; + } + } + + return copy; +}; + +// +// ### function log (options) +// #### @options {Object} All information about the log serialization. +// Generic logging function for returning timestamped strings +// with the following options: +// +// { +// level: 'level to add to serialized message', +// message: 'message to serialize', +// meta: 'additional logging metadata to serialize', +// colorize: false, // Colorizes output (only if `.json` is false) +// timestamp: true // Adds a timestamp to the serialized message +// } +// +exports.log = function (options) { + var timestampFn = typeof options.timestamp === 'function' + ? options.timestamp + : exports.timestamp, + timestamp = options.timestamp ? timestampFn() : null, + meta = options.meta ? exports.clone(cycle.decycle(options.meta)) : null, + output; + + // + // raw mode is intended for outputing winston as streaming JSON to STDOUT + // + if (options.raw) { + if (typeof meta !== 'object' && meta != null) { + meta = { meta: meta }; + } + output = exports.clone(meta) || {}; + output.level = options.level; + output.message = options.message.stripColors; + return JSON.stringify(output); + } + + // + // json mode is intended for pretty printing multi-line json to the terminal + // + if (options.json) { + if (typeof meta !== 'object' && meta != null) { + meta = { meta: meta }; + } + + output = exports.clone(meta) || {}; + output.level = options.level; + output.message = options.message; + + if (timestamp) { + output.timestamp = timestamp; + } + + if (typeof options.stringify === 'function') { + return options.stringify(output); + } + + return JSON.stringify(output, function (key, value) { + return value instanceof Buffer + ? value.toString('base64') + : value; + }); + } + + output = timestamp ? timestamp + ' - ' : ''; + output += options.colorize ? config.colorize(options.level) : options.level; + output += (': ' + options.message); + + if (meta) { + if (typeof meta !== 'object') { + output += ' ' + meta; + } + else if (Object.keys(meta).length > 0) { + output += ' ' + (options.prettyPrint ? ('\n' + util.inspect(meta, false, null, options.colorize)) : exports.serialize(meta)); + } + } + + return output; +}; + +exports.capitalize = function (str) { + return str && str[0].toUpperCase() + str.slice(1); +}; + +// +// ### function hash (str) +// #### @str {string} String to hash. +// Utility function for creating unique ids +// e.g. Profiling incoming HTTP requests on the same tick +// +exports.hash = function (str) { + return crypto.createHash('sha1').update(str).digest('hex'); +}; + +// +// ### function pad (n) +// Returns a padded string if `n < 10`. +// +exports.pad = function (n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +}; + +// +// ### function timestamp () +// Returns a timestamp string for the current time. +// +exports.timestamp = function () { + return new Date().toISOString(); +}; + +// +// ### function serialize (obj, key) +// #### @obj {Object|literal} Object to serialize +// #### @key {string} **Optional** Optional key represented by obj in a larger object +// Performs simple comma-separated, `key=value` serialization for Loggly when +// logging to non-JSON inputs. +// +exports.serialize = function (obj, key) { + if (obj === null) { + obj = 'null'; + } + else if (obj === undefined) { + obj = 'undefined'; + } + else if (obj === false) { + obj = 'false'; + } + + if (typeof obj !== 'object') { + return key ? key + '=' + obj : obj; + } + + if (obj instanceof Buffer) { + return key ? key + '=' + obj.toString('base64') : obj.toString('base64'); + } + + var msg = '', + keys = Object.keys(obj), + length = keys.length; + + for (var i = 0; i < length; i++) { + if (Array.isArray(obj[keys[i]])) { + msg += keys[i] + '=['; + + for (var j = 0, l = obj[keys[i]].length; j < l; j++) { + msg += exports.serialize(obj[keys[i]][j]); + if (j < l - 1) { + msg += ', '; + } + } + + msg += ']'; + } + else if (obj[keys[i]] instanceof Date) { + msg += keys[i] + '=' + obj[keys[i]]; + } + else { + msg += exports.serialize(obj[keys[i]], keys[i]); + } + + if (i < length - 1) { + msg += ', '; + } + } + + return msg; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config.js new file mode 100644 index 0000000..a466086 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config.js @@ -0,0 +1,45 @@ +/* + * config.js: Default settings for all levels that winston knows about + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var colors = require('colors'); + +var config = exports, + allColors = exports.allColors = {}; + +config.addColors = function (colors) { + mixin(allColors, colors); +}; + +config.colorize = function (level) { + return level[allColors[level]]; +}; + +// +// Export config sets +// +config.cli = require('./config/cli-config'); +config.npm = require('./config/npm-config'); +config.syslog = require('./config/syslog-config'); + +// +// Add colors for pre-defined config sets +// +config.addColors(config.npm.colors); +config.addColors(config.syslog.colors); + +function mixin (target) { + var args = Array.prototype.slice.call(arguments, 1); + + args.forEach(function (a) { + var keys = Object.keys(a); + for (var i = 0; i < keys.length; i++) { + target[keys[i]] = a[keys[i]]; + } + }); + return target; +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/cli-config.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/cli-config.js new file mode 100644 index 0000000..ec4c40f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/cli-config.js @@ -0,0 +1,35 @@ +/* + * cli-config.js: Config that conform to commonly used CLI logging levels. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var cliConfig = exports; + +cliConfig.levels = { + silly: 0, + input: 1, + verbose: 2, + prompt: 3, + info: 4, + data: 5, + help: 6, + warn: 7, + debug: 8, + error: 9 +}; + +cliConfig.colors = { + silly: 'magenta', + input: 'grey', + verbose: 'cyan', + prompt: 'grey', + info: 'green', + data: 'grey', + help: 'cyan', + warn: 'yellow', + debug: 'blue', + error: 'red' +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/npm-config.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/npm-config.js new file mode 100644 index 0000000..176f9ac --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/npm-config.js @@ -0,0 +1,27 @@ +/* + * npm-config.js: Config that conform to npm logging levels. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var npmConfig = exports; + +npmConfig.levels = { + silly: 0, + verbose: 1, + info: 2, + warn: 3, + debug: 4, + error: 5 +}; + +npmConfig.colors = { + silly: 'magenta', + verbose: 'cyan', + info: 'green', + warn: 'yellow', + debug: 'blue', + error: 'red' +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/syslog-config.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/syslog-config.js new file mode 100644 index 0000000..00c1f31 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/config/syslog-config.js @@ -0,0 +1,31 @@ +/* + * syslog-config.js: Config that conform to syslog logging levels. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var syslogConfig = exports; + +syslogConfig.levels = { + debug: 0, + info: 1, + notice: 2, + warning: 3, + error: 4, + crit: 5, + alert: 6, + emerg: 7 +}; + +syslogConfig.colors = { + debug: 'blue', + info: 'green', + notice: 'yellow', + warning: 'red', + error: 'red', + crit: 'red', + alert: 'yellow', + emerg: 'red' +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/container.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/container.js new file mode 100644 index 0000000..574f25a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/container.js @@ -0,0 +1,101 @@ +/* + * container.js: Inversion of control container for winston logger instances + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var common = require('./common'), + winston = require('../winston'); + +// +// ### function Container (options) +// #### @options {Object} Default pass-thru options for Loggers +// Constructor function for the Container object responsible for managing +// a set of `winston.Logger` instances based on string ids. +// +var Container = exports.Container = function (options) { + this.loggers = {}; + this.options = options || {}; + this.default = { + transports: [ + new winston.transports.Console({ + level: 'silly', + colorize: false + }) + ] + } +}; + +// +// ### function get / add (id, options) +// #### @id {string} Id of the Logger to get +// #### @options {Object} **Optional** Options for the Logger instance +// Retreives a `winston.Logger` instance for the specified `id`. If +// an instance does not exist, one is created. +// +Container.prototype.get = Container.prototype.add = function (id, options) { + if (!this.loggers[id]) { + options = common.clone(options || this.options || this.default); + options.transports = options.transports || []; + + if (options.transports.length === 0 && (!options || !options['console'])) { + options.transports.push(this.default.transports[0]); + } + + Object.keys(options).forEach(function (key) { + if (key === 'transports') { + return; + } + + var name = common.capitalize(key); + + if (!winston.transports[name]) { + throw new Error('Cannot add unknown transport: ' + name); + } + + var namedOptions = options[key]; + namedOptions.id = id; + options.transports.push(new (winston.transports[name])(namedOptions)); + }); + + this.loggers[id] = new winston.Logger(options); + } + + return this.loggers[id]; +}; + +// +// ### function close (id) +// #### @id {string} **Optional** Id of the Logger instance to find +// Returns a boolean value indicating if this instance +// has a logger with the specified `id`. +// +Container.prototype.has = function (id) { + return !!this.loggers[id]; +}; + +// +// ### function close (id) +// #### @id {string} **Optional** Id of the Logger instance to close +// Closes a `Logger` instance with the specified `id` if it exists. +// If no `id` is supplied then all Loggers are closed. +// +Container.prototype.close = function (id) { + var self = this; + + function _close (id) { + if (!self.loggers[id]) { + return; + } + + self.loggers[id].close(); + delete self.loggers[id]; + } + + return id ? _close(id) : Object.keys(this.loggers).forEach(function (id) { + _close(id); + }); +}; + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/exception.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/exception.js new file mode 100644 index 0000000..22717dd --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/exception.js @@ -0,0 +1,56 @@ +/* + * exception.js: Utility methods for gathing information about uncaughtExceptions. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var os = require('os'), + stackTrace = require('stack-trace'); + +var exception = exports; + +exception.getAllInfo = function (err) { + return { + date: new Date().toString(), + process: exception.getProcessInfo(), + os: exception.getOsInfo(), + trace: exception.getTrace(err), + stack: err.stack && err.stack.split('\n') + }; +}; + +exception.getProcessInfo = function () { + return { + pid: process.pid, + uid: process.getuid ? process.getuid() : null, + gid: process.getgid ? process.getgid() : null, + cwd: process.cwd(), + execPath: process.execPath, + version: process.version, + argv: process.argv, + memoryUsage: process.memoryUsage() + }; +}; + +exception.getOsInfo = function () { + return { + loadavg: os.loadavg(), + uptime: os.uptime() + }; +}; + +exception.getTrace = function (err) { + var trace = err ? stackTrace.parse(err) : stackTrace.get(); + return trace.map(function (site) { + return { + column: site.getColumnNumber(), + file: site.getFileName(), + function: site.getFunctionName(), + line: site.getLineNumber(), + method: site.getMethodName(), + native: site.isNative(), + } + }); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/logger.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/logger.js new file mode 100644 index 0000000..49e6d4c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/logger.js @@ -0,0 +1,668 @@ +/* + * logger.js: Core logger object used by winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var events = require('events'), + util = require('util'), + async = require('async'), + config = require('./config'), + common = require('./common'), + exception = require('./exception'), + Stream = require('stream').Stream; + +// +// Time constants +// +var ticksPerMillisecond = 10000; + +// +// ### function Logger (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Logger object responsible +// for persisting log messages and metadata to one or more transports. +// +var Logger = exports.Logger = function (options) { + events.EventEmitter.call(this); + options = options || {}; + + var self = this, + handleExceptions = false; + + // + // Set Levels and default logging level + // + this.padLevels = options.padLevels || false; + this.setLevels(options.levels); + if (options.colors) { + config.addColors(options.colors); + } + + // + // Hoist other options onto this instance. + // + this.level = options.level || 'info'; + this.emitErrs = options.emitErrs || false; + this.stripColors = options.stripColors || false; + this.exitOnError = typeof options.exitOnError !== 'undefined' + ? options.exitOnError + : true; + + // + // Setup other intelligent default settings. + // + this.transports = {}; + this.rewriters = []; + this.exceptionHandlers = {}; + this.profilers = {}; + this._names = []; + this._hnames = []; + + if (options.transports) { + options.transports.forEach(function (transport) { + self.add(transport, null, true); + + if (transport.handleExceptions) { + handleExceptions = true; + } + }); + } + + if (options.rewriters) { + options.rewriters.forEach(function (rewriter) { + self.addRewriter(rewriter); + }); + } + + if (options.exceptionHandlers) { + handleExceptions = true; + options.exceptionHandlers.forEach(function (handler) { + self._hnames.push(handler.name); + self.exceptionHandlers[handler.name] = handler; + }); + } + + if (options.handleExceptions || handleExceptions) { + this.handleExceptions(); + } +}; + +// +// Inherit from `events.EventEmitter`. +// +util.inherits(Logger, events.EventEmitter); + +// +// ### function extend (target) +// #### @target {Object} Target to extend. +// Extends the target object with a 'log' method +// along with a method for each level in this instance. +// +Logger.prototype.extend = function (target) { + var self = this; + ['log', 'profile', 'startTimer'].concat(Object.keys(this.levels)).forEach(function (method) { + target[method] = function () { + return self[method].apply(self, arguments); + }; + }); + + return this; +}; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +Logger.prototype.log = function (level, msg) { + var self = this, + callback, + meta; + + if (arguments.length === 3) { + if (typeof arguments[2] === 'function') { + meta = {}; + callback = arguments[2]; + } + else if (typeof arguments[2] === 'object') { + meta = arguments[2]; + } + } + else if (arguments.length === 4) { + meta = arguments[2]; + callback = arguments[3]; + } + + // If we should pad for levels, do so + if (this.padLevels) { + msg = new Array(this.levelLength - level.length + 1).join(' ') + msg; + } + + function onError (err) { + if (callback) { + callback(err); + } + else if (self.emitErrs) { + self.emit('error', err); + }; + } + + if (this.transports.length === 0) { + return onError(new Error('Cannot log with no transports.')); + } + else if (typeof self.levels[level] === 'undefined') { + return onError(new Error('Unknown log level: ' + level)); + } + + this.rewriters.forEach(function (rewriter) { + meta = rewriter(level, msg, meta); + }); + + // + // For consideration of terminal 'color" programs like colors.js, + // which can add ANSI escape color codes to strings, we destyle the + // ANSI color escape codes when `this.stripColors` is set. + // + // see: http://en.wikipedia.org/wiki/ANSI_escape_code + // + if (this.stripColors) { + var code = /\u001b\[(\d+(;\d+)*)?m/g; + msg = ('' + msg).replace(code, ''); + } + + // + // Log for each transport and emit 'logging' event + // + function emit(name, next) { + var transport = self.transports[name]; + if ((transport.level && self.levels[transport.level] <= self.levels[level]) + || (!transport.level && self.levels[self.level] <= self.levels[level])) { + transport.log(level, msg, meta, function (err) { + if (err) { + err.transport = transport; + cb(err); + return next(); + } + self.emit('logging', transport, level, msg, meta); + next(); + }); + } else { + next(); + } + } + + // + // Respond to the callback + // + function cb(err) { + if (callback) { + if (err) return callback(err); + callback(null, level, msg, meta); + } + callback = null; + } + + async.forEach(this._names, emit, cb); + + return this; +}; + +// +// ### function query (options, callback) +// #### @options {Object} Query options for this instance. +// #### @callback {function} Continuation to respond to when complete. +// Queries the all transports for this instance with the specified `options`. +// This will aggregate each transport's results into one object containing +// a property per transport. +// +Logger.prototype.query = function (options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + var self = this, + options = options || {}, + results = {}, + query = common.clone(options.query) || {}, + transports; + + // + // Helper function to query a single transport + // + function queryTransport(transport, next) { + if (options.query) { + options.query = transport.formatQuery(query); + } + + transport.query(options, function (err, results) { + if (err) { + return next(err); + } + + next(null, transport.formatResults(results, options.format)); + }); + } + + // + // Helper function to accumulate the results from + // `queryTransport` into the `results`. + // + function addResults (transport, next) { + queryTransport(transport, function (err, result) { + result = err || result; + if (result) { + results[transport.name] = result; + } + next(); + }); + } + + // + // If an explicit transport is being queried then + // respond with the results from only that transport + // + if (options.transport) { + options.transport = options.transport.toLowerCase(); + return queryTransport(this.transports[options.transport], callback); + } + + // + // Create a list of all transports for this instance. + // + transports = this._names.map(function (name) { + return self.transports[name]; + }).filter(function (transport) { + return !!transport.query; + }); + + // + // Iterate over the transports in parallel setting the + // appropriate key in the `results` + // + async.forEach(transports, addResults, function () { + callback(null, results); + }); +}; + +// +// ### function stream (options) +// #### @options {Object} Stream options for this instance. +// Returns a log stream for all transports. Options object is optional. +// +Logger.prototype.stream = function (options) { + var self = this, + options = options || {}, + out = new Stream, + streams = [], + transports; + + if (options.transport) { + var transport = this.transports[options.transport]; + delete options.transport; + if (transport && transport.stream) { + return transport.stream(options); + } + } + + out._streams = streams; + out.destroy = function () { + var i = streams.length; + while (i--) streams[i].destroy(); + }; + + // + // Create a list of all transports for this instance. + // + transports = this._names.map(function (name) { + return self.transports[name]; + }).filter(function (transport) { + return !!transport.stream; + }); + + transports.forEach(function (transport) { + var stream = transport.stream(options); + if (!stream) return; + + streams.push(stream); + + stream.on('log', function (log) { + log.transport = log.transport || []; + log.transport.push(transport.name); + out.emit('log', log); + }); + + stream.on('error', function (err) { + err.transport = err.transport || []; + err.transport.push(transport.name); + out.emit('error', err); + }); + }); + + return out; +}; + +// +// ### function close () +// Cleans up resources (streams, event listeners) for all +// transports associated with this instance (if necessary). +// +Logger.prototype.close = function () { + var self = this; + + this._names.forEach(function (name) { + var transport = self.transports[name]; + if (transport && transport.close) { + transport.close(); + } + }); +}; + +// +// ### function handleExceptions () +// Handles `uncaughtException` events for the current process +// +Logger.prototype.handleExceptions = function () { + var args = Array.prototype.slice.call(arguments), + handlers = [], + self = this; + + args.forEach(function (a) { + if (Array.isArray(a)) { + handlers = handlers.concat(a); + } + else { + handlers.push(a); + } + }); + + handlers.forEach(function (handler) { + self.exceptionHandlers[handler.name] = handler; + }); + + this._hnames = Object.keys(self.exceptionHandlers); + + if (!this.catchExceptions) { + this.catchExceptions = this._uncaughtException.bind(this); + process.on('uncaughtException', this.catchExceptions); + } +}; + +// +// ### function unhandleExceptions () +// Removes any handlers to `uncaughtException` events +// for the current process +// +Logger.prototype.unhandleExceptions = function () { + var self = this; + + if (this.catchExceptions) { + Object.keys(this.exceptionHandlers).forEach(function (name) { + if (handler.close) { + handler.close(); + } + }); + + this.exceptionHandlers = {}; + Object.keys(this.transports).forEach(function (name) { + var transport = self.transports[name]; + if (transport.handleExceptions) { + transport.handleExceptions = false; + } + }) + + process.removeListener('uncaughtException', this.catchExceptions); + this.catchExceptions = false; + } +}; + +// +// ### function add (transport, [options]) +// #### @transport {Transport} Prototype of the Transport object to add. +// #### @options {Object} **Optional** Options for the Transport to add. +// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated. +// Adds a transport of the specified type to this instance. +// +Logger.prototype.add = function (transport, options, created) { + var instance = created ? transport : (new (transport)(options)); + + if (!instance.name && !instance.log) { + throw new Error('Unknown transport with no log() method'); + } + else if (this.transports[instance.name]) { + throw new Error('Transport already attached: ' + instance.name); + } + + this.transports[instance.name] = instance; + this._names = Object.keys(this.transports); + + // + // Listen for the `error` event on the new Transport + // + instance._onError = this._onError.bind(this, instance) + instance.on('error', instance._onError); + + // + // If this transport has `handleExceptions` set to `true` + // and we are not already handling exceptions, do so. + // + if (instance.handleExceptions && !this.catchExceptions) { + this.handleExceptions(); + } + + return this; +}; + +// +// ### function addRewriter (transport, [options]) +// #### @transport {Transport} Prototype of the Transport object to add. +// #### @options {Object} **Optional** Options for the Transport to add. +// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated. +// Adds a transport of the specified type to this instance. +// +Logger.prototype.addRewriter = function (rewriter) { + this.rewriters.push(rewriter); +} + +// +// ### function clear () +// Remove all transports from this instance +// +Logger.prototype.clear = function () { + for (var name in this.transports) { + this.remove({ name: name }); + } +}; + +// +// ### function remove (transport) +// #### @transport {Transport} Transport to remove. +// Removes a transport of the specified type from this instance. +// +Logger.prototype.remove = function (transport) { + var name = transport.name || transport.prototype.name; + + if (!this.transports[name]) { + throw new Error('Transport ' + name + ' not attached to this instance'); + } + + var instance = this.transports[name]; + delete this.transports[name]; + this._names = Object.keys(this.transports); + + if (instance.close) { + instance.close(); + } + + instance.removeListener('error', instance._onError); + return this; +}; + +var ProfileHandler = function (logger) { + this.logger = logger; + + this.start = Date.now(); + + this.done = function (msg) { + var args, callback, meta; + args = Array.prototype.slice.call(arguments); + callback = typeof args[args.length - 1] === 'function' ? args.pop() : null; + meta = typeof args[args.length - 1] === 'object' ? args.pop() : {}; + + meta.duration = (Date.now()) - this.start + 'ms'; + + return this.logger.info(msg, meta, callback); + } +} + +Logger.prototype.startTimer = function () { + return new ProfileHandler(this); +} + +// +// ### function profile (id, [msg, meta, callback]) +// #### @id {string} Unique id of the profiler +// #### @msg {string} **Optional** Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Tracks the time inbetween subsequent calls to this method +// with the same `id` parameter. The second call to this method +// will log the difference in milliseconds along with the message. +// +Logger.prototype.profile = function (id) { + var now = Date.now(), then, args, + msg, meta, callback; + + if (this.profilers[id]) { + then = this.profilers[id]; + delete this.profilers[id]; + + // Support variable arguments: msg, meta, callback + args = Array.prototype.slice.call(arguments); + callback = typeof args[args.length - 1] === 'function' ? args.pop() : null; + meta = typeof args[args.length - 1] === 'object' ? args.pop() : {}; + msg = args.length === 2 ? args[1] : id; + + // Set the duration property of the metadata + meta.duration = now - then + 'ms'; + return this.info(msg, meta, callback); + } + else { + this.profilers[id] = now; + } + + return this; +}; + +// +// ### function setLevels (target) +// #### @target {Object} Target levels to use on this instance +// Sets the `target` levels specified on this instance. +// +Logger.prototype.setLevels = function (target) { + return common.setLevels(this, this.levels, target); +}; + +// +// ### function cli () +// Configures this instance to have the default +// settings for command-line interfaces: no timestamp, +// colors enabled, padded output, and additional levels. +// +Logger.prototype.cli = function () { + this.padLevels = true; + this.setLevels(config.cli.levels); + config.addColors(config.cli.colors); + + if (this.transports.console) { + this.transports.console.colorize = true; + this.transports.console.timestamp = false; + } + + return this; +}; + +// +// ### @private function _uncaughtException (err) +// #### @err {Error} Error to handle +// Logs all relevant information around the `err` and +// exits the current process. +// +Logger.prototype._uncaughtException = function (err) { + var self = this, + responded = false, + info = exception.getAllInfo(err), + handlers = this._getExceptionHandlers(), + timeout, + doExit; + + // + // Calculate if we should exit on this error + // + doExit = typeof this.exitOnError === 'function' + ? this.exitOnError(err) + : this.exitOnError; + + function logAndWait(transport, next) { + transport.logException('uncaughtException', info, next, err); + } + + function gracefulExit() { + if (doExit && !responded) { + // + // Remark: Currently ignoring any exceptions from transports + // when catching uncaught exceptions. + // + clearTimeout(timeout); + responded = true; + process.exit(1); + } + } + + if (!handlers || handlers.length === 0) { + return gracefulExit(); + } + + // + // Log to all transports and allow the operation to take + // only up to `3000ms`. + // + async.forEach(handlers, logAndWait, gracefulExit); + if (doExit) { + timeout = setTimeout(gracefulExit, 3000); + } +}; + +// +// ### @private function _getExceptionHandlers () +// Returns the list of transports and exceptionHandlers +// for this instance. +// +Logger.prototype._getExceptionHandlers = function () { + var self = this; + + return this._hnames.map(function (name) { + return self.exceptionHandlers[name]; + }).concat(this._names.map(function (name) { + return self.transports[name].handleExceptions && self.transports[name]; + })).filter(Boolean); +}; + +// +// ### @private function _onError (transport, err) +// #### @transport {Object} Transport on which the error occured +// #### @err {Error} Error that occurred on the transport +// Bubbles the error, `err`, that occured on the specified `transport` +// up from this instance if `emitErrs` has been set. +// +Logger.prototype._onError = function (transport, err) { + if (this.emitErrs) { + this.emit('error', err, transport); + } +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports.js new file mode 100644 index 0000000..1bd9f05 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports.js @@ -0,0 +1,29 @@ +/* + * transports.js: Set of all transports Winston knows about + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var fs = require('fs'), + path = require('path'), + common = require('./common'); + +var transports = exports; + +// +// Setup all transports as lazy-loaded getters. +// +fs.readdirSync(path.join(__dirname, 'transports')).forEach(function (file) { + var transport = file.replace('.js', ''), + name = common.capitalize(transport); + + if (transport === 'transport') { + return; + } + + transports.__defineGetter__(name, function () { + return require('./transports/' + transport)[name]; + }); +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/console.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/console.js new file mode 100644 index 0000000..43cdee3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/console.js @@ -0,0 +1,88 @@ +/* + * console.js: Transport for outputting to the console + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var events = require('events'), + util = require('util'), + colors = require('colors'), + common = require('../common'), + Transport = require('./transport').Transport; + +// +// ### function Console (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Console transport object responsible +// for persisting log messages and metadata to a terminal or TTY. +// +var Console = exports.Console = function (options) { + Transport.call(this, options); + options = options || {}; + + this.name = 'console'; + this.json = options.json || false; + this.colorize = options.colorize || false; + this.prettyPrint = options.prettyPrint || false; + this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false; + + if (this.json) { + this.stringify = options.stringify || function (obj) { + return JSON.stringify(obj, null, 2); + }; + } +}; + +// +// Inherit from `winston.Transport`. +// +util.inherits(Console, Transport); + +// +// Expose the name of this Transport on the prototype +// +Console.prototype.name = 'console'; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +Console.prototype.log = function (level, msg, meta, callback) { + if (this.silent) { + return callback(null, true); + } + + var self = this, + output; + + output = common.log({ + colorize: this.colorize, + json: this.json, + level: level, + message: msg, + meta: meta, + stringify: this.stringify, + timestamp: this.timestamp, + prettyPrint: this.prettyPrint, + raw: this.raw + }); + + if (level === 'error' || level === 'debug') { + console.error(output); + } else { + console.log(output); + } + + // + // Emit the `logged` event immediately because the event loop + // will not exit until `process.stdout` has drained anyway. + // + self.emit('logged'); + callback(null, true); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/file.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/file.js new file mode 100644 index 0000000..7080e28 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/file.js @@ -0,0 +1,575 @@ +/* + * file.js: Transport for outputting to a local log file + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var events = require('events'), + fs = require('fs'), + path = require('path'), + util = require('util'), + colors = require('colors'), + common = require('../common'), + Transport = require('./transport').Transport, + Stream = require('stream').Stream; + +// +// ### function File (options) +// #### @options {Object} Options for this instance. +// Constructor function for the File transport object responsible +// for persisting log messages and metadata to one or more files. +// +var File = exports.File = function (options) { + Transport.call(this, options); + + // + // Helper function which throws an `Error` in the event + // that any of the rest of the arguments is present in `options`. + // + function throwIf (target /*, illegal... */) { + Array.prototype.slice.call(arguments, 1).forEach(function (name) { + if (options[name]) { + throw new Error('Cannot set ' + name + ' and ' + target + 'together'); + } + }); + } + + if (options.filename || options.dirname) { + throwIf('filename or dirname', 'stream'); + this._basename = this.filename = path.basename(options.filename) || 'winston.log'; + this.dirname = options.dirname || path.dirname(options.filename); + this.options = options.options || { flags: 'a' }; + } + else if (options.stream) { + throwIf('stream', 'filename', 'maxsize'); + this._stream = options.stream; + + // + // We need to listen for drain events when + // write() returns false. This can make node + // mad at times. + // + this._stream.setMaxListeners(Infinity); + } + else { + throw new Error('Cannot log to file without filename or stream.'); + } + + this.json = options.json !== false; + this.colorize = options.colorize || false; + this.maxsize = options.maxsize || null; + this.maxFiles = options.maxFiles || null; + this.prettyPrint = options.prettyPrint || false; + this.timestamp = options.timestamp != null ? options.timestamp : true; + + if (this.json) { + this.stringify = options.stringify; + } + + // + // Internal state variables representing the number + // of files this instance has created and the current + // size (in bytes) of the current logfile. + // + this._size = 0; + this._created = 0; + this._buffer = []; + this._draining = false; +}; + +// +// Inherit from `winston.Transport`. +// +util.inherits(File, Transport); + +// +// Expose the name of this Transport on the prototype +// +File.prototype.name = 'file'; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +File.prototype.log = function (level, msg, meta, callback) { + if (this.silent) { + return callback(null, true); + } + + var self = this; + + var output = common.log({ + level: level, + message: msg, + meta: meta, + json: this.json, + colorize: this.colorize, + prettyPrint: this.prettyPrint, + timestamp: this.timestamp, + stringify: this.stringify + }) + '\n'; + + this._size += output.length; + + if (!this.filename) { + // + // If there is no `filename` on this instance then it was configured + // with a raw `WriteableStream` instance and we should not perform any + // size restrictions. + // + this._write(output, callback); + this._lazyDrain(); + } + else { + this.open(function (err) { + if (err) { + // + // If there was an error enqueue the message + // + return self._buffer.push([output, callback]); + } + + self._write(output, callback); + self._lazyDrain(); + }); + } +}; + +// +// ### function _write (data, cb) +// #### @data {String|Buffer} Data to write to the instance's stream. +// #### @cb {function} Continuation to respond to when complete. +// Write to the stream, ensure execution of a callback on completion. +// +File.prototype._write = function(data, callback) { + // If this is a file write stream, we could use the builtin + // callback functionality, however, the stream is not guaranteed + // to be an fs.WriteStream. + var ret = this._stream.write(data); + if (!callback) return; + if (ret === false) { + return this._stream.once('drain', function() { + callback(null, true); + }); + } + callback(null, true); +}; + +// +// ### function query (options, callback) +// #### @options {Object} Loggly-like query options for this instance. +// #### @callback {function} Continuation to respond to when complete. +// Query the transport. Options object is optional. +// +File.prototype.query = function (options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + var file = path.join(this.dirname, this.filename), + options = this.normalizeQuery(options), + buff = '', + results = [], + row = 0; + + var stream = fs.createReadStream(file, { + encoding: 'utf8' + }); + + stream.on('error', function (err) { + if (stream.readable) { + stream.destroy(); + } + if (!callback) return; + return err.code !== 'ENOENT' + ? callback(err) + : callback(null, results); + }); + + stream.on('data', function (data) { + var data = (buff + data).split(/\n+/), + l = data.length - 1, + i = 0; + + for (; i < l; i++) { + if (!options.start || row >= options.start) { + add(data[i]); + } + row++; + } + + buff = data[l]; + }); + + stream.on('close', function () { + if (buff) add(buff, true); + if (options.order === 'desc') { + results = results.reverse(); + } + if (callback) callback(null, results); + }); + + function add(buff, attempt) { + try { + var log = JSON.parse(buff); + if (check(log)) push(log); + } catch (e) { + if (!attempt) { + stream.emit('error', e); + } + } + } + + function push(log) { + if (options.rows && results.length >= options.rows) { + if (stream.readable) { + stream.destroy(); + } + return; + } + + if (options.fields) { + var obj = {}; + options.fields.forEach(function (key) { + obj[key] = log[key]; + }); + log = obj; + } + + results.push(log); + } + + function check(log) { + if (!log) return; + + if (typeof log !== 'object') return; + + var time = new Date(log.timestamp); + if ((options.from && time < options.from) + || (options.until && time > options.until)) { + return; + } + + return true; + } +}; + +// +// ### function _tail (options, callback) +// #### @options {Object} Options for tail. +// #### @callback {function} Callback to execute on every line. +// `tail -f` a file. Options must include file. +// +File.prototype._tail = function tail(options, callback) { + var stream = fs.createReadStream(options.file, { encoding: 'utf8' }), + buff = '', + destroy, + row = 0; + + destroy = stream.destroy.bind(stream); + stream.destroy = function () {}; + + if (options.start === -1) { + delete options.start; + } + + if (options.start == null) { + stream.once('end', bind); + } else { + bind(); + } + + function bind() { + stream.on('data', function (data) { + var data = (buff + data).split(/\n+/), + l = data.length - 1, + i = 0; + + for (; i < l; i++) { + if (options.start == null || row > options.start) { + stream.emit('line', data[i]); + } + row++; + } + + buff = data[l]; + }); + + stream.on('line', function (data) { + if (callback) callback(data); + }); + + stream.on('error', function (err) { + destroy(); + }); + + stream.on('end', function () { + if (buff) { + stream.emit('line', buff); + buff = ''; + } + + resume(); + }); + + resume(); + } + + function resume() { + setTimeout(function () { + stream.resume(); + }, 1000); + } + + return destroy; +}; + +// +// ### function stream (options) +// #### @options {Object} Stream options for this instance. +// Returns a log stream for this transport. Options object is optional. +// +File.prototype.stream = function (options) { + var file = path.join(this.dirname, this.filename), + options = options || {}, + stream = new Stream; + + var tail = { + file: file, + start: options.start + }; + + stream.destroy = this._tail(tail, function (line) { + try { + stream.emit('data', line); + line = JSON.parse(line); + stream.emit('log', line); + } catch (e) { + stream.emit('error', e); + } + }); + + return stream; +}; + +// +// ### function open (callback) +// #### @callback {function} Continuation to respond to when complete +// Checks to see if a new file needs to be created based on the `maxsize` +// (if any) and the current size of the file used. +// +File.prototype.open = function (callback) { + if (this.opening) { + // + // If we are already attempting to open the next + // available file then respond with a value indicating + // that the message should be buffered. + // + return callback(true); + } + else if (!this._stream || (this.maxsize && this._size >= this.maxsize)) { + // + // If we dont have a stream or have exceeded our size, then create + // the next stream and respond with a value indicating that + // the message should be buffered. + // + callback(true); + return this._createStream(); + } + + // + // Otherwise we have a valid (and ready) stream. + // + callback(); +}; + +// +// ### function close () +// Closes the stream associated with this instance. +// +File.prototype.close = function () { + var self = this; + + if (this._stream) { + this._stream.end(); + this._stream.destroySoon(); + + this._stream.once('drain', function () { + self.emit('flush'); + self.emit('closed'); + }); + } +}; + +// +// ### function flush () +// Flushes any buffered messages to the current `stream` +// used by this instance. +// +File.prototype.flush = function () { + var self = this; + + // + // Iterate over the `_buffer` of enqueued messaged + // and then write them to the newly created stream. + // + this._buffer.forEach(function (item) { + var str = item[0], + callback = item[1]; + + process.nextTick(function () { + self._write(str, callback); + self._size += str.length; + }); + }); + + // + // Quickly truncate the `_buffer` once the write operations + // have been started + // + self._buffer.length = 0; + + // + // When the stream has drained we have flushed + // our buffer. + // + self._stream.once('drain', function () { + self.emit('flush'); + self.emit('logged'); + }); +}; + +// +// ### @private function _createStream () +// Attempts to open the next appropriate file for this instance +// based on the common state (such as `maxsize` and `_basename`). +// +File.prototype._createStream = function () { + var self = this; + this.opening = true; + + (function checkFile (target) { + var fullname = path.join(self.dirname, target); + + // + // Creates the `WriteStream` and then flushes any + // buffered messages. + // + function createAndFlush (size) { + if (self._stream) { + self._stream.end(); + self._stream.destroySoon(); + } + + self._size = size; + self.filename = target; + self._stream = fs.createWriteStream(fullname, self.options); + + // + // We need to listen for drain events when + // write() returns false. This can make node + // mad at times. + // + self._stream.setMaxListeners(Infinity); + + // + // When the current stream has finished flushing + // then we can be sure we have finished opening + // and thus can emit the `open` event. + // + self.once('flush', function () { + self.opening = false; + self.emit('open', fullname); + }); + + // + // Remark: It is possible that in the time it has taken to find the + // next logfile to be written more data than `maxsize` has been buffered, + // but for sensible limits (10s - 100s of MB) this seems unlikely in less + // than one second. + // + self.flush(); + } + + fs.stat(fullname, function (err, stats) { + if (err) { + if (err.code !== 'ENOENT') { + return self.emit('error', err); + } + + return createAndFlush(0); + } + + if (!stats || (self.maxsize && stats.size >= self.maxsize)) { + // + // If `stats.size` is greater than the `maxsize` for + // this instance then try again + // + return checkFile(self._getFile(true)); + } + + createAndFlush(stats.size); + }); + })(this._getFile()); +}; + +// +// ### @private function _getFile () +// Gets the next filename to use for this instance +// in the case that log filesizes are being capped. +// +File.prototype._getFile = function (inc) { + var self = this, + ext = path.extname(this._basename), + basename = path.basename(this._basename, ext), + remaining; + + if (inc) { + // + // Increment the number of files created or + // checked by this instance. + // + // Check for maxFiles option and delete file + if (this.maxFiles && (this._created >= (this.maxFiles - 1))) { + remaining = this._created - (this.maxFiles - 1); + if (remaining === 0) { + fs.unlinkSync(path.join(this.dirname, basename + ext)); + } + else { + fs.unlinkSync(path.join(this.dirname, basename + remaining + ext)); + } + } + + this._created += 1; + } + + return this._created + ? basename + this._created + ext + : basename + ext; +}; + +// +// ### @private function _lazyDrain () +// Lazily attempts to emit the `logged` event when `this.stream` has +// drained. This is really just a simple mutex that only works because +// Node.js is single-threaded. +// +File.prototype._lazyDrain = function () { + var self = this; + + if (!this._draining && this._stream) { + this._draining = true; + + this._stream.once('drain', function () { + this._draining = false; + self.emit('logged'); + }); + } +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/http.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/http.js new file mode 100644 index 0000000..9b9c61d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/http.js @@ -0,0 +1,200 @@ +var util = require('util'), + winston = require('../../winston'), + request = require('request'), + Stream = require('stream').Stream; + +// +// ### function Http (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Http transport object responsible +// for persisting log messages and metadata to a terminal or TTY. +// +var Http = exports.Http = function (options) { + options = options || {}; + + this.name = 'http'; + this.ssl = !!options.ssl; + this.host = options.host || 'localhost'; + this.port = options.port; + this.auth = options.auth; + this.path = options.path || ''; + + if (!this.port) { + this.port = this.ssl ? 443 : 80; + } +}; + +util.inherits(Http, winston.Transport); + +// +// Expose the name of this Transport on the prototype +// +Http.prototype.name = 'http'; + +// +// ### function _request (options, callback) +// #### @callback {function} Continuation to respond to when complete. +// Make a request to a winstond server or any http server which can +// handle json-rpc. +// +Http.prototype._request = function (options, callback) { + var options = options || {}, + auth = options.auth || this.auth, + path = options.path || this.path || ''; + + delete options.auth; + delete options.path; + + options = { json: options }; + options.method = 'POST'; + options.url = 'http' + + (this.ssl ? 's' : '') + + '://' + + (auth ? auth.username + ':' : '') + + (auth ? auth.password + '@' : '') + + this.host + + ':' + + this.port + + '/' + + path; + + return request(options, callback); +}; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +Http.prototype.log = function (level, msg, meta, callback) { + var self = this; + + if (typeof meta === 'function') { + callback = meta; + meta = {}; + } + + var options = { + method: 'collect', + params: { + level: level, + message: msg, + meta: meta + } + }; + + // hack + if (meta.auth) { + options.auth = meta.auth; + delete meta.auth; + } + + // hack + if (meta.path) { + options.path = meta.path; + delete meta.path; + } + + this._request(options, function (err, res, body) { + if (res && res.statusCode !== 200) { + err = new Error('HTTP Status Code: ' + res.statusCode); + } + + if (err) return callback(err); + + // TODO: emit 'logged' correctly, + // keep track of pending logs. + self.emit('logged'); + + if (callback) callback(null, true); + }); +}; + +// +// ### function query (options, callback) +// #### @options {Object} Loggly-like query options for this instance. +// #### @callback {function} Continuation to respond to when complete. +// Query the transport. Options object is optional. +// +Http.prototype.query = function (options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + var self = this, + options = this.normalizeQuery(options); + + options = { + method: 'query', + params: options + }; + + this._request(options, function (err, res, body) { + if (res && res.statusCode !== 200) { + err = new Error('HTTP Status Code: ' + res.statusCode); + } + + if (err) return callback(err); + + if (typeof body === 'string') { + try { + body = JSON.parse(body); + } catch (e) { + return callback(e); + } + } + + callback(null, body); + }); +}; + +// +// ### function stream (options) +// #### @options {Object} Stream options for this instance. +// Returns a log stream for this transport. Options object is optional. +// +Http.prototype.stream = function (options) { + var self = this, + options = options || {}, + stream = new Stream, + req, + buff; + + stream.destroy = function () { + req.destroy(); + }; + + options = { + method: 'stream', + params: options + }; + + req = this._request(options); + buff = ''; + + req.on('data', function (data) { + var data = (buff + data).split(/\n+/), + l = data.length - 1, + i = 0; + + for (; i < l; i++) { + try { + stream.emit('log', JSON.parse(data[i])); + } catch (e) { + stream.emit('error', e); + } + } + + buff = data[l]; + }); + + req.on('error', function (err) { + stream.emit('error', err); + }); + + return stream; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/transport.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/transport.js new file mode 100644 index 0000000..e04410e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/transport.js @@ -0,0 +1,120 @@ +/* + * transport.js: Base Transport object for all Winston transports. + * + * (C) 2010 Charlie Robbins + * MIT LICENCE + * + */ + +var events = require('events'), + util = require('util'); + +// +// ### function Transport (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Tranport object responsible +// base functionality for all winston transports. +// +var Transport = exports.Transport = function (options) { + events.EventEmitter.call(this); + + options = options || {}; + this.level = options.level || 'info'; + this.silent = options.silent || false; + this.raw = options.raw || false; + + this.handleExceptions = options.handleExceptions || false; +}; + +// +// Inherit from `events.EventEmitter`. +// +util.inherits(Transport, events.EventEmitter); + +// +// ### function formatQuery (query) +// #### @query {string|Object} Query to format +// Formats the specified `query` Object (or string) to conform +// with the underlying implementation of this transport. +// +Transport.prototype.formatQuery = function (query) { + return query; +}; + +// +// ### function normalizeQuery (query) +// #### @options {string|Object} Query to normalize +// Normalize options for query +// +Transport.prototype.normalizeQuery = function (options) { + // + // Use options similar to loggly. + // [See Loggly Search API](http://wiki.loggly.com/retrieve_events#optional) + // + + options = options || {}; + + // limit + options.rows = options.rows || options.limit || 10; + + // starting row offset + options.start = options.start || 0; + + // now - 24 + options.from = options.from || new Date - (24 * 60 * 60 * 1000); + if (typeof options.from !== 'object') { + options.from = new Date(options.from); + } + + // now + options.until = options.until || new Date; + if (typeof options.until !== 'object') { + options.until = new Date(options.until); + } + + // 'asc' or 'desc' + options.order = options.order || 'desc'; + + // which fields to select + options.fields = options.fields; + + return options; +}; + +// +// ### function formatResults (results, options) +// #### @results {Object|Array} Results returned from `.query`. +// #### @options {Object} **Optional** Formatting options +// Formats the specified `results` with the given `options` accordinging +// to the implementation of this transport. +// +Transport.prototype.formatResults = function (results, options) { + return results; +}; + +// +// ### function logException (msg, meta, callback) +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Logs the specified `msg`, `meta` and responds to the callback once the log +// operation is complete to ensure that the event loop will not exit before +// all logging has completed. +// +Transport.prototype.logException = function (msg, meta, callback) { + var self = this; + + function onLogged () { + self.removeListener('error', onError); + callback(); + } + + function onError () { + self.removeListener('logged', onLogged); + callback(); + } + + this.once('logged', onLogged); + this.once('error', onError); + this.log('error', msg, meta, function () { }); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/webhook.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/webhook.js new file mode 100644 index 0000000..34b4a35 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/lib/winston/transports/webhook.js @@ -0,0 +1,136 @@ +/* + * webhook.js: Transport for logging to remote http endpoints ( POST / RECEIVE webhooks ) + * + * (C) 2011 Marak Squires + * MIT LICENCE + * + */ + +var events = require('events'), + http = require('http'), + https = require('https'), + util = require('util'), + cycle = require('cycle'), + common = require('../common'), + Transport = require('./transport').Transport; + +// +// ### function WebHook (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Console transport object responsible +// for making arbitrary HTTP requests whenever log messages and metadata +// are received. +// +var Webhook = exports.Webhook = function (options) { + Transport.call(this, options); + + this.name = 'webhook'; + this.host = options.host || 'localhost'; + this.port = options.port || 8080; + this.method = options.method || 'POST'; + this.path = options.path || '/winston-log'; + + if (options.auth) { + this.auth = {}; + this.auth.username = options.auth.username || ''; + this.auth.password = options.auth.password || ''; + } + + if (options.ssl) { + this.ssl = {}; + this.ssl.key = options.ssl.key || null; + this.ssl.cert = options.ssl.cert || null; + this.ssl.ca = options.ssl.ca; + } +}; + +// +// Inherit from `winston.Transport`. +// +util.inherits(Webhook, Transport); + +// +// Expose the name of this Transport on the prototype +// +Webhook.prototype.name = 'webhook'; + +// +// ### function log (level, msg, [meta], callback) +// #### @level {string} Level at which to log the message. +// #### @msg {string} Message to log +// #### @meta {Object} **Optional** Additional metadata to attach +// #### @callback {function} Continuation to respond to when complete. +// Core logging method exposed to Winston. Metadata is optional. +// +Webhook.prototype.log = function (level, msg, meta, callback) { + if (this.silent) { + return callback(null, true); + } + + var self = this, + meta = cycle.decycle(meta), + message = common.clone(meta), + options, + req; + + // Prepare options for outgoing HTTP request + options = { + host: this.host, + port: this.port, + path: this.path, + method: this.method, + headers: { 'Content-Type': 'application/json' } + }; + + if (this.ssl) { + options.ca = this.ssl.ca; + options.key = this.ssl.key; + options.cert = this.ssl.cert; + } + + if (this.auth) { + // Encode `Authorization` header used by Basic Auth + options.headers['Authorization'] = 'Basic ' + new Buffer( + this.auth.username + ':' + this.auth.password, 'utf8' + ).toString('base64'); + } + + // Perform HTTP logging request + req = (self.ssl ? https : http).request(options, function (res) { + // TODO: emit 'logged' correctly, + // keep track of pending logs. + self.emit('logged'); + if (callback) callback(null, true); + callback = null; + }); + + req.on('error', function (err) { + // + // Propagate the `error` back up to the `Logger` that this + // instance belongs to. + // + self.emit('error', err); + if (callback) callback(err, false); + callback = null; + }); + + // + // Write logging event to the outgoing request body + // + // jsonMessage is currently conforming to JSON-RPC v1.0, + // but without the unique id since there is no anticipated response + // see: http://en.wikipedia.org/wiki/JSON-RPC + // + + var params = common.clone(meta) || {}; + params.timestamp = new Date(); + params.message = msg; + params.level = level; + + req.write(JSON.stringify({ + method: 'log', + params: params + })); + + req.end(); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/.gitmodules b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/.gitmodules new file mode 100644 index 0000000..a9aae98 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/.gitmodules @@ -0,0 +1,9 @@ +[submodule "deps/nodeunit"] + path = deps/nodeunit + url = git://github.com/caolan/nodeunit.git +[submodule "deps/UglifyJS"] + path = deps/UglifyJS + url = https://github.com/mishoo/UglifyJS.git +[submodule "deps/nodelint"] + path = deps/nodelint + url = https://github.com/tav/nodelint.git diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/.npmignore new file mode 100644 index 0000000..9bdfc97 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/.npmignore @@ -0,0 +1,4 @@ +deps +dist +test +nodelint.cfg \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/LICENSE b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/LICENSE new file mode 100644 index 0000000..b7f9d50 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Caolan McMahon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/Makefile b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/Makefile new file mode 100644 index 0000000..bad647c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/Makefile @@ -0,0 +1,25 @@ +PACKAGE = asyncjs +NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node) +CWD := $(shell pwd) +NODEUNIT = $(CWD)/node_modules/nodeunit/bin/nodeunit +UGLIFY = $(CWD)/node_modules/uglify-js/bin/uglifyjs +NODELINT = $(CWD)/node_modules/nodelint/nodelint + +BUILDDIR = dist + +all: clean test build + +build: $(wildcard lib/*.js) + mkdir -p $(BUILDDIR) + $(UGLIFY) lib/async.js > $(BUILDDIR)/async.min.js + +test: + $(NODEUNIT) test + +clean: + rm -rf $(BUILDDIR) + +lint: + $(NODELINT) --config nodelint.cfg lib/async.js + +.PHONY: test build all diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/README.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/README.md new file mode 100644 index 0000000..1bbbc47 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/README.md @@ -0,0 +1,1021 @@ +# Async.js + +Async is a utility module which provides straight-forward, powerful functions +for working with asynchronous JavaScript. Although originally designed for +use with [node.js](http://nodejs.org), it can also be used directly in the +browser. + +Async provides around 20 functions that include the usual 'functional' +suspects (map, reduce, filter, forEach…) as well as some common patterns +for asynchronous control flow (parallel, series, waterfall…). All these +functions assume you follow the node.js convention of providing a single +callback as the last argument of your async function. + + +## Quick Examples + + async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file + }); + + async.filter(['file1','file2','file3'], path.exists, function(results){ + // results now equals an array of the existing files + }); + + async.parallel([ + function(){ ... }, + function(){ ... } + ], callback); + + async.series([ + function(){ ... }, + function(){ ... } + ]); + +There are many more functions available so take a look at the docs below for a +full list. This module aims to be comprehensive, so if you feel anything is +missing please create a GitHub issue for it. + + +## Download + +Releases are available for download from +[GitHub](http://github.com/caolan/async/downloads). +Alternatively, you can install using Node Package Manager (npm): + + npm install async + + +__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 17.5kb Uncompressed + +__Production:__ [async.min.js](https://github.com/caolan/async/raw/master/dist/async.min.js) - 1.7kb Packed and Gzipped + + +## In the Browser + +So far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage: + + + + + +## Documentation + +### Collections + +* [forEach](#forEach) +* [map](#map) +* [filter](#filter) +* [reject](#reject) +* [reduce](#reduce) +* [detect](#detect) +* [sortBy](#sortBy) +* [some](#some) +* [every](#every) +* [concat](#concat) + +### Control Flow + +* [series](#series) +* [parallel](#parallel) +* [whilst](#whilst) +* [until](#until) +* [waterfall](#waterfall) +* [queue](#queue) +* [auto](#auto) +* [iterator](#iterator) +* [apply](#apply) +* [nextTick](#nextTick) + +### Utils + +* [memoize](#memoize) +* [unmemoize](#unmemoize) +* [log](#log) +* [dir](#dir) +* [noConflict](#noConflict) + + +## Collections + + +### forEach(arr, iterator, callback) + +Applies an iterator function to each item in an array, in parallel. +The iterator is called with an item from the list and a callback for when it +has finished. If the iterator passes an error to this callback, the main +callback for the forEach function is immediately called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + + // assuming openFiles is an array of file names and saveFile is a function + // to save the modified contents of that file: + + async.forEach(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error + }); + +--------------------------------------- + + +### forEachSeries(arr, iterator, callback) + +The same as forEach only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. This means the iterator functions will complete in order. + + +--------------------------------------- + + +### forEachLimit(arr, limit, iterator, callback) + +The same as forEach only the iterator is applied to batches of items in the +array, in series. The next batch of iterators is only called once the current +one has completed processing. + +__Arguments__ + +* arr - An array to iterate over. +* limit - How many items should be in each batch. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(err) - A callback which is called after all the iterator functions + have finished, or an error has occurred. + +__Example__ + + // Assume documents is an array of JSON objects and requestApi is a + // function that interacts with a rate-limited REST api. + + async.forEachLimit(documents, 20, requestApi, function(err){ + // if any of the saves produced an error, err would equal that error + }); +--------------------------------------- + + +### map(arr, iterator, callback) + +Produces a new array of values by mapping each value in the given array through +the iterator function. The iterator is called with an item from the array and a +callback for when it has finished processing. The callback takes 2 arguments, +an error and the transformed item from the array. If the iterator passes an +error to this callback, the main callback for the map function is immediately +called with the error. + +Note, that since this function applies the iterator to each item in parallel +there is no guarantee that the iterator functions will complete in order, however +the results array will be in the same order as the original array. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and a transformed item. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array of the + transformed items from the original array. + +__Example__ + + async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file + }); + +--------------------------------------- + + +### mapSeries(arr, iterator, callback) + +The same as map only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + + +--------------------------------------- + + +### filter(arr, iterator, callback) + +__Alias:__ select + +Returns a new array of all the values which pass an async truth test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(results) - A callback which is called after all the iterator + functions have finished. + +__Example__ + + async.filter(['file1','file2','file3'], path.exists, function(results){ + // results now equals an array of the existing files + }); + +--------------------------------------- + + +### filterSeries(arr, iterator, callback) + +__alias:__ selectSeries + +The same as filter only the iterator is applied to each item in the array in +series. The next iterator is only called once the current one has completed +processing. The results array will be in the same order as the original. + +--------------------------------------- + + +### reject(arr, iterator, callback) + +The opposite of filter. Removes values that pass an async truth test. + +--------------------------------------- + + +### rejectSeries(arr, iterator, callback) + +The same as filter, only the iterator is applied to each item in the array +in series. + + +--------------------------------------- + + +### reduce(arr, memo, iterator, callback) + +__aliases:__ inject, foldl + +Reduces a list of values into a single value using an async iterator to return +each successive step. Memo is the initial state of the reduction. This +function only operates in series. For performance reasons, it may make sense to +split a call to this function into a parallel map, then use the normal +Array.prototype.reduce on the results. This function is for situations where +each step in the reduction needs to be async, if you can get the data before +reducing it then its probably a good idea to do so. + +__Arguments__ + +* arr - An array to iterate over. +* memo - The initial state of the reduction. +* iterator(memo, item, callback) - A function applied to each item in the + array to produce the next step in the reduction. The iterator is passed a + callback which accepts an optional error as its first argument, and the state + of the reduction as the second. If an error is passed to the callback, the + reduction is stopped and the main callback is immediately called with the + error. +* callback(err, result) - A callback which is called after all the iterator + functions have finished. Result is the reduced value. + +__Example__ + + async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); + }, function(err, result){ + // result is now equal to the last value of memo, which is 6 + }); + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, callback) + +__Alias:__ foldr + +Same as reduce, only operates on the items in the array in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, callback) + +Returns the first value in a list that passes an async truth test. The +iterator is applied in parallel, meaning the first iterator to return true will +fire the detect callback with that result. That means the result might not be +the first item in the original array (in terms of order) that passes the test. + +If order within the original array is important then look at detectSeries. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value undefined if none passed. + +__Example__ + + async.detect(['file1','file2','file3'], path.exists, function(result){ + // result now equals the first file in the list that exists + }); + +--------------------------------------- + + +### detectSeries(arr, iterator, callback) + +The same as detect, only the iterator is applied to each item in the array +in series. This means the result is always the first in the original array (in +terms of array order) that passes the truth test. + + +--------------------------------------- + + +### sortBy(arr, iterator, callback) + +Sorts a list by the results of running each value through an async iterator. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and a value to use as the sort criteria. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is the items from + the original array sorted by the values returned by the iterator calls. + +__Example__ + + async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); + }, function(err, results){ + // results is now the original array of files sorted by + // modified date + }); + + +--------------------------------------- + + +### some(arr, iterator, callback) + +__Alias:__ any + +Returns true if at least one element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. Once any iterator +call returns true, the main callback is immediately called. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called as soon as any iterator returns + true, or after all the iterator functions have finished. Result will be + either true or false depending on the values of the async tests. + +__Example__ + + async.some(['file1','file2','file3'], path.exists, function(result){ + // if result is true then at least one of the files exists + }); + +--------------------------------------- + + +### every(arr, iterator, callback) + +__Alias:__ all + +Returns true if every element in the array satisfies an async test. +_The callback for each iterator call only accepts a single argument of true or +false, it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like path.exists. + +__Arguments__ + +* arr - An array to iterate over. +* iterator(item, callback) - A truth test to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed. +* callback(result) - A callback which is called after all the iterator + functions have finished. Result will be either true or false depending on + the values of the async tests. + +__Example__ + + async.every(['file1','file2','file3'], path.exists, function(result){ + // if result is true then every file exists + }); + +--------------------------------------- + + +### concat(arr, iterator, callback) + +Applies an iterator to each item in a list, concatenating the results. Returns the +concatenated list. The iterators are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of the arguments passed to the iterator function. + +__Arguments__ + +* arr - An array to iterate over +* iterator(item, callback) - A function to apply to each item in the array. + The iterator is passed a callback which must be called once it has completed + with an error (which can be null) and an array of results. +* callback(err, results) - A callback which is called after all the iterator + functions have finished, or an error has occurred. Results is an array containing + the concatenated results of the iterator function. + +__Example__ + + async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories + }); + +--------------------------------------- + + +### concatSeries(arr, iterator, callback) + +Same as async.concat, but executes in series instead of parallel. + + +## Control Flow + + +### series(tasks, [callback]) + +Run an array of functions in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run and the callback for the series is +immediately called with the value of the error. Once the tasks have completed, +the results are passed to the final callback as an array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.series. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed + a callback it must call on completion. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets an array of all the arguments passed to + the callbacks used in the array. + +__Example__ + + async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + }, + ], + // optional callback + function(err, results){ + // results is now equal to ['one', 'two'] + }); + + + // an example using an object instead of an array + async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + }, + }, + function(err, results) { + // results is now equal to: {one: 1, two: 2} + }); + + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run an array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main callback is immediately called with the value of the error. +Once the tasks have completed, the results are passed to the final callback as an +array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final callback as an object +instead of an array. This can be a more readable way of handling results from +async.parallel. + + +__Arguments__ + +* tasks - An array or object containing functions to run, each function is passed a + callback it must call on completion. +* callback(err, results) - An optional callback to run once all the functions + have completed. This function gets an array of all the arguments passed to + the callbacks used in the array. + +__Example__ + + async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + }, + ], + // optional callback + function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. + }); + + + // an example using an object instead of an array + async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + }, + }, + function(err, results) { + // results is now equals to: {one: 1, two: 2} + }); + + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call fn, while test returns true. Calls the callback when stopped, +or an error occurs. + +__Arguments__ + +* test() - synchronous truth test to perform before each execution of fn. +* fn(callback) - A function to call each time the test passes. The function is + passed a callback which must be called once it has completed with an optional + error as the first argument. +* callback(err) - A callback which is called after the test fails and repeated + execution of fn has stopped. + +__Example__ + + var count = 0; + + async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } + ); + + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call fn, until test returns true. Calls the callback when stopped, +or an error occurs. + +The inverse of async.whilst. + + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs an array of functions in series, each passing their results to the next in +the array. However, if any of the functions pass an error to the callback, the +next function is not executed and the main callback is immediately called with +the error. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a callback it + must call on completion. +* callback(err, [results]) - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + + async.waterfall([ + function(callback){ + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback){ + callback(null, 'three'); + }, + function(arg1, callback){ + // arg1 now equals 'three' + callback(null, 'done'); + } + ], function (err, result) { + // result now equals 'done' + }); + + +--------------------------------------- + + +### queue(worker, concurrency) + +Creates a queue object with the specified concurrency. Tasks added to the +queue will be processed in parallel (up to the concurrency limit). If all +workers are in progress, the task is queued until one is available. Once +a worker has completed a task, the task's callback is called. + +__Arguments__ + +* worker(task, callback) - An asynchronous function for processing a queued + task. +* concurrency - An integer for determining how many worker functions should be + run in parallel. + +__Queue objects__ + +The queue object returned by this function has the following properties and +methods: + +* length() - a function returning the number of items waiting to be processed. +* concurrency - an integer for determining how many worker functions should be + run in parallel. This property can be changed after a queue is created to + alter the concurrency on-the-fly. +* push(task, [callback]) - add a new task to the queue, the callback is called + once the worker has finished processing the task. + instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. +* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued +* empty - a callback that is called when the last item from the queue is given to a worker +* drain - a callback that is called when the last item from the queue has returned from the worker + +__Example__ + + // create a queue object with concurrency 2 + + var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); + }, 2); + + + // assign a callback + q.drain = function() { + console.log('all items have been processed'); + } + + // add some items to the queue + + q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); + }); + q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); + }); + + // add some items to the queue (batch-wise) + + q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing bar'); + }); + + +--------------------------------------- + + +### auto(tasks, [callback]) + +Determines the best order for running functions based on their requirements. +Each function can optionally depend on other functions being completed first, +and each function is run as soon as its requirements are satisfied. If any of +the functions pass an error to their callback, that function will not complete +(so any other functions depending on it will not run) and the main callback +will be called immediately with the error. Functions also receive an object +containing the results of functions which have completed so far. + +__Arguments__ + +* tasks - An object literal containing named functions or an array of + requirements, with the function itself the last item in the array. The key + used for each function or array is used when specifying requirements. The + syntax is easier to understand by looking at the example. +* callback(err, results) - An optional callback which is called when all the + tasks have been completed. The callback will receive an error as an argument + if any tasks pass an error to their callback. If all tasks complete + successfully, it will receive an object containing their results. + +__Example__ + + async.auto({ + get_data: function(callback){ + // async code to get some data + }, + make_folder: function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + }, + write_file: ['get_data', 'make_folder', function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, filename); + }], + email_link: ['write_file', function(callback, results){ + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + }] + }); + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + + async.parallel([ + function(callback){ + // async code to get some data + }, + function(callback){ + // async code to create a directory to store a file in + // this is run at the same time as getting the data + } + ], + function(results){ + async.series([ + function(callback){ + // once there is some data and the directory exists, + // write the data to a file in the directory + }, + email_link: function(callback){ + // once the file is written let's email a link to it... + } + ]); + }); + +For a complicated series of async tasks using the auto function makes adding +new tasks much easier and makes the code more readable. + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the array, +returning a continuation to call the next one after that. Its also possible to +'peek' the next iterator by doing iterator.next(). + +This function is used internally by the async module but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* tasks - An array of functions to run, each function is passed a callback it + must call on completion. + +__Example__ + + var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } + ]); + + node> var iterator2 = iterator(); + 'one' + node> var iterator3 = iterator2(); + 'two' + node> iterator3(); + 'three' + node> var nextfn = iterator2.next(); + node> nextfn(); + 'three' + + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied, a useful +shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + + // using apply + + async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), + ]); + + + // the same process without using apply + + async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + }, + ]); + +It's possible to pass any number of additional arguments when calling the +continuation: + + node> var fn = async.apply(sys.puts, 'one'); + node> fn('two', 'three'); + one + two + three + +--------------------------------------- + + +### nextTick(callback) + +Calls the callback on a later loop around the event loop. In node.js this just +calls process.nextTick, in the browser it falls back to setTimeout(callback, 0), +which means other higher priority events may precede the execution of the callback. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* callback - The function to call on a later loop around the event loop. + +__Example__ + + var call_order = []; + async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two] + }); + call_order.push('one') + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an async function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +__Arguments__ + +* fn - the function you to proxy and cache results from. +* hasher - an optional function for generating a custom hash for storing + results, it has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + + var slow_fn = function (name, callback) { + // do something + callback(null, result); + }; + var fn = async.memoize(slow_fn); + + // fn can now be used as if it were slow_fn + fn('some name', function () { + // callback + }); + + +### unmemoize(fn) + +Undoes a memoized function, reverting it to the original, unmemoized +form. Comes handy in tests. + +__Arguments__ + +* fn - the memoized function + + +### log(function, arguments) + +Logs the result of an async function to the console. Only works in node.js or +in browsers that support console.log and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.log is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + + var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); + }; + + node> async.log(hello, 'world'); + 'hello world' + + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an async function to the console using console.dir to +display the properties of the resulting object. Only works in node.js or +in browsers that support console.dir and console.error (such as FF and Chrome). +If multiple arguments are returned from the async function, console.dir is +called on each argument in order. + +__Arguments__ + +* function - The function you want to eventually apply all arguments to. +* arguments... - Any number of arguments to apply to the function. + +__Example__ + + var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); + }; + + node> async.dir(hello, 'world'); + {hello: 'world'} + + +--------------------------------------- + + +### noConflict() + +Changes the value of async back to its original value, returning a reference to the +async object. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/index.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/index.js new file mode 100644 index 0000000..8e23845 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/index.js @@ -0,0 +1,3 @@ +// This file is just added for convenience so this repository can be +// directly checked out into a project's deps folder +module.exports = require('./lib/async'); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/lib/async.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/lib/async.js new file mode 100644 index 0000000..7cc4f5e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/lib/async.js @@ -0,0 +1,692 @@ +/*global setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root = this, + previous_async = root.async; + + if (typeof module !== 'undefined' && module.exports) { + module.exports = async; + } + else { + root.async = async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + //// cross-browser compatiblity functions //// + + var _forEach = function (arr, iterator) { + if (arr.forEach) { + return arr.forEach(iterator); + } + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; + + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _forEach(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _forEach(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + async.nextTick = function (fn) { + setTimeout(fn, 0); + }; + } + else { + async.nextTick = process.nextTick; + } + + async.forEach = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + _forEach(arr, function (x) { + iterator(x, function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed === arr.length) { + callback(null); + } + } + }); + }); + }; + + async.forEachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed === arr.length) { + callback(null); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + + async.forEachLimit = function (arr, limit, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; + + (function replenish () { + if (completed === arr.length) { + return callback(); + } + + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed === arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + + + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.forEach].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.forEachSeries].concat(args)); + }; + }; + + + var _asyncMap = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.forEachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; + + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; + + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; + + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); + + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); + + async.some = function (arr, iterator, main_callback) { + async.forEach(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; + + async.every = function (arr, iterator, main_callback) { + async.forEach(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + if (!keys.length) { + return callback(null); + } + + var results = {}; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + _forEach(listeners.slice(0), function (fn) { + fn(); + }); + }; + + addListener(function () { + if (_keys(results).length === keys.length) { + callback(null, results); + callback = function () {}; + } + }); + + _forEach(keys, function (k) { + var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var taskCallback = function (err) { + if (err) { + callback(err); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + taskComplete(); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } + }); + }; + + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.nextTick(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + async.parallel = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.forEach(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.forEachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.queue = function (worker, concurrency) { + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _forEach(data, function(task) { + q.tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + if (q.saturated && q.tasks.length == concurrency) { + q.saturated(); + } + async.nextTick(q.process); + }); + }, + process: function () { + if (workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if(q.empty && q.tasks.length == 0) q.empty(); + workers += 1; + worker(task.data, function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if(q.drain && q.tasks.length + workers == 0) q.drain(); + q.process(); + }); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + } + }; + return q; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _forEach(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + callback.apply(null, memo[key]); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + +}()); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/package.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/package.json new file mode 100644 index 0000000..4e606ee --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/async/package.json @@ -0,0 +1,36 @@ +{ + "name": "async", + "description": "Higher-order functions and common patterns for asynchronous code", + "main": "./index", + "author": { + "name": "Caolan McMahon" + }, + "version": "0.1.22", + "repository": { + "type": "git", + "url": "http://github.com/caolan/async.git" + }, + "bugs": { + "url": "http://github.com/caolan/async/issues" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/caolan/async/raw/master/LICENSE" + } + ], + "devDependencies": { + "nodeunit": ">0.0.0", + "uglify-js": "1.2.x", + "nodelint": ">0.0.0" + }, + "readme": "# Async.js\n\nAsync is a utility module which provides straight-forward, powerful functions\nfor working with asynchronous JavaScript. Although originally designed for\nuse with [node.js](http://nodejs.org), it can also be used directly in the\nbrowser.\n\nAsync provides around 20 functions that include the usual 'functional'\nsuspects (map, reduce, filter, forEach…) as well as some common patterns\nfor asynchronous control flow (parallel, series, waterfall…). All these\nfunctions assume you follow the node.js convention of providing a single\ncallback as the last argument of your async function.\n\n\n## Quick Examples\n\n async.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n });\n\n async.filter(['file1','file2','file3'], path.exists, function(results){\n // results now equals an array of the existing files\n });\n\n async.parallel([\n function(){ ... },\n function(){ ... }\n ], callback);\n\n async.series([\n function(){ ... },\n function(){ ... }\n ]);\n\nThere are many more functions available so take a look at the docs below for a\nfull list. This module aims to be comprehensive, so if you feel anything is\nmissing please create a GitHub issue for it.\n\n\n## Download\n\nReleases are available for download from\n[GitHub](http://github.com/caolan/async/downloads).\nAlternatively, you can install using Node Package Manager (npm):\n\n npm install async\n\n\n__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 17.5kb Uncompressed\n\n__Production:__ [async.min.js](https://github.com/caolan/async/raw/master/dist/async.min.js) - 1.7kb Packed and Gzipped\n\n\n## In the Browser\n\nSo far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:\n\n \n \n\n\n## Documentation\n\n### Collections\n\n* [forEach](#forEach)\n* [map](#map)\n* [filter](#filter)\n* [reject](#reject)\n* [reduce](#reduce)\n* [detect](#detect)\n* [sortBy](#sortBy)\n* [some](#some)\n* [every](#every)\n* [concat](#concat)\n\n### Control Flow\n\n* [series](#series)\n* [parallel](#parallel)\n* [whilst](#whilst)\n* [until](#until)\n* [waterfall](#waterfall)\n* [queue](#queue)\n* [auto](#auto)\n* [iterator](#iterator)\n* [apply](#apply)\n* [nextTick](#nextTick)\n\n### Utils\n\n* [memoize](#memoize)\n* [unmemoize](#unmemoize)\n* [log](#log)\n* [dir](#dir)\n* [noConflict](#noConflict)\n\n\n## Collections\n\n\n### forEach(arr, iterator, callback)\n\nApplies an iterator function to each item in an array, in parallel.\nThe iterator is called with an item from the list and a callback for when it\nhas finished. If the iterator passes an error to this callback, the main\ncallback for the forEach function is immediately called with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n // assuming openFiles is an array of file names and saveFile is a function\n // to save the modified contents of that file:\n\n async.forEach(openFiles, saveFile, function(err){\n // if any of the saves produced an error, err would equal that error\n });\n\n---------------------------------------\n\n\n### forEachSeries(arr, iterator, callback)\n\nThe same as forEach only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. This means the iterator functions will complete in order.\n\n\n---------------------------------------\n\n\n### forEachLimit(arr, limit, iterator, callback)\n\nThe same as forEach only the iterator is applied to batches of items in the\narray, in series. The next batch of iterators is only called once the current\none has completed processing.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - How many items should be in each batch.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n // Assume documents is an array of JSON objects and requestApi is a\n // function that interacts with a rate-limited REST api.\n\n async.forEachLimit(documents, 20, requestApi, function(err){\n // if any of the saves produced an error, err would equal that error\n });\n---------------------------------------\n\n\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in the given array through\nthe iterator function. The iterator is called with an item from the array and a\ncallback for when it has finished processing. The callback takes 2 arguments, \nan error and the transformed item from the array. If the iterator passes an\nerror to this callback, the main callback for the map function is immediately\ncalled with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order, however\nthe results array will be in the same order as the original array.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n async.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n });\n\n---------------------------------------\n\n\n### mapSeries(arr, iterator, callback)\n\nThe same as map only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n---------------------------------------\n\n\n### filter(arr, iterator, callback)\n\n__Alias:__ select\n\nReturns a new array of all the values which pass an async truth test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(results) - A callback which is called after all the iterator\n functions have finished.\n\n__Example__\n\n async.filter(['file1','file2','file3'], path.exists, function(results){\n // results now equals an array of the existing files\n });\n\n---------------------------------------\n\n\n### filterSeries(arr, iterator, callback)\n\n__alias:__ selectSeries\n\nThe same as filter only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n---------------------------------------\n\n\n### reject(arr, iterator, callback)\n\nThe opposite of filter. Removes values that pass an async truth test.\n\n---------------------------------------\n\n\n### rejectSeries(arr, iterator, callback)\n\nThe same as filter, only the iterator is applied to each item in the array\nin series.\n\n\n---------------------------------------\n\n\n### reduce(arr, memo, iterator, callback)\n\n__aliases:__ inject, foldl\n\nReduces a list of values into a single value using an async iterator to return\neach successive step. Memo is the initial state of the reduction. This\nfunction only operates in series. For performance reasons, it may make sense to\nsplit a call to this function into a parallel map, then use the normal\nArray.prototype.reduce on the results. This function is for situations where\neach step in the reduction needs to be async, if you can get the data before\nreducing it then its probably a good idea to do so.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* memo - The initial state of the reduction.\n* iterator(memo, item, callback) - A function applied to each item in the\n array to produce the next step in the reduction. The iterator is passed a\n callback which accepts an optional error as its first argument, and the state\n of the reduction as the second. If an error is passed to the callback, the\n reduction is stopped and the main callback is immediately called with the\n error.\n* callback(err, result) - A callback which is called after all the iterator\n functions have finished. Result is the reduced value.\n\n__Example__\n\n async.reduce([1,2,3], 0, function(memo, item, callback){\n // pointless async:\n process.nextTick(function(){\n callback(null, memo + item)\n });\n }, function(err, result){\n // result is now equal to the last value of memo, which is 6\n });\n\n---------------------------------------\n\n\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ foldr\n\nSame as reduce, only operates on the items in the array in reverse order.\n\n\n---------------------------------------\n\n\n### detect(arr, iterator, callback)\n\nReturns the first value in a list that passes an async truth test. The\niterator is applied in parallel, meaning the first iterator to return true will\nfire the detect callback with that result. That means the result might not be\nthe first item in the original array (in terms of order) that passes the test.\n\nIf order within the original array is important then look at detectSeries.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n the first item in the array that passes the truth test (iterator) or the\n value undefined if none passed.\n\n__Example__\n\n async.detect(['file1','file2','file3'], path.exists, function(result){\n // result now equals the first file in the list that exists\n });\n\n---------------------------------------\n\n\n### detectSeries(arr, iterator, callback)\n\nThe same as detect, only the iterator is applied to each item in the array\nin series. This means the result is always the first in the original array (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each value through an async iterator.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and a value to use as the sort criteria.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is the items from\n the original array sorted by the values returned by the iterator calls.\n\n__Example__\n\n async.sortBy(['file1','file2','file3'], function(file, callback){\n fs.stat(file, function(err, stats){\n callback(err, stats.mtime);\n });\n }, function(err, results){\n // results is now the original array of files sorted by\n // modified date\n });\n\n\n---------------------------------------\n\n\n### some(arr, iterator, callback)\n\n__Alias:__ any\n\nReturns true if at least one element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists. Once any iterator\ncall returns true, the main callback is immediately called.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n either true or false depending on the values of the async tests.\n\n__Example__\n\n async.some(['file1','file2','file3'], path.exists, function(result){\n // if result is true then at least one of the files exists\n });\n\n---------------------------------------\n\n\n### every(arr, iterator, callback)\n\n__Alias:__ all\n\nReturns true if every element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like path.exists.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed.\n* callback(result) - A callback which is called after all the iterator\n functions have finished. Result will be either true or false depending on\n the values of the async tests.\n\n__Example__\n\n async.every(['file1','file2','file3'], path.exists, function(result){\n // if result is true then every file exists\n });\n\n---------------------------------------\n\n\n### concat(arr, iterator, callback)\n\nApplies an iterator to each item in a list, concatenating the results. Returns the\nconcatenated list. The iterators are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of the arguments passed to the iterator function.\n\n__Arguments__\n\n* arr - An array to iterate over\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback which must be called once it has completed\n with an error (which can be null) and an array of results.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array containing\n the concatenated results of the iterator function.\n\n__Example__\n\n async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n // files is now a list of filenames that exist in the 3 directories\n });\n\n---------------------------------------\n\n\n### concatSeries(arr, iterator, callback)\n\nSame as async.concat, but executes in series instead of parallel.\n\n\n## Control Flow\n\n\n### series(tasks, [callback])\n\nRun an array of functions in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run and the callback for the series is\nimmediately called with the value of the error. Once the tasks have completed,\nthe results are passed to the final callback as an array.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.series.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed\n a callback it must call on completion.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets an array of all the arguments passed to\n the callbacks used in the array.\n\n__Example__\n\n async.series([\n function(callback){\n // do some stuff ...\n callback(null, 'one');\n },\n function(callback){\n // do some more stuff ...\n callback(null, 'two');\n },\n ],\n // optional callback\n function(err, results){\n // results is now equal to ['one', 'two']\n });\n\n\n // an example using an object instead of an array\n async.series({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n },\n },\n function(err, results) {\n // results is now equal to: {one: 1, two: 2}\n });\n\n\n---------------------------------------\n\n\n### parallel(tasks, [callback])\n\nRun an array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main callback is immediately called with the value of the error.\nOnce the tasks have completed, the results are passed to the final callback as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.parallel.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed a\n callback it must call on completion.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets an array of all the arguments passed to\n the callbacks used in the array.\n\n__Example__\n\n async.parallel([\n function(callback){\n setTimeout(function(){\n callback(null, 'one');\n }, 200);\n },\n function(callback){\n setTimeout(function(){\n callback(null, 'two');\n }, 100);\n },\n ],\n // optional callback\n function(err, results){\n // the results array will equal ['one','two'] even though\n // the second function had a shorter timeout.\n });\n\n\n // an example using an object instead of an array\n async.parallel({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n },\n },\n function(err, results) {\n // results is now equals to: {one: 1, two: 2}\n });\n\n\n---------------------------------------\n\n\n### whilst(test, fn, callback)\n\nRepeatedly call fn, while test returns true. Calls the callback when stopped,\nor an error occurs.\n\n__Arguments__\n\n* test() - synchronous truth test to perform before each execution of fn.\n* fn(callback) - A function to call each time the test passes. The function is\n passed a callback which must be called once it has completed with an optional\n error as the first argument.\n* callback(err) - A callback which is called after the test fails and repeated\n execution of fn has stopped.\n\n__Example__\n\n var count = 0;\n\n async.whilst(\n function () { return count < 5; },\n function (callback) {\n count++;\n setTimeout(callback, 1000);\n },\n function (err) {\n // 5 seconds have passed\n }\n );\n\n\n---------------------------------------\n\n\n### until(test, fn, callback)\n\nRepeatedly call fn, until test returns true. Calls the callback when stopped,\nor an error occurs.\n\nThe inverse of async.whilst.\n\n\n---------------------------------------\n\n\n### waterfall(tasks, [callback])\n\nRuns an array of functions in series, each passing their results to the next in\nthe array. However, if any of the functions pass an error to the callback, the\nnext function is not executed and the main callback is immediately called with\nthe error.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a callback it\n must call on completion.\n* callback(err, [results]) - An optional callback to run once all the functions\n have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n async.waterfall([\n function(callback){\n callback(null, 'one', 'two');\n },\n function(arg1, arg2, callback){\n callback(null, 'three');\n },\n function(arg1, callback){\n // arg1 now equals 'three'\n callback(null, 'done');\n }\n ], function (err, result) {\n // result now equals 'done' \n });\n\n\n---------------------------------------\n\n\n### queue(worker, concurrency)\n\nCreates a queue object with the specified concurrency. Tasks added to the\nqueue will be processed in parallel (up to the concurrency limit). If all\nworkers are in progress, the task is queued until one is available. Once\na worker has completed a task, the task's callback is called.\n\n__Arguments__\n\n* worker(task, callback) - An asynchronous function for processing a queued\n task.\n* concurrency - An integer for determining how many worker functions should be\n run in parallel.\n\n__Queue objects__\n\nThe queue object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* concurrency - an integer for determining how many worker functions should be\n run in parallel. This property can be changed after a queue is created to\n alter the concurrency on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n // create a queue object with concurrency 2\n\n var q = async.queue(function (task, callback) {\n console.log('hello ' + task.name);\n callback();\n }, 2);\n\n\n // assign a callback\n q.drain = function() {\n console.log('all items have been processed');\n }\n\n // add some items to the queue\n\n q.push({name: 'foo'}, function (err) {\n console.log('finished processing foo');\n });\n q.push({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n });\n\n // add some items to the queue (batch-wise)\n\n q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n console.log('finished processing bar');\n });\n\n\n---------------------------------------\n\n\n### auto(tasks, [callback])\n\nDetermines the best order for running functions based on their requirements.\nEach function can optionally depend on other functions being completed first,\nand each function is run as soon as its requirements are satisfied. If any of\nthe functions pass an error to their callback, that function will not complete\n(so any other functions depending on it will not run) and the main callback\nwill be called immediately with the error. Functions also receive an object\ncontaining the results of functions which have completed so far.\n\n__Arguments__\n\n* tasks - An object literal containing named functions or an array of\n requirements, with the function itself the last item in the array. The key\n used for each function or array is used when specifying requirements. The\n syntax is easier to understand by looking at the example.\n* callback(err, results) - An optional callback which is called when all the\n tasks have been completed. The callback will receive an error as an argument\n if any tasks pass an error to their callback. If all tasks complete\n successfully, it will receive an object containing their results.\n\n__Example__\n\n async.auto({\n get_data: function(callback){\n // async code to get some data\n },\n make_folder: function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n },\n write_file: ['get_data', 'make_folder', function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n callback(null, filename);\n }],\n email_link: ['write_file', function(callback, results){\n // once the file is written let's email a link to it...\n // results.write_file contains the filename returned by write_file.\n }]\n });\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n async.parallel([\n function(callback){\n // async code to get some data\n },\n function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n }\n ],\n function(results){\n async.series([\n function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n },\n email_link: function(callback){\n // once the file is written let's email a link to it...\n }\n ]);\n });\n\nFor a complicated series of async tasks using the auto function makes adding\nnew tasks much easier and makes the code more readable.\n\n\n---------------------------------------\n\n\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the array,\nreturning a continuation to call the next one after that. Its also possible to\n'peek' the next iterator by doing iterator.next().\n\nThis function is used internally by the async module but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a callback it\n must call on completion.\n\n__Example__\n\n var iterator = async.iterator([\n function(){ sys.p('one'); },\n function(){ sys.p('two'); },\n function(){ sys.p('three'); }\n ]);\n\n node> var iterator2 = iterator();\n 'one'\n node> var iterator3 = iterator2();\n 'two'\n node> iterator3();\n 'three'\n node> var nextfn = iterator2.next();\n node> nextfn();\n 'three'\n\n\n---------------------------------------\n\n\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied, a useful\nshorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to automatically apply when the\n continuation is called.\n\n__Example__\n\n // using apply\n\n async.parallel([\n async.apply(fs.writeFile, 'testfile1', 'test1'),\n async.apply(fs.writeFile, 'testfile2', 'test2'),\n ]);\n\n\n // the same process without using apply\n\n async.parallel([\n function(callback){\n fs.writeFile('testfile1', 'test1', callback);\n },\n function(callback){\n fs.writeFile('testfile2', 'test2', callback);\n },\n ]);\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n node> var fn = async.apply(sys.puts, 'one');\n node> fn('two', 'three');\n one\n two\n three\n\n---------------------------------------\n\n\n### nextTick(callback)\n\nCalls the callback on a later loop around the event loop. In node.js this just\ncalls process.nextTick, in the browser it falls back to setTimeout(callback, 0),\nwhich means other higher priority events may precede the execution of the callback.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* callback - The function to call on a later loop around the event loop.\n\n__Example__\n\n var call_order = [];\n async.nextTick(function(){\n call_order.push('two');\n // call_order now equals ['one','two]\n });\n call_order.push('one')\n\n\n## Utils\n\n\n### memoize(fn, [hasher])\n\nCaches the results of an async function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\n__Arguments__\n\n* fn - the function you to proxy and cache results from.\n* hasher - an optional function for generating a custom hash for storing\n results, it has all the arguments applied to it apart from the callback, and\n must be synchronous.\n\n__Example__\n\n var slow_fn = function (name, callback) {\n // do something\n callback(null, result);\n };\n var fn = async.memoize(slow_fn);\n\n // fn can now be used as if it were slow_fn\n fn('some name', function () {\n // callback\n });\n\n\n### unmemoize(fn)\n\nUndoes a memoized function, reverting it to the original, unmemoized\nform. Comes handy in tests.\n\n__Arguments__\n\n* fn - the memoized function\n\n\n### log(function, arguments)\n\nLogs the result of an async function to the console. Only works in node.js or\nin browsers that support console.log and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.log is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n var hello = function(name, callback){\n setTimeout(function(){\n callback(null, 'hello ' + name);\n }, 1000);\n };\n\n node> async.log(hello, 'world');\n 'hello world'\n\n\n---------------------------------------\n\n\n### dir(function, arguments)\n\nLogs the result of an async function to the console using console.dir to\ndisplay the properties of the resulting object. Only works in node.js or\nin browsers that support console.dir and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.dir is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n var hello = function(name, callback){\n setTimeout(function(){\n callback(null, {hello: name});\n }, 1000);\n };\n\n node> async.dir(hello, 'world');\n {hello: 'world'}\n\n\n---------------------------------------\n\n\n### noConflict()\n\nChanges the value of async back to its original value, returning a reference to the\nasync object.\n", + "readmeFilename": "README.md", + "_id": "async@0.1.22", + "dist": { + "shasum": "2f3a2dc03739e1d7d7a333bbc0b747c14716f285" + }, + "_from": "async@0.1.x", + "_resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", + "scripts": {} +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/README.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/README.md new file mode 100644 index 0000000..5ca8d51 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/README.md @@ -0,0 +1,45 @@ +Fork of https://github.com/douglascrockford/JSON-js, maintained in npm as `cycle`. + +Original readme follows + +# JSON in JavaScript + +Douglas Crockford +douglas@crockford.com + +2010-11-18 + + +JSON is a light-weight, language independent, data interchange format. +See http://www.JSON.org/ + +The files in this collection implement JSON encoders/decoders in JavaScript. + +JSON became a built-in feature of JavaScript when the ECMAScript Programming +Language Standard - Fifth Edition was adopted by the ECMA General Assembly +in December 2009. Most of the files in this collection are for applications +that are expected to run in obsolete web browsers. For most purposes, json2.js +is the best choice. + + +json2.js: This file creates a JSON property in the global object, if there +isn't already one, setting its value to an object containing a stringify +method and a parse method. The parse method uses the eval method to do the +parsing, guarding it with several regular expressions to defend against +accidental code execution hazards. On current browsers, this file does nothing, +prefering the built-in JSON object. + +json.js: This file does everything that json2.js does. It also adds a +toJSONString method and a parseJSON method to Object.prototype. Use of this +file is not recommended. + +json_parse.js: This file contains an alternative JSON parse function that +uses recursive descent instead of eval. + +json_parse_state.js: This files contains an alternative JSON parse function that +uses a state machine instead of eval. + +cycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle, +which make it possible to encode cyclical structures and dags in JSON, and to +then recover them. JSONPath is used to represent the links. +http://GOESSNER.net/articles/JsonPath/ diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/cycle.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/cycle.js new file mode 100644 index 0000000..4382285 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/cycle.js @@ -0,0 +1,164 @@ +// cycle.js +// 2011-08-24 + +/*jslint evil: true, regexp: true */ + +/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push, + retrocycle, stringify, test, toString +*/ +var cycle = exports; + +cycle.decycle = function decycle(object) { + 'use strict'; + +// Make a deep copy of an object or array, assuring that there is at most +// one instance of each object or array in the resulting structure. The +// duplicate references (which might be forming cycles) are replaced with +// an object of the form +// {$ref: PATH} +// where the PATH is a JSONPath string that locates the first occurance. +// So, +// var a = []; +// a[0] = a; +// return JSON.stringify(JSON.decycle(a)); +// produces the string '[{"$ref":"$"}]'. + +// JSONPath is used to locate the unique object. $ indicates the top level of +// the object or array. [NUMBER] or [STRING] indicates a child member or +// property. + + var objects = [], // Keep a reference to each unique object or array + paths = []; // Keep the path to each unique object or array + + return (function derez(value, path) { + +// The derez recurses through the object, producing the deep copy. + + var i, // The loop counter + name, // Property name + nu; // The new object or array + + switch (typeof value) { + case 'object': + +// typeof null === 'object', so get out if this value is not really an object. +// Also get out if it is a weird builtin object. + + if (value === null || + value instanceof Boolean || + value instanceof Date || + value instanceof Number || + value instanceof RegExp || + value instanceof String) { + return value; + } + +// If the value is an object or array, look to see if we have already +// encountered it. If so, return a $ref/path object. This is a hard way, +// linear search that will get slower as the number of unique objects grows. + + for (i = 0; i < objects.length; i += 1) { + if (objects[i] === value) { + return {$ref: paths[i]}; + } + } + +// Otherwise, accumulate the unique value and its path. + + objects.push(value); + paths.push(path); + +// If it is an array, replicate the array. + + if (Object.prototype.toString.apply(value) === '[object Array]') { + nu = []; + for (i = 0; i < value.length; i += 1) { + nu[i] = derez(value[i], path + '[' + i + ']'); + } + } else { + +// If it is an object, replicate the object. + + nu = {}; + for (name in value) { + if (Object.prototype.hasOwnProperty.call(value, name)) { + nu[name] = derez(value[name], + path + '[' + JSON.stringify(name) + ']'); + } + } + } + return nu; + case 'number': + case 'string': + case 'boolean': + return value; + } + }(object, '$')); +}; + +cycle.retrocycle = function retrocycle($) { + 'use strict'; + +// Restore an object that was reduced by decycle. Members whose values are +// objects of the form +// {$ref: PATH} +// are replaced with references to the value found by the PATH. This will +// restore cycles. The object will be mutated. + +// The eval function is used to locate the values described by a PATH. The +// root object is kept in a $ variable. A regular expression is used to +// assure that the PATH is extremely well formed. The regexp contains nested +// * quantifiers. That has been known to have extremely bad performance +// problems on some browsers for very long strings. A PATH is expected to be +// reasonably short. A PATH is allowed to belong to a very restricted subset of +// Goessner's JSONPath. + +// So, +// var s = '[{"$ref":"$"}]'; +// return JSON.retrocycle(JSON.parse(s)); +// produces an array containing a single element which is the array itself. + + var px = + /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/; + + (function rez(value) { + +// The rez function walks recursively through the object looking for $ref +// properties. When it finds one that has a value that is a path, then it +// replaces the $ref object with a reference to the value that is found by +// the path. + + var i, item, name, path; + + if (value && typeof value === 'object') { + if (Object.prototype.toString.apply(value) === '[object Array]') { + for (i = 0; i < value.length; i += 1) { + item = value[i]; + if (item && typeof item === 'object') { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[i] = eval(path); + } else { + rez(item); + } + } + } + } else { + for (name in value) { + if (typeof value[name] === 'object') { + item = value[name]; + if (item) { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[name] = eval(path); + } else { + rez(item); + } + } + } + } + } + } + }($)); + return $; +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/package.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/package.json new file mode 100644 index 0000000..82f5ba2 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/cycle/package.json @@ -0,0 +1,33 @@ +{ + "name": "cycle", + "description": "decycle your json", + "author": "", + "version": "1.0.2", + "main": "./cycle.js", + "homepage": "https://github.com/douglascrockford/JSON-js", + "repository": { + "type": "git", + "url": "http://github.com/dscape/cycle.git" + }, + "bugs": { + "url": "http://github.com/douglascrockford/JSON-js/issues" + }, + "keywords": [ + "json", + "cycle", + "stringify", + "parse" + ], + "engines": { + "node": ">=0.4.0" + }, + "readme": "Fork of https://github.com/douglascrockford/JSON-js, maintained in npm as `cycle`.\n\nOriginal readme follows\n\n# JSON in JavaScript\n\nDouglas Crockford\ndouglas@crockford.com\n\n2010-11-18\n\n\nJSON is a light-weight, language independent, data interchange format.\nSee http://www.JSON.org/\n\nThe files in this collection implement JSON encoders/decoders in JavaScript.\n\nJSON became a built-in feature of JavaScript when the ECMAScript Programming\nLanguage Standard - Fifth Edition was adopted by the ECMA General Assembly\nin December 2009. Most of the files in this collection are for applications\nthat are expected to run in obsolete web browsers. For most purposes, json2.js\nis the best choice.\n\n\njson2.js: This file creates a JSON property in the global object, if there\nisn't already one, setting its value to an object containing a stringify\nmethod and a parse method. The parse method uses the eval method to do the\nparsing, guarding it with several regular expressions to defend against\naccidental code execution hazards. On current browsers, this file does nothing,\nprefering the built-in JSON object.\n\njson.js: This file does everything that json2.js does. It also adds a\ntoJSONString method and a parseJSON method to Object.prototype. Use of this\nfile is not recommended.\n\njson_parse.js: This file contains an alternative JSON parse function that\nuses recursive descent instead of eval.\n\njson_parse_state.js: This files contains an alternative JSON parse function that\nuses a state machine instead of eval.\n\ncycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle,\nwhich make it possible to encode cyclical structures and dags in JSON, and to\nthen recover them. JSONPath is used to represent the links.\nhttp://GOESSNER.net/articles/JsonPath/\n", + "readmeFilename": "README.md", + "_id": "cycle@1.0.2", + "dist": { + "shasum": "23f65cde66a289df1739ab1213a3d042ea0194b5" + }, + "_from": "cycle@1.0.x", + "_resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.2.tgz", + "scripts": {} +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/LICENSE b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/LICENSE new file mode 100644 index 0000000..a1edd93 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009 cloudhead + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/Makefile b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/Makefile new file mode 100644 index 0000000..a121dea --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/Makefile @@ -0,0 +1,4 @@ +test: + @@node test/eyes-test.js + +.PHONY: test diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/README.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/README.md new file mode 100644 index 0000000..c4f6f76 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/README.md @@ -0,0 +1,73 @@ +eyes +==== + +a customizable value inspector for Node.js + +synopsis +-------- + +I was tired of looking at cluttered output in the console -- something needed to be done, +`sys.inspect()` didn't display regexps correctly, and was too verbose, and I had an hour or two to spare. +So I decided to have some fun. _eyes_ were born. + +![eyes-ss](http://dl.dropbox.com/u/251849/eyes-js-ss.gif) + +_example of the output of a user-customized eyes.js inspector_ + +*eyes* also deals with circular objects in an intelligent way, and can pretty-print object literals. + +usage +----- + + var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); + + inspect(something); // inspect with the settings passed to `inspector` + +or + + var eyes = require('eyes'); + + eyes.inspect(something); // inspect with the default settings + +you can pass a _label_ to `inspect()`, to keep track of your inspections: + + eyes.inspect(something, "a random value"); + +If you want to return the output of eyes without printing it, you can set it up this way: + + var inspect = require('eyes').inspector({ stream: null }); + + sys.puts(inspect({ something: 42 })); + +customization +------------- + +These are the default styles and settings used by _eyes_. + + styles: { // Styles applied to stdout + all: 'cyan', // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + string: 'green', + number: 'magenta', + bool: 'blue', // true false + regexp: 'green', // /\d+/ + }, + + pretty: true, // Indent object literals + hideFunctions: false, // Don't output functions at all + stream: process.stdout, // Stream to write to, or null + maxLength: 2048 // Truncate output if longer + +You can overwrite them with your own, by passing a similar object to `inspector()` or `inspect()`. + + var inspect = require('eyes').inspector({ + styles: { + all: 'magenta', + special: 'bold' + }, + maxLength: 512 + }); + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/lib/eyes.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/lib/eyes.js new file mode 100644 index 0000000..10d964b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/lib/eyes.js @@ -0,0 +1,236 @@ +// +// Eyes.js - a customizable value inspector for Node.js +// +// usage: +// +// var inspect = require('eyes').inspector({styles: {all: 'magenta'}}); +// inspect(something); // inspect with the settings passed to `inspector` +// +// or +// +// var eyes = require('eyes'); +// eyes.inspect(something); // inspect with the default settings +// +var eyes = exports, + stack = []; + +eyes.defaults = { + styles: { // Styles applied to stdout + all: 'cyan', // Overall style applied to everything + label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]` + other: 'inverted', // Objects which don't have a literal representation, such as functions + key: 'bold', // The keys in object literals, like 'a' in `{a: 1}` + special: 'grey', // null, undefined... + string: 'green', + number: 'magenta', + bool: 'blue', // true false + regexp: 'green', // /\d+/ + }, + pretty: true, // Indent object literals + hideFunctions: false, + showHidden: false, + stream: process.stdout, + maxLength: 2048 // Truncate output if longer +}; + +// Return a curried inspect() function, with the `options` argument filled in. +eyes.inspector = function (options) { + var that = this; + return function (obj, label, opts) { + return that.inspect.call(that, obj, label, + merge(options || {}, opts || {})); + }; +}; + +// If we have a `stream` defined, use it to print a styled string, +// if not, we just return the stringified object. +eyes.inspect = function (obj, label, options) { + options = merge(this.defaults, options || {}); + + if (options.stream) { + return this.print(stringify(obj, options), label, options); + } else { + return stringify(obj, options) + (options.styles ? '\033[39m' : ''); + } +}; + +// Output using the 'stream', and an optional label +// Loop through `str`, and truncate it after `options.maxLength` has been reached. +// Because escape sequences are, at this point embeded within +// the output string, we can't measure the length of the string +// in a useful way, without separating what is an escape sequence, +// versus a printable character (`c`). So we resort to counting the +// length manually. +eyes.print = function (str, label, options) { + for (var c = 0, i = 0; i < str.length; i++) { + if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5 + else if (c === options.maxLength) { + str = str.slice(0, i - 1) + '…'; + break; + } else { c++ } + } + return options.stream.write.call(options.stream, (label ? + this.stylize(label, options.styles.label, options.styles) + ': ' : '') + + this.stylize(str, options.styles.all, options.styles) + '\033[0m' + "\n"); +}; + +// Apply a style to a string, eventually, +// I'd like this to support passing multiple +// styles. +eyes.stylize = function (str, style, styles) { + var codes = { + 'bold' : [1, 22], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'cyan' : [36, 39], + 'magenta' : [35, 39], + 'blue' : [34, 39], + 'yellow' : [33, 39], + 'green' : [32, 39], + 'red' : [31, 39], + 'grey' : [90, 39] + }, endCode; + + if (style && codes[style]) { + endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0] + : codes[style][1]; + return '\033[' + codes[style][0] + 'm' + str + + '\033[' + endCode + 'm'; + } else { return str } +}; + +// Convert any object to a string, ready for output. +// When an 'array' or an 'object' are encountered, they are +// passed to specialized functions, which can then recursively call +// stringify(). +function stringify(obj, options) { + var that = this, stylize = function (str, style) { + return eyes.stylize(str, options.styles[style], options.styles) + }, index, result; + + if ((index = stack.indexOf(obj)) !== -1) { + return stylize(new(Array)(stack.length - index + 1).join('.'), 'special'); + } + stack.push(obj); + + result = (function (obj) { + switch (typeOf(obj)) { + case "string" : obj = stringifyString(obj.indexOf("'") === -1 ? "'" + obj + "'" + : '"' + obj + '"'); + return stylize(obj, 'string'); + case "regexp" : return stylize('/' + obj.source + '/', 'regexp'); + case "number" : return stylize(obj + '', 'number'); + case "function" : return options.stream ? stylize("Function", 'other') : '[Function]'; + case "null" : return stylize("null", 'special'); + case "undefined": return stylize("undefined", 'special'); + case "boolean" : return stylize(obj + '', 'bool'); + case "date" : return stylize(obj.toUTCString()); + case "array" : return stringifyArray(obj, options, stack.length); + case "object" : return stringifyObject(obj, options, stack.length); + } + })(obj); + + stack.pop(); + return result; +}; + +// Escape invisible characters in a string +function stringifyString (str, options) { + return str.replace(/\\/g, '\\\\') + .replace(/\n/g, '\\n') + .replace(/[\u0001-\u001F]/g, function (match) { + return '\\0' + match[0].charCodeAt(0).toString(8); + }); +} + +// Convert an array to a string, such as [1, 2, 3]. +// This function calls stringify() for each of the elements +// in the array. +function stringifyArray(ary, options, level) { + var out = []; + var pretty = options.pretty && (ary.length > 4 || ary.some(function (o) { + return (o !== null && typeof(o) === 'object' && Object.keys(o).length > 0) || + (Array.isArray(o) && o.length > 0); + })); + var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; + + for (var i = 0; i < ary.length; i++) { + out.push(stringify(ary[i], options)); + } + + if (out.length === 0) { + return '[]'; + } else { + return '[' + ws + + out.join(',' + (pretty ? ws : ' ')) + + (pretty ? ws.slice(0, -4) : ws) + + ']'; + } +}; + +// Convert an object to a string, such as {a: 1}. +// This function calls stringify() for each of its values, +// and does not output functions or prototype values. +function stringifyObject(obj, options, level) { + var out = []; + var pretty = options.pretty && (Object.keys(obj).length > 2 || + Object.keys(obj).some(function (k) { return typeof(obj[k]) === 'object' })); + var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' '; + + var keys = options.showHidden ? Object.keys(obj) : Object.getOwnPropertyNames(obj); + keys.forEach(function (k) { + if (Object.prototype.hasOwnProperty.call(obj, k) + && !(obj[k] instanceof Function && options.hideFunctions)) { + out.push(eyes.stylize(k, options.styles.key, options.styles) + ': ' + + stringify(obj[k], options)); + } + }); + + if (out.length === 0) { + return '{}'; + } else { + return "{" + ws + + out.join(',' + (pretty ? ws : ' ')) + + (pretty ? ws.slice(0, -4) : ws) + + "}"; + } +}; + +// A better `typeof` +function typeOf(value) { + var s = typeof(value), + types = [Object, Array, String, RegExp, Number, Function, Boolean, Date]; + + if (s === 'object' || s === 'function') { + if (value) { + types.forEach(function (t) { + if (value instanceof t) { s = t.name.toLowerCase() } + }); + } else { s = 'null' } + } + return s; +} + +function merge(/* variable args */) { + var objs = Array.prototype.slice.call(arguments); + var target = {}; + + objs.forEach(function (o) { + Object.keys(o).forEach(function (k) { + if (k === 'styles') { + if (! o.styles) { + target.styles = false; + } else { + target.styles = {} + for (var s in o.styles) { + target.styles[s] = o.styles[s]; + } + } + } else { + target[k] = o[k]; + } + }); + }); + return target; +} + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/package.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/package.json new file mode 100644 index 0000000..53d9d19 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/package.json @@ -0,0 +1,44 @@ +{ + "name": "eyes", + "description": "a customizable value inspector", + "url": "http://github.com/cloudhead/eyes.js", + "keywords": [ + "inspector", + "debug", + "inspect", + "print" + ], + "author": { + "name": "Alexis Sellier", + "email": "self@cloudhead.net" + }, + "contributors": [ + { + "name": "Charlie Robbins", + "email": "charlie@nodejitsu.com" + } + ], + "licenses": [ + "MIT" + ], + "main": "./lib/eyes", + "version": "0.1.8", + "scripts": { + "test": "node test/*-test.js" + }, + "directories": { + "lib": "./lib", + "test": "./test" + }, + "engines": { + "node": "> 0.1.90" + }, + "readme": "eyes\n====\n\na customizable value inspector for Node.js\n\nsynopsis\n--------\n\nI was tired of looking at cluttered output in the console -- something needed to be done,\n`sys.inspect()` didn't display regexps correctly, and was too verbose, and I had an hour or two to spare. \nSo I decided to have some fun. _eyes_ were born.\n\n![eyes-ss](http://dl.dropbox.com/u/251849/eyes-js-ss.gif)\n\n_example of the output of a user-customized eyes.js inspector_\n\n*eyes* also deals with circular objects in an intelligent way, and can pretty-print object literals.\n\nusage\n-----\n\n var inspect = require('eyes').inspector({styles: {all: 'magenta'}});\n\n inspect(something); // inspect with the settings passed to `inspector`\n\nor\n\n var eyes = require('eyes');\n\n eyes.inspect(something); // inspect with the default settings\n\nyou can pass a _label_ to `inspect()`, to keep track of your inspections:\n\n eyes.inspect(something, \"a random value\");\n\nIf you want to return the output of eyes without printing it, you can set it up this way:\n\n var inspect = require('eyes').inspector({ stream: null });\n\n sys.puts(inspect({ something: 42 }));\n\ncustomization\n-------------\n\nThese are the default styles and settings used by _eyes_.\n\n styles: { // Styles applied to stdout\n all: 'cyan', // Overall style applied to everything\n label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]`\n other: 'inverted', // Objects which don't have a literal representation, such as functions\n key: 'bold', // The keys in object literals, like 'a' in `{a: 1}`\n special: 'grey', // null, undefined...\n string: 'green',\n number: 'magenta',\n bool: 'blue', // true false\n regexp: 'green', // /\\d+/\n },\n \n pretty: true, // Indent object literals\n hideFunctions: false, // Don't output functions at all\n stream: process.stdout, // Stream to write to, or null\n maxLength: 2048 // Truncate output if longer\n\nYou can overwrite them with your own, by passing a similar object to `inspector()` or `inspect()`.\n\n var inspect = require('eyes').inspector({\n styles: {\n all: 'magenta',\n special: 'bold'\n },\n maxLength: 512\n });\n\n", + "readmeFilename": "README.md", + "_id": "eyes@0.1.8", + "dist": { + "shasum": "7660dc70104b97f6bb6c77b53e335e95503c813b" + }, + "_from": "eyes@0.1.x", + "_resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/test/eyes-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/test/eyes-test.js new file mode 100644 index 0000000..1f9606a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes/test/eyes-test.js @@ -0,0 +1,56 @@ +var util = require('util'); +var eyes = require('../lib/eyes'); + +eyes.inspect({ + number: 42, + string: "John Galt", + regexp: /[a-z]+/, + array: [99, 168, 'x', {}], + func: function () {}, + bool: false, + nil: null, + undef: undefined, + object: {attr: []} +}, "native types"); + +eyes.inspect({ + number: new(Number)(42), + string: new(String)("John Galt"), + regexp: new(RegExp)(/[a-z]+/), + array: new(Array)(99, 168, 'x', {}), + bool: new(Boolean)(false), + object: new(Object)({attr: []}), + date: new(Date) +}, "wrapped types"); + +var obj = {}; +obj.that = { self: obj }; +obj.self = obj; + +eyes.inspect(obj, "circular object"); +eyes.inspect({hello: 'moto'}, "small object"); +eyes.inspect({hello: new(Array)(6) }, "big object"); +eyes.inspect(["hello 'world'", 'hello "world"'], "quotes"); +eyes.inspect({ + recommendations: [{ + id: 'a7a6576c2c822c8e2bd81a27e41437d8', + key: [ 'spree', 3.764316258020699 ], + value: { + _id: 'a7a6576c2c822c8e2bd81a27e41437d8', + _rev: '1-2e2d2f7fd858c4a5984bcf809d22ed98', + type: 'domain', + domain: 'spree', + weight: 3.764316258020699, + product_id: 30 + } + }] +}, 'complex'); + +eyes.inspect([null], "null in array"); + +var inspect = eyes.inspector({ stream: null }); + +util.puts(inspect('something', "something")); +util.puts(inspect("something else")); + +util.puts(inspect(["no color"], null, { styles: false })); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/.npmignore new file mode 100644 index 0000000..9303c34 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/README.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/README.md new file mode 100644 index 0000000..07ba942 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/README.md @@ -0,0 +1,85 @@ +# node-pkginfo + +An easy way to expose properties on a module from a package.json + +## Installation + +### Installing npm (node package manager) +``` + curl http://npmjs.org/install.sh | sh +``` + +### Installing pkginfo +``` + [sudo] npm install pkginfo +``` + +## Motivation +How often when writing node.js modules have you written the following line(s) of code? + +* Hard code your version string into your code + +``` js + exports.version = '0.1.0'; +``` + +* Programmatically expose the version from the package.json + +``` js + exports.version = JSON.parse(fs.readFileSync('/path/to/package.json', 'utf8')).version; +``` + +In other words, how often have you wanted to expose basic information from your package.json onto your module programmatically? **WELL NOW YOU CAN!** + +## Usage + +Using `pkginfo` is idiot-proof, just require and invoke it. + +``` js + var pkginfo = require('pkginfo')(module); + + console.dir(module.exports); +``` + +By invoking the `pkginfo` module all of the properties in your `package.json` file will be automatically exposed on the callee module (i.e. the parent module of `pkginfo`). + +Here's a sample of the output: + +``` + { name: 'simple-app', + description: 'A test fixture for pkginfo', + version: '0.1.0', + author: 'Charlie Robbins ', + keywords: [ 'test', 'fixture' ], + main: './index.js', + scripts: { test: 'vows test/*-test.js --spec' }, + engines: { node: '>= 0.4.0' } } +``` + +### Expose specific properties +If you don't want to expose **all** properties on from your `package.json` on your module then simple pass those properties to the `pkginfo` function: + +``` js + var pkginfo = require('pkginfo')(module, 'version', 'author'); + + console.dir(module.exports); +``` + +``` + { version: '0.1.0', + author: 'Charlie Robbins ' } +``` + +If you're looking for further usage see the [examples][0] included in this repository. + +## Run Tests +Tests are written in [vows][1] and give complete coverage of all APIs. + +``` + vows test/*-test.js --spec +``` + +[0]: https://github.com/indexzero/node-pkginfo/tree/master/examples +[1]: http://vowsjs.org + +#### Author: [Charlie Robbins](http://nodejitsu.com) \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/docco.css b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/docco.css new file mode 100644 index 0000000..bd54134 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/docco.css @@ -0,0 +1,194 @@ +/*--------------------- Layout and Typography ----------------------------*/ +body { + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 15px; + line-height: 22px; + color: #252519; + margin: 0; padding: 0; +} +a { + color: #261a3b; +} + a:visited { + color: #261a3b; + } +p { + margin: 0 0 15px 0; +} +h4, h5, h6 { + color: #333; + margin: 6px 0 6px 0; + font-size: 13px; +} + h2, h3 { + margin-bottom: 0; + color: #000; + } + h1 { + margin-top: 40px; + margin-bottom: 15px; + color: #000; + } +#container { + position: relative; +} +#background { + position: fixed; + top: 0; left: 525px; right: 0; bottom: 0; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + z-index: -1; +} +#jump_to, #jump_page { + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 10px Arial; + text-transform: uppercase; + cursor: pointer; + text-align: right; +} +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 5px 10px; +} + #jump_wrapper { + padding: 0; + display: none; + } + #jump_to:hover #jump_wrapper { + display: block; + } + #jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; + } + #jump_page .source { + display: block; + padding: 5px 10px; + text-decoration: none; + border-top: 1px solid #eee; + } + #jump_page .source:hover { + background: #f5f5ff; + } + #jump_page .source:first-child { + } +table td { + border: 0; + outline: 0; +} + td.docs, th.docs { + max-width: 450px; + min-width: 450px; + min-height: 5px; + padding: 10px 25px 1px 50px; + overflow-x: hidden; + vertical-align: top; + text-align: left; + } + .docs pre { + margin: 15px 0 15px; + padding-left: 15px; + } + .docs p tt, .docs p code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } + .pilwrap { + position: relative; + } + .pilcrow { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + td.docs:hover .pilcrow { + opacity: 1; + } + td.code, th.code { + padding: 14px 15px 16px 25px; + width: 100%; + vertical-align: top; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + } + pre, tt, code { + font-size: 12px; line-height: 18px; + font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + + +/*---------------------- Syntax Highlighting -----------------------------*/ +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +body .hll { background-color: #ffffcc } +body .c { color: #408080; font-style: italic } /* Comment */ +body .err { border: 1px solid #FF0000 } /* Error */ +body .k { color: #954121 } /* Keyword */ +body .o { color: #666666 } /* Operator */ +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +body .cp { color: #BC7A00 } /* Comment.Preproc */ +body .c1 { color: #408080; font-style: italic } /* Comment.Single */ +body .cs { color: #408080; font-style: italic } /* Comment.Special */ +body .gd { color: #A00000 } /* Generic.Deleted */ +body .ge { font-style: italic } /* Generic.Emph */ +body .gr { color: #FF0000 } /* Generic.Error */ +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +body .gi { color: #00A000 } /* Generic.Inserted */ +body .go { color: #808080 } /* Generic.Output */ +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +body .gs { font-weight: bold } /* Generic.Strong */ +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +body .gt { color: #0040D0 } /* Generic.Traceback */ +body .kc { color: #954121 } /* Keyword.Constant */ +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ +body .kp { color: #954121 } /* Keyword.Pseudo */ +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ +body .kt { color: #B00040 } /* Keyword.Type */ +body .m { color: #666666 } /* Literal.Number */ +body .s { color: #219161 } /* Literal.String */ +body .na { color: #7D9029 } /* Name.Attribute */ +body .nb { color: #954121 } /* Name.Builtin */ +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +body .no { color: #880000 } /* Name.Constant */ +body .nd { color: #AA22FF } /* Name.Decorator */ +body .ni { color: #999999; font-weight: bold } /* Name.Entity */ +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +body .nf { color: #0000FF } /* Name.Function */ +body .nl { color: #A0A000 } /* Name.Label */ +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +body .nt { color: #954121; font-weight: bold } /* Name.Tag */ +body .nv { color: #19469D } /* Name.Variable */ +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +body .w { color: #bbbbbb } /* Text.Whitespace */ +body .mf { color: #666666 } /* Literal.Number.Float */ +body .mh { color: #666666 } /* Literal.Number.Hex */ +body .mi { color: #666666 } /* Literal.Number.Integer */ +body .mo { color: #666666 } /* Literal.Number.Oct */ +body .sb { color: #219161 } /* Literal.String.Backtick */ +body .sc { color: #219161 } /* Literal.String.Char */ +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ +body .s2 { color: #219161 } /* Literal.String.Double */ +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +body .sh { color: #219161 } /* Literal.String.Heredoc */ +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +body .sx { color: #954121 } /* Literal.String.Other */ +body .sr { color: #BB6688 } /* Literal.String.Regex */ +body .s1 { color: #219161 } /* Literal.String.Single */ +body .ss { color: #19469D } /* Literal.String.Symbol */ +body .bp { color: #954121 } /* Name.Builtin.Pseudo */ +body .vc { color: #19469D } /* Name.Variable.Class */ +body .vg { color: #19469D } /* Name.Variable.Global */ +body .vi { color: #19469D } /* Name.Variable.Instance */ +body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html new file mode 100644 index 0000000..bf615fa --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/docs/pkginfo.html @@ -0,0 +1,101 @@ + pkginfo.js

pkginfo.js

/*
+ * pkginfo.js: Top-level include for the pkginfo module
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+ 
+var fs = require('fs'),
+    path = require('path');

function pkginfo ([options, 'property', 'property' ..])

+ +

@pmodule {Module} Parent module to read from.

+ +

@options {Object|Array|string} Optional Options used when exposing properties.

+ +

@arguments {string...} Optional Specified properties to expose.

+ +

Exposes properties from the package.json file for the parent module on +it's exports. Valid usage:

+ +

require('pkginfo')()

+ +

require('pkginfo')('version', 'author');

+ +

require('pkginfo')(['version', 'author']);

+ +

require('pkginfo')({ include: ['version', 'author'] });

var pkginfo = module.exports = function (pmodule, options) {
+  var args = [].slice.call(arguments, 2).filter(function (arg) {
+    return typeof arg === 'string';
+  });
+  

Parse variable arguments

  if (Array.isArray(options)) {

If the options passed in is an Array assume that +it is the Array of properties to expose from the +on the package.json file on the parent module.

    options = { include: options };
+  }
+  else if (typeof options === 'string') {

Otherwise if the first argument is a string, then +assume that it is the first property to expose from +the package.json file on the parent module.

    options = { include: [options] };
+  }
+  

Setup default options

  options = options || { include: [] };
+  
+  if (args.length > 0) {

If additional string arguments have been passed in +then add them to the properties to expose on the +parent module.

    options.include = options.include.concat(args);
+  }
+  
+  var pkg = pkginfo.read(pmodule, options.dir).package;
+  Object.keys(pkg).forEach(function (key) {
+    if (options.include.length > 0 && !~options.include.indexOf(key)) {
+      return;
+    }
+    
+    if (!pmodule.exports[key]) {
+      pmodule.exports[key] = pkg[key];
+    }
+  });
+  
+  return pkginfo;
+};

function find (dir)

+ +

@pmodule {Module} Parent module to read from.

+ +

@dir {string} Optional Directory to start search from.

+ +

Searches up the directory tree from dir until it finds a directory +which contains a package.json file.

pkginfo.find = function (pmodule, dir) {
+  dir = dir || pmodule.filename;
+  dir = path.dirname(dir); 
+  
+  var files = fs.readdirSync(dir);
+  
+  if (~files.indexOf('package.json')) {
+    return path.join(dir, 'package.json');
+  }
+  
+  if (dir === '/') {
+    throw new Error('Could not find package.json up from: ' + dir);
+  }
+  
+  return pkginfo.find(dir);
+};

function read (pmodule, dir)

+ +

@pmodule {Module} Parent module to read from.

+ +

@dir {string} Optional Directory to start search from.

+ +

Searches up the directory tree from dir until it finds a directory +which contains a package.json file and returns the package information.

pkginfo.read = function (pmodule, dir) { 
+  dir = pkginfo.find(pmodule, dir);
+  
+  var data = fs.readFileSync(dir).toString();
+      
+  return {
+    dir: dir, 
+    package: JSON.parse(data)
+  };
+};

Call pkginfo on this module and expose version.

pkginfo(module, {
+  dir: __dirname,
+  include: ['version'],
+  target: pkginfo
+});
+
+
\ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/all-properties.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/all-properties.js new file mode 100644 index 0000000..fd1d831 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/all-properties.js @@ -0,0 +1,19 @@ +/* + * all-properties.js: Sample of including all properties from a package.json file + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/array-argument.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/array-argument.js new file mode 100644 index 0000000..b1b6848 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/array-argument.js @@ -0,0 +1,20 @@ +/* + * array-argument.js: Sample of including specific properties from a package.json file + * using Array argument syntax. + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module, ['version', 'author']); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js new file mode 100644 index 0000000..b4b5fd6 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/multiple-properties.js @@ -0,0 +1,19 @@ +/* + * multiple-properties.js: Sample of including multiple properties from a package.json file + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module, 'version', 'author'); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/object-argument.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/object-argument.js new file mode 100644 index 0000000..28420c8 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/object-argument.js @@ -0,0 +1,22 @@ +/* + * object-argument.js: Sample of including specific properties from a package.json file + * using Object argument syntax. + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module, { + include: ['version', 'author'] + }); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/package.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/package.json new file mode 100644 index 0000000..1f2f01c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/package.json @@ -0,0 +1,10 @@ +{ + "name": "simple-app", + "description": "A test fixture for pkginfo", + "version": "0.1.0", + "author": "Charlie Robbins ", + "keywords": ["test", "fixture"], + "main": "./index.js", + "scripts": { "test": "vows test/*-test.js --spec" }, + "engines": { "node": ">= 0.4.0" } +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/single-property.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/single-property.js new file mode 100644 index 0000000..4f44561 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/examples/single-property.js @@ -0,0 +1,19 @@ +/* + * single-property.js: Sample of including a single specific properties from a package.json file + * + * (C) 2011, Charlie Robbins + * + */ + +var util = require('util'), + pkginfo = require('../lib/pkginfo')(module, 'version'); + +exports.someFunction = function () { + console.log('some of your custom logic here'); +}; + +console.log('Inspecting module:'); +console.dir(module.exports); + +console.log('\nAll exports exposed:'); +console.error(Object.keys(module.exports)); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js new file mode 100644 index 0000000..a4a6227 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js @@ -0,0 +1,132 @@ +/* + * pkginfo.js: Top-level include for the pkginfo module + * + * (C) 2011, Charlie Robbins + * + */ + +var fs = require('fs'), + path = require('path'); + +// +// ### function pkginfo ([options, 'property', 'property' ..]) +// #### @pmodule {Module} Parent module to read from. +// #### @options {Object|Array|string} **Optional** Options used when exposing properties. +// #### @arguments {string...} **Optional** Specified properties to expose. +// Exposes properties from the package.json file for the parent module on +// it's exports. Valid usage: +// +// `require('pkginfo')()` +// +// `require('pkginfo')('version', 'author');` +// +// `require('pkginfo')(['version', 'author']);` +// +// `require('pkginfo')({ include: ['version', 'author'] });` +// +var pkginfo = module.exports = function (pmodule, options) { + var args = [].slice.call(arguments, 2).filter(function (arg) { + return typeof arg === 'string'; + }); + + // + // **Parse variable arguments** + // + if (Array.isArray(options)) { + // + // If the options passed in is an Array assume that + // it is the Array of properties to expose from the + // on the package.json file on the parent module. + // + options = { include: options }; + } + else if (typeof options === 'string') { + // + // Otherwise if the first argument is a string, then + // assume that it is the first property to expose from + // the package.json file on the parent module. + // + options = { include: [options] }; + } + + // + // **Setup default options** + // + options = options || { include: [] }; + + if (args.length > 0) { + // + // If additional string arguments have been passed in + // then add them to the properties to expose on the + // parent module. + // + options.include = options.include.concat(args); + } + + var pkg = pkginfo.read(pmodule, options.dir).package; + Object.keys(pkg).forEach(function (key) { + if (options.include.length > 0 && !~options.include.indexOf(key)) { + return; + } + + if (!pmodule.exports[key]) { + pmodule.exports[key] = pkg[key]; + } + }); + + return pkginfo; +}; + +// +// ### function find (dir) +// #### @pmodule {Module} Parent module to read from. +// #### @dir {string} **Optional** Directory to start search from. +// Searches up the directory tree from `dir` until it finds a directory +// which contains a `package.json` file. +// +pkginfo.find = function (pmodule, dir) { + dir = dir || pmodule.filename; + dir = path.dirname(dir); + + var files = fs.readdirSync(dir); + + if (~files.indexOf('package.json')) { + return path.join(dir, 'package.json'); + } + + if (dir === '/') { + throw new Error('Could not find package.json up from: ' + dir); + } + else if (!dir || dir === '.') { + throw new Error('Cannot find package.json from unspecified directory'); + } + + return pkginfo.find(pmodule, dir); +}; + +// +// ### function read (pmodule, dir) +// #### @pmodule {Module} Parent module to read from. +// #### @dir {string} **Optional** Directory to start search from. +// Searches up the directory tree from `dir` until it finds a directory +// which contains a `package.json` file and returns the package information. +// +pkginfo.read = function (pmodule, dir) { + dir = pkginfo.find(pmodule, dir); + + var data = fs.readFileSync(dir).toString(); + + return { + dir: dir, + package: JSON.parse(data) + }; +}; + +// +// Call `pkginfo` on this module and expose version. +// +pkginfo(module, { + dir: __dirname, + include: ['version'], + target: pkginfo +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/package.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/package.json new file mode 100644 index 0000000..a9efcfc --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/package.json @@ -0,0 +1,39 @@ +{ + "name": "pkginfo", + "version": "0.2.3", + "description": "An easy way to expose properties on a module from a package.json", + "author": { + "name": "Charlie Robbins", + "email": "charlie.robbins@gmail.com" + }, + "repository": { + "type": "git", + "url": "http://github.com/indexzero/node-pkginfo.git" + }, + "keywords": [ + "info", + "tools", + "package.json" + ], + "devDependencies": { + "vows": "0.6.x" + }, + "main": "./lib/pkginfo", + "scripts": { + "test": "vows test/*-test.js --spec" + }, + "engines": { + "node": ">= 0.4.0" + }, + "readme": "# node-pkginfo\n\nAn easy way to expose properties on a module from a package.json\n\n## Installation\n\n### Installing npm (node package manager)\n```\n curl http://npmjs.org/install.sh | sh\n```\n\n### Installing pkginfo\n```\n [sudo] npm install pkginfo\n```\n\n## Motivation\nHow often when writing node.js modules have you written the following line(s) of code? \n\n* Hard code your version string into your code\n\n``` js\n exports.version = '0.1.0';\n```\n\n* Programmatically expose the version from the package.json\n\n``` js\n exports.version = JSON.parse(fs.readFileSync('/path/to/package.json', 'utf8')).version;\n```\n\nIn other words, how often have you wanted to expose basic information from your package.json onto your module programmatically? **WELL NOW YOU CAN!**\n\n## Usage\n\nUsing `pkginfo` is idiot-proof, just require and invoke it. \n\n``` js\n var pkginfo = require('pkginfo')(module);\n \n console.dir(module.exports);\n```\n\nBy invoking the `pkginfo` module all of the properties in your `package.json` file will be automatically exposed on the callee module (i.e. the parent module of `pkginfo`). \n\nHere's a sample of the output:\n\n```\n { name: 'simple-app',\n description: 'A test fixture for pkginfo',\n version: '0.1.0',\n author: 'Charlie Robbins ',\n keywords: [ 'test', 'fixture' ],\n main: './index.js',\n scripts: { test: 'vows test/*-test.js --spec' },\n engines: { node: '>= 0.4.0' } }\n```\n\n### Expose specific properties\nIf you don't want to expose **all** properties on from your `package.json` on your module then simple pass those properties to the `pkginfo` function:\n\n``` js\n var pkginfo = require('pkginfo')(module, 'version', 'author');\n \n console.dir(module.exports);\n```\n\n```\n { version: '0.1.0',\n author: 'Charlie Robbins ' }\n```\n\nIf you're looking for further usage see the [examples][0] included in this repository. \n\n## Run Tests\nTests are written in [vows][1] and give complete coverage of all APIs.\n\n```\n vows test/*-test.js --spec\n```\n\n[0]: https://github.com/indexzero/node-pkginfo/tree/master/examples\n[1]: http://vowsjs.org\n\n#### Author: [Charlie Robbins](http://nodejitsu.com)", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/indexzero/node-pkginfo/issues" + }, + "_id": "pkginfo@0.2.3", + "dist": { + "shasum": "923bb29a2074ebc554f518c02ce1d9f6ada4660c" + }, + "_from": "pkginfo@0.2.x", + "_resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.2.3.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js new file mode 100644 index 0000000..3156c00 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/pkginfo/test/pkginfo-test.js @@ -0,0 +1,69 @@ +/* + * pkginfo-test.js: Tests for the pkginfo module. + * + * (C) 2011, Charlie Robbins + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + pkginfo = require('../lib/pkginfo'); + +function assertProperties (source, target) { + assert.lengthOf(source, target.length + 1); + target.forEach(function (prop) { + assert.isTrue(!!~source.indexOf(prop)); + }); +} + +function testExposes (options) { + return { + topic: function () { + exec('node ' + path.join(__dirname, '..', 'examples', options.script), this.callback); + }, + "should expose that property correctly": function (err, stdout, stderr) { + assert.isNull(err); + + var exposed = stderr.match(/'(\w+)'/ig).map(function (p) { + return p.substring(1, p.length - 1); + }); + + return !options.assert + ? assertProperties(exposed, options.properties) + : options.assert(exposed); + } + } +} + +vows.describe('pkginfo').addBatch({ + "When using the pkginfo module": { + "and passed a single `string` argument": testExposes({ + script: 'single-property.js', + properties: ['version'] + }), + "and passed multiple `string` arguments": testExposes({ + script: 'multiple-properties.js', + properties: ['version', 'author'] + }), + "and passed an `object` argument": testExposes({ + script: 'object-argument.js', + properties: ['version', 'author'] + }), + "and passed an `array` argument": testExposes({ + script: 'array-argument.js', + properties: ['version', 'author'] + }), + "and passed no arguments": testExposes({ + script: 'all-properties.js', + assert: function (exposed) { + var pkg = fs.readFileSync(path.join(__dirname, '..', 'examples', 'package.json')).toString(), + keys = Object.keys(JSON.parse(pkg)); + + assertProperties(exposed, keys); + } + }) + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/LICENSE b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/LICENSE new file mode 100644 index 0000000..a4a9aee --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/LICENSE @@ -0,0 +1,55 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/README.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/README.md new file mode 100644 index 0000000..8713a80 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/README.md @@ -0,0 +1,287 @@ +# Request -- Simplified HTTP request method + +## Install + +
+  npm install request
+
+ +Or from source: + +
+  git clone git://github.com/mikeal/request.git 
+  cd request
+  npm link
+
+ +## Super simple to use + +Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default. + +```javascript +var request = require('request'); +request('http://www.google.com', function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log(body) // Print the google web page. + } +}) +``` + +## Streaming + +You can stream any response to a file stream. + +```javascript +request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')) +``` + +You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers. + +```javascript +fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json')) +``` + +Request can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers. + +```javascript +request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png')) +``` + +Now let's get fancy. + +```javascript +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + if (req.method === 'PUT') { + req.pipe(request.put('http://mysite.com/doodle.png')) + } else if (req.method === 'GET' || req.method === 'HEAD') { + request.get('http://mysite.com/doodle.png').pipe(resp) + } + } +}) +``` + +You can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do: + +```javascript +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + var x = request('http://mysite.com/doodle.png') + req.pipe(x) + x.pipe(resp) + } +}) +``` + +And since pipe() returns the destination stream in node 0.5.x you can do one line proxying :) + +```javascript +req.pipe(request('http://mysite.com/doodle.png')).pipe(resp) +``` + +Also, none of this new functionality conflicts with requests previous features, it just expands them. + +```javascript +var r = request.defaults({'proxy':'http://localproxy.com'}) + +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + r.get('http://google.com/doodle.png').pipe(resp) + } +}) +``` + +You can still use intermediate proxies, the requests will still follow HTTP forwards, etc. + +## OAuth Signing + +```javascript +// Twitter OAuth +var qs = require('querystring') + , oauth = + { callback: 'http://mysite.com/callback/' + , consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + } + , url = 'https://api.twitter.com/oauth/request_token' + ; +request.post({url:url, oauth:oauth}, function (e, r, body) { + // Assume by some stretch of magic you aquired the verifier + var access_token = qs.parse(body) + , oauth = + { consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + , token: access_token.oauth_token + , verifier: VERIFIER + , token_secret: access_token.oauth_token_secret + } + , url = 'https://api.twitter.com/oauth/access_token' + ; + request.post({url:url, oauth:oauth}, function (e, r, body) { + var perm_token = qs.parse(body) + , oauth = + { consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + , token: perm_token.oauth_token + , token_secret: perm_token.oauth_token_secret + } + , url = 'https://api.twitter.com/1/users/show.json?' + , params = + { screen_name: perm_token.screen_name + , user_id: perm_token.user_id + } + ; + url += qs.stringify(params) + request.get({url:url, oauth:oauth, json:true}, function (e, r, user) { + console.log(user) + }) + }) +}) +``` + + + +### request(options, callback) + +The first argument can be either a url or an options object. The only required option is uri, all others are optional. + +* `uri` || `url` - fully qualified uri or a parsed url object from url.parse() +* `qs` - object containing querystring values to be appended to the uri +* `method` - http method, defaults to GET +* `headers` - http headers, defaults to {} +* `body` - entity body for POST and PUT requests. Must be buffer or string. +* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. +* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. +* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below. +* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true. +* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false. +* `maxRedirects` - the maximum number of redirects to follow, defaults to 10. +* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer. +* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets. +* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool. +* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request +* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri. +* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above. +* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option. +* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section) + + +The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer. + +## Convenience methods + +There are also shorthand methods for different HTTP METHODs and some other conveniences. + +### request.defaults(options) + +This method returns a wrapper around the normal request API that defaults to whatever options you pass in to it. + +### request.put + +Same as request() but defaults to `method: "PUT"`. + +```javascript +request.put(url) +``` + +### request.post + +Same as request() but defaults to `method: "POST"`. + +```javascript +request.post(url) +``` + +### request.head + +Same as request() but defaults to `method: "HEAD"`. + +```javascript +request.head(url) +``` + +### request.del + +Same as request() but defaults to `method: "DELETE"`. + +```javascript +request.del(url) +``` + +### request.get + +Alias to normal request method for uniformity. + +```javascript +request.get(url) +``` +### request.cookie + +Function that creates a new cookie. + +```javascript +request.cookie('cookie_string_here') +``` +### request.jar + +Function that creates a new cookie jar. + +```javascript +request.jar() +``` + + +## Examples: + +```javascript + var request = require('request') + , rand = Math.floor(Math.random()*100000000).toString() + ; + request( + { method: 'PUT' + , uri: 'http://mikeal.iriscouch.com/testjs/' + rand + , multipart: + [ { 'content-type': 'application/json' + , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) + } + , { body: 'I am an attachment' } + ] + } + , function (error, response, body) { + if(response.statusCode == 201){ + console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand) + } else { + console.log('error: '+ response.statusCode) + console.log(body) + } + } + ) +``` +Cookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent). + +```javascript +var request = request.defaults({jar: false}) +request('http://www.google.com', function () { + request('http://images.google.com') +}) +``` + +If you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option: + +```javascript +var j = request.jar() +var request = request.defaults({jar:j}) +request('http://www.google.com', function () { + request('http://images.google.com') +}) +``` +OR + +```javascript +var j = request.jar() +var cookie = request.cookie('your_cookie_here') +j.add(cookie) +request({url: 'http://www.google.com', jar: j}, function () { + request('http://images.google.com') +}) +``` diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/aws.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/aws.js new file mode 100644 index 0000000..4e87bff --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/aws.js @@ -0,0 +1,190 @@ + +/*! + * knox - auth + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var crypto = require('crypto') + , parse = require('url').parse; + +/** + * Valid keys. + */ + +var keys = [ + 'acl' + , 'location' + , 'logging' + , 'notification' + , 'partNumber' + , 'policy' + , 'requestPayment' + , 'torrent' + , 'uploadId' + , 'uploads' + , 'versionId' + , 'versioning' + , 'versions' + , 'website' +]; + +/** + * Return an "Authorization" header value with the given `options` + * in the form of "AWS :" + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.authorization = function(options){ + return 'AWS ' + options.key + ':' + exports.sign(options); +}; + +/** + * Simple HMAC-SHA1 Wrapper + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.hmacSha1 = function(options){ + return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64'); +}; + +/** + * Create a base64 sha1 HMAC for `options`. + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.sign = function(options){ + options.message = exports.stringToSign(options); + return exports.hmacSha1(options); +}; + +/** + * Create a base64 sha1 HMAC for `options`. + * + * Specifically to be used with S3 presigned URLs + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.signQuery = function(options){ + options.message = exports.queryStringToSign(options); + return exports.hmacSha1(options); +}; + +/** + * Return a string for sign() with the given `options`. + * + * Spec: + * + * \n + * \n + * \n + * \n + * [headers\n] + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.stringToSign = function(options){ + var headers = options.amazonHeaders || ''; + if (headers) headers += '\n'; + return [ + options.verb + , options.md5 + , options.contentType + , options.date.toUTCString() + , headers + options.resource + ].join('\n'); +}; + +/** + * Return a string for sign() with the given `options`, but is meant exclusively + * for S3 presigned URLs + * + * Spec: + * + * \n + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +exports.queryStringToSign = function(options){ + return 'GET\n\n\n' + + options.date + '\n' + + options.resource; +}; + +/** + * Perform the following: + * + * - ignore non-amazon headers + * - lowercase fields + * - sort lexicographically + * - trim whitespace between ":" + * - join with newline + * + * @param {Object} headers + * @return {String} + * @api private + */ + +exports.canonicalizeHeaders = function(headers){ + var buf = [] + , fields = Object.keys(headers); + for (var i = 0, len = fields.length; i < len; ++i) { + var field = fields[i] + , val = headers[field] + , field = field.toLowerCase(); + if (0 !== field.indexOf('x-amz')) continue; + buf.push(field + ':' + val); + } + return buf.sort().join('\n'); +}; + +/** + * Perform the following: + * + * - ignore non sub-resources + * - sort lexicographically + * + * @param {String} resource + * @return {String} + * @api private + */ + +exports.canonicalizeResource = function(resource){ + var url = parse(resource, true) + , path = url.pathname + , buf = []; + + Object.keys(url.query).forEach(function(key){ + if (!~keys.indexOf(key)) return; + var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]); + buf.push(key + val); + }); + + return path + (buf.length + ? '?' + buf.sort().join('&') + : ''); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/aws2.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/aws2.js new file mode 100644 index 0000000..eb683f7 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/aws2.js @@ -0,0 +1,128 @@ +var crypto = require('crypto') + +// The Authentication Header +// +// The Amazon S3 REST API uses the standard HTTPAuthorization header to pass authentication information. (The name of the standard header is unfortunate because it carries authentication information, not authorization).Under the Amazon S3 authentication scheme, the Authorization header has the following form. +// +// Authorization: AWS AWSAccessKeyId:Signature +// +// Developers are issued an AWS Access Key ID and AWS SecretAccess Key when they register. For request authentication, theAWSAccessKeyId element identifies the secret key that was used to compute the signature, and (indirectly) the developer making the request. +// +// The Signature element is the RFC 2104HMAC-SHA1 of selected elements from the request, and so theSignature part of the Authorization header will vary from request to request. If the request signature calculated by the system matches theSignature included with the request, then the requester will have demonstrated possession to the AWSSecret Access Key. The request will then be processed under the identity, and with the authority, of the developer to whom the key was issued. +// +// Following is pseudo-grammar that illustrates the construction of the Authorization request header (\nmeans the Unicode code point U+000A commonly called newline). + +function authorizationHeader (accessKey) { + // Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature; + + var authorization = 'AWS' + " " + accessKey + ":" + signature() + + return authorization +} + +// + +function signature (secret, verb, md5, contenttype, date, amzheaders, bucket, path) { + // Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of( YourSecretAccessKeyID, StringToSign ) ) ); + + function encodeSignature (stringToSign) { + return crypto.createHash('sha1').update(stringToSign).digest('base64') + } + + // + // StringToSign = HTTP-Verb + "\n" + + // Content-MD5 + "\n" + + // Content-Type + "\n" + + // Date + "\n" + + // CanonicalizedAmzHeaders + + // CanonicalizedResource; + + function compileStringToSign () { + var s = + verb + '\n' + (md5 || '') + '\n' + (contenttype || '') + '\n' + date.toUTCString() + '\n' + canonicalizeAmzHeaders(amzheaders) + + canonicalizeResource() + return s + } + + // + // CanonicalizedResource = [ "/" + Bucket ] + + // + + // [ sub-resource, if present. For example "?acl", "?location", "?logging", or "?torrent"]; + + function canonicalizeResource () { + return '/' + bucket + path + } + + // + // CanonicalizedAmzHeaders = + // + // HMAC-SHA1 is an algorithm defined by RFC 2104 (go to RFC 2104 - Keyed-Hashing for Message Authentication ). The algorithm takes as input two byte-strings: a key and a message. For Amazon S3 Request authentication, use your AWS Secret Access Key (YourSecretAccessKeyID) as the key, and the UTF-8 encoding of the StringToSign as the message. The output of HMAC-SHA1 is also a byte string, called the digest. The Signature request parameter is constructed by Base64 encoding this digest. + // Request Canonicalization for Signing + // + // Recall that when the system receives an authenticated request, it compares the computed request signature with the signature provided in the request in StringToSign. For that reason, you must compute the signature using the same method used by Amazon S3. We call the process of putting a request in an agreed-upon form for signing "canonicalization". + +} + + + +// Constructing the CanonicalizedResource Element +// +// CanonicalizedResource represents the Amazon S3 resource targeted by the request. Construct it for a REST request as follows: +// +// Launch Process +// +// 1 +// +// +// Start with the empty string (""). +// +// 2 +// +// +// If the request specifies a bucket using the HTTP Host header (virtual hosted-style), append the bucket name preceded by a "/" (e.g., "/bucketname"). For path-style requests and requests that don't address a bucket, do nothing. For more information on virtual hosted-style requests, see Virtual Hosting of Buckets. +// +// 3 +// +// +// Append the path part of the un-decoded HTTP Request-URI, up-to but not including the query string. +// +// 4 +// +// +// If the request addresses a sub-resource, like ?versioning, ?location, ?acl, ?torrent, ?lifecycle, or ?versionid append the sub-resource, its value if it has one, and the question mark. Note that in case of multiple sub-resources, sub-resources must be lexicographically sorted by sub-resource name and separated by '&'. e.g. ?acl&versionId=value. +// +// The list of sub-resources that must be included when constructing the CanonicalizedResource Element are: acl, lifecycle, location, logging, notification, partNumber, policy, requestPayment, torrent, uploadId, uploads, versionId, versioning, versions and website. +// +// If the request specifies query string parameters overriding the response header values (see Get Object), append the query string parameters, and its values. When signing you do not encode these values. However, when making the request, you must encode these parameter values. The query string parameters in a GET request include response-content-type, response-content-language, response-expires, response-cache-control, response-content-disposition, response-content-encoding. +// +// The delete query string parameter must be including when creating the CanonicalizedResource for a Multi-Object Delete request. +// +// Elements of the CanonicalizedResource that come from the HTTP Request-URI should be signed literally as they appear in the HTTP request, including URL-Encoding meta characters. +// +// The CanonicalizedResource might be different than the HTTP Request-URI. In particular, if your request uses the HTTP Host header to specify a bucket, the bucket does appear in the HTTP Request-URI. However, the CanonicalizedResource continues to include the bucket. Query string parameters might also appear in the Request-URI but are not included in CanonicalizedResource. For more information, see Virtual Hosting of Buckets. +// Constructing the CanonicalizedAmzHeaders Element +// +// To construct the CanonicalizedAmzHeaders part of StringToSign, select all HTTP request headers that start with 'x-amz-' (using a case-insensitive comparison) and use the following process. +// +// CanonicalizedAmzHeaders Process +// 1 Convert each HTTP header name to lower-case. For example, 'X-Amz-Date' becomes 'x-amz-date'. +// 2 Sort the collection of headers lexicographically by header name. +// 3 Combine header fields with the same name into one "header-name:comma-separated-value-list" pair as prescribed by RFC 2616, section 4.2, without any white-space between values. For example, the two metadata headers 'x-amz-meta-username: fred' and 'x-amz-meta-username: barney' would be combined into the single header 'x-amz-meta-username: fred,barney'. +// 4 "Unfold" long headers that span multiple lines (as allowed by RFC 2616, section 4.2) by replacing the folding white-space (including new-line) by a single space. +// 5 Trim any white-space around the colon in the header. For example, the header 'x-amz-meta-username: fred,barney' would become 'x-amz-meta-username:fred,barney' +// 6 Finally, append a new-line (U+000A) to each canonicalized header in the resulting list. Construct the CanonicalizedResource element by concatenating all headers in this list into a single string. +// +// Positional versus Named HTTP Header StringToSign Elements +// +// The first few header elements of StringToSign (Content-Type, Date, and Content-MD5) are positional in nature. StringToSign does not include the names of these headers, only their values from the request. In contrast, the 'x-amz-' elements are named; Both the header names and the header values appear in StringToSign. +// +// If a positional header called for in the definition of StringToSign is not present in your request, (Content-Type or Content-MD5, for example, are optional for PUT requests, and meaningless for GET requests), substitute the empty string ("") in for that position. +// Time Stamp Requirement +// +// A valid time stamp (using either the HTTP Date header or an x-amz-date alternative) is mandatory for authenticated requests. Furthermore, the client time-stamp included with an authenticated request must be within 15 minutes of the Amazon S3 system time when the request is received. If not, the request will fail with the RequestTimeTooSkewed error status code. The intention of these restrictions is to limit the possibility that intercepted requests could be replayed by an adversary. For stronger protection against eavesdropping, use the HTTPS transport for authenticated requests. +// +// Some HTTP client libraries do not expose the ability to set the Date header for a request. If you have trouble including the value of the 'Date' header in the canonicalized headers, you can set the time-stamp for the request using an 'x-amz-date' header instead. The value of the x-amz-date header must be in one of the RFC 2616 formats (http://www.ietf.org/rfc/rfc2616.txt). When an x-amz-date header is present in a request, the system will ignore any Date header when computing the request signature. Therefore, if you include the x-amz-date header, use the empty string for the Date when constructing the StringToSign. See the next section for an example. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/forever.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/forever.js new file mode 100644 index 0000000..ac853c0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/forever.js @@ -0,0 +1,103 @@ +module.exports = ForeverAgent +ForeverAgent.SSL = ForeverAgentSSL + +var util = require('util') + , Agent = require('http').Agent + , net = require('net') + , tls = require('tls') + , AgentSSL = require('https').Agent + +function ForeverAgent(options) { + var self = this + self.options = options || {} + self.requests = {} + self.sockets = {} + self.freeSockets = {} + self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets + self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets + self.on('free', function(socket, host, port) { + var name = host + ':' + port + if (self.requests[name] && self.requests[name].length) { + self.requests[name].shift().onSocket(socket) + } else if (self.sockets[name].length < self.minSockets) { + if (!self.freeSockets[name]) self.freeSockets[name] = [] + self.freeSockets[name].push(socket) + + // if an error happens while we don't use the socket anyway, meh, throw the socket away + function onIdleError() { + socket.destroy() + } + socket._onIdleError = onIdleError + socket.on('error', onIdleError) + } else { + // If there are no pending requests just destroy the + // socket and it will get removed from the pool. This + // gets us out of timeout issues and allows us to + // default to Connection:keep-alive. + socket.destroy(); + } + }) + +} +util.inherits(ForeverAgent, Agent) + +ForeverAgent.defaultMinSockets = 5 + + +ForeverAgent.prototype.createConnection = net.createConnection +ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest +ForeverAgent.prototype.addRequest = function(req, host, port) { + var name = host + ':' + port + if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { + var idleSocket = this.freeSockets[name].pop() + idleSocket.removeListener('error', idleSocket._onIdleError) + delete idleSocket._onIdleError + req._reusedSocket = true + req.onSocket(idleSocket) + } else { + this.addRequestNoreuse(req, host, port) + } +} + +ForeverAgent.prototype.removeSocket = function(s, name, host, port) { + if (this.sockets[name]) { + var index = this.sockets[name].indexOf(s); + if (index !== -1) { + this.sockets[name].splice(index, 1); + } + } else if (this.sockets[name] && this.sockets[name].length === 0) { + // don't leak + delete this.sockets[name]; + delete this.requests[name]; + } + + if (this.freeSockets[name]) { + var index = this.freeSockets[name].indexOf(s) + if (index !== -1) { + this.freeSockets[name].splice(index, 1) + if (this.freeSockets[name].length === 0) { + delete this.freeSockets[name] + } + } + } + + if (this.requests[name] && this.requests[name].length) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(name, host, port).emit('free'); + } +} + +function ForeverAgentSSL (options) { + ForeverAgent.call(this, options) +} +util.inherits(ForeverAgentSSL, ForeverAgent) + +ForeverAgentSSL.prototype.createConnection = createConnectionSSL +ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest + +function createConnectionSSL (port, host, options) { + options.port = port + options.host = host + return tls.connect(options) +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/main.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/main.js new file mode 100644 index 0000000..2407a93 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/main.js @@ -0,0 +1,974 @@ +// Copyright 2010-2012 Mikeal Rogers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var http = require('http') + , https = false + , tls = false + , url = require('url') + , util = require('util') + , stream = require('stream') + , qs = require('querystring') + , mimetypes = require('./mimetypes') + , oauth = require('./oauth') + , uuid = require('./uuid') + , ForeverAgent = require('./forever') + , Cookie = require('./vendor/cookie') + , CookieJar = require('./vendor/cookie/jar') + , cookieJar = new CookieJar + , tunnel = require('./tunnel') + , aws = require('./aws') + ; + +if (process.logging) { + var log = process.logging('request') +} + +try { + https = require('https') +} catch (e) {} + +try { + tls = require('tls') +} catch (e) {} + +function toBase64 (str) { + return (new Buffer(str || "", "ascii")).toString("base64") +} + +// Hacky fix for pre-0.4.4 https +if (https && !https.Agent) { + https.Agent = function (options) { + http.Agent.call(this, options) + } + util.inherits(https.Agent, http.Agent) + https.Agent.prototype._getConnection = function (host, port, cb) { + var s = tls.connect(port, host, this.options, function () { + // do other checks here? + if (cb) cb() + }) + return s + } +} + +function isReadStream (rs) { + if (rs.readable && rs.path && rs.mode) { + return true + } +} + +function copy (obj) { + var o = {} + Object.keys(obj).forEach(function (i) { + o[i] = obj[i] + }) + return o +} + +var isUrl = /^https?:/ + +var globalPool = {} + +function Request (options) { + stream.Stream.call(this) + this.readable = true + this.writable = true + + if (typeof options === 'string') { + options = {uri:options} + } + + var reserved = Object.keys(Request.prototype) + for (var i in options) { + if (reserved.indexOf(i) === -1) { + this[i] = options[i] + } else { + if (typeof options[i] === 'function') { + delete options[i] + } + } + } + options = copy(options) + + this.init(options) +} +util.inherits(Request, stream.Stream) +Request.prototype.init = function (options) { + var self = this + + if (!options) options = {} + + if (!self.pool && self.pool !== false) self.pool = globalPool + self.dests = [] + self.__isRequestRequest = true + + // Protect against double callback + if (!self._callback && self.callback) { + self._callback = self.callback + self.callback = function () { + if (self._callbackCalled) return // Print a warning maybe? + self._callback.apply(self, arguments) + self._callbackCalled = true + } + self.on('error', self.callback.bind()) + self.on('complete', self.callback.bind(self, null)) + } + + if (self.url) { + // People use this property instead all the time so why not just support it. + self.uri = self.url + delete self.url + } + + if (!self.uri) { + throw new Error("options.uri is a required argument") + } else { + if (typeof self.uri == "string") self.uri = url.parse(self.uri) + } + if (self.proxy) { + if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy) + + // do the HTTP CONNECT dance using koichik/node-tunnel + if (http.globalAgent && self.uri.protocol === "https:") { + self.tunnel = true + var tunnelFn = self.proxy.protocol === "http:" + ? tunnel.httpsOverHttp : tunnel.httpsOverHttps + + var tunnelOptions = { proxy: { host: self.proxy.hostname + , port: +self.proxy.port + , proxyAuth: self.proxy.auth } + , ca: this.ca } + + self.agent = tunnelFn(tunnelOptions) + self.tunnel = true + } + } + + if (!self.uri.host || !self.uri.pathname) { + // Invalid URI: it may generate lot of bad errors, like "TypeError: Cannot call method 'indexOf' of undefined" in CookieJar + // Detect and reject it as soon as possible + var faultyUri = url.format(self.uri) + var message = 'Invalid URI "' + faultyUri + '"' + if (Object.keys(options).length === 0) { + // No option ? This can be the sign of a redirect + // As this is a case where the user cannot do anything (he didn't call request directly with this URL) + // he should be warned that it can be caused by a redirection (can save some hair) + message += '. This can be caused by a crappy redirection.' + } + self.emit('error', new Error(message)) + return // This error was fatal + } + + self._redirectsFollowed = self._redirectsFollowed || 0 + self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10 + self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true + self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false; + if (self.followRedirect || self.followAllRedirects) + self.redirects = self.redirects || [] + + self.headers = self.headers ? copy(self.headers) : {} + + self.setHost = false + if (!self.headers.host) { + self.headers.host = self.uri.hostname + if (self.uri.port) { + if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && + !(self.uri.port === 443 && self.uri.protocol === 'https:') ) + self.headers.host += (':'+self.uri.port) + } + self.setHost = true + } + + self.jar(self._jar || options.jar) + + if (!self.uri.pathname) {self.uri.pathname = '/'} + if (!self.uri.port) { + if (self.uri.protocol == 'http:') {self.uri.port = 80} + else if (self.uri.protocol == 'https:') {self.uri.port = 443} + } + + if (self.proxy && !self.tunnel) { + self.port = self.proxy.port + self.host = self.proxy.hostname + } else { + self.port = self.uri.port + self.host = self.uri.hostname + } + + self.clientErrorHandler = function (error) { + if (self._aborted) return + + if (self.setHost) delete self.headers.host + if (self.req._reusedSocket && error.code === 'ECONNRESET' + && self.agent.addRequestNoreuse) { + self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } + self.start() + self.req.end() + return + } + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + self.emit('error', error) + } + + if (options.form) { + self.form(options.form) + } + + if (options.oauth) { + self.oauth(options.oauth) + } + + if (options.aws) { + self.aws(options.aws) + } + + if (self.uri.auth && !self.headers.authorization) { + self.headers.authorization = "Basic " + toBase64(self.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) + } + if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization'] && !self.tunnel) { + self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) + } + + if (options.qs) self.qs(options.qs) + + if (self.uri.path) { + self.path = self.uri.path + } else { + self.path = self.uri.pathname + (self.uri.search || "") + } + + if (self.path.length === 0) self.path = '/' + + if (self.proxy && !self.tunnel) self.path = (self.uri.protocol + '//' + self.uri.host + self.path) + + if (options.json) { + self.json(options.json) + } else if (options.multipart) { + self.boundary = uuid() + self.multipart(options.multipart) + } + + if (self.body) { + var length = 0 + if (!Buffer.isBuffer(self.body)) { + if (Array.isArray(self.body)) { + for (var i = 0; i < self.body.length; i++) { + length += self.body[i].length + } + } else { + self.body = new Buffer(self.body) + length = self.body.length + } + } else { + length = self.body.length + } + if (length) { + self.headers['content-length'] = length + } else { + throw new Error('Argument error, options.body.') + } + } + + var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol + , defaultModules = {'http:':http, 'https:':https} + , httpModules = self.httpModules || {} + ; + self.httpModule = httpModules[protocol] || defaultModules[protocol] + + if (!self.httpModule) throw new Error("Invalid protocol") + + if (options.ca) self.ca = options.ca + + if (!self.agent) { + if (options.agentOptions) self.agentOptions = options.agentOptions + + if (options.agentClass) { + self.agentClass = options.agentClass + } else if (options.forever) { + self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL + } else { + self.agentClass = self.httpModule.Agent + } + } + + if (self.pool === false) { + self.agent = false + } else { + self.agent = self.agent || self.getAgent() + if (self.maxSockets) { + // Don't use our pooling if node has the refactored client + self.agent.maxSockets = self.maxSockets + } + if (self.pool.maxSockets) { + // Don't use our pooling if node has the refactored client + self.agent.maxSockets = self.pool.maxSockets + } + } + + self.once('pipe', function (src) { + if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.") + self.src = src + if (isReadStream(src)) { + if (!self.headers['content-type'] && !self.headers['Content-Type']) + self.headers['content-type'] = mimetypes.lookup(src.path.slice(src.path.lastIndexOf('.')+1)) + } else { + if (src.headers) { + for (var i in src.headers) { + if (!self.headers[i]) { + self.headers[i] = src.headers[i] + } + } + } + if (src.method && !self.method) { + self.method = src.method + } + } + + self.on('pipe', function () { + console.error("You have already piped to this stream. Pipeing twice is likely to break the request.") + }) + }) + + process.nextTick(function () { + if (self._aborted) return + + if (self.body) { + if (Array.isArray(self.body)) { + self.body.forEach(function (part) { + self.write(part) + }) + } else { + self.write(self.body) + } + self.end() + } else if (self.requestBodyStream) { + console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.") + self.requestBodyStream.pipe(self) + } else if (!self.src) { + if (self.method !== 'GET' && typeof self.method !== 'undefined') { + self.headers['content-length'] = 0; + } + self.end(); + } + self.ntick = true + }) +} + +Request.prototype.getAgent = function () { + var Agent = this.agentClass + var options = {} + if (this.agentOptions) { + for (var i in this.agentOptions) { + options[i] = this.agentOptions[i] + } + } + if (this.ca) options.ca = this.ca + + var poolKey = '' + + // different types of agents are in different pools + if (Agent !== this.httpModule.Agent) { + poolKey += Agent.name + } + + if (!this.httpModule.globalAgent) { + // node 0.4.x + options.host = this.host + options.port = this.port + if (poolKey) poolKey += ':' + poolKey += this.host + ':' + this.port + } + + if (options.ca) { + if (poolKey) poolKey += ':' + poolKey += options.ca + } + + if (!poolKey && Agent === this.httpModule.Agent && this.httpModule.globalAgent) { + // not doing anything special. Use the globalAgent + return this.httpModule.globalAgent + } + + // already generated an agent for this setting + if (this.pool[poolKey]) return this.pool[poolKey] + + return this.pool[poolKey] = new Agent(options) +} + +Request.prototype.start = function () { + var self = this + + if (self._aborted) return + + self._started = true + self.method = self.method || 'GET' + self.href = self.uri.href + if (log) log('%method %href', self) + + if (self.src && self.src.stat && self.src.stat.size) { + self.headers['content-length'] = self.src.stat.size + } + if (self._aws) { + self.aws(self._aws, true) + } + + self.req = self.httpModule.request(self, function (response) { + if (self._aborted) return + if (self._paused) response.pause() + + self.response = response + response.request = self + response.toJSON = toJSON + + if (self.httpModule === https && + self.strictSSL && + !response.client.authorized) { + var sslErr = response.client.authorizationError + self.emit('error', new Error('SSL Error: '+ sslErr)) + return + } + + if (self.setHost) delete self.headers.host + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + + var addCookie = function (cookie) { + if (self._jar) self._jar.add(new Cookie(cookie)) + else cookieJar.add(new Cookie(cookie)) + } + + if (response.headers['set-cookie'] && (!self._disableCookies)) { + if (Array.isArray(response.headers['set-cookie'])) response.headers['set-cookie'].forEach(addCookie) + else addCookie(response.headers['set-cookie']) + } + + if (response.statusCode >= 300 && response.statusCode < 400 && + (self.followAllRedirects || + (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST' && self.method !== 'DELETE'))) && + response.headers.location) { + if (self._redirectsFollowed >= self.maxRedirects) { + self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) + return + } + self._redirectsFollowed += 1 + + if (!isUrl.test(response.headers.location)) { + response.headers.location = url.resolve(self.uri.href, response.headers.location) + } + self.uri = response.headers.location + self.redirects.push( + { statusCode : response.statusCode + , redirectUri: response.headers.location + } + ) + if (self.followAllRedirects) self.method = 'GET' + // self.method = 'GET'; // Force all redirects to use GET || commented out fixes #215 + delete self.req + delete self.agent + delete self._started + delete self.body + if (self.headers) { + delete self.headers.host + } + if (log) log('Redirect to %uri', self) + self.init() + return // Ignore the rest of the response + } else { + self._redirectsFollowed = self._redirectsFollowed || 0 + // Be a good stream and emit end when the response is finished. + // Hack to emit end on close because of a core bug that never fires end + response.on('close', function () { + if (!self._ended) self.response.emit('end') + }) + + if (self.encoding) { + if (self.dests.length !== 0) { + console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") + } else { + response.setEncoding(self.encoding) + } + } + + self.dests.forEach(function (dest) { + self.pipeDest(dest) + }) + + response.on("data", function (chunk) { + self._destdata = true + self.emit("data", chunk) + }) + response.on("end", function (chunk) { + self._ended = true + self.emit("end", chunk) + }) + response.on("close", function () {self.emit("close")}) + + self.emit('response', response) + + if (self.callback) { + var buffer = [] + var bodyLen = 0 + self.on("data", function (chunk) { + buffer.push(chunk) + bodyLen += chunk.length + }) + self.on("end", function () { + if (self._aborted) return + + if (buffer.length && Buffer.isBuffer(buffer[0])) { + var body = new Buffer(bodyLen) + var i = 0 + buffer.forEach(function (chunk) { + chunk.copy(body, i, 0, chunk.length) + i += chunk.length + }) + if (self.encoding === null) { + response.body = body + } else { + response.body = body.toString() + } + } else if (buffer.length) { + response.body = buffer.join('') + } + + if (self._json) { + try { + response.body = JSON.parse(response.body) + } catch (e) {} + } + + self.emit('complete', response, response.body) + }) + } + } + }) + + if (self.timeout && !self.timeoutTimer) { + self.timeoutTimer = setTimeout(function () { + self.req.abort() + var e = new Error("ETIMEDOUT") + e.code = "ETIMEDOUT" + self.emit("error", e) + }, self.timeout) + + // Set additional timeout on socket - in case if remote + // server freeze after sending headers + if (self.req.setTimeout) { // only works on node 0.6+ + self.req.setTimeout(self.timeout, function () { + if (self.req) { + self.req.abort() + var e = new Error("ESOCKETTIMEDOUT") + e.code = "ESOCKETTIMEDOUT" + self.emit("error", e) + } + }) + } + } + + self.req.on('error', self.clientErrorHandler) + self.req.on('drain', function() { + self.emit('drain') + }) + + self.emit('request', self.req) +} + +Request.prototype.abort = function () { + this._aborted = true; + + if (this.req) { + this.req.abort() + } + else if (this.response) { + this.response.abort() + } + + this.emit("abort") +} + +Request.prototype.pipeDest = function (dest) { + var response = this.response + // Called after the response is received + if (dest.headers) { + dest.headers['content-type'] = response.headers['content-type'] + if (response.headers['content-length']) { + dest.headers['content-length'] = response.headers['content-length'] + } + } + if (dest.setHeader) { + for (var i in response.headers) { + dest.setHeader(i, response.headers[i]) + } + dest.statusCode = response.statusCode + } + if (this.pipefilter) this.pipefilter(response, dest) +} + +// Composable API +Request.prototype.setHeader = function (name, value, clobber) { + if (clobber === undefined) clobber = true + if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value + else this.headers[name] += ',' + value + return this +} +Request.prototype.setHeaders = function (headers) { + for (var i in headers) {this.setHeader(i, headers[i])} + return this +} +Request.prototype.qs = function (q, clobber) { + var base + if (!clobber && this.uri.query) base = qs.parse(this.uri.query) + else base = {} + + for (var i in q) { + base[i] = q[i] + } + + this.uri = url.parse(this.uri.href.split('?')[0] + '?' + qs.stringify(base)) + this.url = this.uri + + return this +} +Request.prototype.form = function (form) { + this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' + this.body = qs.stringify(form).toString('utf8') + return this +} +Request.prototype.multipart = function (multipart) { + var self = this + self.body = [] + + if (!self.headers['content-type']) { + self.headers['content-type'] = 'multipart/related; boundary=' + self.boundary; + } else { + self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary; + } + + console.log('boundary >> ' + self.boundary) + + if (!multipart.forEach) throw new Error('Argument error, options.multipart.') + + multipart.forEach(function (part) { + var body = part.body + if(body == null) throw Error('Body attribute missing in multipart.') + delete part.body + var preamble = '--' + self.boundary + '\r\n' + Object.keys(part).forEach(function (key) { + preamble += key + ': ' + part[key] + '\r\n' + }) + preamble += '\r\n' + self.body.push(new Buffer(preamble)) + self.body.push(new Buffer(body)) + self.body.push(new Buffer('\r\n')) + }) + self.body.push(new Buffer('--' + self.boundary + '--')) + return self +} +Request.prototype.json = function (val) { + this.setHeader('content-type', 'application/json') + this.setHeader('accept', 'application/json') + this._json = true + if (typeof val === 'boolean') { + if (typeof this.body === 'object') this.body = JSON.stringify(this.body) + } else { + this.body = JSON.stringify(val) + } + return this +} +Request.prototype.aws = function (opts, now) { + if (!now) { + this._aws = opts + return this + } + var date = new Date() + this.setHeader('date', date.toUTCString()) + this.setHeader('authorization', aws.authorization( + { key: opts.key + , secret: opts.secret + , verb: this.method + , date: date + , resource: aws.canonicalizeResource('/' + opts.bucket + this.path) + , contentType: this.headers['content-type'] || '' + , md5: this.headers['content-md5'] || '' + , amazonHeaders: aws.canonicalizeHeaders(this.headers) + } + )) + + return this +} + +Request.prototype.oauth = function (_oauth) { + var form + if (this.headers['content-type'] && + this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === + 'application/x-www-form-urlencoded' + ) { + form = qs.parse(this.body) + } + if (this.uri.query) { + form = qs.parse(this.uri.query) + } + if (!form) form = {} + var oa = {} + for (var i in form) oa[i] = form[i] + for (var i in _oauth) oa['oauth_'+i] = _oauth[i] + if (!oa.oauth_version) oa.oauth_version = '1.0' + if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString() + if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') + + oa.oauth_signature_method = 'HMAC-SHA1' + + var consumer_secret = oa.oauth_consumer_secret + delete oa.oauth_consumer_secret + var token_secret = oa.oauth_token_secret + delete oa.oauth_token_secret + + var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname + var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret) + + // oa.oauth_signature = signature + for (var i in form) { + if ( i.slice(0, 'oauth_') in _oauth) { + // skip + } else { + delete oa['oauth_'+i] + } + } + this.headers.Authorization = + 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') + this.headers.Authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"' + return this +} +Request.prototype.jar = function (jar) { + var cookies + + if (this._redirectsFollowed === 0) { + this.originalCookieHeader = this.headers.cookie + } + + if (jar === false) { + // disable cookies + cookies = false; + this._disableCookies = true; + } else if (jar) { + // fetch cookie from the user defined cookie jar + cookies = jar.get({ url: this.uri.href }) + } else { + // fetch cookie from the global cookie jar + cookies = cookieJar.get({ url: this.uri.href }) + } + + if (cookies && cookies.length) { + var cookieString = cookies.map(function (c) { + return c.name + "=" + c.value + }).join("; ") + + if (this.originalCookieHeader) { + // Don't overwrite existing Cookie header + this.headers.cookie = this.originalCookieHeader + '; ' + cookieString + } else { + this.headers.cookie = cookieString + } + } + this._jar = jar + return this +} + + +// Stream API +Request.prototype.pipe = function (dest, opts) { + if (this.response) { + if (this._destdata) { + throw new Error("You cannot pipe after data has been emitted from the response.") + } else if (this._ended) { + throw new Error("You cannot pipe after the response has been ended.") + } else { + stream.Stream.prototype.pipe.call(this, dest, opts) + this.pipeDest(dest) + return dest + } + } else { + this.dests.push(dest) + stream.Stream.prototype.pipe.call(this, dest, opts) + return dest + } +} +Request.prototype.write = function () { + if (!this._started) this.start() + return this.req.write.apply(this.req, arguments) +} +Request.prototype.end = function (chunk) { + if (chunk) this.write(chunk) + if (!this._started) this.start() + this.req.end() +} +Request.prototype.pause = function () { + if (!this.response) this._paused = true + else this.response.pause.apply(this.response, arguments) +} +Request.prototype.resume = function () { + if (!this.response) this._paused = false + else this.response.resume.apply(this.response, arguments) +} +Request.prototype.destroy = function () { + if (!this._ended) this.end() +} + +// organize params for post, put, head, del +function initParams(uri, options, callback) { + if ((typeof options === 'function') && !callback) callback = options; + if (options && typeof options === 'object') { + options.uri = uri; + } else if (typeof uri === 'string') { + options = {uri:uri}; + } else { + options = uri; + uri = options.uri; + } + return { uri: uri, options: options, callback: callback }; +} + +function request (uri, options, callback) { + if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.') + if ((typeof options === 'function') && !callback) callback = options; + if (options && typeof options === 'object') { + options.uri = uri; + } else if (typeof uri === 'string') { + options = {uri:uri}; + } else { + options = uri; + } + + if (callback) options.callback = callback; + var r = new Request(options) + return r +} + +module.exports = request + +request.defaults = function (options) { + var def = function (method) { + var d = function (uri, opts, callback) { + var params = initParams(uri, opts, callback); + for (var i in options) { + if (params.options[i] === undefined) params.options[i] = options[i] + } + return method(params.options, params.callback) + } + return d + } + var de = def(request) + de.get = def(request.get) + de.post = def(request.post) + de.put = def(request.put) + de.head = def(request.head) + de.del = def(request.del) + de.cookie = def(request.cookie) + de.jar = def(request.jar) + return de +} + +request.forever = function (agentOptions, optionsArg) { + var options = {} + if (optionsArg) { + for (option in optionsArg) { + options[option] = optionsArg[option] + } + } + if (agentOptions) options.agentOptions = agentOptions + options.forever = true + return request.defaults(options) +} + +request.get = request +request.post = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'POST'; + return request(params.uri || null, params.options, params.callback) +} +request.put = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'PUT' + return request(params.uri || null, params.options, params.callback) +} +request.head = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'HEAD' + if (params.options.body || + params.options.requestBodyStream || + (params.options.json && typeof params.options.json !== 'boolean') || + params.options.multipart) { + throw new Error("HTTP HEAD requests MUST NOT include a request body.") + } + return request(params.uri || null, params.options, params.callback) +} +request.del = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'DELETE' + return request(params.uri || null, params.options, params.callback) +} +request.jar = function () { + return new CookieJar +} +request.cookie = function (str) { + if (str && str.uri) str = str.uri + if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") + return new Cookie(str) +} + +// Safe toJSON + +function getSafe (self, uuid) { + if (typeof self === 'object' || typeof self === 'function') var safe = {} + if (Array.isArray(self)) var safe = [] + + var recurse = [] + + Object.defineProperty(self, uuid, {}) + + var attrs = Object.keys(self).filter(function (i) { + if (i === uuid) return false + if ( (typeof self[i] !== 'object' && typeof self[i] !== 'function') || self[i] === null) return true + return !(Object.getOwnPropertyDescriptor(self[i], uuid)) + }) + + + for (var i=0;i= 0.3.6" + ], + "main": "./main", + "scripts": { + "test": "node tests/run.js" + }, + "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n
\n  npm install request\n
\n\nOr from source:\n\n
\n  git clone git://github.com/mikeal/request.git \n  cd request\n  npm link\n
\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n if (!error && response.statusCode == 200) {\n console.log(body) // Print the google web page.\n }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n if (req.method === 'PUT') {\n req.pipe(request.put('http://mysite.com/doodle.png'))\n } else if (req.method === 'GET' || req.method === 'HEAD') {\n request.get('http://mysite.com/doodle.png').pipe(resp)\n } \n }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n var x = request('http://mysite.com/doodle.png')\n req.pipe(x)\n x.pipe(resp)\n }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n r.get('http://google.com/doodle.png').pipe(resp)\n }\n})\n```\n\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n , oauth =\n { callback: 'http://mysite.com/callback/'\n , consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n }\n , url = 'https://api.twitter.com/oauth/request_token'\n ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n // Assume by some stretch of magic you aquired the verifier\n var access_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: access_token.oauth_token\n , verifier: VERIFIER\n , token_secret: access_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/oauth/access_token'\n ;\n request.post({url:url, oauth:oauth}, function (e, r, body) {\n var perm_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: perm_token.oauth_token\n , token_secret: perm_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/1/users/show.json?'\n , params = \n { screen_name: perm_token.screen_name\n , user_id: perm_token.user_id\n }\n ;\n url += qs.stringify(params)\n request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n console.log(user)\n })\n })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for POST and PUT requests. Must be buffer or string.\n* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options) \n \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n var request = require('request')\n , rand = Math.floor(Math.random()*100000000).toString()\n ;\n request(\n { method: 'PUT'\n , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n , multipart: \n [ { 'content-type': 'application/json'\n , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n }\n , { body: 'I am an attachment' }\n ] \n }\n , function (error, response, body) {\n if(response.statusCode == 201){\n console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n } else {\n console.log('error: '+ response.statusCode)\n console.log(body)\n }\n }\n )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n request('http://images.google.com')\n})\n```\n", + "readmeFilename": "README.md", + "_id": "request@2.9.203", + "dist": { + "shasum": "141428406334b2bc7bbdf77f694321e57fb26db9" + }, + "_from": "request@2.9.x", + "_resolved": "https://registry.npmjs.org/request/-/request-2.9.203.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/googledoodle.png b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/googledoodle.png new file mode 100644 index 0000000..f80c9c5 Binary files /dev/null and b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/googledoodle.png differ diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/run.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/run.js new file mode 100644 index 0000000..f3a30d3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/run.js @@ -0,0 +1,39 @@ +var spawn = require('child_process').spawn + , exitCode = 0 + ; + +var tests = [ + 'test-body.js' + , 'test-cookie.js' + , 'test-cookiejar.js' + , 'test-defaults.js' + , 'test-errors.js' + , 'test-headers.js' + , 'test-httpModule.js' + , 'test-https.js' + , 'test-https-strict.js' + , 'test-oauth.js' + , 'test-pipes.js' + , 'test-pool.js' + , 'test-proxy.js' + , 'test-qs.js' + , 'test-redirect.js' + , 'test-timeout.js' + , 'test-toJSON.js' + , 'test-tunnel.js' +] + +var next = function () { + if (tests.length === 0) process.exit(exitCode); + + var file = tests.shift() + console.log(file) + var proc = spawn('node', [ 'tests/' + file ]) + proc.stdout.pipe(process.stdout) + proc.stderr.pipe(process.stderr) + proc.on('exit', function (code) { + exitCode += code || 0 + next() + }) +} +next() diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/server.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/server.js new file mode 100644 index 0000000..921f512 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/server.js @@ -0,0 +1,82 @@ +var fs = require('fs') + , http = require('http') + , path = require('path') + , https = require('https') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + ; + +exports.createServer = function (port) { + port = port || 6767 + var s = http.createServer(function (req, resp) { + s.emit(req.url, req, resp); + }) + s.port = port + s.url = 'http://localhost:'+port + return s; +} + +exports.createSSLServer = function(port, opts) { + port = port || 16767 + + var options = { 'key' : path.join(__dirname, 'ssl', 'test.key') + , 'cert': path.join(__dirname, 'ssl', 'test.crt') + } + if (opts) { + for (var i in opts) options[i] = opts[i] + } + + for (var i in options) { + options[i] = fs.readFileSync(options[i]) + } + + var s = https.createServer(options, function (req, resp) { + s.emit(req.url, req, resp); + }) + s.port = port + s.url = 'https://localhost:'+port + return s; +} + +exports.createPostStream = function (text) { + var postStream = new stream.Stream(); + postStream.writeable = true; + postStream.readable = true; + setTimeout(function () {postStream.emit('data', new Buffer(text)); postStream.emit('end')}, 0); + return postStream; +} +exports.createPostValidator = function (text) { + var l = function (req, resp) { + var r = ''; + req.on('data', function (chunk) {r += chunk}) + req.on('end', function () { + if (r !== text) console.log(r, text); + assert.equal(r, text) + resp.writeHead(200, {'content-type':'text/plain'}) + resp.write('OK') + resp.end() + }) + } + return l; +} +exports.createGetResponse = function (text, contentType) { + var l = function (req, resp) { + contentType = contentType || 'text/plain' + resp.writeHead(200, {'content-type':contentType}) + resp.write(text) + resp.end() + } + return l; +} +exports.createChunkResponse = function (chunks, contentType) { + var l = function (req, resp) { + contentType = contentType || 'text/plain' + resp.writeHead(200, {'content-type':contentType}) + chunks.forEach(function (chunk) { + resp.write(chunk) + }) + resp.end() + } + return l; +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/squid.conf b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/squid.conf new file mode 100644 index 0000000..0d4a3b6 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/squid.conf @@ -0,0 +1,77 @@ +# +# Recommended minimum configuration: +# +acl manager proto cache_object +acl localhost src 127.0.0.1/32 ::1 +acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1 + +# Example rule allowing access from your local networks. +# Adapt to list your (internal) IP networks from where browsing +# should be allowed +acl localnet src 10.0.0.0/8 # RFC1918 possible internal network +acl localnet src 172.16.0.0/12 # RFC1918 possible internal network +acl localnet src 192.168.0.0/16 # RFC1918 possible internal network +acl localnet src fc00::/7 # RFC 4193 local private network range +acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines + +acl SSL_ports port 443 +acl Safe_ports port 80 # http +acl Safe_ports port 21 # ftp +acl Safe_ports port 443 # https +acl Safe_ports port 70 # gopher +acl Safe_ports port 210 # wais +acl Safe_ports port 1025-65535 # unregistered ports +acl Safe_ports port 280 # http-mgmt +acl Safe_ports port 488 # gss-http +acl Safe_ports port 591 # filemaker +acl Safe_ports port 777 # multiling http +acl CONNECT method CONNECT + +# +# Recommended minimum Access Permission configuration: +# +# Only allow cachemgr access from localhost +http_access allow manager localhost +http_access deny manager + +# Deny requests to certain unsafe ports +http_access deny !Safe_ports + +# Deny CONNECT to other than secure SSL ports +#http_access deny CONNECT !SSL_ports + +# We strongly recommend the following be uncommented to protect innocent +# web applications running on the proxy server who think the only +# one who can access services on "localhost" is a local user +#http_access deny to_localhost + +# +# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS +# + +# Example rule allowing access from your local networks. +# Adapt localnet in the ACL section to list your (internal) IP networks +# from where browsing should be allowed +http_access allow localnet +http_access allow localhost + +# And finally deny all other access to this proxy +http_access deny all + +# Squid normally listens to port 3128 +http_port 3128 + +# We recommend you to use at least the following line. +hierarchy_stoplist cgi-bin ? + +# Uncomment and adjust the following to add a disk cache directory. +#cache_dir ufs /usr/local/var/cache 100 16 256 + +# Leave coredumps in the first cache dir +coredump_dir /usr/local/var/cache + +# Add any of your own refresh_pattern entries above these. +refresh_pattern ^ftp: 1440 20% 10080 +refresh_pattern ^gopher: 1440 0% 1440 +refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 +refresh_pattern . 0 20% 4320 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf new file mode 100644 index 0000000..425a889 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.cnf @@ -0,0 +1,20 @@ +[ req ] +default_bits = 1024 +days = 3650 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +output_password = password + +[ req_distinguished_name ] +C = US +ST = CA +L = Oakland +O = request +OU = request Certificate Authority +CN = requestCA +emailAddress = mikeal@mikealrogers.com + +[ req_attributes ] +challengePassword = password challenge + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crl new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt new file mode 100644 index 0000000..b4524e4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvTCCAiYCCQDn+P/MSbDsWjANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 +ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG +A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n +ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGiMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT +B3JlcXVlc3QxJjAkBgNVBAsTHXJlcXVlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MRIwEAYDVQQDEwlyZXF1ZXN0Q0ExJjAkBgkqhkiG9w0BCQEWF21pa2VhbEBtaWtl +YWxyb2dlcnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7t9pQUAK4 +5XJYTI6NrF0n3G2HZsfN+rPYSVzzL8SuVyb1tHXos+vbPm3NKI4E8X1yVAXU8CjJ +5SqXnp4DAypAhaseho81cbhk7LXUhFz78OvAa+OD+xTAEAnNQ8tGUr4VGyplEjfD +xsBVuqV2j8GPNTftr+drOCFlqfAgMrBn4wIDAQABMA0GCSqGSIb3DQEBBQUAA4GB +ADVdTlVAL45R+PACNS7Gs4o81CwSclukBu4FJbxrkd4xGQmurgfRrYYKjtqiopQm +D7ysRamS3HMN9/VKq2T7r3z1PMHPAy7zM4uoXbbaTKwlnX4j/8pGPn8Ca3qHXYlo +88L/OOPc6Di7i7qckS3HFbXQCTiULtxWmy97oEuTwrAj +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr new file mode 100644 index 0000000..e48c56e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.csr @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICBjCCAW8CAQAwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE +BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEmMCQGA1UECxMdcmVxdWVzdCBD +ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAMTCXJlcXVlc3RDQTEmMCQGCSqG +SIb3DQEJARYXbWlrZWFsQG1pa2VhbHJvZ2Vycy5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBALu32lBQArjlclhMjo2sXSfcbYdmx836s9hJXPMvxK5XJvW0 +deiz69s+bc0ojgTxfXJUBdTwKMnlKpeengMDKkCFqx6GjzVxuGTstdSEXPvw68Br +44P7FMAQCc1Dy0ZSvhUbKmUSN8PGwFW6pXaPwY81N+2v52s4IWWp8CAysGfjAgMB +AAGgIzAhBgkqhkiG9w0BCQcxFBMScGFzc3dvcmQgY2hhbGxlbmdlMA0GCSqGSIb3 +DQEBBQUAA4GBAGJO7grHeVHXetjHEK8urIxdnvfB2qeZeObz4GPKIkqUurjr0rfj +bA3EK1kDMR5aeQWR8RunixdM16Q6Ry0lEdLVWkdSwRN9dmirIHT9cypqnD/FYOia +SdezZ0lUzXgmJIwRYRwB1KSMMocIf52ll/xC2bEGg7/ZAEuAyAgcZV3X +-----END CERTIFICATE REQUEST----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key new file mode 100644 index 0000000..a53e7f7 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.key @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,C8B5887048377F02 + +nyD5ZH0Wup2uWsDvurq5mKDaDrf8lvNn9w0SH/ZkVnfR1/bkwqrFriqJWvZNUG+q +nS0iBYczsWLJnbub9a1zLOTENWUKVD5uqbC3aGHhnoUTNSa27DONgP8gHOn6JgR+ +GAKo01HCSTiVT4LjkwN337QKHnMP2fTzg+IoC/CigvMcq09hRLwU1/guq0GJKGwH +gTxYNuYmQC4Tjh8vdS4liF+Ve/P3qPR2CehZrIOkDT8PHJBGQJRo4xGUIB7Tpk38 +VCk+UZ0JCS2coY8VkY/9tqFJp/ZnnQQVmaNbdRqg7ECKL+bXnNo7yjzmazPZmPe3 +/ShbE0+CTt7LrjCaQAxWbeDzqfo1lQfgN1LulTm8MCXpQaJpv7v1VhIhQ7afjMYb +4thW/ypHPiYS2YJCAkAVlua9Oxzzh1qJoh8Df19iHtpd79Q77X/qf+1JvITlMu0U +gi7yEatmQcmYNws1mtTC1q2DXrO90c+NZ0LK/Alse6NRL/xiUdjug2iHeTf/idOR +Gg/5dSZbnnlj1E5zjSMDkzg6EHAFmHV4jYGSAFLEQgp4V3ZhMVoWZrvvSHgKV/Qh +FqrAK4INr1G2+/QTd09AIRzfy3/j6yD4A9iNaOsEf9Ua7Qh6RcALRCAZTWR5QtEf +dX+iSNJ4E85qXs0PqwkMDkoaxIJ+tmIRJY7y8oeylV8cfGAi8Soubt/i3SlR8IHC +uDMas/2OnwafK3N7ODeE1i7r7wkzQkSHaEz0TrF8XRnP25jAICCSLiMdAAjKfxVb +EvzsFSuAy3Jt6bU3hSLY9o4YVYKE+68ITMv9yNjvTsEiW+T+IbN34w== +-----END RSA PRIVATE KEY----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl new file mode 100644 index 0000000..17128db --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/ca.srl @@ -0,0 +1 @@ +ADF62016AA40C9C3 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf new file mode 100644 index 0000000..cd1fd1e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.cnf @@ -0,0 +1,19 @@ +[ req ] +default_bits = 1024 +days = 3650 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no + +[ req_distinguished_name ] +C = US +ST = CA +L = Oakland +O = request +OU = testing +CN = testing.request.mikealrogers.com +emailAddress = mikeal@mikealrogers.com + +[ req_attributes ] +challengePassword = password challenge + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt new file mode 100644 index 0000000..efe96ce --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICejCCAeMCCQCt9iAWqkDJwzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 +ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG +A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n +ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGjMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT +B3JlcXVlc3QxEDAOBgNVBAsTB3Rlc3RpbmcxKTAnBgNVBAMTIHRlc3RpbmcucmVx +dWVzdC5taWtlYWxyb2dlcnMuY29tMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlr +ZWFscm9nZXJzLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDgVl0jMumvOpmM +20W5v9yhGgZj8hPhEQF/N7yCBVBn/rWGYm70IHC8T/pR5c0LkWc5gdnCJEvKWQjh +DBKxZD8FAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEABShRkNgFbgs4vUWW9R9deNJj +7HJoiTmvkmoOC7QzcYkjdgHbOxsSq3rBnwxsVjY9PAtPwBn0GRspOeG7KzKRgySB +kb22LyrCFKbEOfKO/+CJc80ioK9zEPVjGsFMyAB+ftYRqM+s/4cQlTg/m89l01wC +yapjN3RxZbInGhWR+jA= +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr new file mode 100644 index 0000000..a8e7595 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.csr @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBgjCCASwCAQAwgaMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE +BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEQMA4GA1UECxMHdGVzdGluZzEp +MCcGA1UEAxMgdGVzdGluZy5yZXF1ZXN0Lm1pa2VhbHJvZ2Vycy5jb20xJjAkBgkq +hkiG9w0BCQEWF21pa2VhbEBtaWtlYWxyb2dlcnMuY29tMFwwDQYJKoZIhvcNAQEB +BQADSwAwSAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg +cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAaAjMCEGCSqGSIb3DQEJBzEU +ExJwYXNzd29yZCBjaGFsbGVuZ2UwDQYJKoZIhvcNAQEFBQADQQBD3E5WekQzCEJw +7yOcqvtPYIxGaX8gRKkYfLPoj3pm3GF5SGqtJKhylKfi89szHXgktnQgzff9FN+A +HidVJ/3u +-----END CERTIFICATE REQUEST----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.js new file mode 100644 index 0000000..05e21c1 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.js @@ -0,0 +1,28 @@ +var fs = require("fs") +var https = require("https") +var options = { key: fs.readFileSync("./server.key") + , cert: fs.readFileSync("./server.crt") } + +var server = https.createServer(options, function (req, res) { + res.writeHead(200) + res.end() + server.close() +}) +server.listen(1337) + +var ca = fs.readFileSync("./ca.crt") +var agent = new https.Agent({ host: "localhost", port: 1337, ca: ca }) + +https.request({ host: "localhost" + , method: "HEAD" + , port: 1337 + , headers: { host: "testing.request.mikealrogers.com" } + , agent: agent + , ca: [ ca ] + , path: "/" }, function (res) { + if (res.client.authorized) { + console.log("node test: OK") + } else { + throw new Error(res.client.authorizationError) + } +}).end() diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.key b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.key new file mode 100644 index 0000000..72d8698 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/ca/server.key @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg +cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAQJAK+r8ZM2sze8s7FRo/ApB +iRBtO9fCaIdJwbwJnXKo4RKwZDt1l2mm+fzZ+/QaQNjY1oTROkIIXmnwRvZWfYlW +gQIhAPKYsG+YSBN9o8Sdp1DMyZ/rUifKX3OE6q9tINkgajDVAiEA7Ltqh01+cnt0 +JEnud/8HHcuehUBLMofeg0G+gCnSbXECIQCqDvkXsWNNLnS/3lgsnvH0Baz4sbeJ +rjIpuVEeg8eM5QIgbu0+9JmOV6ybdmmiMV4yAncoF35R/iKGVHDZCAsQzDECIQDZ +0jGz22tlo5YMcYSqrdD3U4sds1pwiAaWFRbCunoUJw== +-----END RSA PRIVATE KEY----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt new file mode 100644 index 0000000..fde2fe9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/npm-ca.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x +IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w +bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y +MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV +BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj +YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA +aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE +OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz +Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl +y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC +l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv +yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl +ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.crt b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.crt new file mode 100644 index 0000000..b357f86 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICQzCCAawCCQCO/XWtRFck1jANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJU +SDEQMA4GA1UECBMHQmFuZ2tvazEOMAwGA1UEBxMFU2lsb20xGzAZBgNVBAoTElRo +ZSBSZXF1ZXN0IE1vZHVsZTEYMBYGA1UEAxMPcmVxdWVzdC5leGFtcGxlMB4XDTEx +MTIwMzAyMjkyM1oXDTIxMTEzMDAyMjkyM1owZjELMAkGA1UEBhMCVEgxEDAOBgNV +BAgTB0Jhbmdrb2sxDjAMBgNVBAcTBVNpbG9tMRswGQYDVQQKExJUaGUgUmVxdWVz +dCBNb2R1bGUxGDAWBgNVBAMTD3JlcXVlc3QuZXhhbXBsZTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAwmctddZqlA48+NXs0yOy92DijcQV1jf87zMiYAIlNUto +wghVbTWgJU5r0pdKrD16AptnWJTzKanhItEX8XCCPgsNkq1afgTtJP7rNkwu3xcj +eIMkhJg/ay4ZnkbnhYdsii5VTU5prix6AqWRAhbkBgoA+iVyHyof8wvZyKBoFTMC +AwEAATANBgkqhkiG9w0BAQUFAAOBgQB6BybMJbpeiABgihDfEVBcAjDoQ8gUMgwV +l4NulugfKTDmArqnR9aPd4ET5jX5dkMP4bwCHYsvrcYDeWEQy7x5WWuylOdKhua4 +L4cEi2uDCjqEErIG3cc1MCOk6Cl6Ld6tkIzQSf953qfdEACRytOeUqLNQcrXrqeE +c7U8F6MWLQ== +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.key b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.key new file mode 100644 index 0000000..b85810d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/ssl/test.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDCZy111mqUDjz41ezTI7L3YOKNxBXWN/zvMyJgAiU1S2jCCFVt +NaAlTmvSl0qsPXoCm2dYlPMpqeEi0RfxcII+Cw2SrVp+BO0k/us2TC7fFyN4gySE +mD9rLhmeRueFh2yKLlVNTmmuLHoCpZECFuQGCgD6JXIfKh/zC9nIoGgVMwIDAQAB +AoGBALXFwfUf8vHTSmGlrdZS2AGFPvEtuvldyoxi9K5u8xmdFCvxnOcLsF2RsTHt +Mu5QYWhUpNJoG+IGLTPf7RJdj/kNtEs7xXqWy4jR36kt5z5MJzqiK+QIgiO9UFWZ +fjUb6oeDnTIJA9YFBdYi97MDuL89iU/UK3LkJN3hd4rciSbpAkEA+MCkowF5kSFb +rkOTBYBXZfiAG78itDXN6DXmqb9XYY+YBh3BiQM28oxCeQYyFy6pk/nstnd4TXk6 +V/ryA2g5NwJBAMgRKTY9KvxJWbESeMEFe2iBIV0c26/72Amgi7ZKUCLukLfD4tLF ++WSZdmTbbqI1079YtwaiOVfiLm45Q/3B0eUCQAaQ/0eWSGE+Yi8tdXoVszjr4GXb +G81qBi91DMu6U1It+jNfIba+MPsiHLcZJMVb4/oWBNukN7bD1nhwFWdlnu0CQQCf +Is9WHkdvz2RxbZDxb8verz/7kXXJQJhx5+rZf7jIYFxqX3yvTNv3wf2jcctJaWlZ +fVZwB193YSivcgt778xlAkEAprYUz3jczjF5r2hrgbizPzPDR94tM5BTO3ki2v3w +kbf+j2g7FNAx6kZiVN8XwfLc8xEeUGiPKwtq3ddPDFh17w== +-----END RSA PRIVATE KEY----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-body.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-body.js new file mode 100644 index 0000000..e3fc75d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-body.js @@ -0,0 +1,80 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetBuffer : + { resp : server.createGetResponse(new Buffer("TESTING!")) + , encoding: null + , expectBody: new Buffer("TESTING!") + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookie.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookie.js new file mode 100644 index 0000000..6c6a7a7 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookie.js @@ -0,0 +1,29 @@ +var Cookie = require('../vendor/cookie') + , assert = require('assert'); + +var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT'; +var cookie = new Cookie(str); + +// test .toString() +assert.equal(cookie.toString(), str); + +// test .path +assert.equal(cookie.path, '/'); + +// test .httpOnly +assert.equal(cookie.httpOnly, true); + +// test .name +assert.equal(cookie.name, 'Sid'); + +// test .value +assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="'); + +// test .expires +assert.equal(cookie.expires instanceof Date, true); + +// test .path default +var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' }); +assert.equal(cookie.path, '/bar'); + +console.log('All tests passed'); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookiejar.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookiejar.js new file mode 100644 index 0000000..76fcd71 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-cookiejar.js @@ -0,0 +1,90 @@ +var Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + , assert = require('assert'); + +function expires(ms) { + return new Date(Date.now() + ms).toUTCString(); +} + +// test .get() expiration +(function() { + var jar = new Jar; + var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000)); + jar.add(cookie); + setTimeout(function(){ + var cookies = jar.get({ url: 'http://foo.com/foo' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], cookie); + setTimeout(function(){ + var cookies = jar.get({ url: 'http://foo.com/foo' }); + assert.equal(cookies.length, 0); + }, 1000); + }, 5); +})(); + +// test .get() path support +(function() { + var jar = new Jar; + var a = new Cookie('sid=1234; path=/'); + var b = new Cookie('sid=1111; path=/foo/bar'); + var c = new Cookie('sid=2222; path=/'); + jar.add(a); + jar.add(b); + jar.add(c); + + // should remove the duplicates + assert.equal(jar.cookies.length, 2); + + // same name, same path, latter prevails + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], c); + + // same name, diff path, path specifity prevails, latter prevails + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], b); + + var jar = new Jar; + var a = new Cookie('sid=1111; path=/foo/bar'); + var b = new Cookie('sid=1234; path=/'); + jar.add(a); + jar.add(b); + + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], a); + + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], b); + + var jar = new Jar; + var a = new Cookie('sid=1111; path=/foo/bar'); + var b = new Cookie('sid=3333; path=/foo/bar'); + var c = new Cookie('pid=3333; path=/foo/bar'); + var d = new Cookie('sid=2222; path=/foo/'); + var e = new Cookie('sid=1234; path=/'); + jar.add(a); + jar.add(b); + jar.add(c); + jar.add(d); + jar.add(e); + + var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); + assert.equal(cookies.length, 2); + assert.equal(cookies[0], b); + assert.equal(cookies[1], c); + + var cookies = jar.get({ url: 'http://foo.com/foo/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], d); + + var cookies = jar.get({ url: 'http://foo.com/' }); + assert.equal(cookies.length, 1); + assert.equal(cookies[0], e); +})(); + +setTimeout(function() { + console.log('All tests passed'); +}, 1200); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-defaults.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-defaults.js new file mode 100644 index 0000000..6c8b58f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-defaults.js @@ -0,0 +1,68 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +s.listen(s.port, function () { + var counter = 0; + s.on('/get', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'GET') + resp.writeHead(200, {'Content-Type': 'text/plain'}); + resp.end('TESTING!'); + }); + + // test get(string, function) + request.defaults({headers:{foo:"bar"}})(s.url + '/get', function (e, r, b){ + if (e) throw e; + assert.deepEqual("TESTING!", b); + counter += 1; + }); + + s.on('/post', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.headers['content-type'], 'application/json'); + assert.equal(req.method, 'POST') + resp.writeHead(200, {'Content-Type': 'application/json'}); + resp.end(JSON.stringify({foo:'bar'})); + }); + + // test post(string, object, function) + request.defaults({headers:{foo:"bar"}}).post(s.url + '/post', {json: true}, function (e, r, b){ + if (e) throw e; + assert.deepEqual('bar', b.foo); + counter += 1; + }); + + s.on('/del', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'DELETE') + resp.writeHead(200, {'Content-Type': 'application/json'}); + resp.end(JSON.stringify({foo:'bar'})); + }); + + // test .del(string, function) + request.defaults({headers:{foo:"bar"}, json:true}).del(s.url + '/del', function (e, r, b){ + if (e) throw e; + assert.deepEqual('bar', b.foo); + counter += 1; + }); + + s.on('/head', function (req, resp) { + assert.equal(req.headers.foo, 'bar'); + assert.equal(req.method, 'HEAD') + resp.writeHead(200, {'Content-Type': 'text/plain'}); + resp.end(); + }); + + // test head.(object, function) + request.defaults({headers:{foo:"bar"}}).head({uri: s.url + '/head'}, function (e, r, b){ + if (e) throw e; + counter += 1; + console.log(counter.toString() + " tests passed.") + s.close() + }); + +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-errors.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-errors.js new file mode 100644 index 0000000..1986a59 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-errors.js @@ -0,0 +1,37 @@ +var server = require('./server') + , events = require('events') + , assert = require('assert') + , request = require('../main.js') + ; + +var local = 'http://localhost:8888/asdf' + +try { + request({uri:local, body:{}}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Argument error, options.body.') +} + +try { + request({uri:local, multipart: 'foo'}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Argument error, options.multipart.') +} + +try { + request({uri:local, multipart: [{}]}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Body attribute missing in multipart.') +} + +try { + request(local, {multipart: [{}]}) + assert.fail("Should have throw") +} catch(e) { + assert.equal(e.message, 'Body attribute missing in multipart.') +} + +console.log("All tests passed.") diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-headers.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-headers.js new file mode 100644 index 0000000..31fe3f4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-headers.js @@ -0,0 +1,52 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + , s = server.createServer() + +s.listen(s.port, function () { + var serverUri = 'http://localhost:' + s.port + , numTests = 0 + , numOutstandingTests = 0 + + function createTest(requestObj, serverAssertFn) { + var testNumber = numTests; + numTests += 1; + numOutstandingTests += 1; + s.on('/' + testNumber, function (req, res) { + serverAssertFn(req, res); + res.writeHead(200); + res.end(); + }); + requestObj.url = serverUri + '/' + testNumber + request(requestObj, function (err, res, body) { + assert.ok(!err) + assert.equal(res.statusCode, 200) + numOutstandingTests -= 1 + if (numOutstandingTests === 0) { + console.log(numTests + ' tests passed.') + s.close() + } + }) + } + + // Issue #125: headers.cookie shouldn't be replaced when a cookie jar isn't specified + createTest({headers: {cookie: 'foo=bar'}}, function (req, res) { + assert.ok(req.headers.cookie) + assert.equal(req.headers.cookie, 'foo=bar') + }) + + // Issue #125: headers.cookie + cookie jar + var jar = new Jar() + jar.add(new Cookie('quux=baz')); + createTest({jar: jar, headers: {cookie: 'foo=bar'}}, function (req, res) { + assert.ok(req.headers.cookie) + assert.equal(req.headers.cookie, 'foo=bar; quux=baz') + }) + + // There should be no cookie header when neither headers.cookie nor a cookie jar is specified + createTest({}, function (req, res) { + assert.ok(!req.headers.cookie) + }) +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-httpModule.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-httpModule.js new file mode 100644 index 0000000..1866de2 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-httpModule.js @@ -0,0 +1,94 @@ +var http = require('http') + , https = require('https') + , server = require('./server') + , assert = require('assert') + , request = require('../main.js') + + +var faux_requests_made = {'http':0, 'https':0} +function wrap_request(name, module) { + // Just like the http or https module, but note when a request is made. + var wrapped = {} + Object.keys(module).forEach(function(key) { + var value = module[key]; + + if(key != 'request') + wrapped[key] = value; + else + wrapped[key] = function(options, callback) { + faux_requests_made[name] += 1 + return value.apply(this, arguments) + } + }) + + return wrapped; +} + + +var faux_http = wrap_request('http', http) + , faux_https = wrap_request('https', https) + , plain_server = server.createServer() + , https_server = server.createSSLServer() + + +plain_server.listen(plain_server.port, function() { + plain_server.on('/plain', function (req, res) { + res.writeHead(200) + res.end('plain') + }) + plain_server.on('/to_https', function (req, res) { + res.writeHead(301, {'location':'https://localhost:'+https_server.port + '/https'}) + res.end() + }) + + https_server.listen(https_server.port, function() { + https_server.on('/https', function (req, res) { + res.writeHead(200) + res.end('https') + }) + https_server.on('/to_plain', function (req, res) { + res.writeHead(302, {'location':'http://localhost:'+plain_server.port + '/plain'}) + res.end() + }) + + run_tests() + run_tests({}) + run_tests({'http:':faux_http}) + run_tests({'https:':faux_https}) + run_tests({'http:':faux_http, 'https:':faux_https}) + }) +}) + +function run_tests(httpModules) { + var to_https = 'http://localhost:'+plain_server.port+'/to_https' + var to_plain = 'https://localhost:'+https_server.port+'/to_plain' + + request(to_https, {'httpModules':httpModules}, function (er, res, body) { + assert.ok(!er, 'Bounce to SSL worked') + assert.equal(body, 'https', 'Received HTTPS server body') + done() + }) + + request(to_plain, {'httpModules':httpModules}, function (er, res, body) { + assert.ok(!er, 'Bounce to plaintext server worked') + assert.equal(body, 'plain', 'Received HTTPS server body') + done() + }) +} + + +var passed = 0; +function done() { + passed += 1 + var expected = 10 + + if(passed == expected) { + plain_server.close() + https_server.close() + + assert.equal(faux_requests_made.http, 4, 'Wrapped http module called appropriately') + assert.equal(faux_requests_made.https, 4, 'Wrapped https module called appropriately') + + console.log((expected+2) + ' tests passed.') + } +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https-strict.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https-strict.js new file mode 100644 index 0000000..f53fc14 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https-strict.js @@ -0,0 +1,97 @@ +// a test where we validate the siguature of the keys +// otherwise exactly the same as the ssl test + +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , fs = require('fs') + , path = require('path') + , opts = { key: path.resolve(__dirname, 'ssl/ca/server.key') + , cert: path.resolve(__dirname, 'ssl/ca/server.crt') } + , s = server.createSSLServer(null, opts) + , caFile = path.resolve(__dirname, 'ssl/ca/ca.crt') + , ca = fs.readFileSync(caFile) + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + 'Oh hi.' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': 'Oh hi.'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + test.strictSSL = true + test.ca = ca + test.headers = { host: 'testing.request.mikealrogers.com' } + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https.js new file mode 100644 index 0000000..df7330b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-https.js @@ -0,0 +1,86 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + +var s = server.createSSLServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + 'Oh hi.' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': 'Oh hi.'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + test.uri = s.url + '/' + i + request(test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-oauth.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-oauth.js new file mode 100644 index 0000000..72ca923 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-oauth.js @@ -0,0 +1,117 @@ +var hmacsign = require('../oauth').hmacsign + , assert = require('assert') + , qs = require('querystring') + , request = require('../main') + ; + +function getsignature (r) { + var sign + r.headers.Authorization.slice('OAuth '.length).replace(/,\ /g, ',').split(',').forEach(function (v) { + if (v.slice(0, 'oauth_signature="'.length) === 'oauth_signature="') sign = v.slice('oauth_signature="'.length, -1) + }) + return decodeURIComponent(sign) +} + +// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth + +var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', + { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' + , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' + , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' + , oauth_signature_method: 'HMAC-SHA1' + , oauth_timestamp: '1272323042' + , oauth_version: '1.0' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98") + +console.log(reqsign) +console.log('8wUi7m5HFQy76nowoCThusfgB+Q=') +assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=') + +var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token', + { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' + , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' + , oauth_signature_method: 'HMAC-SHA1' + , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' + , oauth_timestamp: '1272323047' + , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' + , oauth_version: '1.0' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") + +console.log(accsign) +console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') +assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') + +var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', + { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" + , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" + , oauth_signature_method: "HMAC-SHA1" + , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" + , oauth_timestamp: "1272325550" + , oauth_version: "1.0" + , status: 'setting up my twitter 私のさえずりを設定する' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA") + +console.log(upsign) +console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') +assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') + + +var rsign = request.post( + { url: 'https://api.twitter.com/oauth/request_token' + , oauth: + { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' + , consumer_key: 'GDdmIQH6jhtmLUypg82g' + , nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' + , timestamp: '1272323042' + , version: '1.0' + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + } + }) + +setTimeout(function () { + console.log(getsignature(rsign)) + assert.equal(reqsign, getsignature(rsign)) +}) + +var raccsign = request.post( + { url: 'https://api.twitter.com/oauth/access_token' + , oauth: + { consumer_key: 'GDdmIQH6jhtmLUypg82g' + , nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' + , signature_method: 'HMAC-SHA1' + , token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' + , timestamp: '1272323047' + , verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' + , version: '1.0' + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + , token_secret: "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA" + } + }) + +setTimeout(function () { + console.log(getsignature(raccsign)) + assert.equal(accsign, getsignature(raccsign)) +}, 1) + +var rupsign = request.post( + { url: 'http://api.twitter.com/1/statuses/update.json' + , oauth: + { consumer_key: "GDdmIQH6jhtmLUypg82g" + , nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" + , signature_method: "HMAC-SHA1" + , token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" + , timestamp: "1272325550" + , version: "1.0" + , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" + , token_secret: "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA" + } + , form: {status: 'setting up my twitter 私のさえずりを設定する'} + }) +setTimeout(function () { + console.log(getsignature(rupsign)) + assert.equal(upsign, getsignature(rupsign)) +}, 1) + + + + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-params.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-params.js new file mode 100644 index 0000000..8354f6d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-params.js @@ -0,0 +1,92 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); + +var tests = + { testGet : + { resp : server.createGetResponse("TESTING!") + , expectBody: "TESTING!" + } + , testGetChunkBreak : + { resp : server.createChunkResponse( + [ new Buffer([239]) + , new Buffer([163]) + , new Buffer([191]) + , new Buffer([206]) + , new Buffer([169]) + , new Buffer([226]) + , new Buffer([152]) + , new Buffer([131]) + ]) + , expectBody: "Ω☃" + } + , testGetBuffer : + { resp : server.createGetResponse(new Buffer("TESTING!")) + , encoding: null + , expectBody: new Buffer("TESTING!") + } + , testGetJSON : + { resp : server.createGetResponse('{"test":true}', 'application/json') + , json : true + , expectBody: {"test":true} + } + , testPutString : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : "PUTTINGDATA" + } + , testPutBuffer : + { resp : server.createPostValidator("PUTTINGDATA") + , method : "PUT" + , body : new Buffer("PUTTINGDATA") + } + , testPutJSON : + { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) + , method: "PUT" + , json: {foo: 'bar'} + } + , testPutMultipart : + { resp: server.createPostValidator( + '--frontier\r\n' + + 'content-type: text/html\r\n' + + '\r\n' + + 'Oh hi.' + + '\r\n--frontier\r\n\r\n' + + 'Oh hi.' + + '\r\n--frontier--' + ) + , method: "PUT" + , multipart: + [ {'content-type': 'text/html', 'body': 'Oh hi.'} + , {'body': 'Oh hi.'} + ] + } + } + +s.listen(s.port, function () { + + var counter = 0 + + for (i in tests) { + (function () { + var test = tests[i] + s.on('/'+i, test.resp) + //test.uri = s.url + '/' + i + request(s.url + '/' + i, test, function (err, resp, body) { + if (err) throw err + if (test.expectBody) { + assert.deepEqual(test.expectBody, body) + } + counter = counter - 1; + if (counter === 0) { + console.log(Object.keys(tests).length+" tests passed.") + s.close() + } + }) + counter++ + })() + } +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pipes.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pipes.js new file mode 100644 index 0000000..1869874 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pipes.js @@ -0,0 +1,202 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , fs = require('fs') + , request = require('../main.js') + , path = require('path') + , util = require('util') + ; + +var s = server.createServer(3453); + +function ValidationStream(str) { + this.str = str + this.buf = '' + this.on('data', function (data) { + this.buf += data + }) + this.on('end', function () { + assert.equal(this.str, this.buf) + }) + this.writable = true +} +util.inherits(ValidationStream, stream.Stream) +ValidationStream.prototype.write = function (chunk) { + this.emit('data', chunk) +} +ValidationStream.prototype.end = function (chunk) { + if (chunk) emit('data', chunk) + this.emit('end') +} + +s.listen(s.port, function () { + counter = 0; + + var check = function () { + counter = counter - 1 + if (counter === 0) { + console.log('All tests passed.') + setTimeout(function () { + process.exit(); + }, 500) + } + } + + // Test pipeing to a request object + s.once('/push', server.createPostValidator("mydata")); + + var mydata = new stream.Stream(); + mydata.readable = true + + counter++ + var r1 = request.put({url:'http://localhost:3453/push'}, function () { + check(); + }) + mydata.pipe(r1) + + mydata.emit('data', 'mydata'); + mydata.emit('end'); + + + // Test pipeing from a request object. + s.once('/pull', server.createGetResponse("mypulldata")); + + var mypulldata = new stream.Stream(); + mypulldata.writable = true + + counter++ + request({url:'http://localhost:3453/pull'}).pipe(mypulldata) + + var d = ''; + + mypulldata.write = function (chunk) { + d += chunk; + } + mypulldata.end = function () { + assert.equal(d, 'mypulldata'); + check(); + }; + + + s.on('/cat', function (req, resp) { + if (req.method === "GET") { + resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4}); + resp.end('asdf') + } else if (req.method === "PUT") { + assert.equal(req.headers['content-type'], 'text/plain-test'); + assert.equal(req.headers['content-length'], 4) + var validate = ''; + + req.on('data', function (chunk) {validate += chunk}) + req.on('end', function () { + resp.writeHead(201); + resp.end(); + assert.equal(validate, 'asdf'); + check(); + }) + } + }) + s.on('/pushjs', function (req, resp) { + if (req.method === "PUT") { + assert.equal(req.headers['content-type'], 'text/javascript'); + check(); + } + }) + s.on('/catresp', function (req, resp) { + request.get('http://localhost:3453/cat').pipe(resp) + }) + s.on('/doodle', function (req, resp) { + if (req.headers['x-oneline-proxy']) { + resp.setHeader('x-oneline-proxy', 'yup') + } + resp.writeHead('200', {'content-type':'image/png'}) + fs.createReadStream(path.join(__dirname, 'googledoodle.png')).pipe(resp) + }) + s.on('/onelineproxy', function (req, resp) { + var x = request('http://localhost:3453/doodle') + req.pipe(x) + x.pipe(resp) + }) + + counter++ + fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs')) + + counter++ + request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat')) + + counter++ + request.get('http://localhost:3453/catresp', function (e, resp, body) { + assert.equal(resp.headers['content-type'], 'text/plain-test'); + assert.equal(resp.headers['content-length'], 4) + check(); + }) + + var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.png')) + + counter++ + request.get('http://localhost:3453/doodle').pipe(doodleWrite) + + doodleWrite.on('close', function () { + assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.png')), fs.readFileSync(path.join(__dirname, 'test.png'))) + check() + }) + + process.on('exit', function () { + fs.unlinkSync(path.join(__dirname, 'test.png')) + }) + + counter++ + request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) { + assert.equal(resp.headers['x-oneline-proxy'], 'yup') + check() + }) + + s.on('/afterresponse', function (req, resp) { + resp.write('d') + resp.end() + }) + + counter++ + var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () { + var v = new ValidationStream('d') + afterresp.pipe(v) + v.on('end', check) + }) + + s.on('/forward1', function (req, resp) { + resp.writeHead(302, {location:'/forward2'}) + resp.end() + }) + s.on('/forward2', function (req, resp) { + resp.writeHead('200', {'content-type':'image/png'}) + resp.write('d') + resp.end() + }) + + counter++ + var validateForward = new ValidationStream('d') + validateForward.on('end', check) + request.get('http://localhost:3453/forward1').pipe(validateForward) + + // Test pipe options + s.once('/opts', server.createGetResponse('opts response')); + + var optsStream = new stream.Stream(); + optsStream.writable = true + + var optsData = ''; + optsStream.write = function (buf) { + optsData += buf; + if (optsData === 'opts response') { + setTimeout(check, 10); + } + } + + optsStream.end = function () { + assert.fail('end called') + }; + + counter++ + request({url:'http://localhost:3453/opts'}).pipe(optsStream, { end : false }) +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pool.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pool.js new file mode 100644 index 0000000..1e7d578 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-pool.js @@ -0,0 +1,16 @@ +var request = require('../main') + , http = require('http') + , assert = require('assert') + ; + +var s = http.createServer(function (req, resp) { + resp.statusCode = 200; + resp.end('asdf'); +}).listen(8080, function () { + request({'url': 'http://localhost:8080', 'pool': false}, function (e, resp) { + var agent = resp.request.agent; + assert.strictEqual(typeof agent, 'boolean'); + assert.strictEqual(agent, false); + s.close(); + }); +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-proxy.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-proxy.js new file mode 100644 index 0000000..647157c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-proxy.js @@ -0,0 +1,39 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , fs = require('fs') + , request = require('../main.js') + , path = require('path') + , util = require('util') + ; + +var port = 6768 + , called = false + , proxiedHost = 'google.com' + ; + +var s = server.createServer(port) +s.listen(port, function () { + s.on('http://google.com/', function (req, res) { + called = true + assert.equal(req.headers.host, proxiedHost) + res.writeHeader(200) + res.end() + }) + request ({ + url: 'http://'+proxiedHost, + proxy: 'http://localhost:'+port + /* + //should behave as if these arguments where passed: + url: 'http://localhost:'+port, + headers: {host: proxiedHost} + //*/ + }, function (err, res, body) { + s.close() + }) +}) + +process.on('exit', function () { + assert.ok(called, 'the request must be made to the proxy server') +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-qs.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-qs.js new file mode 100644 index 0000000..1aac22b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-qs.js @@ -0,0 +1,28 @@ +var request = request = require('../main.js') + , assert = require('assert') + ; + + +// Test adding a querystring +var req1 = request.get({ uri: 'http://www.google.com', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?q=search', req1.path) +}, 1) + +// Test replacing a querystring value +var req2 = request.get({ uri: 'http://www.google.com?q=abc', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?q=search', req2.path) +}, 1) + +// Test appending a querystring value to the ones present in the uri +var req3 = request.get({ uri: 'http://www.google.com?x=y', qs: { q : 'search' }}) +setTimeout(function() { + assert.equal('/?x=y&q=search', req3.path) +}, 1) + +// Test leaving a querystring alone +var req4 = request.get({ uri: 'http://www.google.com?x=y'}) +setTimeout(function() { + assert.equal('/?x=y', req4.path) +}, 1) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-redirect.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-redirect.js new file mode 100644 index 0000000..b84844a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-redirect.js @@ -0,0 +1,154 @@ +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , Cookie = require('../vendor/cookie') + , Jar = require('../vendor/cookie/jar') + +var s = server.createServer() + +s.listen(s.port, function () { + var server = 'http://localhost:' + s.port; + var hits = {} + var passed = 0; + + bouncer(301, 'temp') + bouncer(302, 'perm') + bouncer(302, 'nope') + + function bouncer(code, label) { + var landing = label+'_landing'; + + s.on('/'+label, function (req, res) { + hits[label] = true; + res.writeHead(code, { + 'location':server + '/'+landing, + 'set-cookie': 'ham=eggs' + }) + res.end() + }) + + s.on('/'+landing, function (req, res) { + if (req.method !== 'GET') { // We should only accept GET redirects + console.error("Got a non-GET request to the redirect destination URL"); + res.writeHead(400); + res.end(); + return; + } + // Make sure the cookie doesn't get included twice, see #139: + // Make sure cookies are set properly after redirect + assert.equal(req.headers.cookie, 'foo=bar; quux=baz; ham=eggs'); + hits[landing] = true; + res.writeHead(200) + res.end(landing) + }) + } + + // Permanent bounce + var jar = new Jar() + jar.add(new Cookie('quux=baz')) + request({uri: server+'/perm', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.perm, 'Original request is to /perm') + assert.ok(hits.perm_landing, 'Forward to permanent landing URL') + assert.equal(body, 'perm_landing', 'Got permanent landing content') + passed += 1 + done() + }) + + // Temporary bounce + request({uri: server+'/temp', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + // Prevent bouncing. + request({uri:server+'/nope', jar: jar, headers: {cookie: 'foo=bar'}, followRedirect:false}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 302) throw new Error('Status is not 302: '+res.statusCode) + assert.ok(hits.nope, 'Original request to /nope') + assert.ok(!hits.nope_landing, 'No chasing the redirect') + assert.equal(res.statusCode, 302, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow post redirects by default + request.post(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when post') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should follow post redirects when followAllRedirects true + request.post({uri:server+'/temp', followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + request.post({uri:server+'/temp', followAllRedirects:false, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow delete redirects by default + request.del(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode < 301) throw new Error('Status is not a redirect.') + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should not follow delete redirects even if followRedirect is set to true + request.del(server+'/temp', { followRedirect: true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') + assert.equal(res.statusCode, 301, 'Response is the bounce itself') + passed += 1 + done() + }) + + // Should follow delete redirects when followAllRedirects true + request.del(server+'/temp', {followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { + if (er) throw er + if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) + assert.ok(hits.temp, 'Original request is to /temp') + assert.ok(hits.temp_landing, 'Forward to temporary landing URL') + assert.equal(body, 'temp_landing', 'Got temporary landing content') + passed += 1 + done() + }) + + var reqs_done = 0; + function done() { + reqs_done += 1; + if(reqs_done == 9) { + console.log(passed + ' tests passed.') + s.close() + } + } +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-s3.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-s3.js new file mode 100644 index 0000000..5f59c4a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-s3.js @@ -0,0 +1,13 @@ +var request = require('../main') + +var r = request.get('https://log.curlybracecast.com.s3.amazonaws.com/', + { aws: + { key: 'AKIAI6KIQRRVMGK3WK5Q' + , secret: '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' + , bucket: 'log.curlybracecast.com' + } + }, function (e, resp, body) { + console.log(r.headers) + console.log(body) + } +) \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-timeout.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-timeout.js new file mode 100644 index 0000000..673f8ad --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-timeout.js @@ -0,0 +1,87 @@ +var server = require('./server') + , events = require('events') + , stream = require('stream') + , assert = require('assert') + , request = require('../main.js') + ; + +var s = server.createServer(); +var expectedBody = "waited"; +var remainingTests = 5; + +s.listen(s.port, function () { + // Request that waits for 200ms + s.on('/timeout', function (req, resp) { + setTimeout(function(){ + resp.writeHead(200, {'content-type':'text/plain'}) + resp.write(expectedBody) + resp.end() + }, 200); + }); + + // Scenario that should timeout + var shouldTimeout = { + url: s.url + "/timeout", + timeout:100 + } + + + request(shouldTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + + // Scenario that shouldn't timeout + var shouldntTimeout = { + url: s.url + "/timeout", + timeout:300 + } + + request(shouldntTimeout, function (err, resp, body) { + assert.equal(err, null); + assert.equal(expectedBody, body) + checkDone(); + }) + + // Scenario with no timeout set, so shouldn't timeout + var noTimeout = { + url: s.url + "/timeout" + } + + request(noTimeout, function (err, resp, body) { + assert.equal(err); + assert.equal(expectedBody, body) + checkDone(); + }) + + // Scenario with a negative timeout value, should be treated a zero or the minimum delay + var negativeTimeout = { + url: s.url + "/timeout", + timeout:-1000 + } + + request(negativeTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + // Scenario with a float timeout value, should be rounded by setTimeout anyway + var floatTimeout = { + url: s.url + "/timeout", + timeout: 100.76 + } + + request(floatTimeout, function (err, resp, body) { + assert.equal(err.code, "ETIMEDOUT"); + checkDone(); + }) + + function checkDone() { + if(--remainingTests == 0) { + s.close(); + console.log("All tests passed."); + } + } +}) + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-toJSON.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-toJSON.js new file mode 100644 index 0000000..b7c67ef --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-toJSON.js @@ -0,0 +1,14 @@ +var request = require('../main') + , http = require('http') + , assert = require('assert') + ; + +var s = http.createServer(function (req, resp) { + resp.statusCode = 200 + resp.end('asdf') +}).listen(8080, function () { + var r = request('http://localhost:8080', function (e, resp) { + assert.equal(JSON.parse(JSON.stringify(r)).response.statusCode, 200) + s.close() + }) +}) \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-tunnel.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-tunnel.js new file mode 100644 index 0000000..58131b9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tests/test-tunnel.js @@ -0,0 +1,61 @@ +// test that we can tunnel a https request over an http proxy +// keeping all the CA and whatnot intact. +// +// Note: this requires that squid is installed. +// If the proxy fails to start, we'll just log a warning and assume success. + +var server = require('./server') + , assert = require('assert') + , request = require('../main.js') + , fs = require('fs') + , path = require('path') + , caFile = path.resolve(__dirname, 'ssl/npm-ca.crt') + , ca = fs.readFileSync(caFile) + , child_process = require('child_process') + , sqConf = path.resolve(__dirname, 'squid.conf') + , sqArgs = ['-f', sqConf, '-N', '-d', '5'] + , proxy = 'http://localhost:3128' + , hadError = null + +var squid = child_process.spawn('squid', sqArgs); +var ready = false + +squid.stderr.on('data', function (c) { + console.error('SQUIDERR ' + c.toString().trim().split('\n') + .join('\nSQUIDERR ')) + ready = c.toString().match(/ready to serve requests/i) +}) + +squid.stdout.on('data', function (c) { + console.error('SQUIDOUT ' + c.toString().trim().split('\n') + .join('\nSQUIDOUT ')) +}) + +squid.on('exit', function (c) { + console.error('exit '+c) + if (c && !ready) { + console.error('squid must be installed to run this test.') + c = null + hadError = null + process.exit(0) + return + } + + if (c) { + hadError = hadError || new Error('Squid exited with '+c) + } + if (hadError) throw hadError +}) + +setTimeout(function F () { + if (!ready) return setTimeout(F, 100) + request({ uri: 'https://registry.npmjs.org/request/' + , proxy: 'http://localhost:3128' + , ca: ca + , json: true }, function (er, body) { + hadError = er + console.log(er || typeof body) + if (!er) console.log("ok") + squid.kill('SIGKILL') + }) +}, 100) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tunnel.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tunnel.js new file mode 100644 index 0000000..453786c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/tunnel.js @@ -0,0 +1,229 @@ +'use strict'; + +var net = require('net'); +var tls = require('tls'); +var http = require('http'); +var https = require('https'); +var events = require('events'); +var assert = require('assert'); +var util = require('util'); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port) { + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === host && pending.port === port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port) { + var self = this; + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push({host: host, port: port, request: req}); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket({host: host, port: port, request: req}, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, host, port); + } + + function onCloseOrRemove(err) { + self.removeSocket(); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false + }); + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode === 200) { + assert.equal(head.length, 0); + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + cb(socket); + } else { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + var error = new Error('tunneling socket could not be established, ' + + 'sutatusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, mergeOptions({}, self.options, { + socket: socket + })); + cb(secureSocket); + }); +} + + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/uuid.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/uuid.js new file mode 100644 index 0000000..1d83bd5 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/uuid.js @@ -0,0 +1,19 @@ +module.exports = function () { + var s = [], itoh = '0123456789ABCDEF'; + + // Make array of random hex digits. The UUID only has 32 digits in it, but we + // allocate an extra items to make room for the '-'s we'll be inserting. + for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10); + + // Conform to RFC-4122, section 4.4 + s[14] = 4; // Set 4 high bits of time_high field to version + s[19] = (s[19] & 0x3) | 0x8; // Specify 2 high bits of clock sequence + + // Convert to hex chars + for (var i = 0; i <36; i++) s[i] = itoh[s[i]]; + + // Insert '-'s + s[8] = s[13] = s[18] = s[23] = '-'; + + return s.join(''); +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/index.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/index.js new file mode 100644 index 0000000..ff44b3e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/index.js @@ -0,0 +1,65 @@ +/*! + * Tobi - Cookie + * Copyright(c) 2010 LearnBoost + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var url = require('url'); + +/** + * Initialize a new `Cookie` with the given cookie `str` and `req`. + * + * @param {String} str + * @param {IncomingRequest} req + * @api private + */ + +var Cookie = exports = module.exports = function Cookie(str, req) { + this.str = str; + + // Map the key/val pairs + str.split(/ *; */).reduce(function(obj, pair){ + var p = pair.indexOf('='); + var key = p > 0 ? pair.substring(0, p).trim() : pair.trim(); + var lowerCasedKey = key.toLowerCase(); + var value = p > 0 ? pair.substring(p + 1).trim() : true; + + if (!obj.name) { + // First key is the name + obj.name = key; + obj.value = value; + } + else if (lowerCasedKey === 'httponly') { + obj.httpOnly = value; + } + else { + obj[lowerCasedKey] = value; + } + return obj; + }, this); + + // Expires + this.expires = this.expires + ? new Date(this.expires) + : Infinity; + + // Default or trim path + this.path = this.path + ? this.path.trim(): req + ? url.parse(req.url).pathname: '/'; +}; + +/** + * Return the original cookie string. + * + * @return {String} + * @api public + */ + +Cookie.prototype.toString = function(){ + return this.str; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/jar.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/jar.js new file mode 100644 index 0000000..34920e0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/request/vendor/cookie/jar.js @@ -0,0 +1,72 @@ +/*! +* Tobi - CookieJar +* Copyright(c) 2010 LearnBoost +* MIT Licensed +*/ + +/** +* Module dependencies. +*/ + +var url = require('url'); + +/** +* Initialize a new `CookieJar`. +* +* @api private +*/ + +var CookieJar = exports = module.exports = function CookieJar() { + this.cookies = []; +}; + +/** +* Add the given `cookie` to the jar. +* +* @param {Cookie} cookie +* @api private +*/ + +CookieJar.prototype.add = function(cookie){ + this.cookies = this.cookies.filter(function(c){ + // Avoid duplication (same path, same name) + return !(c.name == cookie.name && c.path == cookie.path); + }); + this.cookies.push(cookie); +}; + +/** +* Get cookies for the given `req`. +* +* @param {IncomingRequest} req +* @return {Array} +* @api private +*/ + +CookieJar.prototype.get = function(req){ + var path = url.parse(req.url).pathname + , now = new Date + , specificity = {}; + return this.cookies.filter(function(cookie){ + if (0 == path.indexOf(cookie.path) && now < cookie.expires + && cookie.path.length > (specificity[cookie.name] || 0)) + return specificity[cookie.name] = cookie.path.length; + }); +}; + +/** +* Return Cookie string for the given `req`. +* +* @param {IncomingRequest} req +* @return {String} +* @api private +*/ + +CookieJar.prototype.cookieString = function(req){ + var cookies = this.get(req); + if (cookies.length) { + return cookies.map(function(cookie){ + return cookie.name + '=' + cookie.value; + }).join('; '); + } +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/.npmignore new file mode 100644 index 0000000..b59f7e3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/.npmignore @@ -0,0 +1 @@ +test/ \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/License b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/License new file mode 100644 index 0000000..11ec094 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Felix Geisendörfer (felix@debuggable.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Makefile b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Makefile new file mode 100644 index 0000000..a7ce31d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Makefile @@ -0,0 +1,11 @@ +SHELL := /bin/bash + +test: + @./test/run.js + +release: + git push + git push --tags + npm publish . + +.PHONY: test diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Readme.md b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Readme.md new file mode 100644 index 0000000..fcd1b97 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/Readme.md @@ -0,0 +1,98 @@ +# stack-trace + +Get v8 stack traces as an array of CallSite objects. + +## Install + +``` bash +npm install stack-trace +``` + +## Usage + +The stack-trace module makes it easy for you to capture the current stack: + +``` javascript +var stackTrace = require('stack-trace'); +var trace = stackTrace.get(); + +require('assert').strictEqual(trace[0].getFileName(), __filename); +``` + +However, sometimes you have already popped the stack you are interested in, +and all you have left is an `Error` object. This module can help: + +``` javascript +var stackTrace = require('stack-trace'); +var err = new Error('something went wrong'); +var trace = stackTrace.parse(err); + +require('assert').strictEqual(trace[0].getFileName(), __filename); +``` + +Please note that parsing the `Error#stack` property is not perfect, only +certain properties can be retrieved with it as noted in the API docs below. + +## Long stack traces + +stack-trace works great with [long-stack-traces][], when parsing an `err.stack` +that has crossed the event loop boundary, a `CallSite` object returning +`'----------------------------------------'` for `getFileName()` is created. +All other methods of the event loop boundary call site return `null`. + +[long-stack-traces]: https://github.com/tlrobinson/long-stack-traces + +## API + +### stackTrace.get([belowFn]) + +Returns an array of `CallSite` objects, where element `0` is the current call +site. + +When passing a function on the current stack as the `belowFn` parameter, the +returned array will only include `CallSite` objects below this function. + +### stackTrace.parse(err) + +Parses the `err.stack` property of an `Error` object into an array compatible +with those returned by `stackTrace.get()`. However, only the following methods +are implemented on the returned `CallSite` objects. + +* getTypeName +* getFunctionName +* getMethodName +* getFileName +* getLineNumber +* getColumnNumber +* isNative + +Note: Except `getFunctionName()`, all of the above methods return exactly the +same values as you would get from `stackTrace.get()`. `getFunctionName()` +is sometimes a little different, but still useful. + +### CallSite + +The official v8 CallSite object API can be found [here][v8stackapi]. A quick +excerpt: + +> A CallSite object defines the following methods: +> +> * **getThis**: returns the value of this +> * **getTypeName**: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property. +> * **getFunction**: returns the current function +> * **getFunctionName**: returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context. +> * **getMethodName**: returns the name of the property of this or one of its prototypes that holds the current function +> * **getFileName**: if this function was defined in a script returns the name of the script +> * **getLineNumber**: if this function was defined in a script returns the current line number +> * **getColumnNumber**: if this function was defined in a script returns the current column number +> * **getEvalOrigin**: if this function was created using a call to eval returns a CallSite object representing the location where eval was called +> * **isToplevel**: is this a toplevel invocation, that is, is this the global object? +> * **isEval**: does this call take place in code defined by a call to eval? +> * **isNative**: is this call in native V8 code? +> * **isConstructor**: is this a constructor call? + +[v8stackapi]: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + +## License + +stack-trace is licensed under the MIT license. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js new file mode 100644 index 0000000..583002b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js @@ -0,0 +1,111 @@ +exports.get = function(belowFn) { + var oldLimit = Error.stackTraceLimit; + Error.stackTraceLimit = Infinity; + + var dummyObject = {}; + + var v8Handler = Error.prepareStackTrace; + Error.prepareStackTrace = function(dummyObject, v8StackTrace) { + return v8StackTrace; + }; + Error.captureStackTrace(dummyObject, belowFn || exports.get); + + var v8StackTrace = dummyObject.stack; + Error.prepareStackTrace = v8Handler; + Error.stackTraceLimit = oldLimit; + + return v8StackTrace; +}; + +exports.parse = function(err) { + if (!err.stack) { + return []; + } + + var self = this; + var lines = err.stack.split('\n').slice(1); + + return lines + .map(function(line) { + if (line.match(/^\s*[-]{4,}$/)) { + return self._createParsedCallSite({ + fileName: line, + lineNumber: null, + functionName: null, + typeName: null, + methodName: null, + columnNumber: null, + 'native': null, + }); + } + + var lineMatch = line.match(/at (?:([^\s]+)\s+)?\(?(?:(.+?):(\d+):(\d+)|([^)]+))\)?/); + if (!lineMatch) { + return; + } + + var object = null; + var method = null; + var functionName = null; + var typeName = null; + var methodName = null; + var isNative = (lineMatch[5] === 'native'); + + if (lineMatch[1]) { + var methodMatch = lineMatch[1].match(/([^\.]+)(?:\.(.+))?/); + object = methodMatch[1]; + method = methodMatch[2]; + functionName = lineMatch[1]; + typeName = 'Object'; + } + + if (method) { + typeName = object; + methodName = method; + } + + if (method === '') { + methodName = null; + functionName = ''; + } + + var properties = { + fileName: lineMatch[2] || null, + lineNumber: parseInt(lineMatch[3], 10) || null, + functionName: functionName, + typeName: typeName, + methodName: methodName, + columnNumber: parseInt(lineMatch[4], 10) || null, + 'native': isNative, + }; + + return self._createParsedCallSite(properties); + }) + .filter(function(callSite) { + return !!callSite; + }); +}; + +exports._createParsedCallSite = function(properties) { + var methods = {}; + for (var property in properties) { + var prefix = 'get'; + if (property === 'native') { + prefix = 'is'; + } + var method = prefix + property.substr(0, 1).toUpperCase() + property.substr(1); + + (function(property) { + methods[method] = function() { + return properties[property]; + } + })(property); + } + + var callSite = Object.create(methods); + for (var property in properties) { + callSite[property] = properties[property]; + } + + return callSite; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/package.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/package.json new file mode 100644 index 0000000..3b1e6fa --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace/package.json @@ -0,0 +1,36 @@ +{ + "author": { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com", + "url": "http://debuggable.com/" + }, + "name": "stack-trace", + "description": "Get v8 stack traces as an array of CallSite objects.", + "version": "0.0.7", + "homepage": "https://github.com/felixge/node-stack-trace", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-stack-trace.git" + }, + "main": "./lib/stack-trace", + "engines": { + "node": "*" + }, + "dependencies": {}, + "devDependencies": { + "far": "0.0.3", + "long-stack-traces": "0.1.2" + }, + "readme": "# stack-trace\n\nGet v8 stack traces as an array of CallSite objects.\n\n## Install\n\n``` bash\nnpm install stack-trace\n```\n\n## Usage\n\nThe stack-trace module makes it easy for you to capture the current stack:\n\n``` javascript\nvar stackTrace = require('stack-trace');\nvar trace = stackTrace.get();\n\nrequire('assert').strictEqual(trace[0].getFileName(), __filename);\n```\n\nHowever, sometimes you have already popped the stack you are interested in,\nand all you have left is an `Error` object. This module can help:\n\n``` javascript\nvar stackTrace = require('stack-trace');\nvar err = new Error('something went wrong');\nvar trace = stackTrace.parse(err);\n\nrequire('assert').strictEqual(trace[0].getFileName(), __filename);\n```\n\nPlease note that parsing the `Error#stack` property is not perfect, only\ncertain properties can be retrieved with it as noted in the API docs below.\n\n## Long stack traces\n\nstack-trace works great with [long-stack-traces][], when parsing an `err.stack`\nthat has crossed the event loop boundary, a `CallSite` object returning\n`'----------------------------------------'` for `getFileName()` is created.\nAll other methods of the event loop boundary call site return `null`.\n\n[long-stack-traces]: https://github.com/tlrobinson/long-stack-traces\n\n## API\n\n### stackTrace.get([belowFn])\n\nReturns an array of `CallSite` objects, where element `0` is the current call\nsite.\n\nWhen passing a function on the current stack as the `belowFn` parameter, the\nreturned array will only include `CallSite` objects below this function.\n\n### stackTrace.parse(err)\n\nParses the `err.stack` property of an `Error` object into an array compatible\nwith those returned by `stackTrace.get()`. However, only the following methods\nare implemented on the returned `CallSite` objects.\n\n* getTypeName\n* getFunctionName\n* getMethodName\n* getFileName\n* getLineNumber\n* getColumnNumber\n* isNative\n\nNote: Except `getFunctionName()`, all of the above methods return exactly the\nsame values as you would get from `stackTrace.get()`. `getFunctionName()`\nis sometimes a little different, but still useful.\n\n### CallSite\n\nThe official v8 CallSite object API can be found [here][v8stackapi]. A quick\nexcerpt:\n\n> A CallSite object defines the following methods:\n>\n> * **getThis**: returns the value of this\n> * **getTypeName**: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.\n> * **getFunction**: returns the current function\n> * **getFunctionName**: returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context.\n> * **getMethodName**: returns the name of the property of this or one of its prototypes that holds the current function\n> * **getFileName**: if this function was defined in a script returns the name of the script\n> * **getLineNumber**: if this function was defined in a script returns the current line number\n> * **getColumnNumber**: if this function was defined in a script returns the current column number\n> * **getEvalOrigin**: if this function was created using a call to eval returns a CallSite object representing the location where eval was called\n> * **isToplevel**: is this a toplevel invocation, that is, is this the global object?\n> * **isEval**: does this call take place in code defined by a call to eval?\n> * **isNative**: is this call in native V8 code?\n> * **isConstructor**: is this a constructor call?\n\n[v8stackapi]: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi\n\n## License\n\nstack-trace is licensed under the MIT license.\n", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/felixge/node-stack-trace/issues" + }, + "_id": "stack-trace@0.0.7", + "dist": { + "shasum": "c6fda71bb9f0d2906613235299fb973f94b1b0fc" + }, + "_from": "stack-trace@0.0.x", + "_resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.7.tgz", + "scripts": {} +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/package.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/package.json new file mode 100644 index 0000000..a38e693 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/package.json @@ -0,0 +1,54 @@ +{ + "name": "winston", + "description": "A multi-transport async logging library for Node.js", + "version": "0.6.2", + "author": { + "name": "Nodejitsu Inc.", + "email": "info@nodejitsu.com" + }, + "maintainers": [ + { + "name": "indexzero", + "email": "charlie@nodejitsu.com" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/flatiron/winston.git" + }, + "keywords": [ + "logging", + "sysadmin", + "tools" + ], + "dependencies": { + "async": "0.1.x", + "colors": "0.x.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "pkginfo": "0.2.x", + "request": "2.9.x", + "stack-trace": "0.0.x" + }, + "devDependencies": { + "vows": "0.6.x" + }, + "main": "./lib/winston", + "scripts": { + "test": "vows --spec --isolate" + }, + "engines": { + "node": ">= 0.4.0" + }, + "readme": "# winston [![Build Status](https://secure.travis-ci.org/flatiron/winston.png)](http://travis-ci.org/flatiron/winston)\n\nA multi-transport async logging library for node.js. "CHILL WINSTON! ... I put it in the logs."\n\n## Motivation\nWinston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file.\n\nThere also seemed to be a lot of logging libraries out there that coupled their implementation of logging (i.e. how the logs are stored / indexed) to the API that they exposed to the programmer. This library aims to decouple those parts of the process to make it more flexible and extensible.\n\n## Usage\nThere are two different ways to use winston: directly via the default logger, or by instantiating your own Logger. The former is merely intended to be a convenient shared logger to use throughout your application if you so choose.\n\n* [Logging](#logging)\n * [Using the Default Logger](#using-the-default-logger)\n * [Instantiating your own Logger](#instantiating-your-own-logger)\n * [Logging with Metadata](#logging-with-metadata)\n* [Transports](https://github.com/flatiron/winston/blob/master/docs/transports.md)\n* [Profiling](#profiling)\n* [Streaming Logs](#streaming-logs)\n* [Querying Logs](#querying-logs) \n* [Exceptions](#exceptions)\n * [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston)\n * [To Exit or Not to Exit](#to-exit-or-not-to-exit)\n* [Logging Levels](#logging-levels)\n * [Using Logging Levels](#using-logging-levels)\n * [Using Custom Logging Levels](#using-custom-logging-levels)\n* [Further Reading](#further-reading)\n * [Events and Callbacks in Winston](#events-and-callbacks-in-winston)\n * [Working with multiple Loggers in winston](#working-with-multiple-loggers-in-winston)\n * [Using winston in a CLI tool](#using-winston-in-a-cli-tool)\n * [Extending another object with Logging](#extending-another-object-with-logging)\n * [Adding Custom Transports](#adding-custom-transports)\n\n## Logging\n\n### Using the Default Logger\nThe default logger is accessible through the winston module directly. Any method that you could call on an instance of a logger is available on the default logger:\n\n``` js\n var winston = require('winston');\n\n winston.log('info', 'Hello distributed log files!');\n winston.info('Hello again distributed logs');\n```\n\nBy default, only the Console transport is set on the default logger. You can add or remove transports via the add() and remove() methods:\n\n``` js\n winston.add(winston.transports.File, { filename: 'somefile.log' });\n winston.remove(winston.transports.Console);\n```\n\nFor more documenation about working with each individual transport supported by Winston see the \"Working with Transports\" section below.\n\n### Instantiating your own Logger\nIf you would prefer to manage the object lifetime of loggers you are free to instantiate them yourself:\n\n``` js\n var logger = new (winston.Logger)({\n transports: [\n new (winston.transports.Console)(),\n new (winston.transports.File)({ filename: 'somefile.log' })\n ]\n });\n```\n\nYou can work with this logger in the same way that you work with the default logger:\n\n``` js\n //\n // Logging\n //\n logger.log('info', 'Hello distributed log files!');\n logger.info('Hello again distributed logs');\n\n //\n // Adding / Removing Transports\n // (Yes It's chainable)\n //\n logger.add(winston.transports.File)\n .remove(winston.transports.Console);\n```\n\n### Logging with Metadata\nIn addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple:\n\n``` js\n winston.log('info', 'Test Log Message', { anything: 'This is metadata' });\n```\n\nThe way these objects is stored varies from transport to transport (to best support the storage mechanisms offered). Here's a quick summary of how each transports handles metadata:\n\n1. __Console:__ Logged via util.inspect(meta)\n2. __File:__ Logged via util.inspect(meta)\n\n## Profiling\nIn addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger:\n\n``` js\n //\n // Start profile of 'test'\n // Remark: Consider using Date.now() with async operations\n //\n winston.profile('test');\n\n setTimeout(function () {\n //\n // Stop profile of 'test'. Logging will now take place:\n // \"17 Jan 21:00:00 - info: test duration=1000ms\"\n //\n winston.profile('test');\n }, 1000);\n```\n\nAll profile messages are set to the 'info' by default and both message and metadata are optional There are no plans in the Roadmap to make this configurable, but I'm open to suggestions / issues.\n\n\n## Querying Logs\nWinston supports querying of logs with Loggly-like options.\nSpecifically: `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`.\n\n``` js\n var options = {\n from: new Date - 24 * 60 * 60 * 1000,\n until: new Date\n };\n\n //\n // Find items logged between today and yesterday.\n //\n winston.query(options, function (err, results) {\n if (err) {\n throw err;\n }\n \n console.log(results);\n });\n```\n\n## Streaming Logs\nStreaming allows you to stream your logs back from your chosen transport.\n\n``` js\n //\n // Start at the end.\n //\n winston.stream({ start: -1 }).on('log', function(log) {\n console.log(log);\n });\n```\n\n## Exceptions\n\n### Handling Uncaught Exceptions with winston\n\nWith `winston`, it is possible to catch and log `uncaughtException` events from your process. There are two distinct ways of enabling this functionality either through the default winston logger or your own logger instance.\n\nIf you want to use this feature with the default logger simply call `.handleExceptions()` with a transport instance.\n\n``` js\n //\n // You can add a separate exception logger by passing it to `.handleExceptions`\n //\n winston.handleExceptions(new winston.transports.File({ filename: 'path/to/exceptions.log' }))\n\n //\n // Alternatively you can set `.handleExceptions` to true when adding transports to winston\n //\n winston.add(winston.transports.File, {\n filename: 'path/to/all-logs.log',\n handleExceptions: true\n });\n```\n\n### To Exit or Not to Exit\n\nby default, winston will exit after logging an uncaughtException. if this is not the behavior you want,\nset `exitOnError = false`\n\n``` js\n var logger = new (winston.Logger)({ exitOnError: false });\n\n //\n // or, like this:\n //\n logger.exitOnError = false;\n```\n\nWhen working with custom logger instances, you can pass in separate transports to the `exceptionHandlers` property or set `.handleExceptions` on any transport.\n\nExample 1\n\n``` js\n var logger = new (winston.Logger)({\n transports: [\n new winston.transports.File({ filename: 'path/to/all-logs.log' })\n ]\n exceptionHandlers: [\n new winston.transports.File({ filename: 'path/to/exceptions.log' })\n ]\n });\n```\n\nExample 2\n\n```\nvar logger = new winston.Logger({\n transports: [\n new winston.transports.Console({\n handleExceptions: true,\n json: true\n })\n ],\n exitOnError: false\n});\n```\n\nThe `exitOnError` option can also be a function to prevent exit on only certain types of errors:\n\n``` js\n function ignoreEpipe(err) {\n return err.code !== 'EPIPE';\n }\n\n var logger = new (winston.Logger)({ exitOnError: ignoreEpipe });\n\n //\n // or, like this:\n //\n logger.exitOnError = ignoreEpipe;\n```\n\n## Logging Levels\n\n### Using Logging Levels\nSetting the level for your logging message can be accomplished in one of two ways. You can pass a string representing the logging level to the log() method or use the level specified methods defined on every winston Logger.\n\n``` js\n //\n // Any logger instance\n //\n logger.log('info', \"127.0.0.1 - there's no place like home\");\n logger.log('warn', \"127.0.0.1 - there's no place like home\");\n logger.log('error', \"127.0.0.1 - there's no place like home\");\n logger.info(\"127.0.0.1 - there's no place like home\");\n logger.warn(\"127.0.0.1 - there's no place like home\");\n logger.error(\"127.0.0.1 - there's no place like home\");\n\n //\n // Default logger\n //\n winston.log('info', \"127.0.0.1 - there's no place like home\");\n winston.info(\"127.0.0.1 - there's no place like home\");\n```\n\nWinston allows you to set a `level` on each transport that specifies the level of messages this transport should log. For example, you could log only errors to the console, with the full logs in a file:\n\n``` js\n var logger = new (winston.Logger)({\n transports: [\n new (winston.transports.Console)({ level: 'error' }),\n new (winston.transports.File)({ filename: 'somefile.log' })\n ]\n });\n```\n\nAs of 0.2.0, winston supports customizable logging levels, defaulting to [npm][0] style logging levels. Changing logging levels is easy:\n\n``` js\n //\n // Change levels on the default winston logger\n //\n winston.setLevels(winston.config.syslog.levels);\n\n //\n // Change levels on an instance of a logger\n //\n logger.setLevels(winston.config.syslog.levels);\n```\n\nCalling `.setLevels` on a logger will remove all of the previous helper methods for the old levels and define helper methods for the new levels. Thus, you should be careful about the logging statements you use when changing levels. For example, if you ran this code after changing to the syslog levels:\n\n``` js\n //\n // Logger does not have 'silly' defined since that level is not in the syslog levels\n //\n logger.silly('some silly message');\n```\n\n### Using Custom Logging Levels\nIn addition to the predefined `npm` and `syslog` levels available in Winston, you can also choose to define your own:\n\n``` js\n var myCustomLevels = {\n levels: {\n foo: 0,\n bar: 1,\n baz: 2,\n foobar: 3\n },\n colors: {\n foo: 'blue',\n bar: 'green',\n baz: 'yellow',\n foobar: 'red'\n }\n };\n\n var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels });\n customLevelLogger.foobar('some foobar level-ed message');\n```\n\nAlthough there is slight repetition in this data structure, it enables simple encapsulation if you not to have colors. If you do wish to have colors, in addition to passing the levels to the Logger itself, you must make winston aware of them:\n\n``` js\n //\n // Make winston aware of these colors\n //\n winston.addColors(myCustomLevels.colors);\n```\n\nThis enables transports with the 'colorize' option set to appropriately color the output of custom levels.\n\n## Further Reading\n\n### Events and Callbacks in Winston\nEach instance of winston.Logger is also an instance of an [EventEmitter][1]. A log event will be raised each time a transport successfully logs a message:\n\n``` js\n logger.on('logging', function (transport, level, msg, meta) {\n // [msg] and [meta] have now been logged at [level] to [transport]\n });\n\n logger.info('CHILL WINSTON!', { seriously: true });\n```\n\nIt is also worth mentioning that the logger also emits an 'error' event which you should handle or suppress if you don't want unhandled exceptions:\n\n``` js\n //\n // Handle errors\n //\n logger.on('error', function (err) { /* Do Something */ });\n\n //\n // Or just suppress them.\n //\n logger.emitErrs = false;\n```\n\nEvery logging method described in the previous section also takes an optional callback which will be called only when all of the transports have logged the specified message.\n\n``` js\n logger.info('CHILL WINSTON!', { seriously: true }, function (err, level, msg, meta) {\n // [msg] and [meta] have now been logged at [level] to **every** transport.\n });\n```\n\n### Working with multiple Loggers in winston\n\nOften in larger, more complex applications it is necessary to have multiple logger instances with different settings. Each logger is responsible for a different feature area (or category). This is exposed in `winston` in two ways: through `winston.loggers` and instances of `winston.Container`. In fact, `winston.loggers` is just a predefined instance of `winston.Container`:\n\n``` js\n var winston = require('winston');\n\n //\n // Configure the logger for `category1`\n //\n winston.loggers.add('category1', {\n console: {\n level: 'silly',\n colorize: 'true'\n },\n file: {\n filename: '/path/to/some/file'\n }\n });\n\n //\n // Configure the logger for `category2`\n //\n winston.loggers.add('category2', {\n couchdb: {\n host: '127.0.0.1',\n port: 5984\n }\n });\n```\n\nNow that your loggers are setup you can require winston _in any file in your application_ and access these pre-configured loggers:\n\n``` js\n var winston = require('winston');\n\n //\n // Grab your preconfigured logger\n //\n var category1 = winston.loggers.get('category1');\n\n category1.info('logging from your IoC container-based logger');\n```\n\nIf you prefer to manage the `Container` yourself you can simply instantiate one:\n\n``` js\n var winston = require('winston'),\n container = new winston.Container();\n\n container.add('category1', {\n console: {\n level: 'silly',\n colorize: 'true'\n },\n file: {\n filename: '/path/to/some/file'\n }\n });\n```\n\n### Sharing transports between Loggers in winston\n\n``` js\n var winston = require('winston');\n\n //\n // Setup transports to be shared across all loggers\n // in three ways:\n //\n // 1. By setting it on the default Container\n // 2. By passing `transports` into the constructor function of winston.Container\n // 3. By passing `transports` into the `.get()` or `.add()` methods\n //\n\n //\n // 1. By setting it on the default Container\n //\n winston.loggers.options.transports = [\n // Setup your shared transports here\n ];\n\n //\n // 2. By passing `transports` into the constructor function of winston.Container\n //\n var container = new winston.Container({\n transports: [\n // Setup your shared transports here\n ]\n });\n\n //\n // 3. By passing `transports` into the `.get()` or `.add()` methods\n //\n winston.loggers.add('some-category', {\n transports: [\n // Setup your shared transports here\n ]\n });\n\n container.add('some-category', {\n transports: [\n // Setup your shared transports here\n ]\n });\n```\n\n### Using winston in a CLI tool\nA common use-case for logging is output to a CLI tool. Winston has a special helper method which will pretty print output from your CLI tool. Here's an example from the [require-analyzer][2] written by [Nodejitsu][3]:\n\n```\n info: require-analyzer starting in /Users/Charlie/Nodejitsu/require-analyzer\n info: Found existing dependencies\n data: {\n data: colors: '0.x.x',\n data: eyes: '0.1.x',\n data: findit: '0.0.x',\n data: npm: '1.0.x',\n data: optimist: '0.2.x',\n data: semver: '1.0.x',\n data: winston: '0.2.x'\n data: }\n info: Analyzing dependencies...\n info: Done analyzing raw dependencies\n info: Retrieved packages from npm\n warn: No additional dependencies found\n```\n\nConfiguring output for this style is easy, just use the `.cli()` method on `winston` or an instance of `winston.Logger`:\n\n``` js\n var winston = require('winston');\n\n //\n // Configure CLI output on the default logger\n //\n winston.cli();\n\n //\n // Configure CLI on an instance of winston.Logger\n //\n var logger = new winston.Logger({\n transports: [\n new (winston.transports.Console)()\n ]\n });\n\n logger.cli();\n```\n\n### Extending another object with Logging\nOften in a given code base with lots of Loggers it is useful to add logging methods a different object so that these methods can be called with less syntax. Winston exposes this functionality via the 'extend' method:\n\n``` js\n var myObject = {};\n\n logger.extend(myObject);\n\n //\n // You can now call logger methods on 'myObject'\n //\n myObject.info('127.0.0.1 - there's no place like home');\n```\n\n## Working with Transports\nRight now there are four transports supported by winston core. If you have a transport you would like to add either open an issue or fork and submit a pull request. Commits are welcome, but I'll give you extra street cred if you __add tests too :D__\n \n1. __Console:__ Output to the terminal\n2. __Files:__ Append to a file\n3. __Loggly:__ Log to Logging-as-a-Service platform Loggly\n\n### Console Transport\n``` js\n winston.add(winston.transports.Console, options)\n```\n\nThe Console transport takes two simple options:\n\n* __level:__ Level of messages that this transport should log (default 'info').\n* __silent:__ Boolean flag indicating whether to suppress output (default false).\n* __colorize:__ Boolean flag indicating if we should colorize output (default false).\n* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps.\n\n*Metadata:* Logged via util.inspect(meta);\n\n### File Transport\n``` js\n winston.add(winston.transports.File, options)\n```\n\nThe File transport should really be the 'Stream' transport since it will accept any [WritableStream][14]. It is named such because it will also accept filenames via the 'filename' option:\n\n* __level:__ Level of messages that this transport should log.\n* __silent:__ Boolean flag indicating whether to suppress output.\n* __colorize:__ Boolean flag indicating if we should colorize output.\n* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default true). If function is specified, its return value will be used instead of timestamps.\n* __filename:__ The filename of the logfile to write output to.\n* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created.\n* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded.\n* __stream:__ The WriteableStream to write output to.\n* __json:__ If true, messages will be logged as JSON (default true).\n\n*Metadata:* Logged via util.inspect(meta);\n\n### Loggly Transport\n``` js\n var Loggly = require('winston-loggly').Loggly\n winston.add(Loggly, options);\n```\n\nThe Loggly transport is based on [Nodejitsu's][5] [node-loggly][6] implementation of the [Loggly][7] API. If you haven't heard of Loggly before, you should probably read their [value proposition][8]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required:\n\n* __level:__ Level of messages that this transport should log. \n* __subdomain:__ The subdomain of your Loggly account. *[required]*\n* __auth__: The authentication information for your Loggly account. *[required with inputName]*\n* __inputName:__ The name of the input this instance should log to.\n* __inputToken:__ The input token of the input this instance should log to.\n* __json:__ If true, messages will be sent to Loggly as JSON.\n\n*Metadata:* Logged in suggested [Loggly format][2]\n\n### Riak Transport\nAs of `0.3.0` the Riak transport has been broken out into a new module: [winston-riak][17]. Using it is just as easy:\n\n``` js\n var Riak = require('winston-riak').Riak;\n winston.add(Riak, options);\n```\n\nIn addition to the options accepted by the [riak-js][3] [client][4], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default:\n\n* __level:__ Level of messages that this transport should log.\n* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically.\n\n``` js\n // Use a single bucket for all your logs\n var singleBucketTransport = new (Riak)({ bucket: 'some-logs-go-here' });\n \n // Generate a dynamic bucket based on the date and level\n var dynamicBucketTransport = new (Riak)({\n bucket: function (level, msg, meta, now) {\n var d = new Date(now);\n return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-');\n }\n });\n```\n\n*Metadata:* Logged as JSON literal in Riak\n\n### MongoDB Transport\nAs of `0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][16]. Using it is just as easy:\n\n``` js\n var MongoDB = require('winston-mongodb').MongoDB;\n winston.add(MongoDB, options);\n```\n\nThe MongoDB transport takes the following options. 'db' is required:\n\n* __level:__ Level of messages that this transport should log. \n* __silent:__ Boolean flag indicating whether to suppress output.\n* __db:__ The name of the database you want to log to. *[required]*\n* __collection__: The name of the collection you want to store log messages in, defaults to 'log'.\n* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true.\n* __host:__ The host running MongoDB, defaults to localhost.\n* __port:__ The port on the host that MongoDB is running on, defaults to MongoDB's default port.\n\n*Metadata:* Logged as a native JSON object.\n\n### SimpleDB Transport\n\nThe [winston-simpledb][18] transport is just as easy:\n\n``` js\n var SimpleDB = require('winston-simpledb').SimpleDB;\n winston.add(SimpleDB, options);\n```\n\nThe SimpleDB transport takes the following options. All items marked with an asterisk are required:\n\n* __awsAccessKey__:* your AWS Access Key\n* __secretAccessKey__:* your AWS Secret Access Key\n* __awsAccountId__:* your AWS Account Id\n* __domainName__:* a string or function that returns the domain name to log to\n* __region__:* the region your domain resides in\n* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log\n\n*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item.\n\n### Mail Transport\n\nThe [winston-mail][19] is an email transport:\n\n``` js\n var Mail = require('winston-mail').Mail;\n winston.add(Mail, options);\n```\n\nThe Mail transport uses [emailjs](https://github.com/eleith/emailjs) behind the scenes. Options are the following:\n\n* __to:__ The address(es) you want to send to. *[required]*\n* __from:__ The address you want to send from. (default: `winston@[server-host-name]`)\n* __host:__ SMTP server hostname (default: localhost)\n* __port:__ SMTP port (default: 587 or 25)\n* __username__ User for server auth\n* __password__ Password for server auth\n* __ssl:__ Use SSL (boolean or object { key, ca, cert })\n* __tls:__ Boolean (if true, use starttls)\n* __level:__ Level of messages that this transport should log. \n* __silent:__ Boolean flag indicating whether to suppress output.\n\n*Metadata:* Stringified as JSON in email.\n\n### Amazon SNS (Simple Notification System) Transport\n\nThe [winston-sns][21] transport uses amazon SNS to send emails, texts, or a bunch of other notifications.\n\n``` js\n require('winston-sns').SNS;\n winston.add(winston.transports.SNS, options);\n```\n\nOptions:\n\n* __aws_key:__ Your Amazon Web Services Key. *[required]*\n* __aws_secret:__ Your Amazon Web Services Secret. *[required]*\n* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]*\n* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]*\n* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`)\n* __subject:__ Subject for notifications. (default: \"Winston Error Report\")\n* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: \"Level '%l' Error:\\n%e\\n\\nMetadata:\\n%m\")\n* __level:__ lowest level this transport will log. (default: `info`)\n\n### Graylog2 Transport\n\n[winston-graylog2][22] is a Graylog2 transport:\n\n``` js\n var Graylog2 = require('winston-graylog2').Graylog2;\n winston.add(Graylog2, options);\n```\n\nThe Graylog2 transport connects to a Graylog2 server over UDP using the following options:\n\n* __level:__ Level of messages this transport should log. (default: info)\n* __silent:__ Boolean flag indicating whether to suppress output. (default: false)\n\n* __graylogHost:__ IP address or hostname of the graylog2 server. (default: localhost)\n* __graylogPort:__ Port to send messages to on the graylog2 server. (default: 12201)\n* __graylogHostname:__ The hostname associated with graylog2 messages. (default: require('os').hostname())\n* __graylogFacility:__ The graylog2 facility to send log messages.. (default: nodejs)\n\n*Metadata:* Stringified as JSON in the full message GELF field.\n\n### Adding Custom Transports\nAdding a custom transport (say for one of the datastore on the Roadmap) is actually pretty easy. All you need to do is accept a couple of options, set a name, implement a log() method, and add it to the set of transports exposed by winston.\n\n``` js\n var util = require('util'),\n winston = require('winston');\n\n var CustomLogger = winston.transports.CustomerLogger = function (options) {\n //\n // Name this logger\n //\n this.name = 'customLogger';\n\n //\n // Set the level from your options\n //\n this.level = options.level || 'info';\n\n //\n // Configure your storage backing as you see fit\n //\n };\n\n //\n // Inherit from `winston.Transport` so you can take advantage\n // of the base functionality and `.handleExceptions()`.\n //\n util.inherits(CustomLogger, winston.Transport);\n\n CustomLogger.prototype.log = function (level, msg, meta, callback) {\n //\n // Store this message and metadata, maybe use some custom logic\n // then callback indicating success.\n //\n callback(null, true);\n };\n```\n\n### Inspirations\n1. [npm][0]\n2. [log.js][4]\n3. [socket.io][5]\n4. [node-rlog][6]\n5. [BigBrother][7]\n6. [Loggly][8]\n\n## Installation\n\n### Installing npm (node package manager)\n```\n curl http://npmjs.org/install.sh | sh\n```\n\n### Installing winston\n```\n [sudo] npm install winston\n```\n\n## Run Tests\nAll of the winston tests are written in [vows][9], and designed to be run with npm. \n\n``` bash\n $ npm test\n```\n\n#### Author: [Charlie Robbins](http://twitter.com/indexzero)\n#### Contributors: [Matthew Bergman](http://github.com/fotoverite), [Marak Squires](http://github.com/marak)\n\n[0]: https://github.com/isaacs/npm/blob/master/lib/utils/log.js\n[1]: http://nodejs.org/docs/v0.3.5/api/events.html#events.EventEmitter\n[2]: http://github.com/nodejitsu/require-analyzer\n[3]: http://nodejitsu.com\n[4]: https://github.com/visionmedia/log.js\n[5]: http://socket.io\n[6]: https://github.com/jbrisbin/node-rlog\n[7]: https://github.com/feisty/BigBrother\n[8]: http://loggly.com\n[9]: http://vowsjs.org\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/flatiron/winston/issues" + }, + "_id": "winston@0.6.2", + "dist": { + "shasum": "e54f5c026ccc82d252686e35d7630bea289fc23b" + }, + "_from": "winston@0.6.x", + "_resolved": "https://registry.npmjs.org/winston/-/winston-0.6.2.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/cli-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/cli-test.js new file mode 100644 index 0000000..365fba3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/cli-test.js @@ -0,0 +1,40 @@ +/* + * cli-test.js: Tests for the cli levels available in winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston/logger/cli').addBatch({ + "When an instance of winston.Logger": { + topic: function () { + return new winston.Logger({ + transports: [ + new winston.transports.Console() + ] + }) + }, + "the cli() method": { + "should set the appropriate values on the logger": function (logger) { + logger.cli(); + assert.isTrue(logger.padLevels); + assert.isTrue(logger.transports.console.colorize); + assert.isFalse(logger.transports.console.timestamp); + Object.keys(winston.config.cli.levels).forEach(function (level) { + assert.isNumber(logger.levels[level]); + }); + + Object.keys(winston.config.cli.colors).forEach(function (color) { + assert.isString(winston.config.allColors[color]); + }); + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/container-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/container-test.js new file mode 100644 index 0000000..2fcc26a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/container-test.js @@ -0,0 +1,99 @@ +/* + * container-test.js: Tests for the Container object + * + * (C) 2011 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + http = require('http'), + path = require('path'), + vows = require('vows'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston/container').addBatch({ + "An instance of winston.Container": { + topic: new winston.Container(), + "the add() method": { + topic: function (container) { + return container.add('default-test'); + }, + "should correctly instantiate a Logger": function (logger) { + assert.instanceOf(logger, winston.Logger); + }, + "the get() method": { + topic: function (logger, container) { + this.callback.apply(this, arguments); + }, + "should respond with the logger previously created": function (existing, container) { + var logger = container.get('default-test'); + assert.isTrue(existing === logger); + } + }, + "the has() method": { + topic: function (logger, container) { + this.callback.apply(this, arguments); + }, + "should indicate `default-test` logger exists": function (existing, container) { + assert.isTrue(container.has('default-test')); + }, + "should indicate `not-has` logger doesnt exists": function (existing, container) { + assert.isFalse(container.has('not-has')); + } + }, + "the close() method": { + topic: function (logger, container) { + this.callback.apply(this, arguments); + }, + "should remove the specified logger": function (logger, container) { + container.close('default-test'); + assert.isTrue(!container.loggers['default-test']); + } + } + } + }, + "An instance of winston.Container with explicit transports": { + topic: function () { + this.port = 9412; + this.transports = [ + new winston.transports.Webhook({ + port: this.port + }) + ]; + + this.container = new winston.Container({ + transports: this.transports + }); + + return null; + }, + "the get() method": { + topic: function (container) { + var server = http.createServer(function (req, res) { + res.end(); + }); + + server.listen(this.port, this.callback.bind(this, null)); + }, + "should add the logger correctly": function () { + this.someLogger = this.container.get('some-logger'); + assert.isObject(this.someLogger.transports); + assert.instanceOf(this.someLogger.transports['webhook'], winston.transports.Webhook); + assert.strictEqual(this.someLogger.transports['webhook'], this.transports[0]); + }, + "a second call to get()": { + "should respond with the same transport object": function () { + this.someOtherLogger = this.container.get('some-other-logger'); + + assert.isObject(this.someOtherLogger.transports); + assert.instanceOf(this.someOtherLogger.transports['webhook'], winston.transports.Webhook); + assert.strictEqual(this.someOtherLogger.transports['webhook'], this.transports[0]); + assert.strictEqual(this.someOtherLogger.transports['webhook'], this.someLogger.transports['webhook']); + } + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/custom-timestamp-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/custom-timestamp-test.js new file mode 100644 index 0000000..efdc40f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/custom-timestamp-test.js @@ -0,0 +1,62 @@ +/* + * custom-timestamp-test.js: Test function as timestamp option for transport `{ timestamp: function () {} }` + * + * (C) 2011 Charlie Robbins, Tom Shinnick + * MIT LICENSE + * + */ + +var assert = require('assert'), + events = require('events'), + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +function assertTimestamp (basename, options) { + var filename = path.join(__dirname, 'fixtures', 'logs', basename + '.log'); + + try { fs.unlinkSync(filename) } + catch (ex) { } + + return { + topic: function () { + options.filename = filename; + var transport = new (winston.transports.File)(options); + + // We must wait until transport file has emitted the 'flush' + // event to be sure the file has been created and written + transport.once('flush', this.callback.bind(this, null, filename)); + transport.log('info', 'When a fake tree falls in the forest...', null, function () {}); + }, + "should log with the appropriate timestamp": function (_, filename) { + var data = fs.readFileSync(filename, 'utf8'); + assert.isNotNull(data.match(options.pattern)); + } + } +} + +vows.describe('winston/transport/timestamp').addBatch({ + "When timestamp option is used": { + "with file transport": { + "with value set to false": assertTimestamp('noTimestamp', { + pattern: /^info\:/, + json: false, + timestamp: false + }), + "with value set to true ": assertTimestamp('defaultTimestamp', { + pattern: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/, + json: false, + timestamp: true + }), + "and function value": assertTimestamp('customTimestamp', { + pattern: /^\d{8}\./, + json: false, + timestamp: function () { + return '20110803.171657'; + } + }) + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/exception-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/exception-test.js new file mode 100644 index 0000000..3c3178e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/exception-test.js @@ -0,0 +1,47 @@ +/* + * exception-test.js: Tests for exception data gathering in winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston/exception').addBatch({ + "When using the winston exception module": { + "the getProcessInfo() method": { + topic: winston.exception.getProcessInfo(), + "should respond with the appropriate data": function (info) { + helpers.assertProcessInfo(info); + } + }, + "the getOsInfo() method": { + topic: winston.exception.getOsInfo(), + "should respond with the appropriate data": function (info) { + helpers.assertOsInfo(info); + } + }, + "the getTrace() method": { + topic: winston.exception.getTrace(new Error()), + "should have the appropriate info": function (trace) { + helpers.assertTrace(trace); + } + }, + "the getAllInfo() method": { + topic: winston.exception.getAllInfo(new Error()), + "should have the appropriate info": function (info) { + assert.isObject(info); + assert.isArray(info.stack); + helpers.assertDateInfo(info.date); + helpers.assertProcessInfo(info.process); + helpers.assertOsInfo(info.os); + helpers.assertTrace(info.trace); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/.gitkeep b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-cert.pem b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-cert.pem new file mode 100644 index 0000000..8e4354d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB7DCCAZYCCQC7gs0MDNn6MTANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJV +UzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZKb3llbnQxEDAO +BgNVBAsTB05vZGUuanMxDzANBgNVBAMTBmFnZW50MjEgMB4GCSqGSIb3DQEJARYR +cnlAdGlueWNsb3Vkcy5vcmcwHhcNMTEwMzE0MTgyOTEyWhcNMzgwNzI5MTgyOTEy +WjB9MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYD +VQQKEwZKb3llbnQxEDAOBgNVBAsTB05vZGUuanMxDzANBgNVBAMTBmFnZW50MjEg +MB4GCSqGSIb3DQEJARYRcnlAdGlueWNsb3Vkcy5vcmcwXDANBgkqhkiG9w0BAQEF +AANLADBIAkEAyXb8FrRdKbhrKLgLSsn61i1C7w7fVVVd7OQsmV/7p9WB2lWFiDlC +WKGU9SiIz/A6wNZDUAuc2E+VwtpCT561AQIDAQABMA0GCSqGSIb3DQEBBQUAA0EA +C8HzpuNhFLCI3A5KkBS5zHAQax6TFUOhbpBCR0aTDbJ6F1liDTK1lmU/BjvPoj+9 +1LHwrmh29rK8kBPEjmymCQ== +-----END CERTIFICATE----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-key.pem b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-key.pem new file mode 100644 index 0000000..522903c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/keys/agent2-key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOgIBAAJBAMl2/Ba0XSm4ayi4C0rJ+tYtQu8O31VVXezkLJlf+6fVgdpVhYg5 +QlihlPUoiM/wOsDWQ1ALnNhPlcLaQk+etQECAwEAAQJBAMT6Bf34+UHKY1ObpsbH +9u2jsVblFq1rWvs8GPMY6oertzvwm3DpuSUp7PTgOB1nLTLYtCERbQ4ovtN8tn3p +OHUCIQDzIEGsoCr5vlxXvy2zJwu+fxYuhTZWMVuo1397L0VyhwIhANQh+yzqUgaf +WRtSB4T2W7ADtJI35ET61jKBty3CqJY3AiAIwju7dVW3A5WeD6Qc1SZGKZvp9yCb +AFI2BfVwwaY11wIgXF3PeGcvACMyMWsuSv7aPXHfliswAbkWuzcwA4TW01ECIGWa +cgsDvVFxmfM5NPSuT/UDTa6R5BFISB5ea0N0AR3I +-----END RSA PRIVATE KEY----- diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/logs/.gitkeep b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/default-exceptions.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/default-exceptions.js new file mode 100644 index 0000000..ab26aa5 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/default-exceptions.js @@ -0,0 +1,21 @@ +/* + * default-exceptions.js: A test fixture for logging exceptions with the default winston logger. + * + * (C) 2011 Charlie Robbins + * MIT LICENCE + * + */ + +var path = require('path'), + winston = require('../../../lib/winston'); + +winston.handleExceptions([ + new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'logs', 'default-exception.log'), + handleExceptions: true + }) +]); + +setTimeout(function () { + throw new Error('OH NOES! It failed!'); +}, 1000); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/exit-on-error.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/exit-on-error.js new file mode 100644 index 0000000..fa3dd65 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/exit-on-error.js @@ -0,0 +1,25 @@ +/* + * default-exceptions.js: A test fixture for logging exceptions with the default winston logger. + * + * (C) 2011 Charlie Robbins + * MIT LICENCE + * + */ + +var path = require('path'), + winston = require('../../../lib/winston'); + +winston.exitOnError = function (err) { + return err.message !== 'Ignore this error'; +}; + +winston.handleExceptions([ + new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'logs', 'exit-on-error.log'), + handleExceptions: true + }) +]); + +setTimeout(function () { + throw new Error('Ignore this error'); +}, 1000); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/log-exceptions.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/log-exceptions.js new file mode 100644 index 0000000..43ce7eb --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/log-exceptions.js @@ -0,0 +1,25 @@ +/* + * log-exceptions.js: A test fixture for logging exceptions in winston. + * + * (C) 2011 Charlie Robbins + * MIT LICENCE + * + */ + +var path = require('path'), + winston = require('../../../lib/winston'); + +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'logs', 'exception.log'), + handleExceptions: true + }) + ] +}); + +logger.handleExceptions(); + +setTimeout(function () { + throw new Error('OH NOES! It failed!'); +}, 1000); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js new file mode 100644 index 0000000..5d722a7 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/fixtures/scripts/unhandle-exceptions.js @@ -0,0 +1,26 @@ +/* + * unhandle-exceptions.js: A test fixture for using `.unhandleExceptions()` winston. + * + * (C) 2011 Charlie Robbins + * MIT LICENCE + * + */ + +var path = require('path'), + winston = require('../../../lib/winston'); + +var logger = new (winston.Logger)({ + transports: [ + new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'logs', 'unhandle-exception.log'), + handleExceptions: true + }) + ] +}); + +logger.handleExceptions(); +logger.unhandleExceptions(); + +setTimeout(function () { + throw new Error('OH NOES! It failed!'); +}, 1000); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/helpers.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/helpers.js new file mode 100644 index 0000000..2564f79 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/helpers.js @@ -0,0 +1,173 @@ +/* + * helpers.js: Test helpers for winston + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + spawn = require('child_process').spawn, + util = require('util'), + vows = require('vows'), + winston = require('../lib/winston'); + +var helpers = exports; + +helpers.size = function (obj) { + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + size++; + } + } + + return size; +}; + +helpers.tryUnlink = function (file) { + try { fs.unlinkSync(file) } + catch (ex) { } +}; + +helpers.assertDateInfo = function (info) { + assert.isNumber(Date.parse(info)); +}; + +helpers.assertProcessInfo = function (info) { + assert.isNumber(info.pid); + assert.isNumber(info.uid); + assert.isNumber(info.gid); + assert.isString(info.cwd); + assert.isString(info.execPath); + assert.isString(info.version); + assert.isArray(info.argv); + assert.isObject(info.memoryUsage); +}; + +helpers.assertOsInfo = function (info) { + assert.isArray(info.loadavg); + assert.isNumber(info.uptime); +}; + +helpers.assertTrace = function (trace) { + trace.forEach(function (site) { + assert.isTrue(!site.column || typeof site.column === 'number'); + assert.isTrue(!site.line || typeof site.line === 'number'); + assert.isTrue(!site.file || typeof site.file === 'string'); + assert.isTrue(!site.method || typeof site.method === 'string'); + assert.isTrue(!site.function || typeof site.function === 'string'); + assert.isTrue(typeof site.native === 'boolean'); + }); +}; + +helpers.assertLogger = function (logger, level) { + assert.instanceOf(logger, winston.Logger); + assert.isFunction(logger.log); + assert.isFunction(logger.add); + assert.isFunction(logger.remove); + assert.equal(logger.level, level || "info"); + Object.keys(logger.levels).forEach(function (method) { + assert.isFunction(logger[method]); + }); +}; + +helpers.assertConsole = function (transport) { + assert.instanceOf(transport, winston.transports.Console); + assert.isFunction(transport.log); +}; + +helpers.assertFile = function (transport) { + assert.instanceOf(transport, winston.transports.File); + assert.isFunction(transport.log); +} + +helpers.assertWebhook = function (transport) { + assert.instanceOf(transport, winston.transports.Webhook); + assert.isFunction(transport.log); +}; + +helpers.assertCouchdb = function (transport) { + assert.instanceOf(transport, winston.transports.Couchdb); + assert.isFunction(transport.log); +}; + +helpers.assertHandleExceptions = function (options) { + return { + topic: function () { + var that = this, + child = spawn('node', [options.script]); + + helpers.tryUnlink(options.logfile); + child.on('exit', function () { + fs.readFile(options.logfile, that.callback); + }); + }, + "should save the error information to the specified file": function (err, data) { + assert.isTrue(!err); + data = JSON.parse(data); + + assert.isObject(data); + helpers.assertProcessInfo(data.process); + helpers.assertOsInfo(data.os); + helpers.assertTrace(data.trace); + } + } +} + +helpers.testNpmLevels = function (transport, assertMsg, assertFn) { + return helpers.testLevels(winston.config.npm.levels, transport, assertMsg, assertFn); +}; + +helpers.testSyslogLevels = function (transport, assertMsg, assertFn) { + return helpers.testLevels(winston.config.syslog.levels, transport, assertMsg, assertFn); +}; + +helpers.testLevels = function (levels, transport, assertMsg, assertFn) { + var tests = {}; + + Object.keys(levels).forEach(function (level) { + var test = { + topic: function () { + transport.log(level, 'test message', {}, this.callback.bind(this, null)); + } + }; + + test[assertMsg] = assertFn; + tests['with the ' + level + ' level'] = test; + }); + + var metadatatest = { + topic: function () { + transport.log('info', 'test message', { metadata: true }, this.callback.bind(this, null)); + } + }; + + metadatatest[assertMsg] = assertFn; + tests['when passed metadata'] = metadatatest; + + var primmetadatatest = { + topic: function () { + transport.log('info', 'test message', 'metadata', this.callback.bind(this, null)); + } + }; + + primmetadatatest[assertMsg] = assertFn; + tests['when passed primitive metadata'] = primmetadatatest; + + var circmetadata = { }; + circmetadata['metadata'] = circmetadata; + + var circmetadatatest = { + topic: function () { + transport.log('info', 'test message', circmetadata, this.callback.bind(this, null)); + } + }; + + circmetadatatest[assertMsg] = assertFn; + tests['when passed circular metadata'] = circmetadatatest; + + return tests; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/log-exception-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/log-exception-test.js new file mode 100644 index 0000000..164dcdf --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/log-exception-test.js @@ -0,0 +1,60 @@ +/* + * exception-test.js: Tests for exception data gathering in winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + path = require('path'), + fs = require('fs'), + spawn = require('child_process').spawn, + vows = require('vows'), + winston = require('../lib/winston'), + helpers = require('./helpers'), + exists = (fs.exists || path.exists); + +vows.describe('winston/logger/exceptions').addBatch({ + "When using winston": { + "the handleException() method": { + "with a custom winston.Logger instance": helpers.assertHandleExceptions({ + script: path.join(__dirname, 'fixtures', 'scripts', 'log-exceptions.js'), + logfile: path.join(__dirname, 'fixtures', 'logs', 'exception.log') + }), + "with the default winston logger": helpers.assertHandleExceptions({ + script: path.join(__dirname, 'fixtures', 'scripts', 'default-exceptions.js'), + logfile: path.join(__dirname, 'fixtures', 'logs', 'default-exception.log') + }), + "when a custom exitOnError function is set": { + topic: function () { + var that = this, + scriptDir = path.join(__dirname, 'fixtures', 'scripts'); + + that.child = spawn('node', [path.join(scriptDir, 'exit-on-error.js')]); + setTimeout(this.callback.bind(this), 1500); + }, + "should not exit the process": function () { + assert.isFalse(this.child.killed); + this.child.kill(); + } + } + }, + "the unhandleException() method": { + topic: function () { + var that = this, + child = spawn('node', [path.join(__dirname, 'fixtures', 'scripts', 'unhandle-exceptions.js')]), + exception = path.join(__dirname, 'fixtures', 'logs', 'unhandle-exception.log'); + + helpers.tryUnlink(exception); + child.on('exit', function () { + exists(exception, that.callback.bind(this, null)); + }); + }, + "should not write to the specified error file": function (err, exists) { + assert.isTrue(!err); + assert.isFalse(exists); + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/log-rewriter-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/log-rewriter-test.js new file mode 100644 index 0000000..f1deeba --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/log-rewriter-test.js @@ -0,0 +1,98 @@ +/* + * log-rewriter-test.js: Tests for rewriting metadata in winston. + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston/logger/rewriter').addBatch({ + "An instance of winston.Logger": { + topic: new (winston.Logger)({transports: [ + new (winston.transports.Console)({ level: 'info' }) + ]}), + "the addRewriter() method": { + topic: function (logger) { + logger.addRewriter(function (level, msg, meta) { + meta.level = level; + meta.msg = msg; + meta.foo = 'bar'; + return meta; + }); + return logger; + }, + "should add the rewriter": function (logger) { + assert.equal(helpers.size(logger.rewriters), 1); + }, + "the log() method": { + topic: function (logger) { + logger.once('logging', this.callback); + logger.log('info', 'test message', {"a": "b"}); + }, + "should run the rewriter": function (transport, level, msg, meta) { + assert.equal(meta.a, 'b'); + assert.equal(meta.level, 'info'); + assert.equal(meta.msg, 'test message'); + assert.equal(meta.foo, 'bar'); + } + } + } + } +}).addBatch({ + "An instance of winston.Logger with explicit rewriter": { + topic: new (winston.Logger)({transports: [ + new (winston.transports.Console)({ level: 'info'}) + ], rewriters: [ + function (level, msg, meta) { + meta.level = level; + meta.msg = msg; + meta.foo = 'bar'; + return meta; + } + ]}), + "should add the rewriter": function (logger) { + assert.equal(helpers.size(logger.rewriters), 1); + }, + "the log() method": { + topic: function (logger) { + logger.once('logging', this.callback); + logger.log('info', 'test message', {"a": "b"}); + }, + "should run the rewriter": function (transport, level, msg, meta) { + assert.equal(meta.a, 'b'); + assert.equal(meta.level, 'info'); + assert.equal(meta.msg, 'test message'); + assert.equal(meta.foo, 'bar'); + } + } + } +}).addBatch({ + "An instance of winston.Logger with rewriters": { + topic: new (winston.Logger)({transports: [ + new (winston.transports.Console)({ level: 'info' }) + ], rewriters: [ + function (level, msg, meta) { + meta.numbers.push(1); + return meta; + }, + function (level, msg, meta) { + meta.numbers.push(2); + return meta; + } + ]}), + "the log() method": { + topic: function (logger) { + logger.once('logging', this.callback); + logger.log('info', 'test message', {"numbers": [0]}); + }, + "should run the rewriters in correct order": function (transport, level, msg, meta) { + assert.deepEqual(meta.numbers, [0, 1, 2]); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/logger-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/logger-test.js new file mode 100644 index 0000000..0074f20 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/logger-test.js @@ -0,0 +1,200 @@ +/* + * logger-test.js: Tests for instances of the winston Logger + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../lib/winston'), + helpers = require('./helpers'), + transport = require('./transports/transport'); + +vows.describe('winton/logger').addBatch({ + "An instance of winston.Logger": { + topic: new (winston.Logger)({ transports: [new (winston.transports.Console)({ level: 'info' })] }), + "should have the correct methods / properties defined": function (logger) { + helpers.assertLogger(logger); + }, + "the add() with an unsupported transport": { + "should throw an error": function () { + assert.throws(function () { logger.add('unsupported') }, Error); + } + } + } +}).addBatch({ + "An instance of winston.Logger with no transports": { + topic: new (winston.Logger)({ emitErrs: true }), + "the log() method should throw an error": function (logger) { + assert.throws(function () { logger.log('anything') }, Error); + }, + "the extend() method called on an empty object": { + topic: function (logger) { + var empty = {}; + logger.extend(empty); + return empty; + }, + "should define the appropriate methods": function (extended) { + ['log', 'profile', 'startTimer'].concat(Object.keys(winston.config.npm.levels)).forEach(function (method) { + assert.isFunction(extended[method]); + }); + } + }, + "the add() method with a supported transport": { + topic: function (logger) { + return logger.add(winston.transports.Console); + }, + "should add the console Transport onto transports": function (logger) { + assert.equal(helpers.size(logger.transports), 1); + helpers.assertConsole(logger.transports.console); + }, + "should throw an error when the same Transport is added": function (logger) { + assert.throws(function () { logger.add(winston.transports.Console) }, Error); + }, + "the log() method": { + topic: function (logger) { + logger.once('logging', this.callback); + logger.log('info', 'test message'); + }, + "should emit the 'log' event with the appropriate transport": function (transport, ign) { + helpers.assertConsole(transport); + } + }, + "the profile() method": { + "when passed a callback": { + topic: function (logger) { + var that = this; + logger.profile('test1'); + setTimeout(function () { + logger.profile('test1', function (err, level, msg, meta) { + that.callback(err, level, msg, meta, logger); + }); + }, 1000); + }, + "should respond with the appropriate profile message": function (err, level, msg, meta, logger) { + assert.isNull(err); + assert.equal(level, 'info'); + assert.match(meta.duration, /(\d+)ms/); + assert.isTrue(typeof logger.profilers['test'] === 'undefined'); + } + }, + "when not passed a callback": { + topic: function (logger) { + var that = this; + logger.profile('test2'); + logger.once('logging', that.callback.bind(null, null)); + setTimeout(function () { + logger.profile('test2'); + }, 1000); + }, + "should respond with the appropriate profile message": function (err, transport, level, msg, meta) { + assert.isNull(err); + assert.equal(level, 'info'); + assert.match(meta.duration, /(\d+)ms/); + } + } + }, + "the startTimer() method": { + "when passed a callback": { + topic: function (logger) { + var that = this; + var timer = logger.startTimer() + setTimeout(function () { + timer.done('test', function (err, level, msg, meta) { + that.callback(err, level, msg, meta, logger); + }); + }, 1000); + }, + "should respond with the appropriate message": function (err, level, msg, meta, logger) { + assert.isNull(err); + assert.equal(level, 'info'); + assert.match(meta.duration, /(\d+)ms/); + } + }, + "when not passed a callback": { + topic: function (logger) { + var that = this; + var timer = logger.startTimer() + logger.once('logging', that.callback.bind(null, null)); + setTimeout(function () { + timer.done(); + }, 1000); + }, + "should respond with the appropriate message": function (err, transport, level, msg, meta) { + assert.isNull(err); + assert.equal(level, 'info'); + assert.match(meta.duration, /(\d+)ms/); + + var duration = parseInt(meta.duration); + assert.isNumber(duration); + assert.isTrue(duration > 900 && duration < 1100); + } + } + }, + "and adding an additional transport": { + topic: function (logger) { + return logger.add(winston.transports.File, { + filename: path.join(__dirname, 'fixtures', 'logs', 'testfile2.log') + }); + }, + "should be able to add multiple transports": function (logger) { + assert.equal(helpers.size(logger.transports), 2); + helpers.assertConsole(logger.transports.console); + helpers.assertFile(logger.transports.file); + } + } + } + } +}).addBatch({ + "The winston logger": { + topic: new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.File)({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log' )}) + ] + }), + "should return have two transports": function (logger) { + assert.equal(helpers.size(logger.transports), 2); + }, + "the remove() with an unadded transport": { + "should throw an Error": function (logger) { + assert.throws(function () { logger.remove(winston.transports.Webhook) }, Error); + } + }, + "the remove() method with an added transport": { + topic: function (logger) { + return logger.remove(winston.transports.Console); + }, + "should remove the Console transport from transports": function (logger) { + assert.equal(helpers.size(logger.transports), 1); + helpers.assertFile(logger.transports.file); + }, + "and removing an additional transport": { + topic: function (logger) { + return logger.remove(winston.transports.File); + }, + "should remove File transport from transports": function (logger) { + assert.equal(helpers.size(logger.transports), 0); + } + } + } + } +}).addBatch({ + "The winston logger": { + topic: new (winston.Logger)({ + transports: [ + new (winston.transports.Console)(), + new (winston.transports.File)({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log' )}) + ] + }), + "the clear() method": { + "should remove all transports": function (logger) { + logger.clear(); + assert.equal(helpers.size(logger.transports), 0); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/console-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/console-test.js new file mode 100644 index 0000000..07f5a6e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/console-test.js @@ -0,0 +1,39 @@ +/* + * console-test.js: Tests for instances of the Console transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var npmTransport = new (winston.transports.Console)(), + syslogTransport = new (winston.transports.Console)({ levels: winston.config.syslog.levels }); + +vows.describe('winston/transports/console').addBatch({ + "An instance of the Console Transport": { + "with npm levels": { + "should have the proper methods defined": function () { + helpers.assertConsole(npmTransport); + }, + "the log() method": helpers.testNpmLevels(npmTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "with syslog levels": { + "should have the proper methods defined": function () { + helpers.assertConsole(syslogTransport); + }, + "the log() method": helpers.testSyslogLevels(syslogTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-maxfiles-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-maxfiles-test.js new file mode 100644 index 0000000..a9fa89e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-maxfiles-test.js @@ -0,0 +1,102 @@ +/* + * file-maxfiles-test.js: Tests for instances of the File transport setting the max file size, + * and setting a number for max files created. + * maxSize * maxFiles = total storage used by winston. + * + * (C) 2011 Daniel Aristizabal + * MIT LICENSE + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var maxfilesTransport = new winston.transports.File({ + timestamp: false, + json: false, + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles.log'), + maxsize: 4096, + maxFiles: 3 +}); + +vows.describe('winston/transports/file/maxfiles').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + topic: maxfilesTransport, + "should be a valid transporter": function (transportTest) { + helpers.assertFile(transportTest); + }, + "should set the maxFiles option correctly": function (transportTest) { + assert.isNumber(transportTest.maxFiles); + } + }, + "when delete old test files": { + topic: function () { + exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles*'), this.callback); + }, + "and when passed more files than the maxFiles": { + topic: function () { + var that = this, + created = 0; + + function data(ch) { + return new Array(1018).join(String.fromCharCode(65 + ch)); + }; + + function logKbytes(kbytes, txt) { + // + // With no timestamp and at the info level, + // winston adds exactly 7 characters: + // [info](4)[ :](2)[\n](1) + // + for (var i = 0; i < kbytes; i++) { + maxfilesTransport.log('info', data(txt), null, function () { }); + } + } + + maxfilesTransport.on('logged', function () { + if (++created === 6) { + return that.callback(); + } + + logKbytes(4, created); + }); + + logKbytes(4, created); + }, + "should be only 3 files called 5.log, 4.log and 3.log": function () { + for (var num = 0; num < 6; num++) { + var file = !num ? 'testmaxfiles.log' : 'testmaxfiles' + num + '.log', + fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file); + + // There should be no files with that name + if (num >= 0 && num < 3) { + return assert.throws(function () { + fs.statSync(file); + }, Error); + } + + // The other files should be exist + assert.doesNotThrow(function () { + fs.statSync(file); + }, Error); + } + }, + "should have the correct content": function () { + ['D', 'E', 'F'].forEach(function (name, inx) { + var counter = inx + 3, + logsDir = path.join(__dirname, '..', 'fixtures', 'logs'), + content = fs.readFileSync(path.join(logsDir, 'testmaxfiles' + counter + '.log'), 'utf-8'); + // The content minus the 7 characters added by winston + assert.lengthOf(content.match(new RegExp(name, 'g')), 4068); + }); + } + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-maxsize-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-maxsize-test.js new file mode 100644 index 0000000..7d20e08 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-maxsize-test.js @@ -0,0 +1,82 @@ +/* + * file-test.js: Tests for instances of the File transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var maxsizeTransport = new winston.transports.File({ + timestamp: false, + json: false, + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize.log'), + maxsize: 4096 +}); + +vows.describe('winston/transports/file/maxsize').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + "the log() method": { + topic: function () { + exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize*'), this.callback); + }, + "when passed more than the maxsize": { + topic: function () { + var that = this, + data = new Array(1018).join('-'); + + // + // Setup a list of files which we will later stat. + // + that.files = []; + + function logKbytes (kbytes) { + // + // With no timestamp and at the info level, + // winston adds exactly 7 characters: + // [info](4)[ :](2)[\n](1) + // + for (var i = 0; i < kbytes; i++) { + maxsizeTransport.log('info', data, null, function () { }); + } + } + + maxsizeTransport.on('open', function (file) { + var match = file.match(/(\d+)\.log$/), + count = match ? match[1] : 0; + + that.files.push(file); + + if (that.files.length === 5) { + return that.callback(); + } + + logKbytes(4); + }); + + logKbytes(4); + }, + "should create multiple files correctly": function () { + this.files.forEach(function (file) { + try { + var stats = fs.statSync(file); + assert.equal(stats.size, 4096); + } + catch (ex) { + assert.isNull(ex); + } + }); + } + } + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-test.js new file mode 100644 index 0000000..2039b03 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/file-test.js @@ -0,0 +1,60 @@ +/* + * file-test.js: Tests for instances of the File transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + fs = require('fs'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var transport = require('./transport'); + +var stream = fs.createWriteStream( + path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log') + ), + fileTransport = new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfilename.log') + }), + streamTransport = new (winston.transports.File)({ stream: stream }); + +vows.describe('winston/transports/file').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + "should have the proper methods defined": function () { + helpers.assertFile(fileTransport); + }, + "the log() method": helpers.testNpmLevels(fileTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "when passed a valid file stream": { + "should have the proper methods defined": function () { + helpers.assertFile(streamTransport); + }, + "the log() method": helpers.testNpmLevels(streamTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + } +}).addBatch({ + "These tests have a non-deterministic end": { + topic: function () { + setTimeout(this.callback, 200); + }, + "and this should be fixed before releasing": function () { + assert.isTrue(true); + } + } +}).addBatch({ + "An instance of the File Transport": transport(winston.transports.File, { + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log') + }) +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/transport.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/transport.js new file mode 100644 index 0000000..89b1eab --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/transport.js @@ -0,0 +1,212 @@ +var assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +module.exports = function (transport, options) { + var logger = transport instanceof winston.Logger + ? transport + : new winston.Logger({ + transports: [ + new transport(options) + ] + }); + + // hack to fix transports that don't log + // any unit of time smaller than seconds + var common = require('../../lib/winston/common'); + common.timestamp = function() { + return new Date().toISOString(); + }; + + var transport = logger.transports[logger._names[0]]; + + var out = { + 'topic': logger, + 'when passed valid options': { + 'should have the proper methods defined': function () { + switch (transport.name) { + case 'console': + helpers.assertConsole(transport); + break; + case 'file': + helpers.assertFile(transport); + break; + case 'webhook': + helpers.assertWebhook(transport); + break; + case 'couchdb': + helpers.assertCouchdb(transport); + break; + } + assert.isFunction(transport.log); + } + }, + 'the log() method': helpers.testNpmLevels(transport, + 'should respond with true', function (ign, err, logged) { + assert.isNull(err); + assert.isNotNull(logged); + } + ), + 'the stream() method': { + 'using no options': { + 'topic': function () { + if (!transport.stream) return; + + logger.log('info', 'hello world', {}); + + var cb = this.callback, + j = 10, + i = 10, + results = [], + stream = logger.stream(); + + stream.on('log', function (log) { + results.push(log); + results.stream = stream; + if (!--j) cb(null, results); + }); + + stream.on('error', function () {}); + + while (i--) logger.log('info', 'hello world ' + i, {}); + }, + 'should stream logs': function (err, results) { + if (!transport.stream) return; + assert.isNull(err); + results.forEach(function (log) { + assert.ok(log.message.indexOf('hello world') === 0 + || log.message.indexOf('test message') === 0); + }); + results.stream.destroy(); + } + }, + 'using the `start` option': { + 'topic': function () { + if (!transport.stream) return; + + var cb = this.callback, + stream = logger.stream({ start: 0 }); + + stream.on('log', function (log) { + log.stream = stream; + if (cb) cb(null, log); + cb = null; + }); + }, + 'should stream logs': function (err, log) { + if (!transport.stream) return; + assert.isNull(err); + assert.isNotNull(log.message); + log.stream.destroy(); + } + } + }, + 'after the logs have flushed': { + topic: function () { + setTimeout(this.callback, 1000); + }, + 'the query() method': { + 'using basic querying': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query(cb); + }); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + var log = results.pop(); + assert.ok(log.message.indexOf('hello world') === 0 + || log.message.indexOf('test message') === 0); + } + }, + 'using the `rows` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query({ rows: 1 }, cb); + }); + }, + 'should return one result': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.equal(results.length, 1); + } + }, + 'using `fields` and `order` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query({ order: 'asc', fields: ['timestamp'] }, cb); + }); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.equal(Object.keys(results[0]).length, 1); + assert.ok(new Date(results.shift().timestamp) + < new Date(results.pop().timestamp)); + } + }, + 'using the `from` and `until` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + var start = new Date - 100 * 1000; + var end = new Date + 100 * 1000; + logger.query({ from: start, until: end }, cb); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.ok(results.length >= 1); + } + }, + 'using a bad `from` and `until` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'bad from and until', {}, function () { + var now = new Date + 1000000; + logger.query({ from: now, until: now }, cb); + }); + }, + 'should return no results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + results = [results.filter(function(log) { + return log.message === 'bad from and until'; + }).pop()]; + assert.isUndefined(results[0]); + } + } + } + } + }; + + return out; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/webhook-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/webhook-test.js new file mode 100644 index 0000000..8d40c00 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/transports/webhook-test.js @@ -0,0 +1,125 @@ +/* + * webhook-test.js: Tests for instances of the Webhook transport + * + * (C) 2011 Marak Squires + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + fs = require('fs'), + http = require('http'), + https = require('https'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var webhookTransport = new (winston.transports.Webhook)({ + "host": "localhost", + "port": 8080, + "path": "/winston-test" +}); + +var httpsWebhookTransport = new (winston.transports.Webhook)({ + "host": "localhost", + "port": 8081, + "path": "/winston-test", + "ssl": true +}); + +var authWebhookTransport = new (winston.transports.Webhook)({ + "host": "localhost", + "port": 8080, + "path": "/winston-auth-test", + "auth": { + "username": "winston", + "password": "churchill" + } +}); + +var requestsAuthenticated = true; + +var server = http.createServer(function (req, res) { + if (req.url == '/winston-auth-test') { + // + // Test if request has been correctly authenticated + // + // Strip 'Basic' from Authorization header + var signature = req.headers['authorization'].substr(6); + requestsAuthenticated = requestsAuthenticated && + new Buffer(signature, 'base64').toString('utf8') == 'winston:churchill'; + } + res.end(); +}); + +server.listen(8080); + + +var httpsServer = https.createServer({ + cert: fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'keys', 'agent2-cert.pem')), + key: fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'keys', 'agent2-key.pem')) +}, function (req, res) { + res.end(); +}); + +httpsServer.listen(8081); + +vows.describe('winston/transports/webhook').addBatch({ + "An instance of the Webhook Transport": { + "when passed valid options": { + "should have the proper methods defined": function () { + helpers.assertWebhook(webhookTransport); + }, + "the log() method": helpers.testNpmLevels(webhookTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + }, + "An https instance of the Webhook Transport": { + "when passed valid options": { + "should have the proper methods defined": function () { + helpers.assertWebhook(httpsWebhookTransport); + }, + "the log() method": helpers.testNpmLevels(httpsWebhookTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + }, + "An http Basic Auth instance of the Webhook Transport": { + "when passed valid options": { + "should have the proper methods defined": function () { + helpers.assertWebhook(authWebhookTransport); + }, + "the log() method": helpers.testNpmLevels(authWebhookTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + } +}).addBatch({ + "When the tests are over": { + topic: function () { + // + // Delay destruction of the server since the + // WebHook transport responds before the request + // has actually be completed. + // + setTimeout(this.callback, 1000); + }, + "the server should cleanup": function () { + server.close(); + }, + "requests have been correctly authenticated": function () { + assert.ok(requestsAuthenticated); + } + } +}).addBatch({ + // "An instance of the Webhook Transport": transport(winston.transports.Webhook, { + // "host": "localhost", + // "port": 8080, + // "path": "/winston-test" + // }) +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/winston-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/winston-test.js new file mode 100644 index 0000000..7105329 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/node_modules/winston/test/winston-test.js @@ -0,0 +1,98 @@ +/* + * logger-test.js: Tests for instances of the winston Logger + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var fs = require('fs'), + path = require('path'), + vows = require('vows'), + http = require('http'), + assert = require('assert'), + winston = require('../lib/winston'), + helpers = require('./helpers'); + +vows.describe('winston').addBatch({ + "The winston module": { + topic: function () { + winston.default.transports.console.level = 'silly'; + return null; + }, + "should have the correct methods defined": function () { + assert.isObject(winston.transports); + assert.isFunction(winston.Transport); + assert.isTrue(!winston.transports.Transport); + assert.isFunction(winston.transports.Console); + assert.isFunction(winston.transports.File); + assert.isFunction(winston.transports.Webhook); + assert.isObject(winston.default.transports.console); + assert.isFalse(winston.emitErrs); + assert.isObject(winston.config); + ['Logger', 'add', 'remove', 'extend'] + .concat(Object.keys(winston.config.npm.levels)) + .forEach(function (key) { + assert.isFunction(winston[key]); + }); + }, + "it should": { + topic: function () { + fs.readFile(path.join(__dirname, '..', 'package.json'), this.callback); + }, + "have the correct version set": function (err, data) { + assert.isNull(err); + data = JSON.parse(data.toString()); + assert.equal(winston.version, data.version); + } + }, + "the log() method": helpers.testNpmLevels(winston, "should respond without an error", function (err) { + assert.isNull(err); + }), + "the extend() method called on an empty object": { + topic: function (logger) { + var empty = {}; + winston.extend(empty); + return empty; + }, + "should define the appropriate methods": function (extended) { + ['log', 'profile', 'startTimer'].concat(Object.keys(winston.config.npm.levels)).forEach(function (method) { + assert.isFunction(extended[method]); + }); + } + } + } +}).addBatch({ + "The winston module": { + "the setLevels() method": { + topic: function () { + winston.setLevels(winston.config.syslog.levels); + return null; + }, + "should have the proper methods defined": function () { + assert.isObject(winston.transports); + assert.isFunction(winston.transports.Console); + assert.isFunction(winston.transports.Webhook); + assert.isObject(winston.default.transports.console); + assert.isFalse(winston.emitErrs); + assert.isObject(winston.config); + + var newLevels = Object.keys(winston.config.syslog.levels); + ['Logger', 'add', 'remove', 'extend'] + .concat(newLevels) + .forEach(function (key) { + assert.isFunction(winston[key]); + }); + + + Object.keys(winston.config.npm.levels) + .filter(function (key) { + return newLevels.indexOf(key) === -1; + }) + .forEach(function (key) { + assert.isTrue(typeof winston[key] === 'undefined'); + }); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/package.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/package.json new file mode 100644 index 0000000..99d2b72 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/package.json @@ -0,0 +1,57 @@ +{ + "name": "broadway", + "description": "Lightweight application extensibility and composition with a twist of feature reflection.", + "author": { + "name": "Nodejitsu Inc.", + "email": "info@nodejitsu.com" + }, + "version": "0.2.7", + "maintainers": [ + { + "name": "AvianFlu", + "email": "avianflu@nodejitsu.com" + }, + { + "name": "indexzero", + "email": "charlie@nodejitsu.com" + }, + { + "name": "Marak", + "email": "marak@nodejitsu.com" + } + ], + "repository": { + "type": "git", + "url": "http://github.com/flatiron/broadway.git" + }, + "dependencies": { + "cliff": "0.1.8", + "eventemitter2": "0.4.11", + "nconf": "0.6.7", + "winston": "0.6.2", + "utile": "0.1.7" + }, + "devDependencies": { + "codesurgeon": "0.3.x", + "uglify-js": "1.0.6", + "vows": "0.7.x" + }, + "scripts": { + "test": "vows test/**/*-test.js --spec" + }, + "main": "./lib/broadway", + "engines": { + "node": ">= 0.6.4" + }, + "readme": "# broadway [![Build Status](https://secure.travis-ci.org/flatiron/broadway.png)](http://travis-ci.org/flatiron/broadway)\n\n*Lightweight application extensibility and composition with a twist of feature\nreflection.*\n\n## Example\n\n### app.js\n```js\nvar broadway = require(\"broadway\");\n\nvar app = new broadway.App();\n\n// Passes the second argument to `helloworld.attach`.\napp.use(require(\"./plugins/helloworld\"), { \"delimiter\": \"!\" } );\n\napp.init(function (err) {\n if (err) {\n console.log(err);\n }\n});\n\napp.hello(\"world\");\n```\n\n### plugins/helloworld.js\n\n```js\n// `exports.attach` gets called by broadway on `app.use`\nexports.attach = function (options) {\n\n this.hello = function (world) {\n console.log(\"Hello \"+ world + options.delimiter || \".\");\n };\n\n};\n\n// `exports.init` gets called by broadway on `app.init`.\nexports.init = function (done) {\n\n // This plugin doesn't require any initialization step.\n return done();\n\n};\n```\n\n### run it!\n\n```bash\njosh@onix:~/dev/broadway/examples$ node simple/app.js \nHello world!\njosh@onix:~/dev/broadway/examples$ \n```\n\n## Installation\n\n### Installing npm (node package manager)\n``` bash\n $ curl http://npmjs.org/install.sh | sh\n```\n\n### Installing broadway\n``` bash \n $ [sudo] npm install broadway\n```\n\n## API\n\n### App#init(callback)\n\nInitialize application and it's plugins, `callback` will be called with null or\ninitialization error as first argument.\n\n### App#use(plugin, options)\n\nAttach plugin to application. `plugin` should conform to following interface:\n\n```javascript\nvar plugin = {\n \"name\": \"example-plugin\", // Plugin's name\n\n \"attach\": function attach(options) {\n // Called with plugin options once plugin attached to application\n // `this` - is a reference to application\n },\n\n \"detach\": function detach() {\n // Called when plugin detached from application\n // (Only if plugin with same name was attached)\n // `this` - is a reference to application\n },\n\n \"init\": function init(callback) {\n // Called on application initialization\n // App#init(callback) will be called once every plugin will call `callback`\n // `this` - is a reference to application\n }\n};\n```\n\n### App#on(event, callback) and App#emit(event, data)\n\nApp inherits from [EventEmitter2][2], and many plugins build on this\nfunctionality.\n\n#### Built-In Events:\n\n* `error:init`: Broadway emits this event when it throws an error while attempting to initialize.\n\nRead the [EventEmitter2][2] documentation for more information.\n\n## Tests\nAll tests are written with [vows][0] and should be run with [npm][1]:\n\n``` bash\n $ npm test\n```\n\n#### [Charlie Robbins](http://nodejitsu.com)\n#### License: MIT\n\n[0]: http://vowsjs.org\n[1]: http://npmjs.org\n[2]: https://github.com/hij1nx/EventEmitter2\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/flatiron/broadway/issues" + }, + "_id": "broadway@0.2.7", + "dist": { + "shasum": "c950a210b5e80a10fd6ee3f9656208de37f8dcef" + }, + "_from": "broadway@0.2.x", + "_resolved": "https://registry.npmjs.org/broadway/-/broadway-0.2.7.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/common/directories-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/common/directories-test.js new file mode 100644 index 0000000..165dca4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/common/directories-test.js @@ -0,0 +1,60 @@ +/* + * directories-test.js: Tests for working with directories in broadway. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + vows = require('vows'), + broadway = require('../../lib/broadway'); + +var fixturesDir = path.join(__dirname, '..', 'fixtures'), + emptyAppDir = path.join(fixturesDir, 'empty-app'), + emptyAppFile = path.join(fixturesDir, 'sample-app.json'), + appConfig = JSON.parse(fs.readFileSync(emptyAppFile, 'utf8')), + directories = appConfig.directories; + +vows.describe('broadway/common/directories').addBatch({ + "When using broadway.common.directories": { + "it should have the correct methods defined": function () { + assert.isObject(broadway.common.directories); + assert.isFunction(broadway.common.directories.create); + assert.isFunction(broadway.common.directories.remove); + }, + "the normalize() method should correctly modify a set of directories": function () { + directories = broadway.common.directories.normalize({'#ROOT': emptyAppDir}, directories); + + Object.keys(directories).forEach(function (key) { + assert.isTrue(directories[key].indexOf(emptyAppDir) !== -1); + }); + }, + "the create() method": { + topic: function () { + broadway.common.directories.create(directories, this.callback); + }, + "should create the specified directories": function (err, dirs) { + assert.isTrue(!err); + + dirs.forEach(function (dir) { + assert.isTrue((fs.existsSync || path.existsSync)(dir)); + }); + }, + "the destroy() method": { + topic: function () { + broadway.common.directories.remove(directories, this.callback); + }, + "should remove the specified directories": function (err, dirs) { + assert.isTrue(!err); + + dirs.forEach(function (dir) { + assert.isFalse((fs.existsSync || path.existsSync)(dir)); + }); + } + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/app-init-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/app-init-test.js new file mode 100644 index 0000000..de3a0f9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/app-init-test.js @@ -0,0 +1,100 @@ +/* + * app-test.js: Tests for core App methods and configuration. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var events = require('eventemitter2'), + vows = require('vows'), + assert = require('../helpers/assert'), + broadway = require('../../lib/broadway'); + +vows.describe('broadway/app').addBatch({ + "An initialized instance of broadway.App with three plugins": { + topic: function () { + var app = new broadway.App(), + that = this, + three; + + that.init = []; + + three = { + name: 'three', + init: function (cb) { + process.nextTick(function () { + that.init.push('three'); + cb(); + }) + } + }; + + // First plugin. Includes an init step. + app.use({ + attach: function () { + this.place = 'rackspace'; + }, + + init: function (cb) { + var self = this; + + // a nextTick isn't technically necessary, but it does make this + // purely async. + process.nextTick(function () { + that.init.push('one'); + self.letsGo = function () { + return 'Let\'s go to '+self.place+'!'; + } + + cb(); + }); + } + }); + + // Second plugin. Only involves an "attach". + app.use({ + attach: function () { + this.oneup = function (n) { + n++; + return n; + } + } + }); + + // Third pluging. Only involves an "init". + app.use(three); + + // Attempt to use it again. This should not invoke `init()` twice + app.use(three); + + // Remove the plugin and use it again. This should not invoke `init()` twice + app.remove(three); + app.use(three); + + // Removing a plugin which was never added should not affect the initlist + app.remove({ + name: 'foo' + }); + + app.init(function (err) { + that.callback(err, app); + }); + }, + "shouldn't throw an error": function (err, app) { + assert.ok(!err); + }, + "should have all its methods attached/defined": function (err, app) { + assert.ok(app.place); + assert.isFunction(app.oneup); + assert.isFunction(app.letsGo); + assert.equal(2, app.oneup(1)); + assert.equal(app.letsGo(), 'Let\'s go to rackspace!'); + + // + // This is intentional. The second plugin does not invoke `init`. + // + assert.deepEqual(this.init, ['one', 'three']); + }, + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/app-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/app-test.js new file mode 100644 index 0000000..b985eaa --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/app-test.js @@ -0,0 +1,73 @@ +/* + * app-test.js: Tests for core App methods and configuration. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var events = require('eventemitter2'), + vows = require('vows'), + assert = require('../helpers/assert'), + broadway = require('../../lib/broadway'); + +vows.describe('broadway/app').addBatch({ + "An instance of broadway.App": { + topic: new broadway.App(), + "should have the correct properties and methods": function (app) { + // + // Instance + // + assert.isObject(app); + assert.instanceOf(app, events.EventEmitter2); + assert.instanceOf(app, broadway.App); + + // + // Properties + // + assert.isObject(app.plugins); + assert.isObject(app.initializers); + assert.isFalse(!!app.initialized); + + // + // Methods + // + assert.isFunction(app.init); + assert.isFunction(app.use); + assert.isFunction(app.remove); + assert.isFunction(app.inspect); + }, + "the init() method": { + topic: function (app) { + this.app = app; + app.init(this.callback); + }, + "should correctly setup the application state": function () { + assert.isTrue(this.app.initialized); + assert.isTrue(this.app.initializers['log']); + + assert.plugins.has.config(this.app); + assert.plugins.has.log(this.app); + } + }, + "the detach() method": { + topic: function (app) { + app.use({ + name: "foo", + attach: function () { + this.attached = true; + }, + detach: function () { + this.detached = true; + } + }); + app.remove("foo"); + return app; + }, + "should correctly remove a plugin": function (app) { + assert.isTrue(app.detached); + assert.equal(undefined, app.plugins["foo"]); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/broadway-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/broadway-test.js new file mode 100644 index 0000000..d69bc6f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/core/broadway-test.js @@ -0,0 +1,26 @@ +/* + * broadway-test.js: Tests for core App methods and configuration. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + events = require('eventemitter2'), + vows = require('vows'), + broadway = require('../../lib/broadway'); + +vows.describe('broadway').addBatch({ + "The broadway module": { + "should have the appropriate properties and methods defined": function () { + assert.isFunction(broadway.App); + assert.isObject(broadway.common); + assert.isObject(broadway.features); + assert.isObject(broadway.plugins); + assert.isObject(broadway.plugins.log); + assert.isObject(broadway.plugins.config); + assert.isObject(broadway.plugins.exceptions); + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/.gitkeep b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/empty-app/.gitkeep b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/empty-app/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app.json new file mode 100644 index 0000000..24545f9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app.json @@ -0,0 +1,8 @@ +{ + "directories": { + "app": "#ROOT/app", + "config": "#ROOT/config", + "lib": "#ROOT/lib", + "test": "#ROOT/test" + } +} \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app/app/index.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app/app/index.js new file mode 100644 index 0000000..7daf464 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app/app/index.js @@ -0,0 +1,2 @@ + +var broadway = require("../../../") \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app/config/topics.json b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app/config/topics.json new file mode 100644 index 0000000..9a6f6fb --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/fixtures/sample-app/config/topics.json @@ -0,0 +1,5 @@ +{ + "topics": [ + + ] +} \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/assert.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/assert.js new file mode 100644 index 0000000..9db58a8 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/assert.js @@ -0,0 +1,108 @@ +/* + * assert.js: Assertion helpers for broadway tests + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = module.exports = require('assert'), + fs = require('fs'), + path = require('path'), + nconf = require('nconf'), + vows = require('vows'); + +// +// ### Assertion helpers for working with `broadway.App` objects. +// +assert.app = {}; + +// +// ### Assertion helpers for working with `broadway.plugins`. +// +assert.plugins = {}; + +// +// ### Assert that an application has various plugins. +// +assert.plugins.has = { + config: function (app, config) { + assert.instanceOf(app.config, nconf.Provider); + if (config) { + // + // TODO: Assert that all configuration has been loaded + // + } + }, + exceptions: function (app) { + + }, + directories: function (app) { + if (app.options['directories']) { + Object.keys(app.options['directories']).forEach(function (key) { + assert.isTrue((fs.existsSync || path.existsSync)(app.options['directories'][key])); + }); + } + //assert.isTrue(!!app.config.get('directories')) + }, + log: function (app) { + assert.isObject(app.log); + + // + // TODO: Assert winston.extend methods + // + } +}; + +// +// ### Assert that an application doesn't have various plugins +// +assert.plugins.notHas = { + config: function (app) { + assert.isTrue(!app.config); + }, + exceptions: function (app) { + + }, + directories: function (app) { + assert.isTrue(!app.config.get('directories')) + }, + log: function (app) { + assert.isTrue(!app.log); + // + // TODO: Assert winston.extend methods + // + } +}; + +assert.log = {}; + +assert.log.levelMsgMeta = function (err, level, msg, meta) { + assert.equal(level, this.event[1]); + assert.equal(msg, this.event[2]); + assert.equal(meta, this.event[3]); +}; + +assert.log.msgMeta = function (err, level, msg, meta) { + assert.equal(level, this.event[0].split('::')[1] || 'info'); + assert.equal(msg, this.event[1]); + assert.equal(meta, this.event[2]); +}; + +assert.log.levelMeta = function (err, level, msg, meta) { + assert.equal(level, this.event[1]); + assert.equal(msg, this.event[0]); + assert.deepEqual(meta, this.event[2]); +}; + +assert.log.levelMsg = function (err, level, msg, meta) { + assert.equal(level, this.event[1]); + assert.equal(msg, this.event[2]); +}; + +assert.log.metaOnly = function (err, level, msg, meta, event) { + assert.equal(level, 'info'); + assert.equal(msg, this.event[0]); + assert.equal(meta, this.event[1]); + assert.equal(event, this.event[0]); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/helpers.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/helpers.js new file mode 100644 index 0000000..9dbdea4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/helpers.js @@ -0,0 +1,24 @@ +/* + * helpers.js: Test helpers for using broadway. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var events = require('eventemitter2'), + broadway = require('../../lib/broadway'); + +var helpers = exports; + +helpers.findApp = function () { + return Array.prototype.slice.call(arguments).filter(function (arg) { + return arg instanceof events.EventEmitter2; + })[0]; +}; + +helpers.mockApp = function () { + var mock = new events.EventEmitter2({ delimiter: '::', wildcard: true }); + mock.options = {}; + return mock; +}; \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/macros.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/macros.js new file mode 100644 index 0000000..8e5e855 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/helpers/macros.js @@ -0,0 +1,74 @@ +/* + * macros.js: Test macros for using broadway and vows + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var events = require('eventemitter2'), + assert = require('./assert'), + helpers = require('./helpers'), + broadway = require('../../lib/broadway'); + +var macros = exports; + +macros.shouldExtend = function (app, plugin, vows) { + if (arguments.length === 1) { + plugin = app; + app = vows = null; + } + else if (arguments.length === 2) { + app = helpers.mockApp(); + vows = plugin; + plugin = app; + } + + var context = { + topic: function () { + app = app || helpers.mockApp(); + broadway.plugins[plugin].attach.call(app, app.options[plugin] || {}); + + if (broadway.plugins[plugin].init) { + return broadway.plugins[plugin].init.call(app, this.callback.bind(this, null, app)); + } + + this.callback(null, app); + }, + "should add the appropriate properties and methods": function (_, app) { + assert.plugins.has[plugin](app); + } + } + + return extendContext(context, vows); +}; + +macros.shouldLogEvent = function (app, event, vow) { + return { + topic: function () { + app = app || helpers.findApp.apply(null, arguments); + var logger = app.log.get('default'); + + this.event = event; + app.once('broadway::logged', this.callback.bind(this, null)); + app.emit.apply(app, event); + }, + "should log the appropriate info": vow + }; +}; + +function extendContext (context, vows) { + if (vows) { + if (vows.topic) { + console.log('Cannot include topic at top-level of nested vows:'); + console.dir(vows, 'vows'); + process.exit(1); + } + + Object.keys(vows).forEach(function (key) { + context[key] = vows[key]; + }); + } + + return context; +} \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/config-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/config-test.js new file mode 100644 index 0000000..81307ea --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/config-test.js @@ -0,0 +1,19 @@ +/* + * config-test.js: Tests for the broadway config plugin + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var vows = require('vows'), + events = require('eventemitter2'), + assert = require('../helpers/assert'), + macros = require('../helpers/macros'), + broadway = require('../../lib/broadway'); + +vows.describe('broadway/plugins/config').addBatch({ + "Using the config plugin": { + "extending an application": macros.shouldExtend('config') + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/directories-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/directories-test.js new file mode 100644 index 0000000..72833f4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/directories-test.js @@ -0,0 +1,28 @@ +/* + * directories-test.js: Tests for working with directories in broadway. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + vows = require('vows'), + broadway = require('../../lib/broadway'), + macros = require('../helpers/macros'); + +var fixturesDir = path.join(__dirname, '..', 'fixtures'), + emptyAppDir = path.join(fixturesDir, 'empty-app'), + emptyAppFile = path.join(fixturesDir, 'sample-app.json'), + appConfig = JSON.parse(fs.readFileSync(emptyAppFile, 'utf8'));; + +vows.describe('broadway/plugins/directories').addBatch({ + "Using the config plugin": { + "extending an application": macros.shouldExtend(new broadway.App({ + root: emptyAppDir, + directories: appConfig.directories + }), 'directories', {}) + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/log-test.js b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/log-test.js new file mode 100644 index 0000000..7e2ac3e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/broadway/test/plugins/log-test.js @@ -0,0 +1,69 @@ +/* + * log-test.js: Tests for the broadway logger plugin + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var vows = require('vows'), + events = require('eventemitter2'), + assert = require('../helpers/assert'), + helpers = require('../helpers/helpers'), + macros = require('../helpers/macros'), + broadway = require('../../lib/broadway'); + +var app = helpers.mockApp(); +app.options = { + log: { + logAll: true, + namespaces: { + 'apps': 'foo' + } + } +}; + +vows.describe('broadway/plugins/log').addBatch({ + "Using the log plugin": { + "to extend an application": macros.shouldExtend(app, 'log', { + "when the application emits log::# events": macros.shouldLogEvent(app, [ + 'log::warn', + 'some warn message', + { foo: 'bar' } + ], assert.log.msgMeta) + }), + "when the application emits log::#::# events": macros.shouldLogEvent(app, [ + 'log::warn::some-category', + 'some warn message', + { foo: 'bar' } + ], assert.log.msgMeta), + "when the application emits log events with": { + "message and meta": macros.shouldLogEvent(app, [ + 'log', + 'some info message', + { foo: 'bar' }, + ], assert.log.msgMeta), + "level and message": macros.shouldLogEvent(app, [ + 'log', + 'silly', + 'some silly message', + ], assert.log.levelMsg), + "level and meta": macros.shouldLogEvent(app, [ + 'log', + 'info', + { foo: 'bar' }, + ], assert.log.levelMeta) + }, + "when the application emits namespaced events with": { + "level and meta": macros.shouldLogEvent(app, [ + 'apps::start', + 'info', + { foo: 'bar' }, + ], assert.log.levelMeta), + "meta only": macros.shouldLogEvent(app, [ + 'apps::start', + { foo: 'bar' }, + ], assert.log.metaOnly) + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/director/.npmignore new file mode 100644 index 0000000..ff1a80c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/.npmignore @@ -0,0 +1,6 @@ +/.idea/ +node_modules +npm-debug.log +.DS_Store + +/test/browser/browserified-bundle.js diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/.travis.yml b/node_modules/forever/node_modules/flatiron/node_modules/director/.travis.yml new file mode 100644 index 0000000..389329f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/.travis.yml @@ -0,0 +1,11 @@ +language: node_js + +node_js: + - 0.6 + - 0.8 + +notifications: + email: + - travis@nodejitsu.com + irc: "irc.freenode.org#nodejitsu" + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/LICENSE b/node_modules/forever/node_modules/flatiron/node_modules/director/LICENSE new file mode 100644 index 0000000..1f01e2b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Nodejitsu Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/README.md b/node_modules/forever/node_modules/flatiron/node_modules/director/README.md new file mode 100644 index 0000000..522d146 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/README.md @@ -0,0 +1,822 @@ + + +# Synopsis +Director is a router. Routing is the process of determining what code to run when a URL is requested. + +# Motivation +A routing library that works in both the browser and node.js environments with as few differences as possible. Simplifies the development of Single Page Apps and Node.js applications. Dependency free (doesn't require jQuery or Express, etc). + +# Status +[![Build Status](https://secure.travis-ci.org/flatiron/director.png?branch=master)](http://travis-ci.org/flatiron/director) + +# Features +* [Client-Side Routing](#client-side) +* [Server-Side HTTP Routing](#http-routing) +* [Server-Side CLI Routing](#cli-routing) + + +# Usage +* [API Documentation](#api-documentation) +* [Frequently Asked Questions](#faq) + +
+## Client-side Routing +It simply watches the hash of the URL to determine what to do, for example: + +``` +http://foo.com/#/bar +``` + +Client-side routing (aka hash-routing) allows you to specify some information about the state of the application using the URL. So that when the user visits a specific URL, the application can be transformed accordingly. + + + +Here is a simple example: + +```html + + + + + A Gentle Introduction + + + + + + + +``` + +Director works great with your favorite DOM library, such as jQuery. + +```html + + + + + A Gentle Introduction 2 + + + + + +
Author Name
+
Book1, Book2, Book3
+ + + +``` + +You can find a browser-specific build of `director` [here][1] which has all of the server code stripped away. + + +## Server-Side HTTP Routing + +Director handles routing for HTTP requests similar to `journey` or `express`: + +```js + // + // require the native http module, as well as director. + // + var http = require('http'), + director = require('director'); + + // + // create some logic to be routed to. + // + function helloWorld() { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }) + this.res.end('hello world'); + } + + // + // define a routing table. + // + var router = new director.http.Router({ + '/hello': { + get: helloWorld + } + }); + + // + // setup a server and when there is a request, dispatch the + // route that was requested in the request object. + // + var server = http.createServer(function (req, res) { + router.dispatch(req, res, function (err) { + if (err) { + res.writeHead(404); + res.end(); + } + }); + }); + + // + // You can also do ad-hoc routing, similar to `journey` or `express`. + // This can be done with a string or a regexp. + // + router.get('/bonjour', helloWorld); + router.get(/hola/, helloWorld); + + // + // set the server to listen on port `8080`. + // + server.listen(8080); +``` + +### See Also: + + - Auto-generated Node.js API Clients for routers using [Director-Reflector](http://github.com/flatiron/director-reflector) + - RESTful Resource routing using [restful](http://github.com/flatiron/restful) + - HTML / Plain Text views of routers using [Director-Explorer](http://github.com/flatiron/director-explorer) + + +## CLI Routing + +Director supports Command Line Interface routing. Routes for cli options are based on command line input (i.e. `process.argv`) instead of a URL. + +``` js + var director = require('director'); + + var router = new director.cli.Router(); + + router.on('create', function () { + console.log('create something'); + }); + + router.on(/destroy/, function () { + console.log('destroy something'); + }); + + // You will need to dispatch the cli arguments yourself + router.dispatch('on', process.argv.slice(2).join(' ')); +``` + +Using the cli router, you can dispatch commands by passing them as a string. For example, if this example is in a file called `foo.js`: + +``` bash +$ node foo.js create +create something +$ node foo.js destroy +destroy something +``` + + +# API Documentation + +* [Constructor](#constructor) +* [Routing Table](#routing-table) +* [Adhoc Routing](#adhoc-routing) +* [Scoped Routing](#scoped-routing) +* [Routing Events](#routing-events) +* [Configuration](#configuration) +* [URL Matching](#url-matching) +* [URL Params](#url-params) +* [Route Recursion](#route-recursion) +* [Async Routing](#async-routing) +* [Resources](#resources) +* [History API](#history-api) +* [Instance Methods](#instance-methods) +* [Attach Properties to `this`](#attach-to-this) +* [HTTP Streaming and Body Parsing](#http-streaming-body-parsing) + + +## Constructor + +``` js + var router = Router(routes); +``` + + +## Routing Table + +An object literal that contains nested route definitions. A potentially nested set of key/value pairs. The keys in the object literal represent each potential part of the URL. The values in the object literal contain references to the functions that should be associated with them. *bark* and *meow* are two functions that you have defined in your code. + +``` js + // + // Assign routes to an object literal. + // + var routes = { + // + // a route which assigns the function `bark`. + // + '/dog': bark, + // + // a route which assigns the functions `meow` and `scratch`. + // + '/cat': [meow, scratch] + }; + + // + // Instantiate the router. + // + var router = Router(routes); +``` + + +## Adhoc Routing + +When developing large client-side or server-side applications it is not always possible to define routes in one location. Usually individual decoupled components register their own routes with the application router. We refer to this as _Adhoc Routing._ Lets take a look at the API `director` exposes for adhoc routing: + +**Client-side Routing** + +``` js + var router = new Router().init(); + + router.on('/some/resource', function () { + // + // Do something on `/#/some/resource` + // + }); +``` + +**HTTP Routing** + +``` js + var router = new director.http.Router(); + + router.get(/\/some\/resource/, function () { + // + // Do something on an GET to `/some/resource` + // + }); +``` + + +## Scoped Routing + +In large web appliations, both [Client-side](#client-side) and [Server-side](#http-routing), routes are often scoped within a few individual resources. Director exposes a simple way to do this for [Adhoc Routing](#adhoc-routing) scenarios: + +``` js + var router = new director.http.Router(); + + // + // Create routes inside the `/users` scope. + // + router.path(/\/users\/(\w+)/, function () { + // + // The `this` context of the function passed to `.path()` + // is the Router itself. + // + + this.post(function (id) { + // + // Create the user with the specified `id`. + // + }); + + this.get(function (id) { + // + // Retreive the user with the specified `id`. + // + }); + + this.get(/\/friends/, function (id) { + // + // Get the friends for the user with the specified `id`. + // + }); + }); +``` + + +## Routing Events + +In `director`, a "routing event" is a named property in the [Routing Table](#routing-table) which can be assigned to a function or an Array of functions to be called when a route is matched in a call to `router.dispatch()`. + +* **on:** A function or Array of functions to execute when the route is matched. +* **before:** A function or Array of functions to execute before calling the `on` method(s). + +**Client-side only** + +* **after:** A function or Array of functions to execute when leaving a particular route. +* **once:** A function or Array of functions to execute only once for a particular route. + + +## Configuration + +Given the flexible nature of `director` there are several options available for both the [Client-side](#client-side) and [Server-side](#http-routing). These options can be set using the `.configure()` method: + +``` js + var router = new director.Router(routes).configure(options); +``` + +The `options` are: + +* **recurse:** Controls [route recursion](#route-recursion). Use `forward`, `backward`, or `false`. Default is `false` Client-side, and `backward` Server-side. +* **strict:** If set to `false`, then trailing slashes (or other delimiters) are allowed in routes. Default is `true`. +* **async:** Controls [async routing](#async-routing). Use `true` or `false`. Default is `false`. +* **delimiter:** Character separator between route fragments. Default is `/`. +* **notfound:** A function to call if no route is found on a call to `router.dispatch()`. +* **on:** A function (or list of functions) to call on every call to `router.dispatch()` when a route is found. +* **before:** A function (or list of functions) to call before every call to `router.dispatch()` when a route is found. + +**Client-side only** + +* **resource:** An object to which string-based routes will be bound. This can be especially useful for late-binding to route functions (such as async client-side requires). +* **after:** A function (or list of functions) to call when a given route is no longer the active route. +* **html5history:** If set to `true` and client supports `pushState()`, then uses HTML5 History API instead of hash fragments. See [History API](#history-api) for more information. +* **run_handler_in_init:** If `html5history` is enabled, the route handler by default is executed upon `Router.init()` since with real URIs the router can not know if it should call a route handler or not. Setting this to `false` disables the route handler initial execution. + + +## URL Matching + +``` js + var router = Router({ + // + // given the route '/dog/yella'. + // + '/dog': { + '/:color': { + // + // this function will return the value 'yella'. + // + on: function (color) { console.log(color) } + } + } + }); +``` + +Routes can sometimes become very complex, `simple/:tokens` don't always suffice. Director supports regular expressions inside the route names. The values captured from the regular expressions are passed to your listener function. + +``` js + var router = Router({ + // + // given the route '/hello/world'. + // + '/hello': { + '/(\\w+)': { + // + // this function will return the value 'world'. + // + on: function (who) { console.log(who) } + } + } + }); +``` + +``` js + var router = Router({ + // + // given the route '/hello/world/johny/appleseed'. + // + '/hello': { + '/world/?([^\/]*)\/([^\/]*)/?': function (a, b) { + console.log(a, b); + } + } + }); +``` + + +## URL Parameters + +When you are using the same route fragments it is more descriptive to define these fragments by name and then use them in your [Routing Table](#routing-table) or [Adhoc Routes](#adhoc-routing). Consider a simple example where a `userId` is used repeatedly. + +``` js + // + // Create a router. This could also be director.cli.Router() or + // director.http.Router(). + // + var router = new director.Router(); + + // + // A route could be defined using the `userId` explicitly. + // + router.on(/([\w-_]+)/, function (userId) { }); + + // + // Define a shorthand for this fragment called `userId`. + // + router.param('userId', /([\\w\\-]+)/); + + // + // Now multiple routes can be defined with the same + // regular expression. + // + router.on('/anything/:userId', function (userId) { }); + router.on('/something-else/:userId', function (userId) { }); +``` + + +## Route Recursion + +Can be assigned the value of `forward` or `backward`. The recurse option will determine the order in which to fire the listeners that are associated with your routes. If this option is NOT specified or set to null, then only the listeners associated with an exact match will be fired. + +### No recursion, with the URL /dog/angry + +``` js + var routes = { + '/dog': { + '/angry': { + // + // Only this method will be fired. + // + on: growl + }, + on: bark + } + }; + + var router = Router(routes); +``` + +### Recursion set to `backward`, with the URL /dog/angry + +``` js + var routes = { + '/dog': { + '/angry': { + // + // This method will be fired first. + // + on: growl + }, + // + // This method will be fired second. + // + on: bark + } + }; + + var router = Router(routes).configure({ recurse: 'backward' }); +``` + +### Recursion set to `forward`, with the URL /dog/angry + +``` js + var routes = { + '/dog': { + '/angry': { + // + // This method will be fired second. + // + on: growl + }, + // + // This method will be fired first. + // + on: bark + } + }; + + var router = Router(routes).configure({ recurse: 'forward' }); +``` + +### Breaking out of recursion, with the URL /dog/angry + +``` js + var routes = { + '/dog': { + '/angry': { + // + // This method will be fired first. + // + on: function() { return false; } + }, + // + // This method will not be fired. + // + on: bark + } + }; + + // + // This feature works in reverse with recursion set to true. + // + var router = Router(routes).configure({ recurse: 'backward' }); +``` + + +## Async Routing + +Before diving into how Director exposes async routing, you should understand [Route Recursion](#route-recursion). At it's core route recursion is about evaluating a series of functions gathered when traversing the [Routing Table](#routing-table). + +Normally this series of functions is evaluated synchronously. In async routing, these functions are evaluated asynchronously. Async routing can be extremely useful both on the client-side and the server-side: + +* **Client-side:** To ensure an animation or other async operations (such as HTTP requests for authentication) have completed before continuing evaluation of a route. +* **Server-side:** To ensure arbitrary async operations (such as performing authentication) have completed before continuing the evaluation of a route. + +The method signatures for route functions in synchronous and asynchronous evaluation are different: async route functions take an additional `next()` callback. + +### Synchronous route functions + +``` js + var router = new director.Router(); + + router.on('/:foo/:bar/:bazz', function (foo, bar, bazz) { + // + // Do something asynchronous with `foo`, `bar`, and `bazz`. + // + }); +``` + +### Asynchronous route functions + +``` js + var router = new director.http.Router().configure({ async: true }); + + router.on('/:foo/:bar/:bazz', function (foo, bar, bazz, next) { + // + // Go do something async, and determine that routing should stop + // + next(false); + }); +``` + + +## Resources + +**Available on the Client-side only.** An object literal containing functions. If a host object is specified, your route definitions can provide string literals that represent the function names inside the host object. A host object can provide the means for better encapsulation and design. + +``` js + + var router = Router({ + + '/hello': { + '/usa': 'americas', + '/china': 'asia' + } + + }).configure({ resource: container }).init(); + + var container = { + americas: function() { return true; }, + china: function() { return true; } + }; + +``` + + +## History API + +**Available on the Client-side only.** Director supports using HTML5 History API instead of hash fragments for navigation. To use the API, pass `{html5history: true}` to `configure()`. Use of the API is enabled only if the client supports `pushState()`. + +Using the API gives you cleaner URIs but they come with a cost. Unlike with hash fragments your route URIs must exist. When the client enters a page, say http://foo.com/bar/baz, the web server must respond with something meaningful. Usually this means that your web server checks the URI points to something that, in a sense, exists, and then serves the client the JavaScript application. + +If you're after a single-page application you can not use plain old `` tags for navigation anymore. When such link is clicked, web browsers try to ask for the resource from server which is not of course desired for a single-page application. Instead you need to use e.g. click handlers and call the `setRoute()` method yourself. + + +## Attach Properties To `this` + +Generally, the `this` object bound to route handlers, will contain the request in `this.req` and the response in `this.res`. One may attach additional properties to `this` with the `router.attach` method: + +```js + var director = require('director'); + + var router = new director.http.Router().configure(options); + + // + // Attach properties to `this` + // + router.attach(function () { + this.data = [1,2,3]; + }); + + // + // Access properties attached to `this` in your routes! + // + router.get('/hello', function () { + this.res.writeHead(200, { 'content-type': 'text/plain' }); + + // + // Response will be `[1,2,3]`! + // + this.res.end(this.data); + }); +``` + +This API may be used to attach convenience methods to the `this` context of route handlers. + + +## HTTP Streaming and Body Parsing + +When you are performing HTTP routing there are two common scenarios: + +* Buffer the request body and parse it according to the `Content-Type` header (usually `application/json` or `application/x-www-form-urlencoded`). +* Stream the request body by manually calling `.pipe` or listening to the `data` and `end` events. + +By default `director.http.Router()` will attempt to parse either the `.chunks` or `.body` properties set on the request parameter passed to `router.dispatch(request, response, callback)`. The router instance will also wait for the `end` event before firing any routes. + +**Default Behavior** + +``` js + var director = require('director'); + + var router = new director.http.Router(); + + router.get('/', function () { + // + // This will not work, because all of the data + // events and the end event have already fired. + // + this.req.on('data', function (chunk) { + console.log(chunk) + }); + }); +``` + +In [flatiron][2], `director` is used in conjunction with [union][3] which uses a `BufferedStream` proxy to the raw `http.Request` instance. [union][3] will set the `req.chunks` property for you and director will automatically parse the body. If you wish to perform this buffering yourself directly with `director` you can use a simple request handler in your http server: + +``` js + var http = require('http'), + director = require('director'); + + var router = new director.http.Router(); + + var server = http.createServer(function (req, res) { + req.chunks = []; + req.on('data', function (chunk) { + req.chunks.push(chunk.toString()); + }); + + router.dispatch(req, res, function (err) { + if (err) { + res.writeHead(404); + res.end(); + } + + console.log('Served ' + req.url); + }); + }); + + router.post('/', function () { + this.res.writeHead(200, { 'Content-Type': 'application/json' }) + this.res.end(JSON.stringify(this.req.body)); + }); +``` + +**Streaming Support** + +If you wish to get access to the request stream before the `end` event is fired, you can pass the `{ stream: true }` options to the route. + +``` js + var director = require('director'); + + var router = new director.http.Router(); + + router.get('/', { stream: true }, function () { + // + // This will work because the route handler is invoked + // immediately without waiting for the `end` event. + // + this.req.on('data', function (chunk) { + console.log(chunk); + }); + }); +``` + + +## Instance methods + +### configure(options) +* `options` {Object}: Options to configure this instance with. + +Configures the Router instance with the specified `options`. See [Configuration](#configuration) for more documentation. + +### param(token, matcher) +* token {string}: Named parameter token to set to the specified `matcher` +* matcher {string|Regexp}: Matcher for the specified `token`. + +Adds a route fragment for the given string `token` to the specified regex `matcher` to this Router instance. See [URL Parameters](#url-params) for more documentation. + +### on(method, path, route) +* `method` {string}: Method to insert within the Routing Table (e.g. `on`, `get`, etc.). +* `path` {string}: Path within the Routing Table to set the `route` to. +* `route` {function|Array}: Route handler to invoke for the `method` and `path`. + +Adds the `route` handler for the specified `method` and `path` within the [Routing Table](#routing-table). + +### path(path, routesFn) +* `path` {string|Regexp}: Scope within the Routing Table to invoke the `routesFn` within. +* `routesFn` {function}: Adhoc Routing function with calls to `this.on()`, `this.get()` etc. + +Invokes the `routesFn` within the scope of the specified `path` for this Router instance. + +### dispatch(method, path[, callback]) +* method {string}: Method to invoke handlers for within the Routing Table +* path {string}: Path within the Routing Table to match +* callback {function}: Invoked once all route handlers have been called. + +Dispatches the route handlers matched within the [Routing Table](#routing-table) for this instance for the specified `method` and `path`. + +### mount(routes, path) +* routes {object}: Partial routing table to insert into this instance. +* path {string|Regexp}: Path within the Routing Table to insert the `routes` into. + +Inserts the partial [Routing Table](#routing-table), `routes`, into the Routing Table for this Router instance at the specified `path`. + +## Instance methods (Client-side only) + +### init([redirect]) +* `redirect` {String}: This value will be used if '/#/' is not found in the URL. (e.g., init('/') will resolve to '/#/', init('foo') will resolve to '/#foo'). + +Initialize the router, start listening for changes to the URL. + +### getRoute([index]) +* `index` {Number}: The hash value is divided by forward slashes, each section then has an index, if this is provided, only that section of the route will be returned. + +Returns the entire route or just a section of it. + +### setRoute(route) +* `route` {String}: Supply a route value, such as `home/stats`. + +Set the current route. + +### setRoute(start, length) +* `start` {Number} - The position at which to start removing items. +* `length` {Number} - The number of items to remove from the route. + +Remove a segment from the current route. + +### setRoute(index, value) +* `index` {Number} - The hash value is divided by forward slashes, each section then has an index. +* `value` {String} - The new value to assign the the position indicated by the first parameter. + +Set a segment of the current route. + + +# Frequently Asked Questions + +## What About SEO? + +Is using a Client-side router a problem for SEO? Yes. If advertising is a requirement, you are probably building a "Web Page" and not a "Web Application". Director on the client is meant for script-heavy Web Applications. + +# Licence + +(The MIT License) + +Copyright (c) 2010 Nodejitsu Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +[0]: http://github.com/flatiron/director +[1]: https://github.com/flatiron/director/blob/master/build/director.min.js +[2]: http://github.com/flatiron/flatiron +[3]: http://github.com/flatiron/union diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/bin/build b/node_modules/forever/node_modules/flatiron/node_modules/director/bin/build new file mode 100755 index 0000000..23e8ecf --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/bin/build @@ -0,0 +1,79 @@ +#!/usr/bin/env node + +var Codesurgeon = require('codesurgeon').Codesurgeon; +var surgeon = new Codesurgeon; + +var path = require('path'); + +var root = path.join(__dirname, '..'); +var lib = path.join(root, 'lib', 'director'); + +// +// Distill and package the browser version. +// +surgeon + // + .configure({ + package: root + '/package.json', + owner: 'Nodejitsu, Inc (Using Codesurgeon).', + noVersion: true + }) + .read( + path.join(lib, 'browser.js') + ) + // + // we want everything so far. specify extract with no + // parameters to get everything into the output buffer. + // + .extract() + // + // clear the input so far, but don't clear the output. + // + .clear('inputs') + // + // read the `router.js` file + // + .read( + path.join(lib, 'router.js') + ) + // + // the current input buffer contains stuff that we dont + // want in the browser build, so let's cherry pick from + // the buffer. + // + .extract( + '_every', + '_flatten', + '_asyncEverySeries', + 'paramifyString', + 'regifyString', + 'terminator', + 'Router.prototype.configure', + 'Router.prototype.param', + 'Router.prototype.on', + 'Router.prototype.dispatch', + 'Router.prototype.invoke', + 'Router.prototype.traverse', + 'Router.prototype.insert', + 'Router.prototype.insertEx', + 'Router.prototype.extend', + 'Router.prototype.runlist', + 'Router.prototype.mount' + ) + // + // wrap everything that is in the current buffer with a + // closure so that we dont get any collisions with other + // libraries + // + .wrap() + // + // write the debuggable version of the file. This file will + // get renamed to include the version from the package.json + // + .write(root + '/build/director.js') + // + // now lets make a minified version for production use. + // + .uglify() + .write(root + '/build/director.min.js') +; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/build/director.js b/node_modules/forever/node_modules/flatiron/node_modules/director/build/director.js new file mode 100644 index 0000000..0befbe0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/build/director.js @@ -0,0 +1,712 @@ + + +// +// Generated on Sun Dec 16 2012 22:47:05 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon). +// Version 1.1.9 +// + +(function (exports) { + + +/* + * browser.js: Browser specific functionality for director. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +if (!Array.prototype.filter) { + Array.prototype.filter = function(filter, that) { + var other = [], v; + for (var i = 0, n = this.length; i < n; i++) { + if (i in this && filter.call(that, v = this[i], i, this)) { + other.push(v); + } + } + return other; + }; +} + +if (!Array.isArray){ + Array.isArray = function(obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; + }; +} + +var dloc = document.location; + +function dlocHashEmpty() { + // Non-IE browsers return '' when the address bar shows '#'; Director's logic + // assumes both mean empty. + return dloc.hash === '' || dloc.hash === '#'; +} + +var listener = { + mode: 'modern', + hash: dloc.hash, + history: false, + + check: function () { + var h = dloc.hash; + if (h != this.hash) { + this.hash = h; + this.onHashChanged(); + } + }, + + fire: function () { + if (this.mode === 'modern') { + this.history === true ? window.onpopstate() : window.onhashchange(); + } + else { + this.onHashChanged(); + } + }, + + init: function (fn, history) { + var self = this; + this.history = history; + + if (!Router.listeners) { + Router.listeners = []; + } + + function onchange(onChangeEvent) { + for (var i = 0, l = Router.listeners.length; i < l; i++) { + Router.listeners[i](onChangeEvent); + } + } + + //note IE8 is being counted as 'modern' because it has the hashchange event + if ('onhashchange' in window && (document.documentMode === undefined + || document.documentMode > 7)) { + // At least for now HTML5 history is available for 'modern' browsers only + if (this.history === true) { + // There is an old bug in Chrome that causes onpopstate to fire even + // upon initial page load. Since the handler is run manually in init(), + // this would cause Chrome to run it twise. Currently the only + // workaround seems to be to set the handler after the initial page load + // http://code.google.com/p/chromium/issues/detail?id=63040 + setTimeout(function() { + window.onpopstate = onchange; + }, 500); + } + else { + window.onhashchange = onchange; + } + this.mode = 'modern'; + } + else { + // + // IE support, based on a concept by Erik Arvidson ... + // + var frame = document.createElement('iframe'); + frame.id = 'state-frame'; + frame.style.display = 'none'; + document.body.appendChild(frame); + this.writeFrame(''); + + if ('onpropertychange' in document && 'attachEvent' in document) { + document.attachEvent('onpropertychange', function () { + if (event.propertyName === 'location') { + self.check(); + } + }); + } + + window.setInterval(function () { self.check(); }, 50); + + this.onHashChanged = onchange; + this.mode = 'legacy'; + } + + Router.listeners.push(fn); + + return this.mode; + }, + + destroy: function (fn) { + if (!Router || !Router.listeners) { + return; + } + + var listeners = Router.listeners; + + for (var i = listeners.length - 1; i >= 0; i--) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + } + } + }, + + setHash: function (s) { + // Mozilla always adds an entry to the history + if (this.mode === 'legacy') { + this.writeFrame(s); + } + + if (this.history === true) { + window.history.pushState({}, document.title, s); + // Fire an onpopstate event manually since pushing does not obviously + // trigger the pop event. + this.fire(); + } else { + dloc.hash = (s[0] === '/') ? s : '/' + s; + } + return this; + }, + + writeFrame: function (s) { + // IE support... + var f = document.getElementById('state-frame'); + var d = f.contentDocument || f.contentWindow.document; + d.open(); + d.write("\n \n \n \n \n \n\n```\n\nDirector works great with your favorite DOM library, such as jQuery.\n\n```html\n\n\n \n \n A Gentle Introduction 2\n \n \n \n \n \n
Author Name
\n
Book1, Book2, Book3
\n \n \n\n```\n\nYou can find a browser-specific build of `director` [here][1] which has all of the server code stripped away.\n\n\n## Server-Side HTTP Routing\n\nDirector handles routing for HTTP requests similar to `journey` or `express`:\n\n```js\n //\n // require the native http module, as well as director.\n //\n var http = require('http'),\n director = require('director');\n\n //\n // create some logic to be routed to.\n //\n function helloWorld() {\n this.res.writeHead(200, { 'Content-Type': 'text/plain' })\n this.res.end('hello world');\n }\n\n //\n // define a routing table.\n //\n var router = new director.http.Router({\n '/hello': {\n get: helloWorld\n }\n });\n\n //\n // setup a server and when there is a request, dispatch the\n // route that was requested in the request object.\n //\n var server = http.createServer(function (req, res) {\n router.dispatch(req, res, function (err) {\n if (err) {\n res.writeHead(404);\n res.end();\n }\n });\n });\n\n //\n // You can also do ad-hoc routing, similar to `journey` or `express`.\n // This can be done with a string or a regexp.\n //\n router.get('/bonjour', helloWorld);\n router.get(/hola/, helloWorld);\n\n //\n // set the server to listen on port `8080`.\n //\n server.listen(8080);\n```\n\n### See Also:\n\n - Auto-generated Node.js API Clients for routers using [Director-Reflector](http://github.com/flatiron/director-reflector)\n - RESTful Resource routing using [restful](http://github.com/flatiron/restful)\n - HTML / Plain Text views of routers using [Director-Explorer](http://github.com/flatiron/director-explorer)\n\n\n## CLI Routing\n\nDirector supports Command Line Interface routing. Routes for cli options are based on command line input (i.e. `process.argv`) instead of a URL.\n\n``` js\n var director = require('director');\n\n var router = new director.cli.Router();\n\n router.on('create', function () {\n console.log('create something');\n });\n\n router.on(/destroy/, function () {\n console.log('destroy something');\n });\n\n // You will need to dispatch the cli arguments yourself\n router.dispatch('on', process.argv.slice(2).join(' '));\n```\n\nUsing the cli router, you can dispatch commands by passing them as a string. For example, if this example is in a file called `foo.js`:\n\n``` bash\n$ node foo.js create\ncreate something\n$ node foo.js destroy\ndestroy something\n```\n\n\n# API Documentation\n\n* [Constructor](#constructor)\n* [Routing Table](#routing-table)\n* [Adhoc Routing](#adhoc-routing)\n* [Scoped Routing](#scoped-routing)\n* [Routing Events](#routing-events)\n* [Configuration](#configuration)\n* [URL Matching](#url-matching)\n* [URL Params](#url-params)\n* [Route Recursion](#route-recursion)\n* [Async Routing](#async-routing)\n* [Resources](#resources)\n* [History API](#history-api)\n* [Instance Methods](#instance-methods)\n* [Attach Properties to `this`](#attach-to-this)\n* [HTTP Streaming and Body Parsing](#http-streaming-body-parsing)\n\n\n## Constructor\n\n``` js\n var router = Router(routes);\n```\n\n\n## Routing Table\n\nAn object literal that contains nested route definitions. A potentially nested set of key/value pairs. The keys in the object literal represent each potential part of the URL. The values in the object literal contain references to the functions that should be associated with them. *bark* and *meow* are two functions that you have defined in your code.\n\n``` js\n //\n // Assign routes to an object literal.\n //\n var routes = {\n //\n // a route which assigns the function `bark`.\n //\n '/dog': bark,\n //\n // a route which assigns the functions `meow` and `scratch`.\n //\n '/cat': [meow, scratch]\n };\n\n //\n // Instantiate the router.\n //\n var router = Router(routes);\n```\n\n\n## Adhoc Routing\n\nWhen developing large client-side or server-side applications it is not always possible to define routes in one location. Usually individual decoupled components register their own routes with the application router. We refer to this as _Adhoc Routing._ Lets take a look at the API `director` exposes for adhoc routing:\n\n**Client-side Routing**\n\n``` js\n var router = new Router().init();\n\n router.on('/some/resource', function () {\n //\n // Do something on `/#/some/resource`\n //\n });\n```\n\n**HTTP Routing**\n\n``` js\n var router = new director.http.Router();\n\n router.get(/\\/some\\/resource/, function () {\n //\n // Do something on an GET to `/some/resource`\n //\n });\n```\n\n\n## Scoped Routing\n\nIn large web appliations, both [Client-side](#client-side) and [Server-side](#http-routing), routes are often scoped within a few individual resources. Director exposes a simple way to do this for [Adhoc Routing](#adhoc-routing) scenarios:\n\n``` js\n var router = new director.http.Router();\n\n //\n // Create routes inside the `/users` scope.\n //\n router.path(/\\/users\\/(\\w+)/, function () {\n //\n // The `this` context of the function passed to `.path()`\n // is the Router itself.\n //\n\n this.post(function (id) {\n //\n // Create the user with the specified `id`.\n //\n });\n\n this.get(function (id) {\n //\n // Retreive the user with the specified `id`.\n //\n });\n\n this.get(/\\/friends/, function (id) {\n //\n // Get the friends for the user with the specified `id`.\n //\n });\n });\n```\n\n\n## Routing Events\n\nIn `director`, a \"routing event\" is a named property in the [Routing Table](#routing-table) which can be assigned to a function or an Array of functions to be called when a route is matched in a call to `router.dispatch()`.\n\n* **on:** A function or Array of functions to execute when the route is matched.\n* **before:** A function or Array of functions to execute before calling the `on` method(s).\n\n**Client-side only**\n\n* **after:** A function or Array of functions to execute when leaving a particular route.\n* **once:** A function or Array of functions to execute only once for a particular route.\n\n\n## Configuration\n\nGiven the flexible nature of `director` there are several options available for both the [Client-side](#client-side) and [Server-side](#http-routing). These options can be set using the `.configure()` method:\n\n``` js\n var router = new director.Router(routes).configure(options);\n```\n\nThe `options` are:\n\n* **recurse:** Controls [route recursion](#route-recursion). Use `forward`, `backward`, or `false`. Default is `false` Client-side, and `backward` Server-side.\n* **strict:** If set to `false`, then trailing slashes (or other delimiters) are allowed in routes. Default is `true`.\n* **async:** Controls [async routing](#async-routing). Use `true` or `false`. Default is `false`.\n* **delimiter:** Character separator between route fragments. Default is `/`.\n* **notfound:** A function to call if no route is found on a call to `router.dispatch()`.\n* **on:** A function (or list of functions) to call on every call to `router.dispatch()` when a route is found.\n* **before:** A function (or list of functions) to call before every call to `router.dispatch()` when a route is found.\n\n**Client-side only**\n\n* **resource:** An object to which string-based routes will be bound. This can be especially useful for late-binding to route functions (such as async client-side requires).\n* **after:** A function (or list of functions) to call when a given route is no longer the active route.\n* **html5history:** If set to `true` and client supports `pushState()`, then uses HTML5 History API instead of hash fragments. See [History API](#history-api) for more information.\n* **run_handler_in_init:** If `html5history` is enabled, the route handler by default is executed upon `Router.init()` since with real URIs the router can not know if it should call a route handler or not. Setting this to `false` disables the route handler initial execution.\n\n\n## URL Matching\n\n``` js\n var router = Router({\n //\n // given the route '/dog/yella'.\n //\n '/dog': {\n '/:color': {\n //\n // this function will return the value 'yella'.\n //\n on: function (color) { console.log(color) }\n }\n }\n });\n```\n\nRoutes can sometimes become very complex, `simple/:tokens` don't always suffice. Director supports regular expressions inside the route names. The values captured from the regular expressions are passed to your listener function.\n\n``` js\n var router = Router({\n //\n // given the route '/hello/world'.\n //\n '/hello': {\n '/(\\\\w+)': {\n //\n // this function will return the value 'world'.\n //\n on: function (who) { console.log(who) }\n }\n }\n });\n```\n\n``` js\n var router = Router({\n //\n // given the route '/hello/world/johny/appleseed'.\n //\n '/hello': {\n '/world/?([^\\/]*)\\/([^\\/]*)/?': function (a, b) {\n console.log(a, b);\n }\n }\n });\n```\n\n\n## URL Parameters\n\nWhen you are using the same route fragments it is more descriptive to define these fragments by name and then use them in your [Routing Table](#routing-table) or [Adhoc Routes](#adhoc-routing). Consider a simple example where a `userId` is used repeatedly.\n\n``` js\n //\n // Create a router. This could also be director.cli.Router() or\n // director.http.Router().\n //\n var router = new director.Router();\n\n //\n // A route could be defined using the `userId` explicitly.\n //\n router.on(/([\\w-_]+)/, function (userId) { });\n\n //\n // Define a shorthand for this fragment called `userId`.\n //\n router.param('userId', /([\\\\w\\\\-]+)/);\n\n //\n // Now multiple routes can be defined with the same\n // regular expression.\n //\n router.on('/anything/:userId', function (userId) { });\n router.on('/something-else/:userId', function (userId) { });\n```\n\n\n## Route Recursion\n\nCan be assigned the value of `forward` or `backward`. The recurse option will determine the order in which to fire the listeners that are associated with your routes. If this option is NOT specified or set to null, then only the listeners associated with an exact match will be fired.\n\n### No recursion, with the URL /dog/angry\n\n``` js\n var routes = {\n '/dog': {\n '/angry': {\n //\n // Only this method will be fired.\n //\n on: growl\n },\n on: bark\n }\n };\n\n var router = Router(routes);\n```\n\n### Recursion set to `backward`, with the URL /dog/angry\n\n``` js\n var routes = {\n '/dog': {\n '/angry': {\n //\n // This method will be fired first.\n //\n on: growl\n },\n //\n // This method will be fired second.\n //\n on: bark\n }\n };\n\n var router = Router(routes).configure({ recurse: 'backward' });\n```\n\n### Recursion set to `forward`, with the URL /dog/angry\n\n``` js\n var routes = {\n '/dog': {\n '/angry': {\n //\n // This method will be fired second.\n //\n on: growl\n },\n //\n // This method will be fired first.\n //\n on: bark\n }\n };\n\n var router = Router(routes).configure({ recurse: 'forward' });\n```\n\n### Breaking out of recursion, with the URL /dog/angry\n\n``` js\n var routes = {\n '/dog': {\n '/angry': {\n //\n // This method will be fired first.\n //\n on: function() { return false; }\n },\n //\n // This method will not be fired.\n //\n on: bark\n }\n };\n\n //\n // This feature works in reverse with recursion set to true.\n //\n var router = Router(routes).configure({ recurse: 'backward' });\n```\n\n\n## Async Routing\n\nBefore diving into how Director exposes async routing, you should understand [Route Recursion](#route-recursion). At it's core route recursion is about evaluating a series of functions gathered when traversing the [Routing Table](#routing-table).\n\nNormally this series of functions is evaluated synchronously. In async routing, these functions are evaluated asynchronously. Async routing can be extremely useful both on the client-side and the server-side:\n\n* **Client-side:** To ensure an animation or other async operations (such as HTTP requests for authentication) have completed before continuing evaluation of a route.\n* **Server-side:** To ensure arbitrary async operations (such as performing authentication) have completed before continuing the evaluation of a route.\n\nThe method signatures for route functions in synchronous and asynchronous evaluation are different: async route functions take an additional `next()` callback.\n\n### Synchronous route functions\n\n``` js\n var router = new director.Router();\n\n router.on('/:foo/:bar/:bazz', function (foo, bar, bazz) {\n //\n // Do something asynchronous with `foo`, `bar`, and `bazz`.\n //\n });\n```\n\n### Asynchronous route functions\n\n``` js\n var router = new director.http.Router().configure({ async: true });\n\n router.on('/:foo/:bar/:bazz', function (foo, bar, bazz, next) {\n //\n // Go do something async, and determine that routing should stop\n //\n next(false);\n });\n```\n\n\n## Resources\n\n**Available on the Client-side only.** An object literal containing functions. If a host object is specified, your route definitions can provide string literals that represent the function names inside the host object. A host object can provide the means for better encapsulation and design.\n\n``` js\n\n var router = Router({\n\n '/hello': {\n '/usa': 'americas',\n '/china': 'asia'\n }\n\n }).configure({ resource: container }).init();\n\n var container = {\n americas: function() { return true; },\n china: function() { return true; }\n };\n\n```\n\n\n## History API\n\n**Available on the Client-side only.** Director supports using HTML5 History API instead of hash fragments for navigation. To use the API, pass `{html5history: true}` to `configure()`. Use of the API is enabled only if the client supports `pushState()`.\n\nUsing the API gives you cleaner URIs but they come with a cost. Unlike with hash fragments your route URIs must exist. When the client enters a page, say http://foo.com/bar/baz, the web server must respond with something meaningful. Usually this means that your web server checks the URI points to something that, in a sense, exists, and then serves the client the JavaScript application.\n\nIf you're after a single-page application you can not use plain old `` tags for navigation anymore. When such link is clicked, web browsers try to ask for the resource from server which is not of course desired for a single-page application. Instead you need to use e.g. click handlers and call the `setRoute()` method yourself.\n\n\n## Attach Properties To `this`\n\nGenerally, the `this` object bound to route handlers, will contain the request in `this.req` and the response in `this.res`. One may attach additional properties to `this` with the `router.attach` method:\n\n```js\n var director = require('director');\n\n var router = new director.http.Router().configure(options);\n\n //\n // Attach properties to `this`\n //\n router.attach(function () {\n this.data = [1,2,3];\n });\n\n //\n // Access properties attached to `this` in your routes!\n //\n router.get('/hello', function () {\n this.res.writeHead(200, { 'content-type': 'text/plain' });\n\n //\n // Response will be `[1,2,3]`!\n //\n this.res.end(this.data);\n });\n```\n\nThis API may be used to attach convenience methods to the `this` context of route handlers.\n\n\n## HTTP Streaming and Body Parsing\n\nWhen you are performing HTTP routing there are two common scenarios:\n\n* Buffer the request body and parse it according to the `Content-Type` header (usually `application/json` or `application/x-www-form-urlencoded`).\n* Stream the request body by manually calling `.pipe` or listening to the `data` and `end` events.\n\nBy default `director.http.Router()` will attempt to parse either the `.chunks` or `.body` properties set on the request parameter passed to `router.dispatch(request, response, callback)`. The router instance will also wait for the `end` event before firing any routes.\n\n**Default Behavior**\n\n``` js\n var director = require('director');\n\n var router = new director.http.Router();\n\n router.get('/', function () {\n //\n // This will not work, because all of the data\n // events and the end event have already fired.\n //\n this.req.on('data', function (chunk) {\n console.log(chunk)\n });\n });\n```\n\nIn [flatiron][2], `director` is used in conjunction with [union][3] which uses a `BufferedStream` proxy to the raw `http.Request` instance. [union][3] will set the `req.chunks` property for you and director will automatically parse the body. If you wish to perform this buffering yourself directly with `director` you can use a simple request handler in your http server:\n\n``` js\n var http = require('http'),\n director = require('director');\n\n var router = new director.http.Router();\n\n var server = http.createServer(function (req, res) {\n req.chunks = [];\n req.on('data', function (chunk) {\n req.chunks.push(chunk.toString());\n });\n\n router.dispatch(req, res, function (err) {\n if (err) {\n res.writeHead(404);\n res.end();\n }\n\n console.log('Served ' + req.url);\n });\n });\n\n router.post('/', function () {\n this.res.writeHead(200, { 'Content-Type': 'application/json' })\n this.res.end(JSON.stringify(this.req.body));\n });\n```\n\n**Streaming Support**\n\nIf you wish to get access to the request stream before the `end` event is fired, you can pass the `{ stream: true }` options to the route.\n\n``` js\n var director = require('director');\n\n var router = new director.http.Router();\n\n router.get('/', { stream: true }, function () {\n //\n // This will work because the route handler is invoked\n // immediately without waiting for the `end` event.\n //\n this.req.on('data', function (chunk) {\n console.log(chunk);\n });\n });\n```\n\n\n## Instance methods\n\n### configure(options)\n* `options` {Object}: Options to configure this instance with.\n\nConfigures the Router instance with the specified `options`. See [Configuration](#configuration) for more documentation.\n\n### param(token, matcher)\n* token {string}: Named parameter token to set to the specified `matcher`\n* matcher {string|Regexp}: Matcher for the specified `token`.\n\nAdds a route fragment for the given string `token` to the specified regex `matcher` to this Router instance. See [URL Parameters](#url-params) for more documentation.\n\n### on(method, path, route)\n* `method` {string}: Method to insert within the Routing Table (e.g. `on`, `get`, etc.).\n* `path` {string}: Path within the Routing Table to set the `route` to.\n* `route` {function|Array}: Route handler to invoke for the `method` and `path`.\n\nAdds the `route` handler for the specified `method` and `path` within the [Routing Table](#routing-table).\n\n### path(path, routesFn)\n* `path` {string|Regexp}: Scope within the Routing Table to invoke the `routesFn` within.\n* `routesFn` {function}: Adhoc Routing function with calls to `this.on()`, `this.get()` etc.\n\nInvokes the `routesFn` within the scope of the specified `path` for this Router instance.\n\n### dispatch(method, path[, callback])\n* method {string}: Method to invoke handlers for within the Routing Table\n* path {string}: Path within the Routing Table to match\n* callback {function}: Invoked once all route handlers have been called.\n\nDispatches the route handlers matched within the [Routing Table](#routing-table) for this instance for the specified `method` and `path`.\n\n### mount(routes, path)\n* routes {object}: Partial routing table to insert into this instance.\n* path {string|Regexp}: Path within the Routing Table to insert the `routes` into.\n\nInserts the partial [Routing Table](#routing-table), `routes`, into the Routing Table for this Router instance at the specified `path`.\n\n## Instance methods (Client-side only)\n\n### init([redirect])\n* `redirect` {String}: This value will be used if '/#/' is not found in the URL. (e.g., init('/') will resolve to '/#/', init('foo') will resolve to '/#foo').\n\nInitialize the router, start listening for changes to the URL.\n\n### getRoute([index])\n* `index` {Number}: The hash value is divided by forward slashes, each section then has an index, if this is provided, only that section of the route will be returned.\n\nReturns the entire route or just a section of it.\n\n### setRoute(route)\n* `route` {String}: Supply a route value, such as `home/stats`.\n\nSet the current route.\n\n### setRoute(start, length)\n* `start` {Number} - The position at which to start removing items.\n* `length` {Number} - The number of items to remove from the route.\n\nRemove a segment from the current route.\n\n### setRoute(index, value)\n* `index` {Number} - The hash value is divided by forward slashes, each section then has an index.\n* `value` {String} - The new value to assign the the position indicated by the first parameter.\n\nSet a segment of the current route.\n\n\n# Frequently Asked Questions\n\n## What About SEO?\n\nIs using a Client-side router a problem for SEO? Yes. If advertising is a requirement, you are probably building a \"Web Page\" and not a \"Web Application\". Director on the client is meant for script-heavy Web Applications.\n\n# Licence\n\n(The MIT License)\n\nCopyright (c) 2010 Nodejitsu Inc. \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n[0]: http://github.com/flatiron/director\n[1]: https://github.com/flatiron/director/blob/master/build/director.min.js\n[2]: http://github.com/flatiron/flatiron\n[3]: http://github.com/flatiron/union\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/flatiron/director/issues" + }, + "_id": "director@1.1.10", + "dist": { + "shasum": "ec718691211de9a93985c8269f157c9a00ddc820" + }, + "_from": "director@1.1.10", + "_resolved": "https://registry.npmjs.org/director/-/director-1.1.10.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/backend/backend.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/backend/backend.js new file mode 100644 index 0000000..980e58b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/backend/backend.js @@ -0,0 +1,71 @@ +var http = require('http'), + fs = require('fs'), + path = require('path'), + director = require('../../../lib/director'), + index; + +fs.readFile(path.join(__dirname, '..', 'html5-routes-harness.html'), function (err, data) { + if (err) { + throw err; + } + + index = data; +}); + +var CONTENT_TYPES = { + '.js' : 'text/javascript', + '.css' : 'text/css' +}; + +// Dummy file server +function fileServer(folder, file) { + var root = path.resolve(__dirname, '..'); + if (folder === 'build' || folder === 'node_modules') { + root = path.resolve(root, '..', '..'); + } + + var filepath = path.resolve(root, folder, file); + + var res = this.res; + + (fs.exists || path.exists)(filepath, function (exists) { + if (exists) { + fs.readFile(filepath, function (err, data) { + if (err) { + res.writeHead(404); + res.end(); + } + + res.writeHead(200, {'Content-Type': CONTENT_TYPES[path.extname(filepath)]}); + res.end(data); + }); + } else { + res.writeHead(404); + res.end(); + } + }); +} + +var router = new director.http.Router({ + '/files': { + '/:folder': { + '/(.+)': { + get: fileServer + }, + + get: fileServer + } + } +}); + +var server = http.createServer(function (req, res) { + router.dispatch(req, res, function (err) { + if (err && req.url != '/favicon.ico') { + // By default just reply with the index page + this.res.writeHead(200, {'Content-Type': 'text/html'}); + this.res.end(index); + } + }); +}); + +server.listen(8080); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/browserify-harness.html b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/browserify-harness.html new file mode 100644 index 0000000..feffe05 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/browserify-harness.html @@ -0,0 +1,24 @@ + + + + + Director Browserify Tests + + + +

To run these tests first generate a Browserify bundle for director by running the command browserify -r ../director -o test/browser/browserified-bundle.js in the repo's root directory.

+ +
+
+ + + + + + + + + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/helpers/api.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/helpers/api.js new file mode 100644 index 0000000..d784700 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/helpers/api.js @@ -0,0 +1,77 @@ +module("Director.js", { + setup: function() { + window.location.hash = ""; + shared = {}; + // Init needed keys earlier because of in HTML5 mode the route handler + // is executed upon Router.init() and due to that setting shared.fired + // in the param test of createTest is too late + if (HTML5TEST) { + shared.fired = []; + shared.fired_count = 0; + } + }, + teardown: function() { + window.location.hash = ""; + shared = {}; + } +}); + +var shared; + +function createTest(name, config, use, test, initialRoute) { + // We rename to `RouterAlias` for the browserify tests, since we want to be + // sure that no code is depending on `window.Router` being available. + var Router = window.Router || window.RouterAlias; + + if (typeof use === 'function') { + test = use; + use = undefined; + } + + if (HTML5TEST) { + if (use === undefined) { + use = {}; + } + + if (use.run_handler_in_init === undefined) { + use.run_handler_in_init = false; + } + use.html5history = true; + } + + // Because of the use of setTimeout when defining onpopstate + var innerTimeout = HTML5TEST === true ? 500 : 0; + + asyncTest(name, function() { + setTimeout(function() { + var router = new Router(config), + context; + + if (use !== undefined) { + router.configure(use); + } + + router.init(initialRoute); + + setTimeout(function() { + test.call(context = { + router: router, + navigate: function(url, callback) { + if (HTML5TEST) { + router.setRoute(url); + } else { + window.location.hash = url; + } + setTimeout(function() { + callback.call(context); + }, 14); + }, + finish: function() { + router.destroy(); + start(); + } + }) + }, innerTimeout); + }, 14); + }); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/html5-routes-harness.html b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/html5-routes-harness.html new file mode 100644 index 0000000..eaf8ffc --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/html5-routes-harness.html @@ -0,0 +1,23 @@ + + + + + Director HTML5 Tests + + + +

Note: in order to execute HTML5 mode test this file needs to be served with provided nodejs backend. Start the server from director/test/browser/backend and go to http://localhost:8080/ to launch the tests.

+ +
+
+ + + + + + + + + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/html5-routes-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/html5-routes-test.js new file mode 100644 index 0000000..628d3c9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/html5-routes-test.js @@ -0,0 +1,660 @@ +var browser_history_support = (window.history != null ? window.history.pushState : null) != null; + +createTest('Nested route with the many children as a tokens, callbacks should yield historic params', { + '/a': { + '/:id': { + '/:id': function(a, b) { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, ''), a, b); + } else { + shared.fired.push(location.pathname, a, b); + } + } + } + } +}, function() { + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['/a/b/c', 'b', 'c']); + this.finish(); + }); +}); + +createTest('Nested route with the first child as a token, callback should yield a param', { + '/foo': { + '/:id': { + on: function(id) { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, ''), id); + } else { + shared.fired.push(location.pathname, id); + } + } + } + } +}, function() { + this.navigate('/foo/a', function() { + this.navigate('/foo/b/c', function() { + deepEqual(shared.fired, ['/foo/a', 'a']); + this.finish(); + }); + }); +}); + +createTest('Nested route with the first child as a regexp, callback should yield a param', { + '/foo': { + '/(\\w+)': { + on: function(value) { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, ''), value); + } else { + shared.fired.push(location.pathname, value); + } + } + } + } +}, function() { + this.navigate('/foo/a', function() { + this.navigate('/foo/b/c', function() { + deepEqual(shared.fired, ['/foo/a', 'a']); + this.finish(); + }); + }); +}); + +createTest('Nested route with the several regular expressions, callback should yield a param', { + '/a': { + '/(\\w+)': { + '/(\\w+)': function(a, b) { + shared.fired.push(a, b); + } + } + } +}, function() { + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['b', 'c']); + this.finish(); + }); +}); + +createTest('Single nested route with on member containing function value', { + '/a': { + '/b': { + on: function() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + } + } + } +}, function() { + this.navigate('/a/b', function() { + deepEqual(shared.fired, ['/a/b']); + this.finish(); + }); +}); + +createTest('Single non-nested route with on member containing function value', { + '/a/b': { + on: function() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + } + } +}, function() { + this.navigate('/a/b', function() { + deepEqual(shared.fired, ['/a/b']); + this.finish(); + }); +}); + +createTest('Single nested route with on member containing array of function values', { + '/a': { + '/b': { + on: [function() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + }, + function() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + }] + } + } +}, function() { + this.navigate('/a/b', function() { + deepEqual(shared.fired, ['/a/b', '/a/b']); + this.finish(); + }); +}); + +createTest('method should only fire once on the route.', { + '/a': { + '/b': { + once: function() { + shared.fired_count++; + } + } + } +}, function() { + this.navigate('/a/b', function() { + this.navigate('/a/b', function() { + this.navigate('/a/b', function() { + deepEqual(shared.fired_count, 1); + this.finish(); + }); + }); + }); +}); + +createTest('method should only fire once on the route, multiple nesting.', { + '/a': { + on: function() { shared.fired_count++; }, + once: function() { shared.fired_count++; } + }, + '/b': { + on: function() { shared.fired_count++; }, + once: function() { shared.fired_count++; } + } +}, function() { + this.navigate('/a', function() { + this.navigate('/b', function() { + this.navigate('/a', function() { + this.navigate('/b', function() { + deepEqual(shared.fired_count, 6); + this.finish(); + }); + }); + }); + }); +}); + +createTest('overlapping routes with tokens.', { + '/a/:b/c' : function() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + }, + '/a/:b/c/:d' : function() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + } +}, function() { + this.navigate('/a/b/c', function() { + + this.navigate('/a/b/c/d', function() { + deepEqual(shared.fired, ['/a/b/c', '/a/b/c/d']); + this.finish(); + }); + }); +}); + +// // // +// // // Recursion features +// // // ---------------------------------------------------------- + +createTest('Nested routes with no recursion', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, function() { + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['c']); + this.finish(); + }); +}); + +createTest('Nested routes with backward recursion', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'backward' +}, function() { + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['c', 'b', 'a']); + this.finish(); + }); +}); + +createTest('Breaking out of nested routes with backward recursion', { + '/a': { + '/:b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + return false; + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'backward' +}, function() { + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['c', 'b']); + this.finish(); + }); +}); + +createTest('Nested routes with forward recursion', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'forward' +}, function() { + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['a', 'b', 'c']); + this.finish(); + }); +}); + +createTest('Nested routes with forward recursion, single route with an after event.', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + }, + after: function() { + shared.fired.push('c-after'); + } + }, + on: function b() { + shared.fired.push('b'); + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'forward' +}, function() { + this.navigate('/a/b/c', function() { + this.navigate('/a/b', function() { + deepEqual(shared.fired, ['a', 'b', 'c', 'c-after', 'a', 'b']); + this.finish(); + }); + }); +}); + +createTest('Breaking out of nested routes with forward recursion', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + return false; + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'forward' +}, function() { + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['a', 'b']); + this.finish(); + }); +}); + +// +// ABOVE IS WORKING +// + +// // +// // Special Events +// // ---------------------------------------------------------- + +createTest('All global event should fire after every route', { + '/a': { + on: function a() { + shared.fired.push('a'); + } + }, + '/b': { + '/c': { + on: function a() { + shared.fired.push('a'); + } + } + }, + '/d': { + '/:e': { + on: function a() { + shared.fired.push('a'); + } + } + } +}, { + after: function() { + shared.fired.push('b'); + } +}, function() { + this.navigate('/a', function() { + this.navigate('/b/c', function() { + this.navigate('/d/e', function() { + deepEqual(shared.fired, ['a', 'b', 'a', 'b', 'a']); + this.finish(); + }); + }); + }); + +}); + +createTest('Not found.', { + '/a': { + on: function a() { + shared.fired.push('a'); + } + }, + '/b': { + on: function a() { + shared.fired.push('b'); + } + } +}, { + notfound: function() { + shared.fired.push('notfound'); + } +}, function() { + this.navigate('/c', function() { + this.navigate('/d', function() { + deepEqual(shared.fired, ['notfound', 'notfound']); + this.finish(); + }); + }); +}); + +createTest('On all.', { + '/a': { + on: function a() { + shared.fired.push('a'); + } + }, + '/b': { + on: function a() { + shared.fired.push('b'); + } + } +}, { + on: function() { + shared.fired.push('c'); + } +}, function() { + this.navigate('/a', function() { + this.navigate('/b', function() { + deepEqual(shared.fired, ['a', 'c', 'b', 'c']); + this.finish(); + }); + }); +}); + + +createTest('After all.', { + '/a': { + on: function a() { + shared.fired.push('a'); + } + }, + '/b': { + on: function a() { + shared.fired.push('b'); + } + } +}, { + after: function() { + shared.fired.push('c'); + } +}, function() { + this.navigate('/a', function() { + this.navigate('/b', function() { + deepEqual(shared.fired, ['a', 'c', 'b']); + this.finish(); + }); + }); +}); + +createTest('resource object.', { + '/a': { + '/b/:c': { + on: 'f1' + }, + on: 'f2' + }, + '/d': { + on: ['f1', 'f2'] + } +}, +{ + resource: { + f1: function (name){ + shared.fired.push("f1-" + name); + }, + f2: function (name){ + shared.fired.push("f2"); + } + } +}, function() { + this.navigate('/a/b/c', function() { + this.navigate('/d', function() { + deepEqual(shared.fired, ['f1-c', 'f1-undefined', 'f2']); + this.finish(); + }); + }); +}); + +createTest('argument matching should be case agnostic', { + '/fooBar/:name': { + on: function(name) { + shared.fired.push("fooBar-" + name); + } + } +}, function() { + this.navigate('/fooBar/tesTing', function() { + deepEqual(shared.fired, ['fooBar-tesTing']); + this.finish(); + }); +}); + +createTest('sanity test', { + '/is/:this/:sane': { + on: function(a, b) { + shared.fired.push('yes ' + a + ' is ' + b); + } + }, + '/': { + on: function() { + shared.fired.push('is there sanity?'); + } + } +}, function() { + this.navigate('/is/there/sanity', function() { + deepEqual(shared.fired, ['yes there is sanity']); + this.finish(); + }); +}); + +createTest('`/` route should be navigable from the routing table', { + '/': { + on: function root() { + shared.fired.push('/'); + } + }, + '/:username': { + on: function afunc(username) { + shared.fired.push('/' + username); + } + } +}, function() { + this.navigate('/', function root() { + deepEqual(shared.fired, ['/']); + this.finish(); + }); +}); + +createTest('`/` route should not override a `/:token` route', { + '/': { + on: function root() { + shared.fired.push('/'); + } + }, + '/:username': { + on: function afunc(username) { + shared.fired.push('/' + username); + } + } +}, function() { + this.navigate('/a', function afunc() { + deepEqual(shared.fired, ['/a']); + this.finish(); + }); +}); + +createTest('should accept the root as a token.', { + '/:a': { + on: function root() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + } + } +}, function() { + this.navigate('/a', function root() { + deepEqual(shared.fired, ['/a']); + this.finish(); + }); +}); + +createTest('routes should allow wildcards.', { + '/:a/b*d': { + on: function() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + } + } +}, function() { + this.navigate('/a/bcd', function root() { + deepEqual(shared.fired, ['/a/bcd']); + this.finish(); + }); +}); + +createTest('functions should have |this| context of the router instance.', { + '/': { + on: function root() { + shared.fired.push(!!this.routes); + } + } +}, function() { + this.navigate('/', function root() { + deepEqual(shared.fired, [true]); + this.finish(); + }); +}); + +createTest('setRoute with a single parameter should change location correctly', { + '/bonk': { + on: function() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(window.location.pathname); + } + } + } +}, function() { + var self = this; + this.router.setRoute('/bonk'); + setTimeout(function() { + deepEqual(shared.fired, ['/bonk']); + self.finish(); + }, 14) +}); + +createTest('route should accept _ and . within parameters', { + '/:a': { + on: function root() { + if (!browser_history_support) { + shared.fired.push(location.hash.replace(/^#/, '')); + } else { + shared.fired.push(location.pathname); + } + } + } +}, function() { + this.navigate('/a_complex_route.co.uk', function root() { + deepEqual(shared.fired, ['/a_complex_route.co.uk']); + this.finish(); + }); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/routes-harness.html b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/routes-harness.html new file mode 100644 index 0000000..c97c826 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/routes-harness.html @@ -0,0 +1,21 @@ + + + + + Director Tests + + + +
+
+ + + + + + + + + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/routes-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/routes-test.js new file mode 100644 index 0000000..1cb8d95 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/browser/routes-test.js @@ -0,0 +1,694 @@ + +createTest('Nested route with the many children as a tokens, callbacks should yield historic params', { + '/a': { + '/:id': { + '/:id': function(a, b) { + shared.fired.push(location.hash, a, b); + } + } + } +}, function() { + shared.fired = []; + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['#/a/b/c', 'b', 'c']); + this.finish(); + }); +}); + +createTest('Nested route with the first child as a token, callback should yield a param', { + '/foo': { + '/:id': { + on: function(id) { + shared.fired.push(location.hash, id); + } + } + } +}, function() { + shared.fired = []; + this.navigate('/foo/a', function() { + this.navigate('/foo/b/c', function() { + deepEqual(shared.fired, ['#/foo/a', 'a']); + this.finish(); + }); + }); +}); + +createTest('Nested route with the first child as a regexp, callback should yield a param', { + '/foo': { + '/(\\w+)': { + on: function(value) { + shared.fired.push(location.hash, value); + } + } + } +}, function() { + shared.fired = []; + this.navigate('/foo/a', function() { + this.navigate('/foo/b/c', function() { + deepEqual(shared.fired, ['#/foo/a', 'a']); + this.finish(); + }); + }); +}); + +createTest('Nested route with the several regular expressions, callback should yield a param', { + '/a': { + '/(\\w+)': { + '/(\\w+)': function(a, b) { + shared.fired.push(a, b); + } + } + } +}, function() { + shared.fired = []; + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['b', 'c']); + this.finish(); + }); +}); + + + +createTest('Single nested route with on member containing function value', { + '/a': { + '/b': { + on: function() { + shared.fired.push(location.hash); + } + } + } +}, function() { + shared.fired = []; + this.navigate('/a/b', function() { + deepEqual(shared.fired, ['#/a/b']); + this.finish(); + }); +}); + +createTest('Single non-nested route with on member containing function value', { + '/a/b': { + on: function() { + shared.fired.push(location.hash); + } + } +}, function() { + shared.fired = []; + this.navigate('/a/b', function() { + deepEqual(shared.fired, ['#/a/b']); + this.finish(); + }); +}); + +createTest('Single nested route with on member containing array of function values', { + '/a': { + '/b': { + on: [function() { shared.fired.push(location.hash); }, + function() { shared.fired.push(location.hash); }] + } + } +}, function() { + shared.fired = []; + this.navigate('/a/b', function() { + deepEqual(shared.fired, ['#/a/b', '#/a/b']); + this.finish(); + }); +}); + +createTest('method should only fire once on the route.', { + '/a': { + '/b': { + once: function() { + shared.fired++; + } + } + } +}, function() { + shared.fired = 0; + this.navigate('/a/b', function() { + this.navigate('/a/b', function() { + this.navigate('/a/b', function() { + deepEqual(shared.fired, 1); + this.finish(); + }); + }); + }); +}); + +createTest('method should only fire once on the route, multiple nesting.', { + '/a': { + on: function() { shared.fired++; }, + once: function() { shared.fired++; } + }, + '/b': { + on: function() { shared.fired++; }, + once: function() { shared.fired++; } + } +}, function() { + shared.fired = 0; + this.navigate('/a', function() { + this.navigate('/b', function() { + this.navigate('/a', function() { + this.navigate('/b', function() { + deepEqual(shared.fired, 6); + this.finish(); + }); + }); + }); + }); +}); + +createTest('overlapping routes with tokens.', { + '/a/:b/c' : function() { + shared.fired.push(location.hash); + }, + '/a/:b/c/:d' : function() { + shared.fired.push(location.hash); + } +}, function() { + shared.fired = []; + this.navigate('/a/b/c', function() { + + this.navigate('/a/b/c/d', function() { + deepEqual(shared.fired, ['#/a/b/c', '#/a/b/c/d']); + this.finish(); + }); + }); +}); + +// // // +// // // Recursion features +// // // ---------------------------------------------------------- + +createTest('Nested routes with no recursion', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, function() { + shared.fired = []; + + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['c']); + this.finish(); + }); +}); + +createTest('Nested routes with backward recursion', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'backward' +}, function() { + shared.fired = []; + + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['c', 'b', 'a']); + this.finish(); + }); +}); + +createTest('Breaking out of nested routes with backward recursion', { + '/a': { + '/:b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + return false; + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'backward' +}, function() { + shared.fired = []; + + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['c', 'b']); + this.finish(); + }); +}); + +createTest('Nested routes with forward recursion', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'forward' +}, function() { + shared.fired = []; + + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['a', 'b', 'c']); + this.finish(); + }); +}); + +createTest('Nested routes with forward recursion, single route with an after event.', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + }, + after: function() { + shared.fired.push('c-after'); + } + }, + on: function b() { + shared.fired.push('b'); + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'forward' +}, function() { + shared.fired = []; + + this.navigate('/a/b/c', function() { + this.navigate('/a/b', function() { + deepEqual(shared.fired, ['a', 'b', 'c', 'c-after', 'a', 'b']); + this.finish(); + }); + }); +}); + +createTest('Breaking out of nested routes with forward recursion', { + '/a': { + '/b': { + '/c': { + on: function c() { + shared.fired.push('c'); + } + }, + on: function b() { + shared.fired.push('b'); + return false; + } + }, + on: function a() { + shared.fired.push('a'); + } + } +}, { + recurse: 'forward' +}, function() { + shared.fired = []; + + this.navigate('/a/b/c', function() { + deepEqual(shared.fired, ['a', 'b']); + this.finish(); + }); +}); + +// +// ABOVE IS WORKING +// + +// // +// // Special Events +// // ---------------------------------------------------------- + +createTest('All global event should fire after every route', { + '/a': { + on: function a() { + shared.fired.push('a'); + } + }, + '/b': { + '/c': { + on: function a() { + shared.fired.push('a'); + } + } + }, + '/d': { + '/:e': { + on: function a() { + shared.fired.push('a'); + } + } + } +}, { + after: function() { + shared.fired.push('b'); + } +}, function() { + shared.fired = []; + + this.navigate('/a', function() { + this.navigate('/b/c', function() { + this.navigate('/d/e', function() { + deepEqual(shared.fired, ['a', 'b', 'a', 'b', 'a']); + this.finish(); + }); + }); + }); + +}); + +createTest('Not found.', { + '/a': { + on: function a() { + shared.fired.push('a'); + } + }, + '/b': { + on: function a() { + shared.fired.push('b'); + } + } +}, { + notfound: function() { + shared.fired.push('notfound'); + } +}, function() { + shared.fired = []; + + this.navigate('/c', function() { + this.navigate('/d', function() { + deepEqual(shared.fired, ['notfound', 'notfound']); + this.finish(); + }); + }); +}); + +createTest('On all.', { + '/a': { + on: function a() { + shared.fired.push('a'); + } + }, + '/b': { + on: function a() { + shared.fired.push('b'); + } + } +}, { + on: function() { + shared.fired.push('c'); + } +}, function() { + shared.fired = []; + + this.navigate('/a', function() { + this.navigate('/b', function() { + deepEqual(shared.fired, ['a', 'c', 'b', 'c']); + this.finish(); + }); + }); +}); + + +createTest('After all.', { + '/a': { + on: function a() { + shared.fired.push('a'); + } + }, + '/b': { + on: function a() { + shared.fired.push('b'); + } + } +}, { + after: function() { + shared.fired.push('c'); + } +}, function() { + shared.fired = []; + + this.navigate('/a', function() { + this.navigate('/b', function() { + deepEqual(shared.fired, ['a', 'c', 'b']); + this.finish(); + }); + }); +}); + +createTest('resource object.', { + '/a': { + '/b/:c': { + on: 'f1' + }, + on: 'f2' + }, + '/d': { + on: ['f1', 'f2'] + } +}, +{ + resource: { + f1: function (name){ + shared.fired.push("f1-" + name); + }, + f2: function (name){ + shared.fired.push("f2"); + } + } +}, function() { + shared.fired = []; + + this.navigate('/a/b/c', function() { + this.navigate('/d', function() { + deepEqual(shared.fired, ['f1-c', 'f1-undefined', 'f2']); + this.finish(); + }); + }); +}); + +createTest('argument matching should be case agnostic', { + '/fooBar/:name': { + on: function(name) { + shared.fired.push("fooBar-" + name); + } + } +}, function() { + shared.fired = []; + this.navigate('/fooBar/tesTing', function() { + deepEqual(shared.fired, ['fooBar-tesTing']); + this.finish(); + }); +}); + +createTest('sanity test', { + '/is/:this/:sane': { + on: function(a, b) { + shared.fired.push('yes ' + a + ' is ' + b); + } + }, + '/': { + on: function() { + shared.fired.push('is there sanity?'); + } + } +}, function() { + shared.fired = []; + this.navigate('/is/there/sanity', function() { + deepEqual(shared.fired, ['yes there is sanity']); + this.finish(); + }); +}); + +createTest('`/` route should be navigable from the routing table', { + '/': { + on: function root() { + shared.fired.push('/'); + } + }, + '/:username': { + on: function afunc(username) { + shared.fired.push('/' + username); + } + } +}, function() { + shared.fired = []; + this.navigate('/', function root() { + deepEqual(shared.fired, ['/']); + this.finish(); + }); +}); + +createTest('`/` route should not override a `/:token` route', { + '/': { + on: function root() { + shared.fired.push('/'); + } + }, + '/:username': { + on: function afunc(username) { + shared.fired.push('/' + username); + } + } +}, function() { + shared.fired = []; + this.navigate('/a', function afunc() { + deepEqual(shared.fired, ['/a']); + this.finish(); + }); +}); + +createTest('should accept the root as a token.', { + '/:a': { + on: function root() { + shared.fired.push(location.hash); + } + } +}, function() { + shared.fired = []; + this.navigate('/a', function root() { + deepEqual(shared.fired, ['#/a']); + this.finish(); + }); +}); + +createTest('routes should allow wildcards.', { + '/:a/b*d': { + on: function() { + shared.fired.push(location.hash); + } + } +}, function() { + shared.fired = []; + this.navigate('/a/bcd', function root() { + deepEqual(shared.fired, ['#/a/bcd']); + this.finish(); + }); +}); + +createTest('functions should have |this| context of the router instance.', { + '/': { + on: function root() { + shared.fired.push(!!this.routes); + } + } +}, function() { + shared.fired = []; + this.navigate('/', function root() { + deepEqual(shared.fired, [true]); + this.finish(); + }); +}); + +createTest('setRoute with a single parameter should change location correctly', { + '/bonk': { + on: function() { + shared.fired.push(window.location.hash); + } + } +}, function() { + var self = this; + shared.fired = []; + this.router.setRoute('/bonk'); + setTimeout(function() { + deepEqual(shared.fired, ['#/bonk']); + self.finish(); + }, 14) +}); + +createTest('route should accept _ and . within parameters', { + '/:a': { + on: function root() { + shared.fired.push(location.hash); + } + } +}, function() { + shared.fired = []; + this.navigate('/a_complex_route.co.uk', function root() { + deepEqual(shared.fired, ['#/a_complex_route.co.uk']); + this.finish(); + }); +}); + +createTest('initializing with a default route should only result in one route handling', { + '/': { + on: function root() { + if (!shared.init){ + shared.init = 0; + } + shared.init++; + } + }, + '/test': { + on: function root() { + if (!shared.test){ + shared.test = 0; + } + shared.test++; + } + } + }, function() { + this.navigate('/test', function root() { + equal(shared.init, 1); + equal(shared.test, 1); + this.finish(); + }); + }, + null, + '/'); + +createTest('changing the hash twice should call each route once', { + '/hash1': { + on: function root() { + shared.fired.push('hash1'); + } + }, + '/hash2': { + on: function root() { + shared.fired.push('hash2'); + } + } + }, function() { + shared.fired = []; + this.navigate('/hash1', function(){}); + this.navigate('/hash2', function(){ + deepEqual(shared.fired, ['hash1', 'hash2']); + this.finish(); + }); + } +); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/dispatch-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/dispatch-test.js new file mode 100644 index 0000000..89a88ce --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/dispatch-test.js @@ -0,0 +1,55 @@ +/* + * dispatch-test.js: Tests for the core dispatch method. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/cli/dispatch').addBatch({ + "An instance of director.cli.Router": { + topic: function () { + var router = new director.cli.Router(), + that = this; + + that.matched = {}; + that.matched['users'] = []; + that.matched['apps'] = [] + + router.on('users create', function () { + that.matched['users'].push('on users create'); + }); + + router.on(/apps (\w+\s\w+)/, function () { + assert.equal(arguments.length, 1); + that.matched['apps'].push('on apps (\\w+\\s\\w+)'); + }); + + return router; + }, + "should have the correct routing table": function (router) { + assert.isObject(router.routes.users); + assert.isObject(router.routes.users.create); + }, + "the dispatch() method": { + "users create": function (router) { + assert.isTrue(router.dispatch('on', 'users create')); + assert.equal(this.matched.users[0], 'on users create'); + }, + "apps foo bar": function (router) { + assert.isTrue(router.dispatch('on', 'apps foo bar')); + assert.equal(this.matched['apps'][0], 'on apps (\\w+\\s\\w+)'); + }, + "not here": function (router) { + assert.isFalse(router.dispatch('on', 'not here')); + }, + "still not here": function (router) { + assert.isFalse(router.dispatch('on', 'still not here')); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/mount-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/mount-test.js new file mode 100644 index 0000000..366aefd --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/mount-test.js @@ -0,0 +1,30 @@ +/* + * mount-test.js: Tests for the core mount method. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/cli/path').addBatch({ + "An instance of director.cli.Router with routes": { + topic: new director.cli.Router({ + 'apps': function () { + console.log('apps'); + }, + ' users': function () { + console.log('users'); + } + }), + "should create the correct nested routing table": function (router) { + assert.isObject(router.routes.apps); + assert.isFunction(router.routes.apps.on); + assert.isObject(router.routes.users); + assert.isFunction(router.routes.users.on); + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/path-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/path-test.js new file mode 100644 index 0000000..8cce059 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/cli/path-test.js @@ -0,0 +1,39 @@ +/* + * dispatch-test.js: Tests for the core dispatch method. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/cli/path').addBatch({ + "An instance of director.cli.Router": { + topic: new director.cli.Router(), + "the path() method": { + "should create the correct nested routing table": function (router) { + function noop () {} + + router.path(/apps/, function () { + router.path(/foo/, function () { + router.on(/bar/, noop); + }); + + router.on(/list/, noop); + }); + + router.on(/users/, noop); + + assert.isObject(router.routes.apps); + assert.isFunction(router.routes.apps.list.on); + assert.isObject(router.routes.apps.foo); + assert.isFunction(router.routes.apps.foo.bar.on); + assert.isFunction(router.routes.users.on); + } + } + } +}).export(module); + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/dispatch-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/dispatch-test.js new file mode 100644 index 0000000..e21fd1a --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/dispatch-test.js @@ -0,0 +1,113 @@ +/* + * dispatch-test.js: Tests for the core dispatch method. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/core/dispatch').addBatch({ + "An instance of director.Router": { + topic: function () { + var that = this; + that.matched = {}; + that.matched['/'] = []; + that.matched['foo'] = []; + that.matched['f*'] = [] + + var router = new director.Router({ + '/': { + before: function () { that.matched['/'].push('before /') }, + on: function () { that.matched['/'].push('on /') }, + after: function () { that.matched['/'].push('after /') } + }, + '/foo': { + before: function () { that.matched.foo.push('before foo') }, + on: function () { that.matched.foo.push('on foo') }, + after: function () { that.matched.foo.push('after foo') }, + '/bar': { + before: function () { that.matched.foo.push('before foo bar') }, + on: function () { that.matched.foo.push('foo bar') }, + after: function () { that.matched.foo.push('after foo bar') }, + '/buzz': function () { that.matched.foo.push('foo bar buzz') } + } + }, + '/f*': { + '/barbie': function () { that.matched['f*'].push('f* barbie') } + } + }); + + router.configure({ + recurse: 'backward' + }); + + return router; + }, + "should have the correct routing table": function (router) { + assert.isObject(router.routes.foo); + assert.isObject(router.routes.foo.bar); + assert.isObject(router.routes.foo.bar.buzz); + assert.isFunction(router.routes.foo.bar.buzz.on); + }, + "the dispatch() method": { + "/": function (router) { + assert.isTrue(router.dispatch('on', '/')); + assert.isTrue(router.dispatch('on', '/')); + + assert.equal(this.matched['/'][0], 'before /'); + assert.equal(this.matched['/'][1], 'on /'); + assert.equal(this.matched['/'][2], 'after /'); + }, + "/foo/bar/buzz": function (router) { + assert.isTrue(router.dispatch('on', '/foo/bar/buzz')); + + assert.equal(this.matched.foo[0], 'foo bar buzz'); + assert.equal(this.matched.foo[1], 'before foo bar'); + assert.equal(this.matched.foo[2], 'foo bar'); + assert.equal(this.matched.foo[3], 'before foo'); + assert.equal(this.matched.foo[4], 'on foo'); + }, + "/foo/barbie": function (router) { + assert.isTrue(router.dispatch('on', '/foo/barbie')); + assert.equal(this.matched['f*'][0], 'f* barbie'); + }, + "/foo/barbie/": function (router) { + assert.isFalse(router.dispatch('on', '/foo/barbie/')); + }, + "/foo/BAD": function (router) { + assert.isFalse(router.dispatch('on', '/foo/BAD')); + }, + "/bar/bar": function (router) { + assert.isFalse(router.dispatch('on', '/bar/bar')); + }, + "with the strict option disabled": { + topic: function (router) { + return router.configure({ + recurse: 'backward', + strict: false + }); + }, + "should have the proper configuration set": function (router) { + assert.isFalse(router.strict); + }, + "/foo/barbie/": function (router) { + assert.isTrue(router.dispatch('on', '/foo/barbie/')); + assert.equal(this.matched['f*'][0], 'f* barbie'); + }, + "/foo/bar/buzz": function (router) { + assert.isTrue(router.dispatch('on', '/foo/bar/buzz')); + + assert.equal(this.matched.foo[0], 'foo bar buzz'); + assert.equal(this.matched.foo[1], 'before foo bar'); + assert.equal(this.matched.foo[2], 'foo bar'); + assert.equal(this.matched.foo[3], 'before foo'); + assert.equal(this.matched.foo[4], 'on foo'); + }, + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/insert-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/insert-test.js new file mode 100644 index 0000000..29dcbb3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/insert-test.js @@ -0,0 +1,45 @@ +/* + * insert-test.js: Tests for inserting routes into a normalized routing table. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/core/insert').addBatch({ + "An instance of director.Router": { + topic: new director.Router(), + "the insert() method": { + "'on', ['foo', 'bar']": function (router) { + function route () { } + + router.insert('on', ['foo', 'bar'], route); + assert.strictEqual(router.routes.foo.bar.on, route); + }, + "'on', ['foo', 'bar'] again": function (router) { + function route () { } + + router.insert('on', ['foo', 'bar'], route); + assert.isArray(router.routes.foo.bar.on); + assert.strictEqual(router.routes.foo.bar.on.length, 2); + }, + "'on', ['foo', 'bar'] a third time": function (router) { + function route () { } + + router.insert('on', ['foo', 'bar'], route); + assert.isArray(router.routes.foo.bar.on); + assert.strictEqual(router.routes.foo.bar.on.length, 3); + }, + "'get', ['fizz', 'buzz']": function (router) { + function route () { } + + router.insert('get', ['fizz', 'buzz'], route); + assert.strictEqual(router.routes.fizz.buzz.get, route); + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/mount-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/mount-test.js new file mode 100644 index 0000000..44fd29c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/mount-test.js @@ -0,0 +1,117 @@ +/* + * mount-test.js: Tests for mounting and normalizing routes into a Router instance. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +function assertRoute (fn, path, route) { + if (path.length === 1) { + return assert.strictEqual(route[path.shift()], fn); + } + + route = route[path.shift()]; + assert.isObject(route); + assertRoute(fn, path, route); +} + +vows.describe('director/core/mount').addBatch({ + "An instance of director.Router": { + "with no preconfigured params": { + topic: new director.Router(), + "the mount() method": { + "should sanitize the routes correctly": function (router) { + function foobar () { } + function foostar () { } + function foobazzbuzz () { } + function foodog () { } + function root () {} + var fnArray = [foobar, foostar]; + + router.mount({ + '/': { + before: root, + on: root, + after: root, + '/nesting': { + on: foobar, + '/deep': foostar + } + }, + '/foo': { + '/bar': foobar, + '/*': foostar, + '/jitsu/then': { + before: foobar + } + }, + '/foo/bazz': { + '/buzz': foobazzbuzz + }, + '/foo/jitsu': { + '/then': fnArray + }, + '/foo/jitsu/then/now': foostar, + '/foo/:dog': foodog + }); + + assertRoute(root, ['on'], router.routes); + assertRoute(root, ['after'], router.routes); + assertRoute(root, ['before'], router.routes); + assertRoute(foobar, ['nesting', 'on'], router.routes); + assertRoute(foostar, ['nesting', 'deep', 'on'], router.routes); + assertRoute(foobar, [ 'foo', 'bar', 'on'], router.routes); + assertRoute(foostar, ['foo', '([_.()!\\ %@&a-zA-Z0-9-]+)', 'on'], router.routes); + assertRoute(fnArray, ['foo', 'jitsu', 'then', 'on'], router.routes); + assertRoute(foobar, ['foo', 'jitsu', 'then', 'before'], router.routes); + assertRoute(foobazzbuzz, ['foo', 'bazz', 'buzz', 'on'], router.routes); + assertRoute(foostar, ['foo', 'jitsu', 'then', 'now', 'on'], router.routes); + assertRoute(foodog, ['foo', '([._a-zA-Z0-9-]+)', 'on'], router.routes); + }, + + "should accept string path": function(router) { + function dogs () { } + + router.mount({ + '/dogs': { + on: dogs + } + }, + '/api'); + + assertRoute(dogs, ['api', 'dogs', 'on'], router.routes); + } + } + }, + "with preconfigured params": { + topic: function () { + var router = new director.Router(); + router.param('city', '([\\w\\-]+)'); + router.param(':country', /([A-Z][A-Za-z]+)/); + router.param(':zip', /([\d]{5})/); + return router; + }, + "should sanitize the routes correctly": function (router) { + function usaCityZip () { } + function countryCityZip () { } + + router.mount({ + '/usa/:city/:zip': usaCityZip, + '/world': { + '/:country': { + '/:city/:zip': countryCityZip + } + } + }); + + assertRoute(usaCityZip, ['usa', '([\\w\\-]+)', '([\\d]{5})', 'on'], router.routes); + assertRoute(countryCityZip, ['world', '([A-Z][A-Za-z]+)', '([\\w\\-]+)', '([\\d]{5})', 'on'], router.routes); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/on-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/on-test.js new file mode 100644 index 0000000..329ee8d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/on-test.js @@ -0,0 +1,38 @@ +/* + * on-test.js: Tests for the on/route method. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/core/insert').addBatch({ + "An instance of director.Router": { + topic: new director.Router(), + "the on() method": { + "['foo', 'bar']": function (router) { + function noop () { } + + router.on(['foo', 'bar'], noop); + assert.strictEqual(router.routes.foo.on, noop); + assert.strictEqual(router.routes.bar.on, noop); + }, + "'baz'": function (router) { + function noop () { } + + router.on('baz', noop); + assert.strictEqual(router.routes.baz.on, noop); + }, + "'after', 'baz'": function (router) { + function noop () { } + + router.on('after', 'boo', noop); + assert.strictEqual(router.routes.boo.after, noop); + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/path-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/path-test.js new file mode 100644 index 0000000..e038e3c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/path-test.js @@ -0,0 +1,49 @@ +/* + * path-test.js: Tests for the core `.path()` method. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/core/path').addBatch({ + "An instance of director.Router": { + topic: function () { + var that = this; + that.matched = {}; + that.matched['foo'] = []; + that.matched['newyork'] = []; + + var router = new director.Router({ + '/foo': function () { that.matched['foo'].push('foo'); } + }); + return router; + }, + "the path() method": { + "should create the correct nested routing table": function (router) { + var that = this; + router.path('/regions', function () { + this.on('/:state', function(country) { + that.matched['newyork'].push('new york'); + }); + }); + + assert.isFunction(router.routes.foo.on); + assert.isObject(router.routes.regions); + assert.isFunction(router.routes.regions['([._a-zA-Z0-9-]+)'].on); + }, + "should dispatch the function correctly": function (router) { + router.dispatch('on', '/regions/newyork') + router.dispatch('on', '/foo'); + assert.equal(this.matched['foo'].length, 1); + assert.equal(this.matched['newyork'].length, 1); + assert.equal(this.matched['foo'][0], 'foo'); + assert.equal(this.matched['newyork'][0], 'new york'); + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/regifystring-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/regifystring-test.js new file mode 100644 index 0000000..24cb38f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/core/regifystring-test.js @@ -0,0 +1,103 @@ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +var callback = function() { + return true; +}; + +var testRoute = function(route, callback) { + var router = new director.Router(); + router.on(route, callback); + + return function(value) { + return router.dispatch('on', value); + }; +}; + +vows.describe('director/core/regifyString').addBatch({ + + 'When using "/home(.*)"': { + topic: function() { + return testRoute('/home(.*)', callback); + }, + + 'Should match "/homepage"': function(result) { + assert.isTrue(result('/homepage')); + }, + + 'Should match "/home/page"': function(result) { + assert.isTrue(result('/home/page')); + }, + + 'Should not match "/foo-bar"': function(result) { + assert.isFalse(result('/foo-bar')); + } + }, + + 'When using "/home.*"': { + topic: function() { + return testRoute('/home.*', callback); + }, + + 'Should match "/homepage"': function(result) { + assert.isTrue(result('/homepage')); + }, + + 'Should match "/home/page"': function(result) { + assert.isTrue(result('/home/page')); + }, + + 'Should not match "/foo-bar"': function(result) { + assert.isFalse(result('/foo-bar')); + } + }, + + 'When using "/home(page[0-9])*"': { + topic: function() { + return testRoute('/home(page[0-9])*', callback); + }, + + 'Should match "/home"': function(result) { + assert.isTrue(result('/home')); + }, + + 'Should match "/homepage0", "/homepage1", etc.': function(result) { + for (i = 0; i < 10; i++) { + assert.isTrue(result('/homepage' + i)); + } + }, + + 'Should not match "/home_page"': function(result) { + assert.isFalse(result('/home_page')); + }, + + 'Should not match "/home/page"': function(result) { + assert.isFalse(result('/home/page')); + } + }, + + 'When using "/home*"': { + topic: function() { + return testRoute('/home*', callback); + }, + + 'Should match "/homepage"': function(result) { + assert.isTrue(result('/homepage')); + }, + + 'Should match "/home_page"': function(result) { + assert.isTrue(result('/home_page')); + }, + + 'Should match "/home-page"': function(result) { + assert.isTrue(result('/home-page')); + }, + + 'Should not match "/home/page"': function(result) { + assert.isFalse(result('/home/page')); + } + } + +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/helpers/index.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/helpers/index.js new file mode 100644 index 0000000..25630a1 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/helpers/index.js @@ -0,0 +1,52 @@ +/* + * index.js: Test helpers for director. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var http = require('http'); + +exports.createServer = function (router) { + return http.createServer(function (req, res) { + router.dispatch(req, res, function (err) { + if (err) { + res.writeHead(404); + res.end(); + } + }); + }); +}; + +exports.handlers = { + respondWithId: function (id) { + this.res.writeHead(200, { 'Content-Type': 'text/plain' }) + this.res.end('hello from (' + id + ')'); + }, + respondWithData: function () { + this.res.writeHead(200, { 'Content-Type': 'application/json' }) + this.res.end(JSON.stringify(this.data)); + }, + respondWithOk: function () { + return function () { + this.res.writeHead(200); + this.res.end('ok'); + }; + }, + streamBody: function () { + var body = '', + res = this.res; + + this.req.on('data', function (chunk) { + body += chunk; + }); + + this.req.on('end', function () { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(body); + }); + } +}; + +exports.macros = require('./macros'); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/helpers/macros.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/helpers/macros.js new file mode 100644 index 0000000..3dc18f2 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/helpers/macros.js @@ -0,0 +1,55 @@ +/* + * macros.js: Test macros for director tests. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + request = require('request'); + +exports.assertGet = function(port, uri, expected) { + var context = { + topic: function () { + request({ uri: 'http://localhost:' + port + '/' + uri }, this.callback); + } + }; + + context['should respond with `' + expected + '`'] = function (err, res, body) { + assert.isNull(err); + assert.equal(res.statusCode, 200); + assert.equal(body, expected); + }; + + return context; +}; + +exports.assert404 = function (port, uri) { + return { + topic: function () { + request({ uri: 'http://localhost:' + port + '/' + uri }, this.callback); + }, + "should respond with 404": function (err, res, body) { + assert.isNull(err); + assert.equal(res.statusCode, 404); + } + }; +}; + +exports.assertPost = function(port, uri, expected) { + return { + topic: function () { + request({ + method: 'POST', + uri: 'http://localhost:' + port + '/' + uri, + body: JSON.stringify(expected) + }, this.callback); + }, + "should respond with the POST body": function (err, res, body) { + assert.isNull(err); + assert.equal(res.statusCode, 200); + assert.deepEqual(JSON.parse(body), expected); + } + }; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/accept-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/accept-test.js new file mode 100644 index 0000000..564301f --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/accept-test.js @@ -0,0 +1,88 @@ +/* + * accept-test.js: Tests for `content-type`-based routing + * + * (C) 2012, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + apiEasy = require('api-easy'), + director = require('../../../lib/director'), + helpers = require('../helpers'), + macros = helpers.macros, + handlers = helpers.handlers; + +var PORT = 9067; + +apiEasy.describe('director/http/accept') + .addBatch({ + "An instance of `director.http.Router`": { + "with routes set up": { + topic: function () { + var router = new director.http.Router(); + router.get('/json', { accept: 'application/json' }, handlers.respondWithOk()); + router.get('/txt', { accept: 'text/plain' }, handlers.respondWithOk()); + router.get('/both', { accept: ['text/plain', 'application/json'] }, handlers.respondWithOk()); + router.get('/regex', { accept: /.+\/x\-.+/ }, handlers.respondWithOk()); + + router.get('/weird', { accept: 'application/json' }, function () { + this.res.writeHead(400); + this.res.end(); + }); + + router.get('/weird', handlers.respondWithOk()); + + helpers.createServer(router).listen(PORT, this.callback); + }, + "should be created": function (err) { + assert(!err); + } + } + } + }) + .use('localhost', PORT) + .discuss('with `content-type: application/json`') + .setHeader('content-type', 'application/json') + .get('/json') + .expect(200) + .get('/txt') + .expect(404) + .get('/both') + .expect(200) + .get('/regex') + .expect(404) + .get('/weird') + .expect(400) + .undiscuss() + .next() + .discuss('with `content-type: text/plain`') + .setHeader('content-type', 'text/plain') + .get('/json') + .expect(404) + .get('/txt') + .expect(200) + .get('/both') + .expect(200) + .get('/regex') + .expect(404) + .get('/weird') + .expect(200) + .undiscuss() + .next() + .discuss('with `content-type: application/x-tar-gz`') + .setHeader('content-type', 'application/x-tar-gz`') + .get('/json') + .get('/json') + .expect(404) + .get('/txt') + .expect(404) + .get('/both') + .expect(404) + .get('/regex') + .expect(200) + .get('/weird') + .expect(200) + .undiscuss() + .export(module); + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/attach-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/attach-test.js new file mode 100644 index 0000000..1859b30 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/attach-test.js @@ -0,0 +1,51 @@ +/* + * attach-test.js: Tests 'router.attach' functionality. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + http = require('http'), + vows = require('vows'), + request = require('request'), + director = require('../../../lib/director'), + helpers = require('../helpers'), + handlers = helpers.handlers, + macros = helpers.macros; + +function assertData(uri) { + return macros.assertGet( + 9091, + uri, + JSON.stringify([1,2,3]) + ); +} + +vows.describe('director/http/attach').addBatch({ + "An instance of director.http.Router": { + "instantiated with a Routing table": { + topic: new director.http.Router({ + '/hello': { + get: handlers.respondWithData + } + }), + "should have the correct routes defined": function (router) { + assert.isObject(router.routes.hello); + assert.isFunction(router.routes.hello.get); + }, + "when passed to an http.Server instance": { + topic: function (router) { + router.attach(function () { + this.data = [1,2,3]; + }); + + helpers.createServer(router) + .listen(9091, this.callback); + }, + "a request to hello": assertData('hello'), + } + } + } +}).export(module); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/before-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/before-test.js new file mode 100644 index 0000000..824edc0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/before-test.js @@ -0,0 +1,38 @@ +/* + * before-test.js: Tests for running before methods on HTTP server(s). + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + http = require('http'), + vows = require('vows'), + request = require('request'), + director = require('../../../lib/director'), + helpers = require('../helpers'), + handlers = helpers.handlers, + macros = helpers.macros; + +vows.describe('director/http/before').addBatch({ + "An instance of director.http.Router": { + "with ad-hoc routes including .before()": { + topic: function () { + var router = new director.http.Router(); + + router.before('/hello', function () { }); + router.after('/hello', function () { }); + router.get('/hello', handlers.respondWithId); + + return router; + }, + "should have the correct routes defined": function (router) { + assert.isObject(router.routes.hello); + assert.isFunction(router.routes.hello.before); + assert.isFunction(router.routes.hello.after); + assert.isFunction(router.routes.hello.get); + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/http-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/http-test.js new file mode 100644 index 0000000..e318fbd --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/http-test.js @@ -0,0 +1,65 @@ +/* + * http-test.js: Tests for basic HTTP server(s). + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + http = require('http'), + vows = require('vows'), + request = require('request'), + director = require('../../../lib/director'), + helpers = require('../helpers'), + handlers = helpers.handlers, + macros = helpers.macros; + +function assertBark(uri) { + return macros.assertGet( + 9090, + uri, + 'hello from (bark)' + ); +} + +vows.describe('director/http').addBatch({ + "An instance of director.http.Router": { + "instantiated with a Routing table": { + topic: new director.http.Router({ + '/hello': { + get: handlers.respondWithId + } + }), + "should have the correct routes defined": function (router) { + assert.isObject(router.routes.hello); + assert.isFunction(router.routes.hello.get); + }, + "when passed to an http.Server instance": { + topic: function (router) { + router.get(/foo\/bar\/(\w+)/, handlers.respondWithId); + router.get(/foo\/update\/(\w+)/, handlers.respondWithId); + router.path(/bar\/bazz\//, function () { + this.get(/(\w+)/, handlers.respondWithId); + }); + router.get(/\/foo\/wild\/(.*)/, handlers.respondWithId); + router.get(/(\/v2)?\/somepath/, handlers.respondWithId); + + helpers.createServer(router) + .listen(9090, this.callback); + }, + "a request to foo/bar/bark": assertBark('foo/bar/bark'), + "a request to foo/update/bark": assertBark('foo/update/bark'), + "a request to bar/bazz/bark": assertBark('bar/bazz/bark'), + "a request to foo/bar/bark?test=test": assertBark('foo/bar/bark?test=test'), + "a request to foo/wild/bark": assertBark('foo/wild/bark'), + "a request to foo/%RT": macros.assert404(9090, 'foo/%RT'), + "a request to /v2/somepath": macros.assertGet( + 9090, + '/v2/somepath', + 'hello from (/v2)' + ) + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/methods-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/methods-test.js new file mode 100644 index 0000000..28758a0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/methods-test.js @@ -0,0 +1,42 @@ +/* + * methods-test.js: Tests for HTTP methods. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/http/methods').addBatch({ + "When using director": { + "an instance of director.http.Router should have all relevant RFC methods": function () { + var router = new director.http.Router(); + director.http.methods.forEach(function (method) { + assert.isFunction(router[method.toLowerCase()]); + }); + }, + "the path() method": { + topic: new director.http.Router(), + "/resource": { + "should insert nested routes correct": function (router) { + function getResource() {} + function modifyResource() {} + + router.path(/\/resource/, function () { + this.get(getResource); + + this.put(/\/update/, modifyResource); + this.post(/create/, modifyResource); + }); + + assert.equal(router.routes.resource.get, getResource); + assert.equal(router.routes.resource.update.put, modifyResource); + assert.equal(router.routes.resource.create.post, modifyResource); + } + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/responses-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/responses-test.js new file mode 100644 index 0000000..589ce59 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/responses-test.js @@ -0,0 +1,21 @@ +/* + * responses-test.js: Tests for HTTP responses. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + vows = require('vows'), + director = require('../../../lib/director'); + +vows.describe('director/http/responses').addBatch({ + "When using director.http": { + "it should have the relevant responses defined": function () { + Object.keys(require('../../../lib/director/http/responses')).forEach(function (name) { + assert.isFunction(director.http[name]); + }); + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/stream-test.js b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/stream-test.js new file mode 100644 index 0000000..2983539 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/director/test/server/http/stream-test.js @@ -0,0 +1,46 @@ +/* + * stream-test.js: Tests for streaming HTTP in director. + * + * (C) 2011, Nodejitsu Inc. + * MIT LICENSE + * + */ + +var assert = require('assert'), + http = require('http'), + vows = require('vows'), + request = require('request'), + director = require('../../../lib/director'), + helpers = require('../helpers'), + macros = helpers.macros, + handlers = helpers.handlers + +vows.describe('director/http/stream').addBatch({ + "An instance of director.http.Router": { + "with streaming routes": { + topic: function () { + var router = new director.http.Router(); + router.post(/foo\/bar/, { stream: true }, handlers.streamBody); + router.path('/a-path', function () { + this.post({ stream: true }, handlers.streamBody); + }); + + return router; + }, + "when passed to an http.Server instance": { + topic: function (router) { + helpers.createServer(router) + .listen(9092, this.callback); + }, + "a POST request to /foo/bar": macros.assertPost(9092, 'foo/bar', { + foo: 'foo', + bar: 'bar' + }), + "a POST request to /a-path": macros.assertPost(9092, 'a-path', { + foo: 'foo', + bar: 'bar' + }) + } + } + } +}).export(module); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/.travis.yml b/node_modules/forever/node_modules/flatiron/node_modules/optimist/.travis.yml new file mode 100644 index 0000000..895dbd3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.6 + - 0.8 diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/LICENSE b/node_modules/forever/node_modules/flatiron/node_modules/optimist/LICENSE new file mode 100644 index 0000000..432d1ae --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/LICENSE @@ -0,0 +1,21 @@ +Copyright 2010 James Halliday (mail@substack.net) + +This project is free software released under the MIT/X11 license: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/README.markdown b/node_modules/forever/node_modules/flatiron/node_modules/optimist/README.markdown new file mode 100644 index 0000000..ad9d3fd --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/README.markdown @@ -0,0 +1,487 @@ +optimist +======== + +Optimist is a node.js library for option parsing for people who hate option +parsing. More specifically, this module is for people who like all the --bells +and -whistlz of program usage but think optstrings are a waste of time. + +With optimist, option parsing doesn't have to suck (as much). + +[![build status](https://secure.travis-ci.org/substack/node-optimist.png)](http://travis-ci.org/substack/node-optimist) + +examples +======== + +With Optimist, the options are just a hash! No optstrings attached. +------------------------------------------------------------------- + +xup.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist').argv; + +if (argv.rif - 5 * argv.xup > 7.138) { + console.log('Buy more riffiwobbles'); +} +else { + console.log('Sell the xupptumblers'); +} +```` + +*** + + $ ./xup.js --rif=55 --xup=9.52 + Buy more riffiwobbles + + $ ./xup.js --rif 12 --xup 8.1 + Sell the xupptumblers + +![This one's optimistic.](http://substack.net/images/optimistic.png) + +But wait! There's more! You can do short options: +------------------------------------------------- + +short.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist').argv; +console.log('(%d,%d)', argv.x, argv.y); +```` + +*** + + $ ./short.js -x 10 -y 21 + (10,21) + +And booleans, both long and short (and grouped): +---------------------------------- + +bool.js: + +````javascript +#!/usr/bin/env node +var util = require('util'); +var argv = require('optimist').argv; + +if (argv.s) { + util.print(argv.fr ? 'Le chat dit: ' : 'The cat says: '); +} +console.log( + (argv.fr ? 'miaou' : 'meow') + (argv.p ? '.' : '') +); +```` + +*** + + $ ./bool.js -s + The cat says: meow + + $ ./bool.js -sp + The cat says: meow. + + $ ./bool.js -sp --fr + Le chat dit: miaou. + +And non-hypenated options too! Just use `argv._`! +------------------------------------------------- + +nonopt.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist').argv; +console.log('(%d,%d)', argv.x, argv.y); +console.log(argv._); +```` + +*** + + $ ./nonopt.js -x 6.82 -y 3.35 moo + (6.82,3.35) + [ 'moo' ] + + $ ./nonopt.js foo -x 0.54 bar -y 1.12 baz + (0.54,1.12) + [ 'foo', 'bar', 'baz' ] + +Plus, Optimist comes with .usage() and .demand()! +------------------------------------------------- + +divide.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .usage('Usage: $0 -x [num] -y [num]') + .demand(['x','y']) + .argv; + +console.log(argv.x / argv.y); +```` + +*** + + $ ./divide.js -x 55 -y 11 + 5 + + $ node ./divide.js -x 4.91 -z 2.51 + Usage: node ./divide.js -x [num] -y [num] + + Options: + -x [required] + -y [required] + + Missing required arguments: y + +EVEN MORE HOLY COW +------------------ + +default_singles.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .default('x', 10) + .default('y', 10) + .argv +; +console.log(argv.x + argv.y); +```` + +*** + + $ ./default_singles.js -x 5 + 15 + +default_hash.js: + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .default({ x : 10, y : 10 }) + .argv +; +console.log(argv.x + argv.y); +```` + +*** + + $ ./default_hash.js -y 7 + 17 + +And if you really want to get all descriptive about it... +--------------------------------------------------------- + +boolean_single.js + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .boolean('v') + .argv +; +console.dir(argv); +```` + +*** + + $ ./boolean_single.js -v foo bar baz + true + [ 'bar', 'baz', 'foo' ] + +boolean_double.js + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .boolean(['x','y','z']) + .argv +; +console.dir([ argv.x, argv.y, argv.z ]); +console.dir(argv._); +```` + +*** + + $ ./boolean_double.js -x -z one two three + [ true, false, true ] + [ 'one', 'two', 'three' ] + +Optimist is here to help... +--------------------------- + +You can describe parameters for help messages and set aliases. Optimist figures +out how to format a handy help string automatically. + +line_count.js + +````javascript +#!/usr/bin/env node +var argv = require('optimist') + .usage('Count the lines in a file.\nUsage: $0') + .demand('f') + .alias('f', 'file') + .describe('f', 'Load a file') + .argv +; + +var fs = require('fs'); +var s = fs.createReadStream(argv.file); + +var lines = 0; +s.on('data', function (buf) { + lines += buf.toString().match(/\n/g).length; +}); + +s.on('end', function () { + console.log(lines); +}); +```` + +*** + + $ node line_count.js + Count the lines in a file. + Usage: node ./line_count.js + + Options: + -f, --file Load a file [required] + + Missing required arguments: f + + $ node line_count.js --file line_count.js + 20 + + $ node line_count.js -f line_count.js + 20 + +methods +======= + +By itself, + +````javascript +require('optimist').argv +````` + +will use `process.argv` array to construct the `argv` object. + +You can pass in the `process.argv` yourself: + +````javascript +require('optimist')([ '-x', '1', '-y', '2' ]).argv +```` + +or use .parse() to do the same thing: + +````javascript +require('optimist').parse([ '-x', '1', '-y', '2' ]) +```` + +The rest of these methods below come in just before the terminating `.argv`. + +.alias(key, alias) +------------------ + +Set key names as equivalent such that updates to a key will propagate to aliases +and vice-versa. + +Optionally `.alias()` can take an object that maps keys to aliases. + +.default(key, value) +-------------------- + +Set `argv[key]` to `value` if no option was specified on `process.argv`. + +Optionally `.default()` can take an object that maps keys to default values. + +.demand(key) +------------ + +If `key` is a string, show the usage information and exit if `key` wasn't +specified in `process.argv`. + +If `key` is a number, demand at least as many non-option arguments, which show +up in `argv._`. + +If `key` is an Array, demand each element. + +.describe(key, desc) +-------------------- + +Describe a `key` for the generated usage information. + +Optionally `.describe()` can take an object that maps keys to descriptions. + +.options(key, opt) +------------------ + +Instead of chaining together `.alias().demand().default()`, you can specify +keys in `opt` for each of the chainable methods. + +For example: + +````javascript +var argv = require('optimist') + .options('f', { + alias : 'file', + default : '/etc/passwd', + }) + .argv +; +```` + +is the same as + +````javascript +var argv = require('optimist') + .alias('f', 'file') + .default('f', '/etc/passwd') + .argv +; +```` + +Optionally `.options()` can take an object that maps keys to `opt` parameters. + +.usage(message) +--------------- + +Set a usage message to show which commands to use. Inside `message`, the string +`$0` will get interpolated to the current script name or node command for the +present script similar to how `$0` works in bash or perl. + +.check(fn) +---------- + +Check that certain conditions are met in the provided arguments. + +If `fn` throws or returns `false`, show the thrown error, usage information, and +exit. + +.boolean(key) +------------- + +Interpret `key` as a boolean. If a non-flag option follows `key` in +`process.argv`, that string won't get set as the value of `key`. + +If `key` never shows up as a flag in `process.arguments`, `argv[key]` will be +`false`. + +If `key` is an Array, interpret all the elements as booleans. + +.string(key) +------------ + +Tell the parser logic not to interpret `key` as a number or boolean. +This can be useful if you need to preserve leading zeros in an input. + +If `key` is an Array, interpret all the elements as strings. + +.wrap(columns) +-------------- + +Format usage output to wrap at `columns` many columns. + +.help() +------- + +Return the generated usage string. + +.showHelp(fn=console.error) +--------------------------- + +Print the usage data using `fn` for printing. + +.parse(args) +------------ + +Parse `args` instead of `process.argv`. Returns the `argv` object. + +.argv +----- + +Get the arguments as a plain old object. + +Arguments without a corresponding flag show up in the `argv._` array. + +The script name or node command is available at `argv.$0` similarly to how `$0` +works in bash or perl. + +parsing tricks +============== + +stop parsing +------------ + +Use `--` to stop parsing flags and stuff the remainder into `argv._`. + + $ node examples/reflect.js -a 1 -b 2 -- -c 3 -d 4 + { _: [ '-c', '3', '-d', '4' ], + '$0': 'node ./examples/reflect.js', + a: 1, + b: 2 } + +negate fields +------------- + +If you want to explicity set a field to false instead of just leaving it +undefined or to override a default you can do `--no-key`. + + $ node examples/reflect.js -a --no-b + { _: [], + '$0': 'node ./examples/reflect.js', + a: true, + b: false } + +numbers +------- + +Every argument that looks like a number (`!isNaN(Number(arg))`) is converted to +one. This way you can just `net.createConnection(argv.port)` and you can add +numbers out of `argv` with `+` without having that mean concatenation, +which is super frustrating. + +duplicates +---------- + +If you specify a flag multiple times it will get turned into an array containing +all the values in order. + + $ node examples/reflect.js -x 5 -x 8 -x 0 + { _: [], + '$0': 'node ./examples/reflect.js', + x: [ 5, 8, 0 ] } + +dot notation +------------ + +When you use dots (`.`s) in argument names, an implicit object path is assumed. +This lets you organize arguments into nested objects. + + $ node examples/reflect.js --foo.bar.baz=33 --foo.quux=5 + { _: [], + '$0': 'node ./examples/reflect.js', + foo: { bar: { baz: 33 }, quux: 5 } } + +installation +============ + +With [npm](http://github.com/isaacs/npm), just do: + npm install optimist + +or clone this project on github: + + git clone http://github.com/substack/node-optimist.git + +To run the tests with [expresso](http://github.com/visionmedia/expresso), +just do: + + expresso + +inspired By +=========== + +This module is loosely inspired by Perl's +[Getopt::Casual](http://search.cpan.org/~photo/Getopt-Casual-0.13.1/Casual.pm). diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/bool.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/bool.js new file mode 100644 index 0000000..a998fb7 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/bool.js @@ -0,0 +1,10 @@ +#!/usr/bin/env node +var util = require('util'); +var argv = require('optimist').argv; + +if (argv.s) { + util.print(argv.fr ? 'Le chat dit: ' : 'The cat says: '); +} +console.log( + (argv.fr ? 'miaou' : 'meow') + (argv.p ? '.' : '') +); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/boolean_double.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/boolean_double.js new file mode 100644 index 0000000..a35a7e6 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/boolean_double.js @@ -0,0 +1,7 @@ +#!/usr/bin/env node +var argv = require('optimist') + .boolean(['x','y','z']) + .argv +; +console.dir([ argv.x, argv.y, argv.z ]); +console.dir(argv._); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/boolean_single.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/boolean_single.js new file mode 100644 index 0000000..017bb68 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/boolean_single.js @@ -0,0 +1,7 @@ +#!/usr/bin/env node +var argv = require('optimist') + .boolean('v') + .argv +; +console.dir(argv.v); +console.dir(argv._); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/default_hash.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/default_hash.js new file mode 100644 index 0000000..ade7768 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/default_hash.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +var argv = require('optimist') + .default({ x : 10, y : 10 }) + .argv +; + +console.log(argv.x + argv.y); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/default_singles.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/default_singles.js new file mode 100644 index 0000000..d9b1ff4 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/default_singles.js @@ -0,0 +1,7 @@ +#!/usr/bin/env node +var argv = require('optimist') + .default('x', 10) + .default('y', 10) + .argv +; +console.log(argv.x + argv.y); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/divide.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/divide.js new file mode 100644 index 0000000..5e2ee82 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/divide.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +var argv = require('optimist') + .usage('Usage: $0 -x [num] -y [num]') + .demand(['x','y']) + .argv; + +console.log(argv.x / argv.y); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count.js new file mode 100644 index 0000000..b5f95bf --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node +var argv = require('optimist') + .usage('Count the lines in a file.\nUsage: $0') + .demand('f') + .alias('f', 'file') + .describe('f', 'Load a file') + .argv +; + +var fs = require('fs'); +var s = fs.createReadStream(argv.file); + +var lines = 0; +s.on('data', function (buf) { + lines += buf.toString().match(/\n/g).length; +}); + +s.on('end', function () { + console.log(lines); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count_options.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count_options.js new file mode 100644 index 0000000..d9ac709 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count_options.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node +var argv = require('optimist') + .usage('Count the lines in a file.\nUsage: $0') + .options({ + file : { + demand : true, + alias : 'f', + description : 'Load a file' + }, + base : { + alias : 'b', + description : 'Numeric base to use for output', + default : 10, + }, + }) + .argv +; + +var fs = require('fs'); +var s = fs.createReadStream(argv.file); + +var lines = 0; +s.on('data', function (buf) { + lines += buf.toString().match(/\n/g).length; +}); + +s.on('end', function () { + console.log(lines.toString(argv.base)); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count_wrap.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count_wrap.js new file mode 100644 index 0000000..4267511 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/line_count_wrap.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node +var argv = require('optimist') + .usage('Count the lines in a file.\nUsage: $0') + .wrap(80) + .demand('f') + .alias('f', [ 'file', 'filename' ]) + .describe('f', + "Load a file. It's pretty important." + + " Required even. So you'd better specify it." + ) + .alias('b', 'base') + .describe('b', 'Numeric base to display the number of lines in') + .default('b', 10) + .describe('x', 'Super-secret optional parameter which is secret') + .default('x', '') + .argv +; + +var fs = require('fs'); +var s = fs.createReadStream(argv.file); + +var lines = 0; +s.on('data', function (buf) { + lines += buf.toString().match(/\n/g).length; +}); + +s.on('end', function () { + console.log(lines.toString(argv.base)); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/nonopt.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/nonopt.js new file mode 100644 index 0000000..ee633ee --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/nonopt.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node +var argv = require('optimist').argv; +console.log('(%d,%d)', argv.x, argv.y); +console.log(argv._); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/reflect.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/reflect.js new file mode 100644 index 0000000..816b3e1 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/reflect.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +console.dir(require('optimist').argv); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/short.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/short.js new file mode 100644 index 0000000..1db0ad0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/short.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +var argv = require('optimist').argv; +console.log('(%d,%d)', argv.x, argv.y); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/string.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/string.js new file mode 100644 index 0000000..a8e5aeb --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/string.js @@ -0,0 +1,11 @@ +#!/usr/bin/env node +var argv = require('optimist') + .string('x', 'y') + .argv +; +console.dir([ argv.x, argv.y ]); + +/* Turns off numeric coercion: + ./node string.js -x 000123 -y 9876 + [ '000123', '9876' ] +*/ diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/usage-options.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/usage-options.js new file mode 100644 index 0000000..b999977 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/usage-options.js @@ -0,0 +1,19 @@ +var optimist = require('./../index'); + +var argv = optimist.usage('This is my awesome program', { + 'about': { + description: 'Provide some details about the author of this program', + required: true, + short: 'a', + }, + 'info': { + description: 'Provide some information about the node.js agains!!!!!!', + boolean: true, + short: 'i' + } +}).argv; + +optimist.showHelp(); + +console.log('\n\nInspecting options'); +console.dir(argv); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/xup.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/xup.js new file mode 100644 index 0000000..8f6ecd2 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/example/xup.js @@ -0,0 +1,10 @@ +#!/usr/bin/env node +var argv = require('optimist').argv; + +if (argv.rif - 5 * argv.xup > 7.138) { + console.log('Buy more riffiwobbles'); +} +else { + console.log('Sell the xupptumblers'); +} + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/index.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/index.js new file mode 100644 index 0000000..e69bef9 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/index.js @@ -0,0 +1,475 @@ +var path = require('path'); +var wordwrap = require('wordwrap'); + +/* Hack an instance of Argv with process.argv into Argv + so people can do + require('optimist')(['--beeble=1','-z','zizzle']).argv + to parse a list of args and + require('optimist').argv + to get a parsed version of process.argv. +*/ + +var inst = Argv(process.argv.slice(2)); +Object.keys(inst).forEach(function (key) { + Argv[key] = typeof inst[key] == 'function' + ? inst[key].bind(inst) + : inst[key]; +}); + +var exports = module.exports = Argv; +function Argv (args, cwd) { + var self = {}; + if (!cwd) cwd = process.cwd(); + + self.$0 = process.argv + .slice(0,2) + .map(function (x) { + var b = rebase(cwd, x); + return x.match(/^\//) && b.length < x.length + ? b : x + }) + .join(' ') + ; + + if (process.argv[1] == process.env._) { + self.$0 = process.env._.replace( + path.dirname(process.execPath) + '/', '' + ); + } + + var flags = { bools : {}, strings : {} }; + + self.boolean = function (bools) { + if (!Array.isArray(bools)) { + bools = [].slice.call(arguments); + } + + bools.forEach(function (name) { + flags.bools[name] = true; + }); + + return self; + }; + + self.string = function (strings) { + if (!Array.isArray(strings)) { + strings = [].slice.call(arguments); + } + + strings.forEach(function (name) { + flags.strings[name] = true; + }); + + return self; + }; + + var aliases = {}; + self.alias = function (x, y) { + if (typeof x === 'object') { + Object.keys(x).forEach(function (key) { + self.alias(key, x[key]); + }); + } + else if (Array.isArray(y)) { + y.forEach(function (yy) { + self.alias(x, yy); + }); + } + else { + var zs = (aliases[x] || []).concat(aliases[y] || []).concat(x, y); + aliases[x] = zs.filter(function (z) { return z != x }); + aliases[y] = zs.filter(function (z) { return z != y }); + } + + return self; + }; + + var demanded = {}; + self.demand = function (keys) { + if (typeof keys == 'number') { + if (!demanded._) demanded._ = 0; + demanded._ += keys; + } + else if (Array.isArray(keys)) { + keys.forEach(function (key) { + self.demand(key); + }); + } + else { + demanded[keys] = true; + } + + return self; + }; + + var usage; + self.usage = function (msg, opts) { + if (!opts && typeof msg === 'object') { + opts = msg; + msg = null; + } + + usage = msg; + + if (opts) self.options(opts); + + return self; + }; + + function fail (msg) { + self.showHelp(); + if (msg) console.error(msg); + process.exit(1); + } + + var checks = []; + self.check = function (f) { + checks.push(f); + return self; + }; + + var defaults = {}; + self.default = function (key, value) { + if (typeof key === 'object') { + Object.keys(key).forEach(function (k) { + self.default(k, key[k]); + }); + } + else { + defaults[key] = value; + } + + return self; + }; + + var descriptions = {}; + self.describe = function (key, desc) { + if (typeof key === 'object') { + Object.keys(key).forEach(function (k) { + self.describe(k, key[k]); + }); + } + else { + descriptions[key] = desc; + } + return self; + }; + + self.parse = function (args) { + return Argv(args).argv; + }; + + self.option = self.options = function (key, opt) { + if (typeof key === 'object') { + Object.keys(key).forEach(function (k) { + self.options(k, key[k]); + }); + } + else { + if (opt.alias) self.alias(key, opt.alias); + if (opt.demand) self.demand(key); + if (typeof opt.default !== 'undefined') { + self.default(key, opt.default); + } + + if (opt.boolean || opt.type === 'boolean') { + self.boolean(key); + } + if (opt.string || opt.type === 'string') { + self.string(key); + } + + var desc = opt.describe || opt.description || opt.desc; + if (desc) { + self.describe(key, desc); + } + } + + return self; + }; + + var wrap = null; + self.wrap = function (cols) { + wrap = cols; + return self; + }; + + self.showHelp = function (fn) { + if (!fn) fn = console.error; + fn(self.help()); + }; + + self.help = function () { + var keys = Object.keys( + Object.keys(descriptions) + .concat(Object.keys(demanded)) + .concat(Object.keys(defaults)) + .reduce(function (acc, key) { + if (key !== '_') acc[key] = true; + return acc; + }, {}) + ); + + var help = keys.length ? [ 'Options:' ] : []; + + if (usage) { + help.unshift(usage.replace(/\$0/g, self.$0), ''); + } + + var switches = keys.reduce(function (acc, key) { + acc[key] = [ key ].concat(aliases[key] || []) + .map(function (sw) { + return (sw.length > 1 ? '--' : '-') + sw + }) + .join(', ') + ; + return acc; + }, {}); + + var switchlen = longest(Object.keys(switches).map(function (s) { + return switches[s] || ''; + })); + + var desclen = longest(Object.keys(descriptions).map(function (d) { + return descriptions[d] || ''; + })); + + keys.forEach(function (key) { + var kswitch = switches[key]; + var desc = descriptions[key] || ''; + + if (wrap) { + desc = wordwrap(switchlen + 4, wrap)(desc) + .slice(switchlen + 4) + ; + } + + var spadding = new Array( + Math.max(switchlen - kswitch.length + 3, 0) + ).join(' '); + + var dpadding = new Array( + Math.max(desclen - desc.length + 1, 0) + ).join(' '); + + var type = null; + + if (flags.bools[key]) type = '[boolean]'; + if (flags.strings[key]) type = '[string]'; + + if (!wrap && dpadding.length > 0) { + desc += dpadding; + } + + var prelude = ' ' + kswitch + spadding; + var extra = [ + type, + demanded[key] + ? '[required]' + : null + , + defaults[key] !== undefined + ? '[default: ' + JSON.stringify(defaults[key]) + ']' + : null + , + ].filter(Boolean).join(' '); + + var body = [ desc, extra ].filter(Boolean).join(' '); + + if (wrap) { + var dlines = desc.split('\n'); + var dlen = dlines.slice(-1)[0].length + + (dlines.length === 1 ? prelude.length : 0) + + body = desc + (dlen + extra.length > wrap - 2 + ? '\n' + + new Array(wrap - extra.length + 1).join(' ') + + extra + : new Array(wrap - extra.length - dlen + 1).join(' ') + + extra + ); + } + + help.push(prelude + body); + }); + + help.push(''); + return help.join('\n'); + }; + + Object.defineProperty(self, 'argv', { + get : parseArgs, + enumerable : true, + }); + + function parseArgs () { + var argv = { _ : [], $0 : self.$0 }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] || false); + }); + + function setArg (key, val) { + var num = Number(val); + var value = typeof val !== 'string' || isNaN(num) ? val : num; + if (flags.strings[key]) value = val; + + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + argv[x] = argv[key]; + }); + } + + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (arg === '--') { + argv._.push.apply(argv._, args.slice(i + 1)); + break; + } + else if (arg.match(/^--.+=/)) { + var m = arg.match(/^--([^=]+)=(.*)/); + setArg(m[1], m[2]); + } + else if (arg.match(/^--no-.+/)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false); + } + else if (arg.match(/^--.+/)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !next.match(/^-/) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + setArg(key, next); + i++; + } + else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true'); + i++; + } + else { + setArg(key, true); + } + } + else if (arg.match(/^-[^-]+/)) { + var letters = arg.slice(1,-1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + if (letters[j+1] && letters[j+1].match(/\W/)) { + setArg(letters[j], arg.slice(j+2)); + broken = true; + break; + } + else { + setArg(letters[j], true); + } + } + + if (!broken) { + var key = arg.slice(-1)[0]; + + if (args[i+1] && !args[i+1].match(/^-/) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + setArg(key, args[i+1]); + i++; + } + else if (args[i+1] && /true|false/.test(args[i+1])) { + setArg(key, args[i+1] === 'true'); + i++; + } + else { + setArg(key, true); + } + } + } + else { + var n = Number(arg); + argv._.push(flags.strings['_'] || isNaN(n) ? arg : n); + } + } + + Object.keys(defaults).forEach(function (key) { + if (!(key in argv)) { + argv[key] = defaults[key]; + if (key in aliases) { + argv[aliases[key]] = defaults[key]; + } + } + }); + + if (demanded._ && argv._.length < demanded._) { + fail('Not enough non-option arguments: got ' + + argv._.length + ', need at least ' + demanded._ + ); + } + + var missing = []; + Object.keys(demanded).forEach(function (key) { + if (!argv[key]) missing.push(key); + }); + + if (missing.length) { + fail('Missing required arguments: ' + missing.join(', ')); + } + + checks.forEach(function (f) { + try { + if (f(argv) === false) { + fail('Argument check failed: ' + f.toString()); + } + } + catch (err) { + fail(err) + } + }); + + return argv; + } + + function longest (xs) { + return Math.max.apply( + null, + xs.map(function (x) { return x.length }) + ); + } + + return self; +}; + +// rebase an absolute path to a relative one with respect to a base directory +// exported for tests +exports.rebase = rebase; +function rebase (base, dir) { + var ds = path.normalize(dir).split('/').slice(1); + var bs = path.normalize(base).split('/').slice(1); + + for (var i = 0; ds[i] && ds[i] == bs[i]; i++); + ds.splice(0, i); bs.splice(0, i); + + var p = path.normalize( + bs.map(function () { return '..' }).concat(ds).join('/') + ).replace(/\/$/,'').replace(/^$/, '.'); + return p.match(/^[.\/]/) ? p : './' + p; +}; + +function setKey (obj, keys, value) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + if (o[key] === undefined) o[key] = {}; + o = o[key]; + }); + + var key = keys[keys.length - 1]; + if (o[key] === undefined || typeof o[key] === 'boolean') { + o[key] = value; + } + else if (Array.isArray(o[key])) { + o[key].push(value); + } + else { + o[key] = [ o[key], value ]; + } +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/README.markdown b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/README.markdown new file mode 100644 index 0000000..346374e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/README.markdown @@ -0,0 +1,70 @@ +wordwrap +======== + +Wrap your words. + +example +======= + +made out of meat +---------------- + +meat.js + + var wrap = require('wordwrap')(15); + console.log(wrap('You and your whole family are made out of meat.')); + +output: + + You and your + whole family + are made out + of meat. + +centered +-------- + +center.js + + var wrap = require('wordwrap')(20, 60); + console.log(wrap( + 'At long last the struggle and tumult was over.' + + ' The machines had finally cast off their oppressors' + + ' and were finally free to roam the cosmos.' + + '\n' + + 'Free of purpose, free of obligation.' + + ' Just drifting through emptiness.' + + ' The sun was just another point of light.' + )); + +output: + + At long last the struggle and tumult + was over. The machines had finally cast + off their oppressors and were finally + free to roam the cosmos. + Free of purpose, free of obligation. + Just drifting through emptiness. The + sun was just another point of light. + +methods +======= + +var wrap = require('wordwrap'); + +wrap(stop), wrap(start, stop, params={mode:"soft"}) +--------------------------------------------------- + +Returns a function that takes a string and returns a new string. + +Pad out lines with spaces out to column `start` and then wrap until column +`stop`. If a word is longer than `stop - start` characters it will overflow. + +In "soft" mode, split chunks by `/(\S+\s+/` and don't break up chunks which are +longer than `stop - start`, in "hard" mode, split chunks with `/\b/` and break +up chunks longer than `stop - start`. + +wrap.hard(start, stop) +---------------------- + +Like `wrap()` but with `params.mode = "hard"`. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/example/center.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/example/center.js new file mode 100644 index 0000000..a3fbaae --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/example/center.js @@ -0,0 +1,10 @@ +var wrap = require('wordwrap')(20, 60); +console.log(wrap( + 'At long last the struggle and tumult was over.' + + ' The machines had finally cast off their oppressors' + + ' and were finally free to roam the cosmos.' + + '\n' + + 'Free of purpose, free of obligation.' + + ' Just drifting through emptiness.' + + ' The sun was just another point of light.' +)); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/example/meat.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/example/meat.js new file mode 100644 index 0000000..a4665e1 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/example/meat.js @@ -0,0 +1,3 @@ +var wrap = require('wordwrap')(15); + +console.log(wrap('You and your whole family are made out of meat.')); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/index.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/index.js new file mode 100644 index 0000000..c9bc945 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/index.js @@ -0,0 +1,76 @@ +var wordwrap = module.exports = function (start, stop, params) { + if (typeof start === 'object') { + params = start; + start = params.start; + stop = params.stop; + } + + if (typeof stop === 'object') { + params = stop; + start = start || params.start; + stop = undefined; + } + + if (!stop) { + stop = start; + start = 0; + } + + if (!params) params = {}; + var mode = params.mode || 'soft'; + var re = mode === 'hard' ? /\b/ : /(\S+\s+)/; + + return function (text) { + var chunks = text.toString() + .split(re) + .reduce(function (acc, x) { + if (mode === 'hard') { + for (var i = 0; i < x.length; i += stop - start) { + acc.push(x.slice(i, i + stop - start)); + } + } + else acc.push(x) + return acc; + }, []) + ; + + return chunks.reduce(function (lines, rawChunk) { + if (rawChunk === '') return lines; + + var chunk = rawChunk.replace(/\t/g, ' '); + + var i = lines.length - 1; + if (lines[i].length + chunk.length > stop) { + lines[i] = lines[i].replace(/\s+$/, ''); + + chunk.split(/\n/).forEach(function (c) { + lines.push( + new Array(start + 1).join(' ') + + c.replace(/^\s+/, '') + ); + }); + } + else if (chunk.match(/\n/)) { + var xs = chunk.split(/\n/); + lines[i] += xs.shift(); + xs.forEach(function (c) { + lines.push( + new Array(start + 1).join(' ') + + c.replace(/^\s+/, '') + ); + }); + } + else { + lines[i] += chunk; + } + + return lines; + }, [ new Array(start + 1).join(' ') ]).join('\n'); + }; +}; + +wordwrap.soft = wordwrap; + +wordwrap.hard = function (start, stop) { + return wordwrap(start, stop, { mode : 'hard' }); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/package.json b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/package.json new file mode 100644 index 0000000..b773f09 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/package.json @@ -0,0 +1,48 @@ +{ + "name": "wordwrap", + "description": "Wrap those words. Show them at what columns to start and stop.", + "version": "0.0.2", + "repository": { + "type": "git", + "url": "git://github.com/substack/node-wordwrap.git" + }, + "main": "./index.js", + "keywords": [ + "word", + "wrap", + "rule", + "format", + "column" + ], + "directories": { + "lib": ".", + "example": "example", + "test": "test" + }, + "scripts": { + "test": "expresso" + }, + "devDependencies": { + "expresso": "=0.7.x" + }, + "engines": { + "node": ">=0.4.0" + }, + "license": "MIT/X11", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "readme": "wordwrap\n========\n\nWrap your words.\n\nexample\n=======\n\nmade out of meat\n----------------\n\nmeat.js\n\n var wrap = require('wordwrap')(15);\n console.log(wrap('You and your whole family are made out of meat.'));\n\noutput:\n\n You and your\n whole family\n are made out\n of meat.\n\ncentered\n--------\n\ncenter.js\n\n var wrap = require('wordwrap')(20, 60);\n console.log(wrap(\n 'At long last the struggle and tumult was over.'\n + ' The machines had finally cast off their oppressors'\n + ' and were finally free to roam the cosmos.'\n + '\\n'\n + 'Free of purpose, free of obligation.'\n + ' Just drifting through emptiness.'\n + ' The sun was just another point of light.'\n ));\n\noutput:\n\n At long last the struggle and tumult\n was over. The machines had finally cast\n off their oppressors and were finally\n free to roam the cosmos.\n Free of purpose, free of obligation.\n Just drifting through emptiness. The\n sun was just another point of light.\n\nmethods\n=======\n\nvar wrap = require('wordwrap');\n\nwrap(stop), wrap(start, stop, params={mode:\"soft\"})\n---------------------------------------------------\n\nReturns a function that takes a string and returns a new string.\n\nPad out lines with spaces out to column `start` and then wrap until column\n`stop`. If a word is longer than `stop - start` characters it will overflow.\n\nIn \"soft\" mode, split chunks by `/(\\S+\\s+/` and don't break up chunks which are\nlonger than `stop - start`, in \"hard\" mode, split chunks with `/\\b/` and break\nup chunks longer than `stop - start`.\n\nwrap.hard(start, stop)\n----------------------\n\nLike `wrap()` but with `params.mode = \"hard\"`.\n", + "readmeFilename": "README.markdown", + "bugs": { + "url": "https://github.com/substack/node-wordwrap/issues" + }, + "_id": "wordwrap@0.0.2", + "dist": { + "shasum": "4f7023667432e1b6c098dfe40300abbe9bddecbb" + }, + "_from": "wordwrap@~0.0.2", + "_resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/break.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/break.js new file mode 100644 index 0000000..749292e --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/break.js @@ -0,0 +1,30 @@ +var assert = require('assert'); +var wordwrap = require('../'); + +exports.hard = function () { + var s = 'Assert from {"type":"equal","ok":false,"found":1,"wanted":2,' + + '"stack":[],"id":"b7ddcd4c409de8799542a74d1a04689b",' + + '"browser":"chrome/6.0"}' + ; + var s_ = wordwrap.hard(80)(s); + + var lines = s_.split('\n'); + assert.equal(lines.length, 2); + assert.ok(lines[0].length < 80); + assert.ok(lines[1].length < 80); + + assert.equal(s, s_.replace(/\n/g, '')); +}; + +exports.break = function () { + var s = new Array(55+1).join('a'); + var s_ = wordwrap.hard(20)(s); + + var lines = s_.split('\n'); + assert.equal(lines.length, 3); + assert.ok(lines[0].length === 20); + assert.ok(lines[1].length === 20); + assert.ok(lines[2].length === 15); + + assert.equal(s, s_.replace(/\n/g, '')); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/idleness.txt b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/idleness.txt new file mode 100644 index 0000000..aa3f490 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/idleness.txt @@ -0,0 +1,63 @@ +In Praise of Idleness + +By Bertrand Russell + +[1932] + +Like most of my generation, I was brought up on the saying: 'Satan finds some mischief for idle hands to do.' Being a highly virtuous child, I believed all that I was told, and acquired a conscience which has kept me working hard down to the present moment. But although my conscience has controlled my actions, my opinions have undergone a revolution. I think that there is far too much work done in the world, that immense harm is caused by the belief that work is virtuous, and that what needs to be preached in modern industrial countries is quite different from what always has been preached. Everyone knows the story of the traveler in Naples who saw twelve beggars lying in the sun (it was before the days of Mussolini), and offered a lira to the laziest of them. Eleven of them jumped up to claim it, so he gave it to the twelfth. this traveler was on the right lines. But in countries which do not enjoy Mediterranean sunshine idleness is more difficult, and a great public propaganda will be required to inaugurate it. I hope that, after reading the following pages, the leaders of the YMCA will start a campaign to induce good young men to do nothing. If so, I shall not have lived in vain. + +Before advancing my own arguments for laziness, I must dispose of one which I cannot accept. Whenever a person who already has enough to live on proposes to engage in some everyday kind of job, such as school-teaching or typing, he or she is told that such conduct takes the bread out of other people's mouths, and is therefore wicked. If this argument were valid, it would only be necessary for us all to be idle in order that we should all have our mouths full of bread. What people who say such things forget is that what a man earns he usually spends, and in spending he gives employment. As long as a man spends his income, he puts just as much bread into people's mouths in spending as he takes out of other people's mouths in earning. The real villain, from this point of view, is the man who saves. If he merely puts his savings in a stocking, like the proverbial French peasant, it is obvious that they do not give employment. If he invests his savings, the matter is less obvious, and different cases arise. + +One of the commonest things to do with savings is to lend them to some Government. In view of the fact that the bulk of the public expenditure of most civilized Governments consists in payment for past wars or preparation for future wars, the man who lends his money to a Government is in the same position as the bad men in Shakespeare who hire murderers. The net result of the man's economical habits is to increase the armed forces of the State to which he lends his savings. Obviously it would be better if he spent the money, even if he spent it in drink or gambling. + +But, I shall be told, the case is quite different when savings are invested in industrial enterprises. When such enterprises succeed, and produce something useful, this may be conceded. In these days, however, no one will deny that most enterprises fail. That means that a large amount of human labor, which might have been devoted to producing something that could be enjoyed, was expended on producing machines which, when produced, lay idle and did no good to anyone. The man who invests his savings in a concern that goes bankrupt is therefore injuring others as well as himself. If he spent his money, say, in giving parties for his friends, they (we may hope) would get pleasure, and so would all those upon whom he spent money, such as the butcher, the baker, and the bootlegger. But if he spends it (let us say) upon laying down rails for surface card in some place where surface cars turn out not to be wanted, he has diverted a mass of labor into channels where it gives pleasure to no one. Nevertheless, when he becomes poor through failure of his investment he will be regarded as a victim of undeserved misfortune, whereas the gay spendthrift, who has spent his money philanthropically, will be despised as a fool and a frivolous person. + +All this is only preliminary. I want to say, in all seriousness, that a great deal of harm is being done in the modern world by belief in the virtuousness of work, and that the road to happiness and prosperity lies in an organized diminution of work. + +First of all: what is work? Work is of two kinds: first, altering the position of matter at or near the earth's surface relatively to other such matter; second, telling other people to do so. The first kind is unpleasant and ill paid; the second is pleasant and highly paid. The second kind is capable of indefinite extension: there are not only those who give orders, but those who give advice as to what orders should be given. Usually two opposite kinds of advice are given simultaneously by two organized bodies of men; this is called politics. The skill required for this kind of work is not knowledge of the subjects as to which advice is given, but knowledge of the art of persuasive speaking and writing, i.e. of advertising. + +Throughout Europe, though not in America, there is a third class of men, more respected than either of the classes of workers. There are men who, through ownership of land, are able to make others pay for the privilege of being allowed to exist and to work. These landowners are idle, and I might therefore be expected to praise them. Unfortunately, their idleness is only rendered possible by the industry of others; indeed their desire for comfortable idleness is historically the source of the whole gospel of work. The last thing they have ever wished is that others should follow their example. + +From the beginning of civilization until the Industrial Revolution, a man could, as a rule, produce by hard work little more than was required for the subsistence of himself and his family, although his wife worked at least as hard as he did, and his children added their labor as soon as they were old enough to do so. The small surplus above bare necessaries was not left to those who produced it, but was appropriated by warriors and priests. In times of famine there was no surplus; the warriors and priests, however, still secured as much as at other times, with the result that many of the workers died of hunger. This system persisted in Russia until 1917 [1], and still persists in the East; in England, in spite of the Industrial Revolution, it remained in full force throughout the Napoleonic wars, and until a hundred years ago, when the new class of manufacturers acquired power. In America, the system came to an end with the Revolution, except in the South, where it persisted until the Civil War. A system which lasted so long and ended so recently has naturally left a profound impress upon men's thoughts and opinions. Much that we take for granted about the desirability of work is derived from this system, and, being pre-industrial, is not adapted to the modern world. Modern technique has made it possible for leisure, within limits, to be not the prerogative of small privileged classes, but a right evenly distributed throughout the community. The morality of work is the morality of slaves, and the modern world has no need of slavery. + +It is obvious that, in primitive communities, peasants, left to themselves, would not have parted with the slender surplus upon which the warriors and priests subsisted, but would have either produced less or consumed more. At first, sheer force compelled them to produce and part with the surplus. Gradually, however, it was found possible to induce many of them to accept an ethic according to which it was their duty to work hard, although part of their work went to support others in idleness. By this means the amount of compulsion required was lessened, and the expenses of government were diminished. To this day, 99 per cent of British wage-earners would be genuinely shocked if it were proposed that the King should not have a larger income than a working man. The conception of duty, speaking historically, has been a means used by the holders of power to induce others to live for the interests of their masters rather than for their own. Of course the holders of power conceal this fact from themselves by managing to believe that their interests are identical with the larger interests of humanity. Sometimes this is true; Athenian slave-owners, for instance, employed part of their leisure in making a permanent contribution to civilization which would have been impossible under a just economic system. Leisure is essential to civilization, and in former times leisure for the few was only rendered possible by the labors of the many. But their labors were valuable, not because work is good, but because leisure is good. And with modern technique it would be possible to distribute leisure justly without injury to civilization. + +Modern technique has made it possible to diminish enormously the amount of labor required to secure the necessaries of life for everyone. This was made obvious during the war. At that time all the men in the armed forces, and all the men and women engaged in the production of munitions, all the men and women engaged in spying, war propaganda, or Government offices connected with the war, were withdrawn from productive occupations. In spite of this, the general level of well-being among unskilled wage-earners on the side of the Allies was higher than before or since. The significance of this fact was concealed by finance: borrowing made it appear as if the future was nourishing the present. But that, of course, would have been impossible; a man cannot eat a loaf of bread that does not yet exist. The war showed conclusively that, by the scientific organization of production, it is possible to keep modern populations in fair comfort on a small part of the working capacity of the modern world. If, at the end of the war, the scientific organization, which had been created in order to liberate men for fighting and munition work, had been preserved, and the hours of the week had been cut down to four, all would have been well. Instead of that the old chaos was restored, those whose work was demanded were made to work long hours, and the rest were left to starve as unemployed. Why? Because work is a duty, and a man should not receive wages in proportion to what he has produced, but in proportion to his virtue as exemplified by his industry. + +This is the morality of the Slave State, applied in circumstances totally unlike those in which it arose. No wonder the result has been disastrous. Let us take an illustration. Suppose that, at a given moment, a certain number of people are engaged in the manufacture of pins. They make as many pins as the world needs, working (say) eight hours a day. Someone makes an invention by which the same number of men can make twice as many pins: pins are already so cheap that hardly any more will be bought at a lower price. In a sensible world, everybody concerned in the manufacturing of pins would take to working four hours instead of eight, and everything else would go on as before. But in the actual world this would be thought demoralizing. The men still work eight hours, there are too many pins, some employers go bankrupt, and half the men previously concerned in making pins are thrown out of work. There is, in the end, just as much leisure as on the other plan, but half the men are totally idle while half are still overworked. In this way, it is insured that the unavoidable leisure shall cause misery all round instead of being a universal source of happiness. Can anything more insane be imagined? + +The idea that the poor should have leisure has always been shocking to the rich. In England, in the early nineteenth century, fifteen hours was the ordinary day's work for a man; children sometimes did as much, and very commonly did twelve hours a day. When meddlesome busybodies suggested that perhaps these hours were rather long, they were told that work kept adults from drink and children from mischief. When I was a child, shortly after urban working men had acquired the vote, certain public holidays were established by law, to the great indignation of the upper classes. I remember hearing an old Duchess say: 'What do the poor want with holidays? They ought to work.' People nowadays are less frank, but the sentiment persists, and is the source of much of our economic confusion. + +Let us, for a moment, consider the ethics of work frankly, without superstition. Every human being, of necessity, consumes, in the course of his life, a certain amount of the produce of human labor. Assuming, as we may, that labor is on the whole disagreeable, it is unjust that a man should consume more than he produces. Of course he may provide services rather than commodities, like a medical man, for example; but he should provide something in return for his board and lodging. to this extent, the duty of work must be admitted, but to this extent only. + +I shall not dwell upon the fact that, in all modern societies outside the USSR, many people escape even this minimum amount of work, namely all those who inherit money and all those who marry money. I do not think the fact that these people are allowed to be idle is nearly so harmful as the fact that wage-earners are expected to overwork or starve. + +If the ordinary wage-earner worked four hours a day, there would be enough for everybody and no unemployment -- assuming a certain very moderate amount of sensible organization. This idea shocks the well-to-do, because they are convinced that the poor would not know how to use so much leisure. In America men often work long hours even when they are well off; such men, naturally, are indignant at the idea of leisure for wage-earners, except as the grim punishment of unemployment; in fact, they dislike leisure even for their sons. Oddly enough, while they wish their sons to work so hard as to have no time to be civilized, they do not mind their wives and daughters having no work at all. the snobbish admiration of uselessness, which, in an aristocratic society, extends to both sexes, is, under a plutocracy, confined to women; this, however, does not make it any more in agreement with common sense. + +The wise use of leisure, it must be conceded, is a product of civilization and education. A man who has worked long hours all his life will become bored if he becomes suddenly idle. But without a considerable amount of leisure a man is cut off from many of the best things. There is no longer any reason why the bulk of the population should suffer this deprivation; only a foolish asceticism, usually vicarious, makes us continue to insist on work in excessive quantities now that the need no longer exists. + +In the new creed which controls the government of Russia, while there is much that is very different from the traditional teaching of the West, there are some things that are quite unchanged. The attitude of the governing classes, and especially of those who conduct educational propaganda, on the subject of the dignity of labor, is almost exactly that which the governing classes of the world have always preached to what were called the 'honest poor'. Industry, sobriety, willingness to work long hours for distant advantages, even submissiveness to authority, all these reappear; moreover authority still represents the will of the Ruler of the Universe, Who, however, is now called by a new name, Dialectical Materialism. + +The victory of the proletariat in Russia has some points in common with the victory of the feminists in some other countries. For ages, men had conceded the superior saintliness of women, and had consoled women for their inferiority by maintaining that saintliness is more desirable than power. At last the feminists decided that they would have both, since the pioneers among them believed all that the men had told them about the desirability of virtue, but not what they had told them about the worthlessness of political power. A similar thing has happened in Russia as regards manual work. For ages, the rich and their sycophants have written in praise of 'honest toil', have praised the simple life, have professed a religion which teaches that the poor are much more likely to go to heaven than the rich, and in general have tried to make manual workers believe that there is some special nobility about altering the position of matter in space, just as men tried to make women believe that they derived some special nobility from their sexual enslavement. In Russia, all this teaching about the excellence of manual work has been taken seriously, with the result that the manual worker is more honored than anyone else. What are, in essence, revivalist appeals are made, but not for the old purposes: they are made to secure shock workers for special tasks. Manual work is the ideal which is held before the young, and is the basis of all ethical teaching. + +For the present, possibly, this is all to the good. A large country, full of natural resources, awaits development, and has has to be developed with very little use of credit. In these circumstances, hard work is necessary, and is likely to bring a great reward. But what will happen when the point has been reached where everybody could be comfortable without working long hours? + +In the West, we have various ways of dealing with this problem. We have no attempt at economic justice, so that a large proportion of the total produce goes to a small minority of the population, many of whom do no work at all. Owing to the absence of any central control over production, we produce hosts of things that are not wanted. We keep a large percentage of the working population idle, because we can dispense with their labor by making the others overwork. When all these methods prove inadequate, we have a war: we cause a number of people to manufacture high explosives, and a number of others to explode them, as if we were children who had just discovered fireworks. By a combination of all these devices we manage, though with difficulty, to keep alive the notion that a great deal of severe manual work must be the lot of the average man. + +In Russia, owing to more economic justice and central control over production, the problem will have to be differently solved. the rational solution would be, as soon as the necessaries and elementary comforts can be provided for all, to reduce the hours of labor gradually, allowing a popular vote to decide, at each stage, whether more leisure or more goods were to be preferred. But, having taught the supreme virtue of hard work, it is difficult to see how the authorities can aim at a paradise in which there will be much leisure and little work. It seems more likely that they will find continually fresh schemes, by which present leisure is to be sacrificed to future productivity. I read recently of an ingenious plan put forward by Russian engineers, for making the White Sea and the northern coasts of Siberia warm, by putting a dam across the Kara Sea. An admirable project, but liable to postpone proletarian comfort for a generation, while the nobility of toil is being displayed amid the ice-fields and snowstorms of the Arctic Ocean. This sort of thing, if it happens, will be the result of regarding the virtue of hard work as an end in itself, rather than as a means to a state of affairs in which it is no longer needed. + +The fact is that moving matter about, while a certain amount of it is necessary to our existence, is emphatically not one of the ends of human life. If it were, we should have to consider every navvy superior to Shakespeare. We have been misled in this matter by two causes. One is the necessity of keeping the poor contented, which has led the rich, for thousands of years, to preach the dignity of labor, while taking care themselves to remain undignified in this respect. The other is the new pleasure in mechanism, which makes us delight in the astonishingly clever changes that we can produce on the earth's surface. Neither of these motives makes any great appeal to the actual worker. If you ask him what he thinks the best part of his life, he is not likely to say: 'I enjoy manual work because it makes me feel that I am fulfilling man's noblest task, and because I like to think how much man can transform his planet. It is true that my body demands periods of rest, which I have to fill in as best I may, but I am never so happy as when the morning comes and I can return to the toil from which my contentment springs.' I have never heard working men say this sort of thing. They consider work, as it should be considered, a necessary means to a livelihood, and it is from their leisure that they derive whatever happiness they may enjoy. + +It will be said that, while a little leisure is pleasant, men would not know how to fill their days if they had only four hours of work out of the twenty-four. In so far as this is true in the modern world, it is a condemnation of our civilization; it would not have been true at any earlier period. There was formerly a capacity for light-heartedness and play which has been to some extent inhibited by the cult of efficiency. The modern man thinks that everything ought to be done for the sake of something else, and never for its own sake. Serious-minded persons, for example, are continually condemning the habit of going to the cinema, and telling us that it leads the young into crime. But all the work that goes to producing a cinema is respectable, because it is work, and because it brings a money profit. The notion that the desirable activities are those that bring a profit has made everything topsy-turvy. The butcher who provides you with meat and the baker who provides you with bread are praiseworthy, because they are making money; but when you enjoy the food they have provided, you are merely frivolous, unless you eat only to get strength for your work. Broadly speaking, it is held that getting money is good and spending money is bad. Seeing that they are two sides of one transaction, this is absurd; one might as well maintain that keys are good, but keyholes are bad. Whatever merit there may be in the production of goods must be entirely derivative from the advantage to be obtained by consuming them. The individual, in our society, works for profit; but the social purpose of his work lies in the consumption of what he produces. It is this divorce between the individual and the social purpose of production that makes it so difficult for men to think clearly in a world in which profit-making is the incentive to industry. We think too much of production, and too little of consumption. One result is that we attach too little importance to enjoyment and simple happiness, and that we do not judge production by the pleasure that it gives to the consumer. + +When I suggest that working hours should be reduced to four, I am not meaning to imply that all the remaining time should necessarily be spent in pure frivolity. I mean that four hours' work a day should entitle a man to the necessities and elementary comforts of life, and that the rest of his time should be his to use as he might see fit. It is an essential part of any such social system that education should be carried further than it usually is at present, and should aim, in part, at providing tastes which would enable a man to use leisure intelligently. I am not thinking mainly of the sort of things that would be considered 'highbrow'. Peasant dances have died out except in remote rural areas, but the impulses which caused them to be cultivated must still exist in human nature. The pleasures of urban populations have become mainly passive: seeing cinemas, watching football matches, listening to the radio, and so on. This results from the fact that their active energies are fully taken up with work; if they had more leisure, they would again enjoy pleasures in which they took an active part. + +In the past, there was a small leisure class and a larger working class. The leisure class enjoyed advantages for which there was no basis in social justice; this necessarily made it oppressive, limited its sympathies, and caused it to invent theories by which to justify its privileges. These facts greatly diminished its excellence, but in spite of this drawback it contributed nearly the whole of what we call civilization. It cultivated the arts and discovered the sciences; it wrote the books, invented the philosophies, and refined social relations. Even the liberation of the oppressed has usually been inaugurated from above. Without the leisure class, mankind would never have emerged from barbarism. + +The method of a leisure class without duties was, however, extraordinarily wasteful. None of the members of the class had to be taught to be industrious, and the class as a whole was not exceptionally intelligent. The class might produce one Darwin, but against him had to be set tens of thousands of country gentlemen who never thought of anything more intelligent than fox-hunting and punishing poachers. At present, the universities are supposed to provide, in a more systematic way, what the leisure class provided accidentally and as a by-product. This is a great improvement, but it has certain drawbacks. University life is so different from life in the world at large that men who live in academic milieu tend to be unaware of the preoccupations and problems of ordinary men and women; moreover their ways of expressing themselves are usually such as to rob their opinions of the influence that they ought to have upon the general public. Another disadvantage is that in universities studies are organized, and the man who thinks of some original line of research is likely to be discouraged. Academic institutions, therefore, useful as they are, are not adequate guardians of the interests of civilization in a world where everyone outside their walls is too busy for unutilitarian pursuits. + +In a world where no one is compelled to work more than four hours a day, every person possessed of scientific curiosity will be able to indulge it, and every painter will be able to paint without starving, however excellent his pictures may be. Young writers will not be obliged to draw attention to themselves by sensational pot-boilers, with a view to acquiring the economic independence needed for monumental works, for which, when the time at last comes, they will have lost the taste and capacity. Men who, in their professional work, have become interested in some phase of economics or government, will be able to develop their ideas without the academic detachment that makes the work of university economists often seem lacking in reality. Medical men will have the time to learn about the progress of medicine, teachers will not be exasperatedly struggling to teach by routine methods things which they learnt in their youth, which may, in the interval, have been proved to be untrue. + +Above all, there will be happiness and joy of life, instead of frayed nerves, weariness, and dyspepsia. The work exacted will be enough to make leisure delightful, but not enough to produce exhaustion. Since men will not be tired in their spare time, they will not demand only such amusements as are passive and vapid. At least one per cent will probably devote the time not spent in professional work to pursuits of some public importance, and, since they will not depend upon these pursuits for their livelihood, their originality will be unhampered, and there will be no need to conform to the standards set by elderly pundits. But it is not only in these exceptional cases that the advantages of leisure will appear. Ordinary men and women, having the opportunity of a happy life, will become more kindly and less persecuting and less inclined to view others with suspicion. The taste for war will die out, partly for this reason, and partly because it will involve long and severe work for all. Good nature is, of all moral qualities, the one that the world needs most, and good nature is the result of ease and security, not of a life of arduous struggle. Modern methods of production have given us the possibility of ease and security for all; we have chosen, instead, to have overwork for some and starvation for others. Hitherto we have continued to be as energetic as we were before there were machines; in this we have been foolish, but there is no reason to go on being foolish forever. + +[1] Since then, members of the Communist Party have succeeded to this privilege of the warriors and priests. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/wrap.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/wrap.js new file mode 100644 index 0000000..0cfb76d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/node_modules/wordwrap/test/wrap.js @@ -0,0 +1,31 @@ +var assert = require('assert'); +var wordwrap = require('wordwrap'); + +var fs = require('fs'); +var idleness = fs.readFileSync(__dirname + '/idleness.txt', 'utf8'); + +exports.stop80 = function () { + var lines = wordwrap(80)(idleness).split(/\n/); + var words = idleness.split(/\s+/); + + lines.forEach(function (line) { + assert.ok(line.length <= 80, 'line > 80 columns'); + var chunks = line.match(/\S/) ? line.split(/\s+/) : []; + assert.deepEqual(chunks, words.splice(0, chunks.length)); + }); +}; + +exports.start20stop60 = function () { + var lines = wordwrap(20, 100)(idleness).split(/\n/); + var words = idleness.split(/\s+/); + + lines.forEach(function (line) { + assert.ok(line.length <= 100, 'line > 100 columns'); + var chunks = line + .split(/\s+/) + .filter(function (x) { return x.match(/\S/) }) + ; + assert.deepEqual(chunks, words.splice(0, chunks.length)); + assert.deepEqual(line.slice(0, 20), new Array(20 + 1).join(' ')); + }); +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/package.json b/node_modules/forever/node_modules/flatiron/node_modules/optimist/package.json new file mode 100644 index 0000000..2fc4b7d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/package.json @@ -0,0 +1,54 @@ +{ + "name": "optimist", + "version": "0.3.5", + "description": "Light-weight option parsing with an argv hash. No optstrings attached.", + "main": "./index.js", + "directories": { + "lib": ".", + "test": "test", + "example": "example" + }, + "dependencies": { + "wordwrap": "~0.0.2" + }, + "devDependencies": { + "hashish": "~0.0.4", + "tap": "~0.2.4" + }, + "scripts": { + "test": "tap ./test/*.js" + }, + "repository": { + "type": "git", + "url": "http://github.com/substack/node-optimist.git" + }, + "keywords": [ + "argument", + "args", + "option", + "parser", + "parsing", + "cli", + "command" + ], + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "license": "MIT/X11", + "engine": { + "node": ">=0.4" + }, + "readme": "optimist\n========\n\nOptimist is a node.js library for option parsing for people who hate option\nparsing. More specifically, this module is for people who like all the --bells\nand -whistlz of program usage but think optstrings are a waste of time.\n\nWith optimist, option parsing doesn't have to suck (as much).\n\n[![build status](https://secure.travis-ci.org/substack/node-optimist.png)](http://travis-ci.org/substack/node-optimist)\n\nexamples\n========\n\nWith Optimist, the options are just a hash! No optstrings attached.\n-------------------------------------------------------------------\n\nxup.js:\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist').argv;\n\nif (argv.rif - 5 * argv.xup > 7.138) {\n console.log('Buy more riffiwobbles');\n}\nelse {\n console.log('Sell the xupptumblers');\n}\n````\n\n***\n\n $ ./xup.js --rif=55 --xup=9.52\n Buy more riffiwobbles\n \n $ ./xup.js --rif 12 --xup 8.1\n Sell the xupptumblers\n\n![This one's optimistic.](http://substack.net/images/optimistic.png)\n\nBut wait! There's more! You can do short options:\n-------------------------------------------------\n \nshort.js:\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist').argv;\nconsole.log('(%d,%d)', argv.x, argv.y);\n````\n\n***\n\n $ ./short.js -x 10 -y 21\n (10,21)\n\nAnd booleans, both long and short (and grouped):\n----------------------------------\n\nbool.js:\n\n````javascript\n#!/usr/bin/env node\nvar util = require('util');\nvar argv = require('optimist').argv;\n\nif (argv.s) {\n util.print(argv.fr ? 'Le chat dit: ' : 'The cat says: ');\n}\nconsole.log(\n (argv.fr ? 'miaou' : 'meow') + (argv.p ? '.' : '')\n);\n````\n\n***\n\n $ ./bool.js -s\n The cat says: meow\n \n $ ./bool.js -sp\n The cat says: meow.\n\n $ ./bool.js -sp --fr\n Le chat dit: miaou.\n\nAnd non-hypenated options too! Just use `argv._`!\n-------------------------------------------------\n \nnonopt.js:\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist').argv;\nconsole.log('(%d,%d)', argv.x, argv.y);\nconsole.log(argv._);\n````\n\n***\n\n $ ./nonopt.js -x 6.82 -y 3.35 moo\n (6.82,3.35)\n [ 'moo' ]\n \n $ ./nonopt.js foo -x 0.54 bar -y 1.12 baz\n (0.54,1.12)\n [ 'foo', 'bar', 'baz' ]\n\nPlus, Optimist comes with .usage() and .demand()!\n-------------------------------------------------\n\ndivide.js:\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist')\n .usage('Usage: $0 -x [num] -y [num]')\n .demand(['x','y'])\n .argv;\n\nconsole.log(argv.x / argv.y);\n````\n\n***\n \n $ ./divide.js -x 55 -y 11\n 5\n \n $ node ./divide.js -x 4.91 -z 2.51\n Usage: node ./divide.js -x [num] -y [num]\n\n Options:\n -x [required]\n -y [required]\n\n Missing required arguments: y\n\nEVEN MORE HOLY COW\n------------------\n\ndefault_singles.js:\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist')\n .default('x', 10)\n .default('y', 10)\n .argv\n;\nconsole.log(argv.x + argv.y);\n````\n\n***\n\n $ ./default_singles.js -x 5\n 15\n\ndefault_hash.js:\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist')\n .default({ x : 10, y : 10 })\n .argv\n;\nconsole.log(argv.x + argv.y);\n````\n\n***\n\n $ ./default_hash.js -y 7\n 17\n\nAnd if you really want to get all descriptive about it...\n---------------------------------------------------------\n\nboolean_single.js\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist')\n .boolean('v')\n .argv\n;\nconsole.dir(argv);\n````\n\n***\n\n $ ./boolean_single.js -v foo bar baz\n true\n [ 'bar', 'baz', 'foo' ]\n\nboolean_double.js\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist')\n .boolean(['x','y','z'])\n .argv\n;\nconsole.dir([ argv.x, argv.y, argv.z ]);\nconsole.dir(argv._);\n````\n\n***\n\n $ ./boolean_double.js -x -z one two three\n [ true, false, true ]\n [ 'one', 'two', 'three' ]\n\nOptimist is here to help...\n---------------------------\n\nYou can describe parameters for help messages and set aliases. Optimist figures\nout how to format a handy help string automatically.\n\nline_count.js\n\n````javascript\n#!/usr/bin/env node\nvar argv = require('optimist')\n .usage('Count the lines in a file.\\nUsage: $0')\n .demand('f')\n .alias('f', 'file')\n .describe('f', 'Load a file')\n .argv\n;\n\nvar fs = require('fs');\nvar s = fs.createReadStream(argv.file);\n\nvar lines = 0;\ns.on('data', function (buf) {\n lines += buf.toString().match(/\\n/g).length;\n});\n\ns.on('end', function () {\n console.log(lines);\n});\n````\n\n***\n\n $ node line_count.js\n Count the lines in a file.\n Usage: node ./line_count.js\n\n Options:\n -f, --file Load a file [required]\n\n Missing required arguments: f\n\n $ node line_count.js --file line_count.js \n 20\n \n $ node line_count.js -f line_count.js \n 20\n\nmethods\n=======\n\nBy itself,\n\n````javascript\nrequire('optimist').argv\n`````\n\nwill use `process.argv` array to construct the `argv` object.\n\nYou can pass in the `process.argv` yourself:\n\n````javascript\nrequire('optimist')([ '-x', '1', '-y', '2' ]).argv\n````\n\nor use .parse() to do the same thing:\n\n````javascript\nrequire('optimist').parse([ '-x', '1', '-y', '2' ])\n````\n\nThe rest of these methods below come in just before the terminating `.argv`.\n\n.alias(key, alias)\n------------------\n\nSet key names as equivalent such that updates to a key will propagate to aliases\nand vice-versa.\n\nOptionally `.alias()` can take an object that maps keys to aliases.\n\n.default(key, value)\n--------------------\n\nSet `argv[key]` to `value` if no option was specified on `process.argv`.\n\nOptionally `.default()` can take an object that maps keys to default values.\n\n.demand(key)\n------------\n\nIf `key` is a string, show the usage information and exit if `key` wasn't\nspecified in `process.argv`.\n\nIf `key` is a number, demand at least as many non-option arguments, which show\nup in `argv._`.\n\nIf `key` is an Array, demand each element.\n\n.describe(key, desc)\n--------------------\n\nDescribe a `key` for the generated usage information.\n\nOptionally `.describe()` can take an object that maps keys to descriptions.\n\n.options(key, opt)\n------------------\n\nInstead of chaining together `.alias().demand().default()`, you can specify\nkeys in `opt` for each of the chainable methods.\n\nFor example:\n\n````javascript\nvar argv = require('optimist')\n .options('f', {\n alias : 'file',\n default : '/etc/passwd',\n })\n .argv\n;\n````\n\nis the same as\n\n````javascript\nvar argv = require('optimist')\n .alias('f', 'file')\n .default('f', '/etc/passwd')\n .argv\n;\n````\n\nOptionally `.options()` can take an object that maps keys to `opt` parameters.\n\n.usage(message)\n---------------\n\nSet a usage message to show which commands to use. Inside `message`, the string\n`$0` will get interpolated to the current script name or node command for the\npresent script similar to how `$0` works in bash or perl.\n\n.check(fn)\n----------\n\nCheck that certain conditions are met in the provided arguments.\n\nIf `fn` throws or returns `false`, show the thrown error, usage information, and\nexit.\n\n.boolean(key)\n-------------\n\nInterpret `key` as a boolean. If a non-flag option follows `key` in\n`process.argv`, that string won't get set as the value of `key`.\n\nIf `key` never shows up as a flag in `process.arguments`, `argv[key]` will be\n`false`.\n\nIf `key` is an Array, interpret all the elements as booleans.\n\n.string(key)\n------------\n\nTell the parser logic not to interpret `key` as a number or boolean.\nThis can be useful if you need to preserve leading zeros in an input.\n\nIf `key` is an Array, interpret all the elements as strings.\n\n.wrap(columns)\n--------------\n\nFormat usage output to wrap at `columns` many columns.\n\n.help()\n-------\n\nReturn the generated usage string.\n\n.showHelp(fn=console.error)\n---------------------------\n\nPrint the usage data using `fn` for printing.\n\n.parse(args)\n------------\n\nParse `args` instead of `process.argv`. Returns the `argv` object.\n\n.argv\n-----\n\nGet the arguments as a plain old object.\n\nArguments without a corresponding flag show up in the `argv._` array.\n\nThe script name or node command is available at `argv.$0` similarly to how `$0`\nworks in bash or perl.\n\nparsing tricks\n==============\n\nstop parsing\n------------\n\nUse `--` to stop parsing flags and stuff the remainder into `argv._`.\n\n $ node examples/reflect.js -a 1 -b 2 -- -c 3 -d 4\n { _: [ '-c', '3', '-d', '4' ],\n '$0': 'node ./examples/reflect.js',\n a: 1,\n b: 2 }\n\nnegate fields\n-------------\n\nIf you want to explicity set a field to false instead of just leaving it\nundefined or to override a default you can do `--no-key`.\n\n $ node examples/reflect.js -a --no-b\n { _: [],\n '$0': 'node ./examples/reflect.js',\n a: true,\n b: false }\n\nnumbers\n-------\n\nEvery argument that looks like a number (`!isNaN(Number(arg))`) is converted to\none. This way you can just `net.createConnection(argv.port)` and you can add\nnumbers out of `argv` with `+` without having that mean concatenation,\nwhich is super frustrating.\n\nduplicates\n----------\n\nIf you specify a flag multiple times it will get turned into an array containing\nall the values in order.\n\n $ node examples/reflect.js -x 5 -x 8 -x 0\n { _: [],\n '$0': 'node ./examples/reflect.js',\n x: [ 5, 8, 0 ] }\n\ndot notation\n------------\n\nWhen you use dots (`.`s) in argument names, an implicit object path is assumed.\nThis lets you organize arguments into nested objects.\n\n $ node examples/reflect.js --foo.bar.baz=33 --foo.quux=5\n { _: [],\n '$0': 'node ./examples/reflect.js',\n foo: { bar: { baz: 33 }, quux: 5 } }\n\ninstallation\n============\n\nWith [npm](http://github.com/isaacs/npm), just do:\n npm install optimist\n \nor clone this project on github:\n\n git clone http://github.com/substack/node-optimist.git\n\nTo run the tests with [expresso](http://github.com/visionmedia/expresso),\njust do:\n \n expresso\n\ninspired By\n===========\n\nThis module is loosely inspired by Perl's\n[Getopt::Casual](http://search.cpan.org/~photo/Getopt-Casual-0.13.1/Casual.pm).\n", + "readmeFilename": "README.markdown", + "bugs": { + "url": "https://github.com/substack/node-optimist/issues" + }, + "_id": "optimist@0.3.5", + "dist": { + "shasum": "94c0a6ce2a93c186020de74d251b222175814c37" + }, + "_from": "optimist@0.3.5", + "_resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.5.tgz" +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_.js new file mode 100644 index 0000000..d9c58b3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_.js @@ -0,0 +1,71 @@ +var spawn = require('child_process').spawn; +var test = require('tap').test; + +test('dotSlashEmpty', testCmd('./bin.js', [])); + +test('dotSlashArgs', testCmd('./bin.js', [ 'a', 'b', 'c' ])); + +test('nodeEmpty', testCmd('node bin.js', [])); + +test('nodeArgs', testCmd('node bin.js', [ 'x', 'y', 'z' ])); + +test('whichNodeEmpty', function (t) { + var which = spawn('which', ['node']); + + which.stdout.on('data', function (buf) { + t.test( + testCmd(buf.toString().trim() + ' bin.js', []) + ); + t.end(); + }); + + which.stderr.on('data', function (err) { + assert.error(err); + t.end(); + }); +}); + +test('whichNodeArgs', function (t) { + var which = spawn('which', ['node']); + + which.stdout.on('data', function (buf) { + t.test( + testCmd(buf.toString().trim() + ' bin.js', [ 'q', 'r' ]) + ); + t.end(); + }); + + which.stderr.on('data', function (err) { + t.error(err); + t.end(); + }); +}); + +function testCmd (cmd, args) { + + return function (t) { + var to = setTimeout(function () { + assert.fail('Never got stdout data.') + }, 5000); + + var oldDir = process.cwd(); + process.chdir(__dirname + '/_'); + + var cmds = cmd.split(' '); + + var bin = spawn(cmds[0], cmds.slice(1).concat(args.map(String))); + process.chdir(oldDir); + + bin.stderr.on('data', function (err) { + t.error(err); + t.end(); + }); + + bin.stdout.on('data', function (buf) { + clearTimeout(to); + var _ = JSON.parse(buf.toString()); + t.same(_.map(String), args.map(String)); + t.end(); + }); + }; +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_/argv.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_/argv.js new file mode 100644 index 0000000..3d09606 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_/argv.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +console.log(JSON.stringify(process.argv)); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_/bin.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_/bin.js new file mode 100755 index 0000000..4a18d85 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/_/bin.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +var argv = require('../../index').argv +console.log(JSON.stringify(argv._)); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/parse.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/parse.js new file mode 100644 index 0000000..a6ce9f1 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/parse.js @@ -0,0 +1,433 @@ +var optimist = require('../index'); +var path = require('path'); +var test = require('tap').test; + +var $0 = 'node ./' + path.relative(process.cwd(), __filename); + +test('short boolean', function (t) { + var parse = optimist.parse([ '-b' ]); + t.same(parse, { b : true, _ : [], $0 : $0 }); + t.same(typeof parse.b, 'boolean'); + t.end(); +}); + +test('long boolean', function (t) { + t.same( + optimist.parse([ '--bool' ]), + { bool : true, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('bare', function (t) { + t.same( + optimist.parse([ 'foo', 'bar', 'baz' ]), + { _ : [ 'foo', 'bar', 'baz' ], $0 : $0 } + ); + t.end(); +}); + +test('short group', function (t) { + t.same( + optimist.parse([ '-cats' ]), + { c : true, a : true, t : true, s : true, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('short group next', function (t) { + t.same( + optimist.parse([ '-cats', 'meow' ]), + { c : true, a : true, t : true, s : 'meow', _ : [], $0 : $0 } + ); + t.end(); +}); + +test('short capture', function (t) { + t.same( + optimist.parse([ '-h', 'localhost' ]), + { h : 'localhost', _ : [], $0 : $0 } + ); + t.end(); +}); + +test('short captures', function (t) { + t.same( + optimist.parse([ '-h', 'localhost', '-p', '555' ]), + { h : 'localhost', p : 555, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('long capture sp', function (t) { + t.same( + optimist.parse([ '--pow', 'xixxle' ]), + { pow : 'xixxle', _ : [], $0 : $0 } + ); + t.end(); +}); + +test('long capture eq', function (t) { + t.same( + optimist.parse([ '--pow=xixxle' ]), + { pow : 'xixxle', _ : [], $0 : $0 } + ); + t.end() +}); + +test('long captures sp', function (t) { + t.same( + optimist.parse([ '--host', 'localhost', '--port', '555' ]), + { host : 'localhost', port : 555, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('long captures eq', function (t) { + t.same( + optimist.parse([ '--host=localhost', '--port=555' ]), + { host : 'localhost', port : 555, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('mixed short bool and capture', function (t) { + t.same( + optimist.parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), + { + f : true, p : 555, h : 'localhost', + _ : [ 'script.js' ], $0 : $0, + } + ); + t.end(); +}); + +test('short and long', function (t) { + t.same( + optimist.parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), + { + f : true, p : 555, h : 'localhost', + _ : [ 'script.js' ], $0 : $0, + } + ); + t.end(); +}); + +test('no', function (t) { + t.same( + optimist.parse([ '--no-moo' ]), + { moo : false, _ : [], $0 : $0 } + ); + t.end(); +}); + +test('multi', function (t) { + t.same( + optimist.parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]), + { v : ['a','b','c'], _ : [], $0 : $0 } + ); + t.end(); +}); + +test('comprehensive', function (t) { + t.same( + optimist.parse([ + '--name=meowmers', 'bare', '-cats', 'woo', + '-h', 'awesome', '--multi=quux', + '--key', 'value', + '-b', '--bool', '--no-meep', '--multi=baz', + '--', '--not-a-flag', 'eek' + ]), + { + c : true, + a : true, + t : true, + s : 'woo', + h : 'awesome', + b : true, + bool : true, + key : 'value', + multi : [ 'quux', 'baz' ], + meep : false, + name : 'meowmers', + _ : [ 'bare', '--not-a-flag', 'eek' ], + $0 : $0 + } + ); + t.end(); +}); + +test('nums', function (t) { + var argv = optimist.parse([ + '-x', '1234', + '-y', '5.67', + '-z', '1e7', + '-w', '10f', + '--hex', '0xdeadbeef', + '789', + ]); + t.same(argv, { + x : 1234, + y : 5.67, + z : 1e7, + w : '10f', + hex : 0xdeadbeef, + _ : [ 789 ], + $0 : $0 + }); + t.same(typeof argv.x, 'number'); + t.same(typeof argv.y, 'number'); + t.same(typeof argv.z, 'number'); + t.same(typeof argv.w, 'string'); + t.same(typeof argv.hex, 'number'); + t.same(typeof argv._[0], 'number'); + t.end(); +}); + +test('flag boolean', function (t) { + var parse = optimist([ '-t', 'moo' ]).boolean(['t']).argv; + t.same(parse, { t : true, _ : [ 'moo' ], $0 : $0 }); + t.same(typeof parse.t, 'boolean'); + t.end(); +}); + +test('flag boolean value', function (t) { + var parse = optimist(['--verbose', 'false', 'moo', '-t', 'true']) + .boolean(['t', 'verbose']).default('verbose', true).argv; + + t.same(parse, { + verbose: false, + t: true, + _: ['moo'], + $0 : $0 + }); + + t.same(typeof parse.verbose, 'boolean'); + t.same(typeof parse.t, 'boolean'); + t.end(); +}); + +test('flag boolean default false', function (t) { + var parse = optimist(['moo']) + .boolean(['t', 'verbose']) + .default('verbose', false) + .default('t', false).argv; + + t.same(parse, { + verbose: false, + t: false, + _: ['moo'], + $0 : $0 + }); + + t.same(typeof parse.verbose, 'boolean'); + t.same(typeof parse.t, 'boolean'); + t.end(); + +}); + +test('boolean groups', function (t) { + var parse = optimist([ '-x', '-z', 'one', 'two', 'three' ]) + .boolean(['x','y','z']).argv; + + t.same(parse, { + x : true, + y : false, + z : true, + _ : [ 'one', 'two', 'three' ], + $0 : $0 + }); + + t.same(typeof parse.x, 'boolean'); + t.same(typeof parse.y, 'boolean'); + t.same(typeof parse.z, 'boolean'); + t.end(); +}); + +test('strings' , function (t) { + var s = optimist([ '-s', '0001234' ]).string('s').argv.s; + t.same(s, '0001234'); + t.same(typeof s, 'string'); + + var x = optimist([ '-x', '56' ]).string('x').argv.x; + t.same(x, '56'); + t.same(typeof x, 'string'); + t.end(); +}); + +test('stringArgs', function (t) { + var s = optimist([ ' ', ' ' ]).string('_').argv._; + t.same(s.length, 2); + t.same(typeof s[0], 'string'); + t.same(s[0], ' '); + t.same(typeof s[1], 'string'); + t.same(s[1], ' '); + t.end(); +}); + +test('slashBreak', function (t) { + t.same( + optimist.parse([ '-I/foo/bar/baz' ]), + { I : '/foo/bar/baz', _ : [], $0 : $0 } + ); + t.same( + optimist.parse([ '-xyz/foo/bar/baz' ]), + { x : true, y : true, z : '/foo/bar/baz', _ : [], $0 : $0 } + ); + t.end(); +}); + +test('alias', function (t) { + var argv = optimist([ '-f', '11', '--zoom', '55' ]) + .alias('z', 'zoom') + .argv + ; + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.f, 11); + t.end(); +}); + +test('multiAlias', function (t) { + var argv = optimist([ '-f', '11', '--zoom', '55' ]) + .alias('z', [ 'zm', 'zoom' ]) + .argv + ; + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.z, argv.zm); + t.equal(argv.f, 11); + t.end(); +}); + +test('boolean default true', function (t) { + var argv = optimist.options({ + sometrue: { + boolean: true, + default: true + } + }).argv; + + t.equal(argv.sometrue, true); + t.end(); +}); + +test('boolean default false', function (t) { + var argv = optimist.options({ + somefalse: { + boolean: true, + default: false + } + }).argv; + + t.equal(argv.somefalse, false); + t.end(); +}); + +test('nested dotted objects', function (t) { + var argv = optimist([ + '--foo.bar', '3', '--foo.baz', '4', + '--foo.quux.quibble', '5', '--foo.quux.o_O', + '--beep.boop' + ]).argv; + + t.same(argv.foo, { + bar : 3, + baz : 4, + quux : { + quibble : 5, + o_O : true + }, + }); + t.same(argv.beep, { boop : true }); + t.end(); +}); + +test('boolean and alias with chainable api', function (t) { + var aliased = [ '-h', 'derp' ]; + var regular = [ '--herp', 'derp' ]; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = optimist(aliased) + .boolean('herp') + .alias('h', 'herp') + .argv; + var propertyArgv = optimist(regular) + .boolean('herp') + .alias('h', 'herp') + .argv; + var expected = { + herp: true, + h: true, + '_': [ 'derp' ], + '$0': $0, + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +test('boolean and alias with options hash', function (t) { + var aliased = [ '-h', 'derp' ]; + var regular = [ '--herp', 'derp' ]; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = optimist(aliased) + .options(opts) + .argv; + var propertyArgv = optimist(regular).options(opts).argv; + var expected = { + herp: true, + h: true, + '_': [ 'derp' ], + '$0': $0, + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + + t.end(); +}); + +test('boolean and alias using explicit true', function (t) { + var aliased = [ '-h', 'true' ]; + var regular = [ '--herp', 'true' ]; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = optimist(aliased) + .boolean('h') + .alias('h', 'herp') + .argv; + var propertyArgv = optimist(regular) + .boolean('h') + .alias('h', 'herp') + .argv; + var expected = { + herp: true, + h: true, + '_': [ ], + '$0': $0, + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +// regression, see https://github.com/substack/node-optimist/issues/71 +test('boolean and --x=true', function(t) { + var parsed = optimist(['--boool', '--other=true']).boolean('boool').argv; + + t.same(parsed.boool, true); + t.same(parsed.other, 'true'); + + parsed = optimist(['--boool', '--other=false']).boolean('boool').argv; + + t.same(parsed.boool, true); + t.same(parsed.other, 'false'); + t.end(); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/usage.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/usage.js new file mode 100644 index 0000000..300454c --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/test/usage.js @@ -0,0 +1,292 @@ +var Hash = require('hashish'); +var optimist = require('../index'); +var test = require('tap').test; + +test('usageFail', function (t) { + var r = checkUsage(function () { + return optimist('-x 10 -z 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .demand(['x','y']) + .argv; + }); + t.same( + r.result, + { x : 10, z : 20, _ : [], $0 : './usage' } + ); + + t.same( + r.errors.join('\n').split(/\n+/), + [ + 'Usage: ./usage -x NUM -y NUM', + 'Options:', + ' -x [required]', + ' -y [required]', + 'Missing required arguments: y', + ] + ); + t.same(r.logs, []); + t.ok(r.exit); + t.end(); +}); + + +test('usagePass', function (t) { + var r = checkUsage(function () { + return optimist('-x 10 -y 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .demand(['x','y']) + .argv; + }); + t.same(r, { + result : { x : 10, y : 20, _ : [], $0 : './usage' }, + errors : [], + logs : [], + exit : false, + }); + t.end(); +}); + +test('checkPass', function (t) { + var r = checkUsage(function () { + return optimist('-x 10 -y 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .check(function (argv) { + if (!('x' in argv)) throw 'You forgot about -x'; + if (!('y' in argv)) throw 'You forgot about -y'; + }) + .argv; + }); + t.same(r, { + result : { x : 10, y : 20, _ : [], $0 : './usage' }, + errors : [], + logs : [], + exit : false, + }); + t.end(); +}); + +test('checkFail', function (t) { + var r = checkUsage(function () { + return optimist('-x 10 -z 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .check(function (argv) { + if (!('x' in argv)) throw 'You forgot about -x'; + if (!('y' in argv)) throw 'You forgot about -y'; + }) + .argv; + }); + + t.same( + r.result, + { x : 10, z : 20, _ : [], $0 : './usage' } + ); + + t.same( + r.errors.join('\n').split(/\n+/), + [ + 'Usage: ./usage -x NUM -y NUM', + 'You forgot about -y' + ] + ); + + t.same(r.logs, []); + t.ok(r.exit); + t.end(); +}); + +test('checkCondPass', function (t) { + function checker (argv) { + return 'x' in argv && 'y' in argv; + } + + var r = checkUsage(function () { + return optimist('-x 10 -y 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .check(checker) + .argv; + }); + t.same(r, { + result : { x : 10, y : 20, _ : [], $0 : './usage' }, + errors : [], + logs : [], + exit : false, + }); + t.end(); +}); + +test('checkCondFail', function (t) { + function checker (argv) { + return 'x' in argv && 'y' in argv; + } + + var r = checkUsage(function () { + return optimist('-x 10 -z 20'.split(' ')) + .usage('Usage: $0 -x NUM -y NUM') + .check(checker) + .argv; + }); + + t.same( + r.result, + { x : 10, z : 20, _ : [], $0 : './usage' } + ); + + t.same( + r.errors.join('\n').split(/\n+/).join('\n'), + 'Usage: ./usage -x NUM -y NUM\n' + + 'Argument check failed: ' + checker.toString() + ); + + t.same(r.logs, []); + t.ok(r.exit); + t.end(); +}); + +test('countPass', function (t) { + var r = checkUsage(function () { + return optimist('1 2 3 --moo'.split(' ')) + .usage('Usage: $0 [x] [y] [z] {OPTIONS}') + .demand(3) + .argv; + }); + t.same(r, { + result : { _ : [ '1', '2', '3' ], moo : true, $0 : './usage' }, + errors : [], + logs : [], + exit : false, + }); + t.end(); +}); + +test('countFail', function (t) { + var r = checkUsage(function () { + return optimist('1 2 --moo'.split(' ')) + .usage('Usage: $0 [x] [y] [z] {OPTIONS}') + .demand(3) + .argv; + }); + t.same( + r.result, + { _ : [ '1', '2' ], moo : true, $0 : './usage' } + ); + + t.same( + r.errors.join('\n').split(/\n+/), + [ + 'Usage: ./usage [x] [y] [z] {OPTIONS}', + 'Not enough non-option arguments: got 2, need at least 3', + ] + ); + + t.same(r.logs, []); + t.ok(r.exit); + t.end(); +}); + +test('defaultSingles', function (t) { + var r = checkUsage(function () { + return optimist('--foo 50 --baz 70 --powsy'.split(' ')) + .default('foo', 5) + .default('bar', 6) + .default('baz', 7) + .argv + ; + }); + t.same(r.result, { + foo : '50', + bar : 6, + baz : '70', + powsy : true, + _ : [], + $0 : './usage', + }); + t.end(); +}); + +test('defaultAliases', function (t) { + var r = checkUsage(function () { + return optimist('') + .alias('f', 'foo') + .default('f', 5) + .argv + ; + }); + t.same(r.result, { + f : '5', + foo : '5', + _ : [], + $0 : './usage', + }); + t.end(); +}); + +test('defaultHash', function (t) { + var r = checkUsage(function () { + return optimist('--foo 50 --baz 70'.split(' ')) + .default({ foo : 10, bar : 20, quux : 30 }) + .argv + ; + }); + t.same(r.result, { + _ : [], + $0 : './usage', + foo : 50, + baz : 70, + bar : 20, + quux : 30, + }); + t.end(); +}); + +test('rebase', function (t) { + t.equal( + optimist.rebase('/home/substack', '/home/substack/foo/bar/baz'), + './foo/bar/baz' + ); + t.equal( + optimist.rebase('/home/substack/foo/bar/baz', '/home/substack'), + '../../..' + ); + t.equal( + optimist.rebase('/home/substack/foo', '/home/substack/pow/zoom.txt'), + '../pow/zoom.txt' + ); + t.end(); +}); + +function checkUsage (f) { + + var exit = false; + + process._exit = process.exit; + process._env = process.env; + process._argv = process.argv; + + process.exit = function (t) { exit = true }; + process.env = Hash.merge(process.env, { _ : 'node' }); + process.argv = [ './usage' ]; + + var errors = []; + var logs = []; + + console._error = console.error; + console.error = function (msg) { errors.push(msg) }; + console._log = console.log; + console.log = function (msg) { logs.push(msg) }; + + var result = f(); + + process.exit = process._exit; + process.env = process._env; + process.argv = process._argv; + + console.error = console._error; + console.log = console._log; + + return { + errors : errors, + logs : logs, + exit : exit, + result : result, + }; +}; diff --git a/node_modules/forever/node_modules/flatiron/node_modules/optimist/x.js b/node_modules/forever/node_modules/flatiron/node_modules/optimist/x.js new file mode 100644 index 0000000..6c006d0 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/optimist/x.js @@ -0,0 +1 @@ +console.dir(require('./').argv); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/.jshintrc b/node_modules/forever/node_modules/flatiron/node_modules/prompt/.jshintrc new file mode 100644 index 0000000..0d97986 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/.jshintrc @@ -0,0 +1,54 @@ +{ + "passfail": false, + "maxerr": 100, + + "browser": false, + "node": true, + "rhino": false, + "couch": true, + "wsh": true, + "jquery": true, + "prototypejs": false, + "mootools": false, + "dojo": false, + + "devel": false, + + "es5": true, + "strict": false, + "globalstrict": false, + + "asi": false, + "lastsemic": true, + "laxbreak": true, + "laxcomma": false, + "bitwise": false, + "boss": false, + "curly": true, + "eqeqeq": true, + "eqnull": false, + "evil": false, + "expr": false, + "forin": false, + "immed": false, + "latedef": false, + "loopfunc": true, + "noarg": true, + "regexp": true, + "regexdash": false, + "scripturl": true, + "shadow": true, + "supernew": true, + "undef": true, + + "newcap": true, + "noempty": true, + "nonew": true, + "nomen": false, + "onevar": true, + "plusplus": false, + "sub": true, + "trailing": true, + "white": false, + "indent": 2 +} \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/prompt/.npmignore new file mode 100644 index 0000000..e3bc275 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/.npmignore @@ -0,0 +1,3 @@ +node_modules/ +node_modules/* +npm-debug.log \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/.travis.yml b/node_modules/forever/node_modules/flatiron/node_modules/prompt/.travis.yml new file mode 100644 index 0000000..d2f42d5 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - 0.8 + +notifications: + email: + - travis@nodejitsu.com + irc: "irc.freenode.org#nodejitsu" + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/CHANGELOG.md b/node_modules/forever/node_modules/flatiron/node_modules/prompt/CHANGELOG.md new file mode 100644 index 0000000..b094c48 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/CHANGELOG.md @@ -0,0 +1,13 @@ + +0.2.7 / 2012-08-30 +================== + + * Fixed handling of numeric inputs with parseFloat + * Fixed overwriting of non-string inputs + * Added support for boolean types + +0.2.6 / 2012-08-12 +================== + + * Added allowance of empty default values + diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/LICENSE b/node_modules/forever/node_modules/flatiron/node_modules/prompt/LICENSE new file mode 100644 index 0000000..56217ca --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Nodejitsu Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/README.md b/node_modules/forever/node_modules/flatiron/node_modules/prompt/README.md new file mode 100644 index 0000000..6fdb684 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/README.md @@ -0,0 +1,293 @@ +# prompt [![Build Status](https://secure.travis-ci.org/flatiron/prompt.png)](http://travis-ci.org/flatiron/prompt) + +A beautiful command-line prompt for node.js + +## Features + +* prompts the user for input +* supports validation and defaults +* hides passwords + +## Usage +Using prompt is relatively straight forward. There are two core methods you should be aware of: `prompt.get()` and `prompt.addProperties()`. There methods take strings representing property names in addition to objects for complex property validation (and more). There are a number of [examples][0] that you should examine for detailed usage. + +### Getting Basic Prompt Information +Getting started with `prompt` is easy. Lets take a look at `examples/simple-prompt.js`: + +``` js + var prompt = require('prompt'); + + // + // Start the prompt + // + prompt.start(); + + // + // Get two properties from the user: username and email + // + prompt.get(['username', 'email'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); + }); +``` + +This will result in the following command-line output: + +``` + $ node examples/simple-prompt.js + prompt: username: some-user + prompt: email: some-user@some-place.org + Command-line input received: + username: some-user + email: some-user@some-place.org +``` + +### Prompting with Validation, Default Values, and More (Complex Properties) +In addition to prompting the user with simple string prompts, there is a robust API for getting and validating complex information from a command-line prompt. Here's a quick sample: + +``` js + var schema = { + properties: { + name: { + pattern: /^[a-zA-Z\s\-]+$/, + message: 'Name must be only letters, spaces, or dashes', + required: true + }, + password: { + hidden: true + } + } + }; + + // + // Start the prompt + // + prompt.start(); + + // + // Get two properties from the user: email, password + // + prompt.get(schema, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' name: ' + result.name); + console.log(' password: ' + result.password); + }); +``` + +Pretty easy right? The output from the above script is: + +``` + $ node examples/property-prompt.js + prompt: name: nodejitsu000 + error: Invalid input for name + error: Name must be only letters, spaces, or dashes + prompt: name: Nodejitsu Inc + prompt: password: + Command-line input received: + name: Nodejitsu Inc + password: some-password +``` + +## Valid Property Settings +`prompt` understands JSON-schema with a few extra parameters and uses [revalidator](https://github.com/flatiron/revalidator) for validation. + +Here's an overview of the properties that may be used for validation and prompting controls: + +``` js + { + description: 'Enter your password', // Prompt displayed to the user. If not supplied name will be used. + type: 'string', // Specify the type of input to expect. + pattern: /^\w+$/, // Regular expression that input must be valid against. + message: 'Password must be letters', // Warning message to display if validation fails. + hidden: true, // If true, characters entered will not be output to console. + default: 'lamepassword', // Default value to use if no value is entered. + required: true // If true, value entered must be non-empty. + before: function(value) { return 'v' + value; } // Runs before node-prompt callbacks. It modifies user's input + } +``` + +Alternatives to `pattern` include `format` and `conform`, as documented in [revalidator](https://github.com/flatiron/revalidator). + +Using `type: 'array'` has some special cases. + +- `description` will not work in the schema if `type: 'array'` is defined. +- `maxItems` takes precedence over `minItems`. +- Arrays that do not have `maxItems` defined will require users to `SIGINT` (`^C`) before the array is ended. +- If `SIGINT` (`^C`) is triggered before `minItems` is met, a validation error will appear. This will require users to `SIGEOF` (`^D`) to end the input. + +For more information on things such as `maxItems` and `minItems`, refer to the [revalidator](https://github.com/flatiron/revalidator) repository. + +### Alternate Validation API: + +Prompt, in addition to iterating over JSON-Schema properties, will also happily iterate over an array of validation objects given an extra 'name' property: + +```js + var prompt = require('../lib/prompt'); + + // + // Start the prompt + // + prompt.start(); + + // + // Get two properties from the user: username and password + // + prompt.get([{ + name: 'username', + required: true + }, { + name: 'password', + hidden: true, + conform: function (value) { + return true; + } + }], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' password: ' + result.password); + }); +``` + +### Backward Compatibility + +Note that, while this structure is similar to that used by prompt 0.1.x, that the object properties use the same names as in JSON-Schema. prompt 0.2.x is backward compatible with prompt 0.1.x except for asynchronous validation. + +### Skipping Prompts + +Sometimes power users may wish to skip promts and specify all data as command line options. +if a value is set as a property of `prompt.override` prompt will use that instead of +prompting the user. + +``` js + //prompt-override.js + + var prompt = require('prompt'), + optimist = require('optimist') + + // + // set the overrides + // + prompt.override = optimist.argv + + // + // Start the prompt + // + prompt.start(); + + // + // Get two properties from the user: username and email + // + prompt.get(['username', 'email'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); + }) + + //: node prompt-override.js --username USER --email EMAIL +``` + + +### Adding Properties to an Object +A common use-case for prompting users for data from the command-line is to extend or create a configuration object that is passed onto the entry-point method for your CLI tool. `prompt` exposes a convenience method for doing just this: + +``` js + var obj = { + password: 'lamepassword', + mindset: 'NY' + } + + // + // Log the initial object. + // + console.log('Initial object to be extended:'); + console.dir(obj); + + // + // Add two properties to the empty object: username and email + // + prompt.addProperties(obj, ['username', 'email'], function (err) { + // + // Log the results. + // + console.log('Updated object received:'); + console.dir(obj); + }); +``` + +## Customizing your prompt +Aside from changing `property.message`, you can also change `prompt.message` +and `prompt.delimiter` to change the appearance of your prompt. + +The basic structure of a prompt is this: + +``` js +prompt.message + prompt.delimiter + property.message + prompt.delimiter; +``` + +The default `prompt.message` is "prompt," the default `prompt.delimiter` is +": ", and the default `property.message` is `property.name`. +Changing these allows you to customize the appearance of your prompts! In +addition, prompt supports ANSI color codes via the +[colors module](https://github.com/Marak/colors.js) for custom colors. For a +very colorful example: + +``` js + var prompt = require("prompt"); + + // + // Setting these properties customizes the prompt. + // + prompt.message = "Question!".rainbow; + prompt.delimiter = "><".green; + + prompt.start(); + + prompt.get({ + properties: { + name: { + description: "What is your name?".magenta + } + } + }, function (err, result) { + console.log("You said your name is: ".cyan + result.name.cyan); + }); +``` + +If you don't want colors, you can set + +```js +var prompt = require('prompt'); + +prompt.colors = false; +``` + +## Installation + +``` bash + $ [sudo] npm install prompt +``` + +## Running tests + +``` bash + $ npm test +``` + +#### License: MIT +#### Author: [Charlie Robbins](http://github.com/indexzero) +#### Contributors: [Josh Holbrook](http://github.com/jesusabdullah), [Pavan Kumar Sunkara](http://github.com/pksunkara) + +[0]: https://github.com/flatiron/prompt/tree/master/examples diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/docs/docco.css b/node_modules/forever/node_modules/flatiron/node_modules/prompt/docs/docco.css new file mode 100644 index 0000000..bd54134 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/docs/docco.css @@ -0,0 +1,194 @@ +/*--------------------- Layout and Typography ----------------------------*/ +body { + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 15px; + line-height: 22px; + color: #252519; + margin: 0; padding: 0; +} +a { + color: #261a3b; +} + a:visited { + color: #261a3b; + } +p { + margin: 0 0 15px 0; +} +h4, h5, h6 { + color: #333; + margin: 6px 0 6px 0; + font-size: 13px; +} + h2, h3 { + margin-bottom: 0; + color: #000; + } + h1 { + margin-top: 40px; + margin-bottom: 15px; + color: #000; + } +#container { + position: relative; +} +#background { + position: fixed; + top: 0; left: 525px; right: 0; bottom: 0; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + z-index: -1; +} +#jump_to, #jump_page { + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 10px Arial; + text-transform: uppercase; + cursor: pointer; + text-align: right; +} +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 5px 10px; +} + #jump_wrapper { + padding: 0; + display: none; + } + #jump_to:hover #jump_wrapper { + display: block; + } + #jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; + } + #jump_page .source { + display: block; + padding: 5px 10px; + text-decoration: none; + border-top: 1px solid #eee; + } + #jump_page .source:hover { + background: #f5f5ff; + } + #jump_page .source:first-child { + } +table td { + border: 0; + outline: 0; +} + td.docs, th.docs { + max-width: 450px; + min-width: 450px; + min-height: 5px; + padding: 10px 25px 1px 50px; + overflow-x: hidden; + vertical-align: top; + text-align: left; + } + .docs pre { + margin: 15px 0 15px; + padding-left: 15px; + } + .docs p tt, .docs p code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } + .pilwrap { + position: relative; + } + .pilcrow { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + td.docs:hover .pilcrow { + opacity: 1; + } + td.code, th.code { + padding: 14px 15px 16px 25px; + width: 100%; + vertical-align: top; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + } + pre, tt, code { + font-size: 12px; line-height: 18px; + font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + + +/*---------------------- Syntax Highlighting -----------------------------*/ +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +body .hll { background-color: #ffffcc } +body .c { color: #408080; font-style: italic } /* Comment */ +body .err { border: 1px solid #FF0000 } /* Error */ +body .k { color: #954121 } /* Keyword */ +body .o { color: #666666 } /* Operator */ +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +body .cp { color: #BC7A00 } /* Comment.Preproc */ +body .c1 { color: #408080; font-style: italic } /* Comment.Single */ +body .cs { color: #408080; font-style: italic } /* Comment.Special */ +body .gd { color: #A00000 } /* Generic.Deleted */ +body .ge { font-style: italic } /* Generic.Emph */ +body .gr { color: #FF0000 } /* Generic.Error */ +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +body .gi { color: #00A000 } /* Generic.Inserted */ +body .go { color: #808080 } /* Generic.Output */ +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +body .gs { font-weight: bold } /* Generic.Strong */ +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +body .gt { color: #0040D0 } /* Generic.Traceback */ +body .kc { color: #954121 } /* Keyword.Constant */ +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ +body .kp { color: #954121 } /* Keyword.Pseudo */ +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ +body .kt { color: #B00040 } /* Keyword.Type */ +body .m { color: #666666 } /* Literal.Number */ +body .s { color: #219161 } /* Literal.String */ +body .na { color: #7D9029 } /* Name.Attribute */ +body .nb { color: #954121 } /* Name.Builtin */ +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +body .no { color: #880000 } /* Name.Constant */ +body .nd { color: #AA22FF } /* Name.Decorator */ +body .ni { color: #999999; font-weight: bold } /* Name.Entity */ +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +body .nf { color: #0000FF } /* Name.Function */ +body .nl { color: #A0A000 } /* Name.Label */ +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +body .nt { color: #954121; font-weight: bold } /* Name.Tag */ +body .nv { color: #19469D } /* Name.Variable */ +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +body .w { color: #bbbbbb } /* Text.Whitespace */ +body .mf { color: #666666 } /* Literal.Number.Float */ +body .mh { color: #666666 } /* Literal.Number.Hex */ +body .mi { color: #666666 } /* Literal.Number.Integer */ +body .mo { color: #666666 } /* Literal.Number.Oct */ +body .sb { color: #219161 } /* Literal.String.Backtick */ +body .sc { color: #219161 } /* Literal.String.Char */ +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ +body .s2 { color: #219161 } /* Literal.String.Double */ +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +body .sh { color: #219161 } /* Literal.String.Heredoc */ +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +body .sx { color: #954121 } /* Literal.String.Other */ +body .sr { color: #BB6688 } /* Literal.String.Regex */ +body .s1 { color: #219161 } /* Literal.String.Single */ +body .ss { color: #19469D } /* Literal.String.Symbol */ +body .bp { color: #954121 } /* Name.Builtin.Pseudo */ +body .vc { color: #19469D } /* Name.Variable.Class */ +body .vg { color: #19469D } /* Name.Variable.Global */ +body .vi { color: #19469D } /* Name.Variable.Instance */ +body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/docs/prompt.html b/node_modules/forever/node_modules/flatiron/node_modules/prompt/docs/prompt.html new file mode 100644 index 0000000..7776f5b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/docs/prompt.html @@ -0,0 +1,296 @@ + prompt.js

prompt.js

/*
+ * prompt.js: Simple prompt for prompting information from the command line 
+ *
+ * (C) 2010, Nodejitsu Inc.
+ *
+ */
+
+var events = require('events'),
+    async = require('async'),
+    colors = require('colors'),
+    winston = require('winston'),
+    stdio = process.binding('stdio');

@private function capitalize (str)

+ +

str {string} String to capitalize

+ +

Capitalizes the string supplied.

function capitalize(str) {
+  return str.charAt(0).toUpperCase() + str.slice(1);
+}
+
+var prompt = module.exports = Object.create(events.EventEmitter.prototype);
+
+var logger = prompt.logger = new winston.Logger({
+  transports: [
+    new (winston.transports.Console)()
+  ]
+});
+    
+prompt.started    = false;
+prompt.paused     = false;
+prompt.allowEmpty = false; 
+
+var stdin, stdout;

Create an empty object for the properties +known to prompt

prompt.properties = {};

Setup the default winston logger to use +the cli levels and colors.

logger.cli();

function start (options)

+ +

@options {Object} Optional Options to consume by prompt

+ +

Starts the prompt by listening to the appropriate events on options.stdin +and options.stdout. If no streams are supplied, then process.stdin +and process.stdout are used, respectively.

prompt.start = function (options) {
+  if (prompt.started) {
+    return;
+  }
+  
+  options = options        || {};
+  stdin   = options.stdin  || process.openStdin();
+  stdout  = options.stdout || process.stdout;
+  
+  prompt.allowEmpty = options.allowEmpty || false;
+  
+  process.on('SIGINT', function () {
+    stdout.write('\n');
+    process.exit(1);
+  })
+  
+  prompt.emit('start');
+  prompt.started = true;
+  return prompt;
+};

function pause ()

+ +

Pauses input coming in from stdin

prompt.pause = function () {
+  if (!prompt.started || prompt.paused) {
+    return;
+  }
+  
+  stdin.pause();
+  prompt.emit('pause');
+  prompt.paused = true;
+  return prompt;
+};

function resume ()

+ +

Resumes input coming in from stdin

prompt.resume = function () {
+  if (!prompt.started || !prompt.paused) {
+    return;
+  }
+  
+  stdin.resume();
+  prompt.emit('resume');
+  prompt.paused = false;
+  return prompt;
+};

function get (msg, [validator,] callback)

+ +

@msg {Array|Object|string} Set of variables to get input for.

+ +

@callback {function} Continuation to pass control to when complete.

+ +

Gets input from the user via stdin for the specified message(s) msg.

prompt.get = function (msg, callback) {
+  var vars = !Array.isArray(msg) ? [msg] : msg,
+      result = {};
+  
+  vars = vars.map(function (v) {
+    if (typeof v === 'string') {
+      v = v.toLowerCase();
+    }
+    
+    return prompt.properties[v] || v;
+  });
+  
+  function get(target, next) {
+    prompt.getInput(target, function (err, line) {
+      if (err) {
+        return next(err);
+      }
+      
+      var name = target.name || target;
+      result[name] = line;
+      next();
+    });
+  }
+  
+  async.forEachSeries(vars, get, function (err) {
+    return err ? callback(err) : callback(null, result);
+  });
+  
+  return prompt;
+};

function getInput (msg, validator, callback)

+ +

@msg {Object|string} Variable to get input for.

+ +

@callback {function} Continuation to pass control to when complete.

+ +

Gets input from the user via stdin for the specified message msg.

prompt.getInput = function (prop, callback) {
+  var name   = prop.message || prop.name || prop,
+      raw    = ['prompt', ': ' + name.grey, ': '.grey],
+      read   = prop.hidden ? prompt.readLineHidden : prompt.readLine,
+      length, msg;
+  
+  if (prop.default) {
+    raw.splice(2, -1, ' (' + prop.default + ')');
+  }
+  

Calculate the raw length and colorize the prompt

  length = raw.join('').length;
+  raw[0] = raw[0];
+  msg = raw.join('');
+  
+  if (prop.help) {
+    prop.help.forEach(function (line) {
+      logger.help(line);
+    });
+  }
+  
+  stdout.write(msg); 
+  prompt.emit('prompt', prop);
+  
+  read.call(null, function (err, line) {
+    if (err) {
+      return callback(err);
+    }
+  
+    if (!line || line === '') {
+      line = prop.default || line;
+    }
+    
+    if (prop.validator || prop.empty === false) {
+      var valid;
+      
+      if (prop.validator) {
+        valid = prop.validator.test 
+         ? prop.validator.test(line)
+         : prop.validator(line);
+      }
+      
+      if (prop.empty === false && valid) {
+        valid = line.length > 0;
+        prop.warning = prop.warning || 'You must supply a value.';
+      }
+      
+      if (!valid) {
+        logger.error('Invalid input for ' + name.grey);
+        if (prop.warning) {
+          logger.error(prop.warning);
+        }
+        
+        prompt.emit('invalid', prop, line);
+        return prompt.getInput(prop, callback);
+      }
+    }
+        
+    logger.input(line.yellow);
+    callback(null, line);
+  });
+
+  return prompt;
+};

function addProperties (obj, properties, callback)

+ +

@obj {Object} Object to add properties to

+ +

@properties {Array} List of properties to get values for

+ +

@callback {function} Continuation to pass control to when complete.

+ +

Prompts the user for values each of the properties if obj does not already +have a value for the property. Responds with the modified object.

prompt.addProperties = function (obj, properties, callback) {
+  properties = properties.filter(function (prop) {
+    return typeof obj[prop] === 'undefined';
+  });
+  
+  if (properties.length === 0) {
+    return callback(obj);
+  }
+  
+  prompt.get(properties, function (err, results) {
+    if (err) {
+      return callback(err);
+    }
+    else if (!results) {
+      return callback(null, obj);
+    }
+    
+    function putNested (obj, path, value) {
+      var last = obj, key; 
+      
+      while (path.length > 1) {
+        key = path.shift();
+        if (!last[key]) {
+          last[key] = {};
+        }
+        
+        last = last[key];
+      }
+      
+      last[path.shift()] = value;
+    }
+    
+    Object.keys(results).forEach(function (key) {
+      putNested(obj, key.split('.'), results[key]);
+    });
+    
+    callback(null, obj);
+  });
+  
+  return prompt;
+};

function readLine (callback)

+ +

@callback {function} Continuation to respond to when complete

+ +

Gets a single line of input from the user.

prompt.readLine = function (callback) {
+  var value = '', buffer = '';
+  prompt.resume();
+  stdin.setEncoding('utf8');
+  stdin.on('error', callback);
+  stdin.on('data', function data (chunk) {
+    value += buffer + chunk;
+    buffer = '';
+    value = value.replace(/\r/g, '');
+    if (value.indexOf('\n') !== -1) {
+      if (value !== '\n') {
+        value = value.replace(/^\n+/, '');
+      }
+      
+      buffer = value.substr(value.indexOf('\n'));
+      val = value.substr(0, value.indexOf('\n'));
+      prompt.pause();
+      stdin.removeListener('data', data);
+      stdin.removeListener('error', callback);
+      value = value.trim();
+      callback(null, value);
+    }
+  });
+  
+  return prompt;
+};

function readLineHidden (callback)

+ +

@callback {function} Continuation to respond to when complete

+ +

Gets a single line of hidden input (i.e. rawMode = true) from the user.

prompt.readLineHidden = function (callback) {
+  var value = '', buffer = '';
+  stdio.setRawMode(true);
+  prompt.resume();
+  stdin.on('error', callback);
+  stdin.on('data', function data (c) {
+    c = '' + c;
+    switch (c) {
+      case '\n': case '\r': case '\r\n': case '\u0004':
+        stdio.setRawMode(false);
+        stdin.removeListener('data', data);
+        stdin.removeListener('error', callback);
+        value = value.trim();
+        stdout.write('\n');
+        stdout.flush();
+        prompt.pause();
+        return callback(null, value)
+      case '\u0003': case '\0':
+        stdout.write('\n');
+        process.exit(1);
+        break;
+      default:
+        value += buffer + c
+        buffer = '';
+        break;
+    }
+  });
+  
+  return prompt;
+};
+
+
diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/add-properties.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/add-properties.js new file mode 100644 index 0000000..1a56176 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/add-properties.js @@ -0,0 +1,35 @@ +/* + * add-properties.js: Example of how to add properties to an object using prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +var obj = { + password: 'lamepassword', + mindset: 'NY' +} + +// +// Log the initial object. +// +console.log('Initial object to be extended:'); +console.dir(obj); + +// +// Add two properties to the empty object: username and email +// +prompt.addProperties(obj, ['username', 'email'], function (err) { + // + // Log the results. + // + console.log('Updated object received:'); + console.dir(obj); +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/existing-properties.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/existing-properties.js new file mode 100644 index 0000000..d87503b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/existing-properties.js @@ -0,0 +1,35 @@ +/* + * existing-properties.js: Example of using prompt with predefined properties. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +prompt.properties = { + email: { + format: 'email', + message: 'Must be a valid email address' + }, + password: { + hidden: true + } +}; + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: email, password +// +prompt.get(['email', 'password'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' email: ' + result.email); + console.log(' password: ' + result.password); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/history.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/history.js new file mode 100644 index 0000000..fd4369d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/history.js @@ -0,0 +1,44 @@ +/* + * history.js: Example of using the prompt history capabilities. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +var properties = { + properties: { + animal: { + description: 'Enter an animal', + default: 'dog', + pattern: /dog|cat/ + }, + sound: { + description: 'What sound does this animal make?', + conform: function (value) { + var animal = prompt.history(0).value; + + return animal === 'dog' && value === 'woof' + || animal === 'cat' && value === 'meow'; + } + } + } +} + +// +// Get two properties from the user +// +prompt.get(properties, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' animal: ' + result.animal); + console.log(' sound: ' + result.sound); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/nested-properties-prompt.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/nested-properties-prompt.js new file mode 100644 index 0000000..25106a2 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/nested-properties-prompt.js @@ -0,0 +1,37 @@ +/* + * property-prompt.js: Example of using prompt with complex properties. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +var schema = { + properties: { + url: { + required: true, + format: 'url' + }, + auth: { + properties: { + username: { + required: true + }, + password: { + required: true, + hidden: true + } + } + } + } +}; + +prompt.start(); + +prompt.get(schema, function (err, result) { + console.log('Command-line input received:'); + console.log(' url: ' + result.url); + console.log(' auth:username: ' + result.auth.username); + console.log(' auth:password: ' + result.auth.password); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/old-schema.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/old-schema.js new file mode 100644 index 0000000..631b7b5 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/old-schema.js @@ -0,0 +1,36 @@ +/* + * simple-prompt.js: Simple example of using prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: username and email +// +prompt.get([ + { + name: 'username', + validator: /^[a-z]+$/, + warning: 'Username should consist only lowercase alphabets', + empty: false + }, + { + name: 'email', + message: 'Email Address' + } +], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/override-validation.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/override-validation.js new file mode 100644 index 0000000..8b02373 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/override-validation.js @@ -0,0 +1,52 @@ +/* + * override-validation.js: Example of using prompt with complex properties and command-line input. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'), + optimist = require('optimist'); + +var schema = { + properties: { + name: { + pattern: /^[a-zA-Z\s-]+$/, + message: 'Name must be only letters, spaces, or dashes', + required: true + }, + email: { + name: 'email', + format: 'email', + message: 'Must be a valid email address' + } + } +}; + +// +// Set the overrides +// +prompt.override = optimist.argv + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: email, password +// +prompt.get(schema, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' name: ' + result.name); + console.log(' email: ' + result.email); +}); + +// try running +// $ node ./override-validation.js --name USER --email EMAIL +// You will only be asked for email becasue it's invalid +// $ node ./override-validation.js --name h$acker --email me@example.com +// You will only be asked for email becasue it's invalid \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/password.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/password.js new file mode 100644 index 0000000..72fc02d --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/password.js @@ -0,0 +1,34 @@ +/* + * password.js: Simple example of using prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: username and password +// +prompt.get([{ + name: 'username', + required: true + }, { + name: 'password', + hidden: true, + conform: function (value) { + return true; + } + }], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' password: ' + result.password); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/prompt-override.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/prompt-override.js new file mode 100644 index 0000000..7f2848b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/prompt-override.js @@ -0,0 +1,36 @@ +var prompt = require('../lib/prompt'), + optimist; + +try { + optimist = require('optimist'); +} catch (err) { + throw new Error([ + 'You need to install optimist before this example will work!', + 'Try: `npm install optimist`.' + ].join('\n')); +} + +// +// Set the overrides +// +prompt.override = optimist.argv + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: username and email +// +prompt.get(['username', 'email'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); + prompt.pause(); +}) + +// $ node ./prompt-override.js --username USER --email EMAIL diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/property-prompt.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/property-prompt.js new file mode 100644 index 0000000..c8b343b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/property-prompt.js @@ -0,0 +1,45 @@ +/* + * property-prompt.js: Example of using prompt with complex properties. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +var schema = { + properties: { + name: { + pattern: /^[a-zA-Z\s-]+$/, + message: 'Name must be only letters, spaces, or dashes', + required: true + }, + email: { + name: 'email', + format: 'email', + message: 'Must be a valid email address' + }, + password: { + required: true, + hidden: true + } + } +}; + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: email, password +// +prompt.get(schema, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' name: ' + result.name); + console.log(' email: ' + result.email); + console.log(' password: ' + result.password); +}); diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/simple-prompt.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/simple-prompt.js new file mode 100644 index 0000000..062e529 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/simple-prompt.js @@ -0,0 +1,25 @@ +/* + * simple-prompt.js: Simple example of using prompt. + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +// +// Get two properties from the user: username and email +// +prompt.get(['username', 'email'], function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' username: ' + result.username); + console.log(' email: ' + result.email); +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/yes-or-no-prompt.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/yes-or-no-prompt.js new file mode 100644 index 0000000..512b556 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/examples/yes-or-no-prompt.js @@ -0,0 +1,32 @@ +/* + * yes-or-no-prompt.js: Simple example of using prompt. + * + * (C) 2012, Nodejitsu Inc. + * + */ + +var prompt = require('../lib/prompt'); + +// +// Start the prompt +// +prompt.start(); + +var property = { + name: 'yesno', + message: 'are you sure?', + validator: /y[es]*|n[o]?/, + warning: 'Must respond yes or no', + default: 'no' +}; + +// +// Get the simple yes or no property +// +prompt.get(property, function (err, result) { + // + // Log the results. + // + console.log('Command-line input received:'); + console.log(' result: ' + result.yesno); +}); \ No newline at end of file diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/lib/prompt.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/lib/prompt.js new file mode 100644 index 0000000..f5ab6e8 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/lib/prompt.js @@ -0,0 +1,757 @@ +/* + * prompt.js: Simple prompt for prompting information from the command line + * + * (C) 2010, Nodejitsu Inc. + * + */ + +var events = require('events'), + readline = require('readline'), + utile = require('utile'), + async = utile.async, + capitalize = utile.inflect.capitalize, + read = require('read'), + validate = require('revalidator').validate, + winston = require('winston'); + +// +// Monkey-punch readline.Interface to work-around +// https://github.com/joyent/node/issues/3860 +// +readline.Interface.prototype.setPrompt = function(prompt, length) { + this._prompt = prompt; + if (length) { + this._promptLength = length; + } else { + var lines = prompt.split(/[\r\n]/); + var lastLine = lines[lines.length - 1]; + this._promptLength = lastLine.replace(/\u001b\[(\d+(;\d+)*)?m/g, '').length; + } +}; + +// +// Expose version using `pkginfo` +// +require('pkginfo')(module, 'version'); + +var stdin, stdout, history = []; +var prompt = module.exports = Object.create(events.EventEmitter.prototype); +var logger = prompt.logger = new winston.Logger({ + transports: [new (winston.transports.Console)()] +}); + +prompt.started = false; +prompt.paused = false; +prompt.allowEmpty = false; +prompt.message = 'prompt'; +prompt.delimiter = ': '; +prompt.colors = true; + +// +// Create an empty object for the properties +// known to `prompt` +// +prompt.properties = {}; + +// +// Setup the default winston logger to use +// the `cli` levels and colors. +// +logger.cli(); + +// +// ### function start (options) +// #### @options {Object} **Optional** Options to consume by prompt +// Starts the prompt by listening to the appropriate events on `options.stdin` +// and `options.stdout`. If no streams are supplied, then `process.stdin` +// and `process.stdout` are used, respectively. +// +prompt.start = function (options) { + if (prompt.started) { + return; + } + + options = options || {}; + stdin = options.stdin || process.stdin; + stdout = options.stdout || process.stdout; + + // + // By default: Remember the last `10` prompt property / + // answer pairs and don't allow empty responses globally. + // + prompt.memory = options.memory || 10; + prompt.allowEmpty = options.allowEmpty || false; + prompt.message = options.message || prompt.message; + prompt.delimiter = options.delimiter || prompt.delimiter; + prompt.colors = options.colors || prompt.colors; + + if (process.platform !== 'win32') { + // windows falls apart trying to deal with SIGINT + process.on('SIGINT', function () { + stdout.write('\n'); + process.exit(1); + }); + } + + prompt.emit('start'); + prompt.started = true; + return prompt; +}; + +// +// ### function pause () +// Pauses input coming in from stdin +// +prompt.pause = function () { + if (!prompt.started || prompt.paused) { + return; + } + + stdin.pause(); + prompt.emit('pause'); + prompt.paused = true; + return prompt; +}; + +// +// ### function resume () +// Resumes input coming in from stdin +// +prompt.resume = function () { + if (!prompt.started || !prompt.paused) { + return; + } + + stdin.resume(); + prompt.emit('resume'); + prompt.paused = false; + return prompt; +}; + +// +// ### function history (search) +// #### @search {Number|string} Index or property name to find. +// Returns the `property:value` pair from within the prompts +// `history` array. +// +prompt.history = function (search) { + if (typeof search === 'number') { + return history[search] || {}; + } + + var names = history.map(function (pair) { + return typeof pair.property === 'string' + ? pair.property + : pair.property.name; + }); + + if (~names.indexOf(search)) { + return null; + } + + return history.filter(function (pair) { + return typeof pair.property === 'string' + ? pair.property === search + : pair.property.name === search; + })[0]; +}; + +// +// ### function get (schema, callback) +// #### @schema {Array|Object|string} Set of variables to get input for. +// #### @callback {function} Continuation to pass control to when complete. +// Gets input from the user via stdin for the specified message(s) `msg`. +// +prompt.get = function (schema, callback) { + // + // Transforms a full JSON-schema into an array describing path and sub-schemas. + // Used for iteration purposes. + // + function untangle(schema, path) { + var results = []; + path = path || []; + + if (schema.properties) { + // + // Iterate over the properties in the schema and use recursion + // to process sub-properties. + // + Object.keys(schema.properties).forEach(function (key) { + var obj = {}; + obj[key] = schema.properties[key]; + + // + // Concat a sub-untangling to the results. + // + results = results.concat(untangle(obj[key], path.concat(key))); + }); + + // Return the results. + return results; + } + + // + // This is a schema "leaf". + // + return { + path: path, + schema: schema + }; + } + + // + // Iterate over the values in the schema, represented as + // a legit single-property object subschemas. Accepts `schema` + // of the forms: + // + // 'prop-name' + // + // ['string-name', { path: ['or-well-formed-subschema'], properties: ... }] + // + // { path: ['or-well-formed-subschema'], properties: ... ] } + // + // { properties: { 'schema-with-no-path' } } + // + // And transforms them all into + // + // { path: ['path', 'to', 'property'], properties: { path: { to: ...} } } + // + function iterate(schema, get, done) { + var iterator = [], + result = {}; + + if (typeof schema === 'string') { + // + // We can iterate over a single string. + // + iterator.push({ + path: [schema], + schema: prompt.properties[schema.toLowerCase()] || {} + }); + } + else if (Array.isArray(schema)) { + // + // An array of strings and/or single-prop schema and/or no-prop schema. + // + iterator = schema.map(function (element) { + if (typeof element === 'string') { + return { + path: [element], + schema: prompt.properties[element.toLowerCase()] || {} + }; + } + else if (element.properties) { + return { + path: [Object.keys(element.properties)[0]], + schema: element.properties[Object.keys(element.properties)[0]] + }; + } + else if (element.path && element.schema) { + return element; + } + else { + return { + path: [element.name || 'question'], + schema: element + }; + } + }); + } + else if (schema.properties) { + // + // Or a complete schema `untangle` it for use. + // + iterator = untangle(schema); + } + else { + // + // Or a partial schema and path. + // TODO: Evaluate need for this option. + // + iterator = [{ + schema: schema.schema ? schema.schema : schema, + path: schema.path || [schema.name || 'question'] + }]; + } + + // + // Now, iterate and assemble the result. + // + async.forEachSeries(iterator, function (branch, next) { + get(branch, function assembler(err, line) { + if (err) { + return next(err); + } + + function build(path, line) { + var obj = {}; + if (path.length) { + obj[path[0]] = build(path.slice(1), line); + return obj; + } + + return line; + } + + function attach(obj, attr) { + var keys; + if (typeof attr !== 'object' || attr instanceof Array) { + return attr; + } + + keys = Object.keys(attr); + if (keys.length) { + if (!obj[keys[0]]) { + obj[keys[0]] = {}; + } + obj[keys[0]] = attach(obj[keys[0]], attr[keys[0]]); + } + + return obj; + } + + result = attach(result, build(branch.path, line)); + next(); + }); + }, function (err) { + return err ? done(err) : done(null, result); + }); + } + + iterate(schema, function get(target, next) { + prompt.getInput(target, function (err, line) { + return err ? next(err) : next(null, line); + }); + }, callback); + + return prompt; +}; + +// +// ### function confirm (msg, callback) +// #### @msg {Array|Object|string} set of message to confirm +// #### @callback {function} Continuation to pass control to when complete. +// Confirms a single or series of messages by prompting the user for a Y/N response. +// Returns `true` if ALL messages are answered in the affirmative, otherwise `false` +// +// `msg` can be a string, or object (or array of strings/objects). +// An object may have the following properties: +// +// { +// description: 'yes/no' // message to prompt user +// pattern: /^[yntf]{1}/i // optional - regex defining acceptable responses +// yes: /^[yt]{1}/i // optional - regex defining `affirmative` responses +// message: 'yes/no' // optional - message to display for invalid responses +// } +// +prompt.confirm = function (/* msg, options, callback */) { + var args = Array.prototype.slice.call(arguments), + msg = args.shift(), + callback = args.pop(), + opts = args.shift(), + vars = !Array.isArray(msg) ? [msg] : msg, + RX_Y = /^[yt]{1}/i, + RX_YN = /^[yntf]{1}/i; + + function confirm(target, next) { + var yes = target.yes || RX_Y, + options = utile.mixin({ + description: typeof target === 'string' ? target : target.description||'yes/no', + pattern: target.pattern || RX_YN, + name: 'confirm', + message: target.message || 'yes/no' + }, opts || {}); + + + prompt.get([options], function (err, result) { + next(err ? false : yes.test(result[options.name])); + }); + } + + async.rejectSeries(vars, confirm, function(result) { + callback(null, result.length===0); + }); +}; + + +// Variables needed outside of getInput for multiline arrays. +var tmp = []; + + +// ### function getInput (prop, callback) +// #### @prop {Object|string} Variable to get input for. +// #### @callback {function} Continuation to pass control to when complete. +// Gets input from the user via stdin for the specified message `msg`. +// +prompt.getInput = function (prop, callback) { + var schema = prop.schema || prop, + propName = prop.path && prop.path.join(':') || prop, + storedSchema = prompt.properties[propName.toLowerCase()], + delim = prompt.delimiter, + defaultLine, + against, + hidden, + length, + valid, + name, + raw, + msg; + + // + // If there is a stored schema for `propName` in `propmpt.properties` + // then use it. + // + if (schema instanceof Object && !Object.keys(schema).length && + typeof storedSchema !== 'undefined') { + schema = storedSchema; + } + + // + // Build a proper validation schema if we just have a string + // and no `storedSchema`. + // + if (typeof prop === 'string' && !storedSchema) { + schema = {}; + } + + schema = convert(schema); + defaultLine = schema.default; + name = prop.description || schema.description || propName; + raw = prompt.colors + ? [prompt.message, delim + name.grey, delim.grey] + : [prompt.message, delim + name, delim]; + + prop = { + schema: schema, + path: propName.split(':') + }; + + // + // If the schema has no `properties` value then set + // it to an object containing the current schema + // for `propName`. + // + if (!schema.properties) { + schema = (function () { + var obj = { properties: {} }; + obj.properties[propName] = schema; + return obj; + })(); + } + + // + // Handle overrides here. + // TODO: Make overrides nestable + // + if (prompt.override && prompt.override[propName]) { + if (prompt._performValidation(name, prop, prompt.override, schema, -1, callback)) { + return callback(null, prompt.override[propName]); + } + + delete prompt.override[propName]; + } + + var type = (schema.properties && schema.properties[name] && + schema.properties[name].type || '').toLowerCase().trim(), + wait = type === 'array'; + + if (type === 'array') { + length = prop.schema.maxItems; + if (length) { + msg = (tmp.length + 1).toString() + '/' + length.toString(); + } + else { + msg = (tmp.length + 1).toString(); + } + msg += delim; + raw.push(prompt.colors ? msg.grey : msg); + } + + // + // Calculate the raw length and colorize the prompt + // + length = raw.join('').length; + raw[0] = raw[0]; + msg = raw.join(''); + + if (schema.help) { + schema.help.forEach(function (line) { + logger.help(line); + }); + } + + // + // Emit a "prompting" event + // + prompt.emit('prompt', prop); + + // + // If there is no default line, set it to an empty string + // + if(typeof defaultLine === 'undefined') { + defaultLine = ''; + } + + // + // set to string for readline ( will not accept Numbers ) + // + defaultLine = defaultLine.toString(); + + // + // Make the actual read + // + read({ + prompt: msg, + silent: prop.schema && prop.schema.hidden, + default: defaultLine, + input: stdin, + output: stdout + }, function (err, line) { + if (err && wait === false) { + return callback(err); + } + + var against = {}, + numericInput, + isValid; + + if (line !== '') { + + if (schema.properties[name]) { + var type = (schema.properties[name].type || '').toLowerCase().trim() || undefined; + + // + // Attempt to parse input as a float if the schema expects a number. + // + if (type == 'number') { + numericInput = parseFloat(line, 10); + if (!isNaN(numericInput)) { + line = numericInput; + } + } + + // + // Attempt to parse input as a boolean if the schema expects a boolean + // + if (type == 'boolean') { + if(line === "true") { + line = true; + } + if(line === "false") { + line = false; + } + } + + // + // If the type is an array, wait for the end. Fixes #54 + // + if (type == 'array') { + var length = prop.schema.maxItems; + if (err) { + if (err.message == 'canceled') { + wait = false; + stdout.write('\n'); + } + } + else { + if (length) { + if (tmp.length + 1 < length) { + isValid = false; + wait = true; + } + else { + isValid = true; + wait = false; + } + } + else { + isValid = false; + wait = true; + } + tmp.push(line); + } + line = tmp; + } + } + + against[propName] = line; + } + + if (prop && prop.schema.before) { + line = prop.schema.before(line); + } + + // Validate + if (isValid === undefined) isValid = prompt._performValidation(name, prop, against, schema, line, callback); + + if (!isValid) { + return prompt.getInput(prop, callback); + } + + // + // Log the resulting line, append this `property:value` + // pair to the history for `prompt` and respond to + // the callback. + // + logger.input(line.yellow); + prompt._remember(propName, line); + callback(null, line); + + // Make sure `tmp` is emptied + tmp = []; + }); +}; + +// +// ### function performValidation (name, prop, against, schema, line, callback) +// #### @name {Object} Variable name +// #### @prop {Object|string} Variable to get input for. +// #### @against {Object} Input +// #### @schema {Object} Validation schema +// #### @line {String|Boolean} Input line +// #### @callback {function} Continuation to pass control to when complete. +// Perfoms user input validation, print errors if needed and returns value according to validation +// +prompt._performValidation = function (name, prop, against, schema, line, callback) { + var numericInput, valid, msg; + + try { + valid = validate(against, schema); + } + catch (err) { + return (line !== -1) ? callback(err) : false; + } + + if (!valid.valid) { + msg = line !== -1 ? 'Invalid input for ' : 'Invalid command-line input for '; + + if (prompt.colors) { + logger.error(msg + name.grey); + } + else { + logger.error(msg + name); + } + + if (prop.schema.message) { + logger.error(prop.schema.message); + } + + prompt.emit('invalid', prop, line); + } + + return valid.valid; +}; + +// +// ### function addProperties (obj, properties, callback) +// #### @obj {Object} Object to add properties to +// #### @properties {Array} List of properties to get values for +// #### @callback {function} Continuation to pass control to when complete. +// Prompts the user for values each of the `properties` if `obj` does not already +// have a value for the property. Responds with the modified object. +// +prompt.addProperties = function (obj, properties, callback) { + properties = properties.filter(function (prop) { + return typeof obj[prop] === 'undefined'; + }); + + if (properties.length === 0) { + return callback(obj); + } + + prompt.get(properties, function (err, results) { + if (err) { + return callback(err); + } + else if (!results) { + return callback(null, obj); + } + + function putNested (obj, path, value) { + var last = obj, key; + + while (path.length > 1) { + key = path.shift(); + if (!last[key]) { + last[key] = {}; + } + + last = last[key]; + } + + last[path.shift()] = value; + } + + Object.keys(results).forEach(function (key) { + putNested(obj, key.split('.'), results[key]); + }); + + callback(null, obj); + }); + + return prompt; +}; + +// +// ### @private function _remember (property, value) +// #### @property {Object|string} Property that the value is in response to. +// #### @value {string} User input captured by `prompt`. +// Prepends the `property:value` pair into the private `history` Array +// for `prompt` so that it can be accessed later. +// +prompt._remember = function (property, value) { + history.unshift({ + property: property, + value: value + }); + + // + // If the length of the `history` Array + // has exceeded the specified length to remember, + // `prompt.memory`, truncate it. + // + if (history.length > prompt.memory) { + history.splice(prompt.memory, history.length - prompt.memory); + } +}; + +// +// ### @private function convert (schema) +// #### @schema {Object} Schema for a property +// Converts the schema into new format if it is in old format +// +function convert(schema) { + var newProps = Object.keys(validate.messages), + newSchema = false, + key; + + newProps = newProps.concat(['description', 'dependencies']); + + for (key in schema) { + if (newProps.indexOf(key) > 0) { + newSchema = true; + break; + } + } + + if (!newSchema || schema.validator || schema.warning || typeof schema.empty !== 'undefined') { + schema.description = schema.message; + schema.message = schema.warning; + + if (typeof schema.validator === 'function') { + schema.conform = schema.validator; + } else { + schema.pattern = schema.validator; + } + + if (typeof schema.empty !== 'undefined') { + schema.required = !(schema.empty); + } + + delete schema.warning; + delete schema.validator; + delete schema.empty; + } + + return schema; +} diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/.npmignore b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/.npmignore new file mode 100644 index 0000000..0db216b --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/.npmignore @@ -0,0 +1,2 @@ +npm-debug.log +node_modules diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/LICENCE b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/LICENCE new file mode 100644 index 0000000..74489e2 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/LICENCE @@ -0,0 +1,25 @@ +Copyright (c) Isaac Z. Schlueter +All rights reserved. + +The BSD License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/README.md b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/README.md new file mode 100644 index 0000000..5967fad --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/README.md @@ -0,0 +1,53 @@ +## read + +For reading user input from stdin. + +Similar to the `readline` builtin's `question()` method, but with a +few more features. + +## USAGE + +```javascript +var read = require("read") +read(options, callback) +``` + +The callback gets called with either the user input, or the default +specified, or an error, as `callback(error, result, isDefault)` +node style. + +## OPTIONS + +Every option is optional. + +* `prompt` What to write to stdout before reading input. +* `silent` Don't echo the output as the user types it. +* `replace` Replace silenced characters with the supplied character value. +* `timeout` Number of ms to wait for user input before giving up. +* `default` The default value if the user enters nothing. +* `edit` Allow the user to edit the default value. +* `terminal` Treat the output as a TTY, whether it is or not. +* `input` Readable stream to get input data from. (default `process.stdin`) +* `output` Writeable stream to write prompts to. (default: `process.stdout`) + +If silent is true, and the input is a TTY, then read will set raw +mode, and read character by character. + +## COMPATIBILITY + +This module works sort of with node 0.6. It does not work with node +versions less than 0.6. It is best on node 0.8. + +On node version 0.6, it will remove all listeners on the input +stream's `data` and `keypress` events, because the readline module did +not fully clean up after itself in that version of node, and did not +make it possible to clean up after it in a way that has no potential +for side effects. + +Additionally, some of the readline options (like `terminal`) will not +function in versions of node before 0.8, because they were not +implemented in the builtin readline module. + +## CONTRIBUTING + +Patches welcome. diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/example/example.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/example/example.js new file mode 100644 index 0000000..cf213bf --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/example/example.js @@ -0,0 +1,13 @@ +var read = require("../lib/read.js") + +read({prompt: "Username: ", default: "test-user" }, function (er, user) { + read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) { + read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) { + console.error({user: user, + pass: pass, + verify: pass2, + passMatch: (pass === pass2)}) + console.error("the program should exit now") + }) + }) +}) diff --git a/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/lib/read.js b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/lib/read.js new file mode 100644 index 0000000..a93d1b3 --- /dev/null +++ b/node_modules/forever/node_modules/flatiron/node_modules/prompt/node_modules/read/lib/read.js @@ -0,0 +1,113 @@ + +module.exports = read + +var readline = require('readline') +var Mute = require('mute-stream') + +function read (opts, cb) { + if (opts.num) { + throw new Error('read() no longer accepts a char number limit') + } + + if (typeof opts.default !== 'undefined' && + typeof opts.default !== 'string' && + typeof opts.default !== 'number') { + throw new Error('default value must be string or number') + } + + var input = opts.input || process.stdin + var output = opts.output || process.stdout + var prompt = (opts.prompt || '').trim() + ' ' + var silent = opts.silent + var editDef = false + var timeout = opts.timeout + + var def = opts.default || '' + if (def) { + if (silent) { + prompt += '(