1
0
mirror of https://github.com/mgerb/mywebsite synced 2026-01-11 18:32:50 +00:00

Added files

This commit is contained in:
2015-06-25 16:28:41 -05:00
parent 656dca9289
commit eb27b55a54
5621 changed files with 1630154 additions and 0 deletions

1
node_modules/.bin/forever generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../forever/bin/forever

53
node_modules/forever/.jshintrc generated vendored Executable file
View File

@@ -0,0 +1,53 @@
{
"passfail": false,
"maxerr": 100,
"browser": false,
"node": true,
"rhino": false,
"couch": true,
"wsh": true,
"jquery": true,
"prototypejs": false,
"mootools": false,
"dojo": false,
"devel": 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
}

7
node_modules/forever/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,7 @@
test/*.log
node_modules/
node_modules/*
npm-debug.log
.*.sw[op]
test/fixtures/*.log
.idea

13
node_modules/forever/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,13 @@
language: node_js
node_js:
- 0.8
- 0.10
before_install:
- curl --location http://git.io/1OcIZA | bash -s
branches:
only:
- master
notifications:
email:
- travis@nodejitsu.com
irc: "irc.freenode.org#nodejitsu"

700
node_modules/forever/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,700 @@
v0.13.0 / Tue, 4 Nov 2014
=========================
* [8707877] [dist] Version bump. 0.13.0 (`indexzero`)
* [3865596] [dist] Up-to-date linting with JSHint. Fixes #419. (`indexzero`)
* [1d863ba] Renaming stoppid -> stopbypid (`Anthony Akentiev`)
* [4adf834] Little bug fix: comparing integers (`Anthony Akentiev`)
* [c29de4b] README updated (`Anthony Akentiev`)
* [54194df] stoppid command added to stop running under forever process by PID (`Anthony Akentiev`)
* [c568f89] [minor] Some small style changes to new(er) tests. (`indexzero`)
* [8e4f1fb] code 0 should be treated as a Number too. (`Tjatse`)
* [663e49a] wait more... (`Tjatse`)
* [1f184e8] test case for start/stop peaceful (`Tjatse`)
* [8f7dfba] [fix] relative script file should works fine, both with `start` or `stop`. (`Tjatse`)
* [84cf5ad] Add --workingDir option to specify the CWD of the process in which SCRIPT is run (`Myk Willis`)
* [cb72aed] [dist] Update several dependencies to latest. (`indexzero`)
v0.12.0 / Thu, 30 Oct 2014
==========================
* [b01eabb] [dist] Version bump. 0.12.0 (`indexzero`)
* [9b6c8f7] [dist] Assign things to the author and the contributors. (`indexzero`)
* [af8d228] fixes EACCESS error with .sock (UNIX domain sockets) on Windows. Uses named pipes instead. (`Miroslav Mocek`)
* [eecf6a2] improved error handling (`Kevin "Schmidty" Smith`)
* [6707a40] improved error handling (`Kevin "Schmidty" Smith`)
* [a2320aa] [minor] Do not check for a variable twice. (`indexzero`)
* [283f210] [refactor] Update to `forever-monitor@1.4.0` and do not use the deprecated `.options` option. You can see why it is deprecated. (`indexzero`)
* [73359e8] [doc] Make note that the new root is actually NOT the default since it looks like it could be. (`indexzero`)
* [a74e87c] [fix] inherits configuration from parent process when using `startDaemon` method. - make variable names camelCasing (`Tjatse`)
* [1f9b7f7] Test case of startDaemon() method - configuration inheritance issue. (`Tjatse`)
* [1102d11] [fix] inherits configuration from parent process when using `startDaemon` method. (`Tjatse`)
* [521d91a] Merge pull request #607 from ramen-dev/zero-status-code (`Charlie Robbins`)
* [487fc54] An 'error' on stopall is not actually an error (`Ryan Angilly`)
* [250a4f8] [fix doc] More documentation around `forever.startServer`. Fixes #566. (`indexzero`)
* [dfed754] [fix] Set `forever.root` and `forever.config.get(root)` for symmetry. (`indexzero`)
* [9eeeeb1] [fix doc] Update documentation. Fixes #594. (`indexzero`)
* [35f477f] [fix] Update documentation for `forever.list`. Fixes #598. (`indexzero`)
* [c21f55d] [doc fix] Document FOREVER_ROOT environment variable. Properly respect -p. Fixes #548. Fixes #541. Fixes #568. (`indexzero`)
* [0f227e5] [dist] Remove `foreverd` from scripts. Fixes #581. (`indexzero`)
* [5fb6329] [dist breaking api] Remove `forever.service`. Fixes #372. (`indexzero`)
* [938bf33] [fix] Properly boolean-ize `--killTree`. Fixes #579. (`indexzero`)
* [45f321c] [fix] Actually support the documented `--uid` or `-u` CLI option. Fixes #424. (`indexzero`)
* [3a40761] Added uid information to help usage as per README (`brianmarco`)
* [fefce03] fixed wrong usage for option fifo (`lulurun`)
* [a216e76] checks proc.running and writes STOPPED instead of uptime if stopped (`smoodiver`)
* [55141c8] Adds id parameter as outlined in https://github.com/nodejitsu/forever/issues/461. (`Jackson Gariety`)
* [99ee565] [dist] Bump to `forever-monitor@1.3.0` (`indexzero`)
* [99cddb5] [dist] Added .jshintrc (`indexzero`)
* [b8282d1] Merge pull request #577 from Mithgol/patch-1 (`Arnout Kazemier`)
* [16b1013] use SVG to display Travis CI build testing status (`Mithgol`)
* [d60d50d] Merge pull request #553 from andrewmartin/master (`Jarrett Cruger`)
* [b4a8135] fixing a small typo in the 'e.g.' portion of request, whoops. (`Andrew Martin`)
* [a248968] updating docs with the uid flag (`Andrew Martin`)
* [f730407] [dist] v0.11.1 (`Julian Duque`)
* [09c4362] Merge pull request #533 from Kontakter/master (`Julian Duque`)
* [23a217c] Fix remark from @julianduque (`Ignat Kolesnichenko`)
* [8fd4699] Merge pull request #520 from kevinkhill/feature1 (`Julian Duque`)
* [8dc2dee] Merge pull request #538 from dandv/patch-1 (`Charlie Robbins`)
* [7b20f0f] Slightly better English for the 'restarting' messages (`Dan Dascalescu`)
* [af83c0e] Allow to get logFile and pidFile from config (`Ignat Kolesnichenko`)
* [2cb60e8] Update cli.js (`Kevin Hill`)
v0.11.0 / Thu, 10 Apr 2014
==========================
* [09d8403] [dist] Version bump. 0.11.0 (`Jarrett Cruger`)
* [dd08616] Merge pull request #531 from jeromew/patch-1 (`Jarrett Cruger`)
* [5e15626] FIX: added FOREVER_ROOT variable (`srossross`)
* [3cbabf4] "forever start" hangs with node 0.11.9 (`jeromew`)
* [b873164] Merge pull request #516 from meritt/patch-1 (`Julian Duque`)
* [7ff651b] Delete CHANGELOG.md (`Alexey Simonenko`)
* [786271f] [dist] v0.10.11 (`Julian Duque`)
* [7f4e4e9] [dist] Bump dependencies (`Julian Duque`)
* [4822fec] [fix] Trying to avoid the non-determinism in tests (`Julian Duque`)
* [2e75aa1] [fix] Add --killSignal to help (`Julian Duque`)
* [b2b49d1] [minor] Change order of option in help (`Julian Duque`)
* [45800aa] Merge pull request #457 from jmav/patch-1 (`Julian Duque`)
* [88071a2] Merge pull request #423 from kbackowski/fix_watch_ignore_pattern_array (`Julian Duque`)
* [b0ec661] [dist] v0.10.10 (`Julian Duque`)
* [f356fe1] Merge branch 'master' of https://github.com/nodejitsu/forever (`Julian Duque`)
* [2db62a6] Merge branch 'alternative' of https://github.com/chester1000/forever into chester1000-alternative (`Julian Duque`)
* [8b7c92b] Merge pull request #498 from askhogan/patch-2 (`Julian Duque`)
* [c3199b8] Merge branch 'master' of https://github.com/jillix/forever into jillix-master (`Julian Duque`)
* [bc48ca6] [fix] Make vows happy (`Julian Duque`)
* [2df789d] Updated timespan to 2.1.0 (`Gabriel Petrovay`)
* [70ab37e] Add --watchIgnore and colors (`Patrick Hogan`)
* [a7d419c] Update README.md (`Jure`)
* [2ba3158] Fixed watchIgnorePatterns assignment (`kbackowski`)
* [acf59a7] Proper Revert "[fix] Make `-v|--version` work. Fixes #303." (`Maurycy Damian Wasilewski`)
v0.10.9 / Tue, 15 Oct 2013
==========================
* [bc55bbf] [dist] Bump version to 0.10.9 (`Maciej Małecki`)
* [b4b0541] [dist] Use `forever-monitor@1.2.3` (`Maciej Małecki`)
v0.10.8 / Fri, 10 May 2013
==========================
* [a4289d1] [dist] Bump version to 0.10.8 (`Maciej Małecki`)
* [8afad64] [ui dist] Output info about process being killed by signal (`Maciej Małecki`)
v0.10.7 / Sat, 27 Apr 2013
==========================
* [22a3923] [dist] Version bump. 0.10.7 (`indexzero`)
* [6440b4e] [fix] remove duplicate option (`Julian Duque`)
v0.10.6 / Sun, 21 Apr 2013
==========================
* [e8c48d4] [dist] Version bump. 0.10.6 (`indexzero`)
v0.10.5 / Sun, 21 Apr 2013
==========================
* [a9d7aa1] [dist] Version bump. 0.10.5 (`indexzero`)
* [02b44b1] Merge pull request #390 from yyx990803/cli-restartall-fix (`Charlie Robbins`)
* [1a1ba32] [fix] Make `-v|--version` work. Fixes #303. (`indexzero`)
* [10fa40f] [fix dist] Bump to `nssocket@0.10.0` to support `node@0.10.x`. Update travis to test it. Fixes #370. Fixes #400. (`indexzero`)
* [bd42888] [fix] Manually merge #405. Fixes #405. (`indexzero`)
* [d3675fa] process exit on error (`Noah H. Smith`)
* [b641a4a] [minor] Style compliance for #403. Fixes #403. (`indexzero`)
* [477082b] add the --watchIgnore option to be able to ignore files or directories when --watch is enabled (`Stéphane Gully`)
* [5fa39ce] [fix] Return `monitor` from `.startDaemon()`. Fixes #387. Fixes #389. (`indexzero`)
* [bda8604] [fix] Manually merge `plain-feature` because of trailing space noise. Fixes #381. [dist] Bump dependencies (`indexzero`)
* [6047462] [fix] Added the default `dir` column which outputs the sourceDir from `forever-monitor`. Fixes #367. (`indexzero`)
* [9cbe4cb] [fix dist] Update to the latest `forever-monitor`. Fixes #361. (`indexzero`)
* [055c483] [fix] Warn users if `--minUptime` or `--spinSleepTime` are not specified. Fixes #344. (`indexzero`)
* [1e4b2f6] added and cli options for streaming log output, updated README.md and tests to reflect changes (`John Lancaster`)
* [94f61f5] removed trailing whitespace from lib/forever.js and lib/forever/cli.js ☠ (`John Lancaster`)
* [1ec1a16] Merge pull request #395 from vanthome/patch-2 (`Nathan Zadoks`)
* [352947e] Update package.json (`Thomas`)
* [dc1c3f9] Merge pull request #352 from ingmr/master (`Charlie Robbins`)
* [e442ea9] add no process error handling to cli.restartAll (`Evan You`)
* [3b3d04b] Merge pull request #380 from nodejitsu/timestamp-logs (`Charlie Robbins`)
* [2e52eaa] Merge pull request #345 from jazzzz/fix-index-parsing (`Julian Duque`)
* [c4d2274] Merge pull request #360 from filipovskii/master (`Julian Duque`)
* [d3ff4bd] Add timestamp support to forever log (`Julian Duque`)
* [9b2b451] Merge pull request #362 from estliberitas/master (`Charlie Robbins`)
* [b999bc2] Support exit signal customization (comes from another commit to forever-monitor) (`Alexander Makarenko`)
* [3feef60] Use `path` option as forever root if given. (`filipovskii_off`)
* [6ee6f9a] Merge pull request #333 from fb55/master (`Charlie Robbins`)
* [3496b64] use process.env.USERPROFILE as alternative to process.env.HOME (for windows) (`ingmr`)
* [2b2ebbc] Fix uids mistakenly taken for an id (`Jazz`)
* [e52b063] wrapped fs.unlinkSync in try-catch-block (`Felix Böhm`)
* [094ebd4] Merge pull request #340 from fb55/patch-1 (`Maciej Małecki`)
* [33dc125] added a helpful error message (`Felix Böhm`)
* [f69eb4d] Updated flatiron dependency to 0.2.8 (`Ian Babrou`)
* [4e7fa8f] pid variable not use. (`Thomas Tourlourat`)
* [5b7f30b] don't remove log files (`Felix Böhm`)
* [a73eb5a] remove pid- & logfiles on `exit` and `stop` (`Felix Böhm`)
* [70a6acd] [api] Accept --killTree from CLI (`indexzero`)
* [d3aedc9] Merge pull request #330 from bramstein/patch-1 (`Charlie Robbins`)
* [777256f] Update lib/forever.js (`Bram Stein`)
v0.10.1 / Sun, 8 Jul 2012
=========================
* [4ed446f] [dist] Version bump. 0.10.1 (`indexzero`)
* [df802d0] [dist] Bump forever-monitor version (`indexzero`)
v0.10.0 / Sun, 8 Jul 2012
=========================
* [c8afac3] [dist] Version bump. 0.10.0 (`indexzero`)
* [c2baf66] [minor] Prefer no spaces when declaring Array instances (`indexzero`)
* [9823d13] [fix] Ensure pidFile is written to disk (and updated on restart) by bin/monitor (`indexzero`)
* [1dfe0d0] [dist] Update dependencies to hard versions (`indexzero`)
* [6921e6c] [refactor minor] Final integrations for `forever-monitor@1.0.1` (`indexzero`)
* [f27cdaa] [doc] Remove documenetation specific to `forever-monitor` (`indexzero`)
* [d9e5faa] [fix] Remove require for unused `ps-tree` (`indexzero`)
* [14e5bda] [dist] Only support node@0.8.x (`indexzero`)
* [91bda36] [refactor] Examples are now in `forever-monitor` (`indexzero`)
* [c1f1e6f] [dist] Remove outdated docco docs (`indexzero`)
* [b5ce548] [refactor] Finish refactor of core Monitor functionality into `forever-monitor` (`indexzero`)
* [5225d68] [refactor] Moved test/core/check-process-test.js into `forever-monitor` (`indexzero`)
* [b46c4c0] [refactor] Remove all code in `forever-monitor` (`indexzero`)
* [a5343df] [fix] Use process.execPath for spawning. (`Charlie McConnell`)
* [4ed1beb] [fix] Use process.execPath instead of a hashbang. (`Charlie McConnell`)
* [4f72f8c] [fix] Fix bad require path. (`Charlie McConnell`)
* [665e1ec] [test] Temporary: prevent test failure from deprecation warning in core. (`Charlie McConnell`)
* [1e8d7ca] [refactor] Remove unused fork-shim (`Charlie McConnell`)
* [a1e8f21] [test] Only test on node 0.8.x (`Charlie McConnell`)
* [b7c303a] [refactor] Implement silent fork via spawn stdio options. (`Charlie McConnell`)
* [4fed919] [refactor] Refactor to remove daemon.node (`Charlie McConnell`)
* [485a18b] [dist] Remove microtime dependency (`Charlie McConnell`)
* [45a7e51] [dist] Remove `node-fork` dependency (`Maciej Małecki`)
* [ba6b76d] [test] Remove test for `forkShim` option (`Maciej Małecki`)
* [16d1419] [refactor api] Start using native fork (`Maciej Małecki`)
* [d000278] [docs] Add Travis CI badge to README. (`Charlie McConnell`)
* [2e2d18a] [test] Add .travis.yml for Travis CI. (`Charlie McConnell`)
v0.9.2 / Mon, 11 Jun 2012
=========================
* [02abd44] [dist] Version bump v0.9.2 (`Charlie McConnell`)
* [95d3e1a] [minor] Remove unused argument. (`Charlie McConnell`)
* [44490e6] [test fix] Add missing .foreverignore test fixture. (`Charlie McConnell`)
* [4245e54] [fix] Update startOrRestart to fix bugs. (`Christian Howe`)
* [6a9a268] Merge pull request #290 from fedot/patch-1 (`Marak Squires`)
* [592a1eb] Added `watchDirectory` to the list of options in README (to fulfill #271) (`Fedot Praslov`)
* [cf5e5be] [dist] Use daemon.node v0.5.x (`Charlie McConnell`)
* [13ef52f] [dist] Fix maintainers field (`Christian Howe`)
v0.9.1 / Sat, 5 May 2012
========================
* [75bfdab] [dist] Version bump v0.9.1 (`Charlie McConnell`)
* [4116f85] [fix] Pass argv options properly. (`Charlie McConnell`)
* [44c2337] closes #164 and #235 fix wrong usage of matchBase option of minimatch, use relative to watchDirectory path fore matching (`Oleg Slobodskoi`)
* [2a7c477] Added watchDirectory to command line options (`Fedot Praslov`)
* [8af6803] [fix] Revert bad options commit. (`Charlie McConnell`)
* [5d21f97] [fix] Fix unhandled `error` event in `forever stopall` (`Maciej Małecki`)
* [49c2c47] [fix] Correct function name (`Maciej Małecki`)
* [f3b119b] [dist] Version bump v0.9.0 (`Charlie McConnell`)
* [b4798d8] [test fix] Make logger test more consistent. (`Charlie McConnell`)
* [4848f90] [test] Add test fixture for producing logging output. (`Charlie McConnell`)
* [73b10be] [test] New logging test for the new logging plugin. (`Charlie McConnell`)
* [8ec0bce] [fix] Restore stdout and stderr events, fix semantics of silent option. (`Charlie McConnell`)
* [0b80e4d] Minor wording fix (`Andrew Radev`)
* [9c787df] Stop or restart a process by its uid (`Andrew Radev`)
* [af5b8c2] [fix] cli pidFile text (`Bradley Meck`)
* [1ad16b0] [pull-request] #244, from @michaelcdillon (`Bradley Meck`)
* [ea5317c] [doc] Remove unused `forever` option from docs (`Maciej Małecki`)
* [8474c9c] [api] forkShim option should allow a string to say which module to use when shimming (rather than the one currently used by this process) (`Bradley Meck`)
* [2f93ba4] [fix] Destroy log file streams in a more intelligent way. (`Charlie McConnell`)
* [89f3614] [fix] Logging now survives child process restarts. (`Charlie McConnell`)
* [2d7d462] [minor] Dont use optimist directly (`Joshua Holbrook`)
* [cda371d] [fix] Pass argvOptions to app.config.argv as well. (`Joshua Holbrook`)
* [8529281] [refactor] Remove logging code from monitor. (`Charlie McConnell`)
* [70ae4f4] [refactor] Replace logging plugin. (`Charlie McConnell`)
* [a6a1675] [fix] Remove duplicate alias. (`Charlie McConnell`)
* [dd1508b] [fix] s/appendLog/append/g to make --append work. (`Charlie McConnell`)
* [298ec73] [fix] Restore optional logfile destination functionality. (`Charlie McConnell`)
* [a0c9ac5] [fix] Restore self.warn method on monitor instance. (`Charlie McConnell`)
* [114e378] [dist] Update package.json to use fork of daemon.node. (`Charlie McConnell`)
* [8186994] [fix] Alter logging paths to reduce memory leakage and prevent stdio issues. (`Charlie McConnell`)
* [5c8fcc5] [fix] Update forever.startDaemon to use adjusted daemon.node api. (`Charlie McConnell`)
* [f44d5f4] Fix worker crash from bad socket client (`Felix Geisendörfer`)
* [b093bfc] [fix api] Expose `checkFile` and fix logical condition (`Maciej Małecki`)
* [e154a50] [fix] Pass options.argv instead of options (cli.js, line 188) (`Joshua Holbrook`)
* [5aa16c3] [dist] v0.8.5 (`Bradley Meck`)
* [157ce7b] [fix] use env `bash` rather than bin/sh (`Bradley Meck`)
* [205e6f3] [fix] EACCESS should still go to next() in `forever list` (`Bradley Meck`)
v0.8.4 / Sun, 15 Jan 2012
=========================
* [6094c7c] [dist] Version bump. 0.8.4 (`indexzero`)
* [1f4f5dc] [fix test] Make test/monitor/fork-test.js idempotent for processes created (`indexzero`)
* [b6daac5] [dist] `node-fork@0.4.x` (`indexzero`)
* [92d7dee] [doc] Update examples/cli-multiple-start (`indexzero`)
* [1fa4943] [refactor] Create unique worker socket files using the `microtime` module (`indexzero`)
* [72dac45] [fix] Update bad reference variable to forever in watch plugin (`indexzero`)
v0.8.3 / Fri, 13 Jan 2012
=========================
* [96277b7] [dist] Version bump. 0.8.3. (`indexzero`)
* [432a088] [fix] Allow for `forever set` to include values with `/` (i.e. directories) (`indexzero`)
* [6bfe071] [fix test] try/catch around test/fixtures/* (`indexzero`)
* [80f9bec] Merge pull request #222 from skyisle/master (`Charlie Robbins`)
* [7064adb] Show -a option when user met log file exist error. (`skyisle`)
* [4e2ab81] [fix] Don't leak `fs`, `path`, `nssocket`, `utile` and `forever` (`Maciej Małecki`)
* [9b0ad25] [fix] Don't leak `mkdirp` and `async` (`Maciej Małecki`)
v0.8.2 / Fri, 6 Jan 2012
========================
* [6779342] [dist] Version bump. 0.8.2 (`indexzero`)
* [6588f59] [api test] Expose `.forkShim` for communicating between `0.6.x` and `0.4.x` processes (`indexzero`)
* [82e2a7d] [api refactor] Remove fork hack since we are now using `node-fork` (`indexzero`)
* [a2c4313] [test fix] Fix test/worker/multiple-workers-test.js to pass on node@0.4.x and be idempotent (`indexzero`)
* [63676ed] [minor] Whitespace update (`indexzero`)
* [a987826] [fix] Attempt to listen again if EADDRINUSE in forever.Worker (`indexzero`)
* [d711ab8] [minor] Whitespace update (`indexzero`)
v0.8.1 / Thu, 5 Jan 2012
========================
* [b15cd34] [dist] Version bump. 0.8.1 (`indexzero`)
* [4e25765] [fix] Print help on just `forever` (`indexzero`)
* [0d5e893] [api] Added `forever restartall` and `forever.restartAll()`. Fixes #131 (`indexzero`)
* [cef3435] [doc fix] Update `.cleanup` to `.cleanUp`. Fixes #199 (`indexzero`)
v0.8.0 / Thu, 5 Jan 2012
========================
* [53ba981] [dist] Version bump. 0.8.0 (`indexzero`)
* [7fc258c] [dist] Added @mmalecki to contributors (`indexzero`)
* [93b3fd0] [dist] Update node version to reflect backwards compatibility (`indexzero`)
* [49de211] [dist test] Move test/fork-test.js to test/monitor/fork-test.js (`indexzero`)
* [4ab4438] [fix] A couple of minor fixes to CLI edge cases (`indexzero`)
* [b830218] [fix] Ensure `forever script.js` works (`indexzero`)
* [285b659] [merge] Resolve bad cherry-pick from `fork` branch (`indexzero`)
* [1f673f9] [fix] use node-fork for listing (`bradleymeck`)
* [fa02258] [fix] use node-fork so 0.6 can talk to 0.4 using the fork: true in combination with command (`bradleymeck`)
* [b06d58b] [api] Expose `Monitor.fork` for using `child_process.fork()` (`indexzero`)
* [2c6800a] [api] Expose `Monitor.fork` for using `child_process.fork()` (`indexzero`)
* [7aa72c9] [api test doc] Expose `.fork()` through forever for node-specific processes. Currently blocked by joyent/node#2454 (`indexzero`)
* [1f78240] [test minor] A couple of small updates for tests after recent API changes. Readd Worker.exitOnStop (`indexzero`)
* [3888dbd] [merge] Resolve merge conflicts of `rewrite` into master (`indexzero`)
* [bde27e0] [refactor] Use the nssocket defined protocol for stopping and restarting worker processes (`indexzero`)
* [dc0b457] [dist] Remove bin/forever-worker now that it `daemon.node` works again (`indexzero`)
* [9cee338] [wtf.node] BLACK VOODOO MAGIC. `daemon.node` somehow works even though libuv isnt fork(2)-safe (`indexzero`)
* [ebd80a2] [refactor] Attempt to spawn workers via bin/forever-worker. (`indexzero`)
* [8f9f0ad] [refactor] Significant refactor to how forever works in the rewrite (`indexzero`)
* [bca8ed9] [test] Basic CLI test in `sh` (`Maciej Małecki`)
* [a9247de] [dist] Update `watch` to `watch@0.5` (`Maciej Małecki`)
* [e57568b] [test] Remove `cli` test (`Maciej Małecki`)
* [9ff117d] [refactor] Move `daemon` to devDependencies on its way to deprecation (`indexzero`)
* [84be160] [fix] Make logs work again (`Maciej Małecki`)
* [d983726] [bin] Make `forever start` work with parameters (`Maciej Małecki`)
* [55d96b2] [fix] Wrap parsing data from socket into `try .. catch` (`Maciej Małecki`)
* [85c4542] [minor] Remove unused `daemon` require (`Maciej Małecki`)
* [321c182] [refactor] Replace `daemon.node` with `child_process.fork` (`Maciej Małecki`)
* [df8d71d] [bin] Supress `stdout` and `stderr` when run as a fork (`Maciej Małecki`)
* [2ead453] [test] Test `kill` action (`Maciej Małecki`)
* [a0d09d2] [api] `kill` action for `Worker` (`Maciej Małecki`)
* [6517f74] [test] Add `MonitorMock.kill` (`Maciej Małecki`)
* [883e712] [api] First pass at Worker integration (`Maciej Małecki`)
* [bbc23e2] [test] DRY tests a bit (`Maciej Małecki`)
* [831f76f] [api] Worker `spawn` command (`Maciej Małecki`)
* [768f074] [api] If worker is a fork, notify master that it's listening (`Maciej Małecki`)
* [cf716d5] [api] Guard for no options for Worker (`Maciej Małecki`)
* [d174539] [test] Test if worker responds to `data` (`Maciej Małecki`)
* [3059a9d] [api] Worker responds to `data` now (`Maciej Małecki`)
* [e248716] [test] Add `data` property to `MonitorMock` (`Maciej Małecki`)
* [748380b] [test] Don't hardcode socket path in tests (`Maciej Małecki`)
* [d8b81dd] [api] `Worker.start` calls back with socket path (`Maciej Małecki`)
* [7be6917] [test refactor] Restructure worker test a bit (`Maciej Małecki`)
* [c710dc5] [test] Basic test for worker (`Maciej Małecki`)
* [f06c345] [api] Sketch of `Worker` (`Maciej Małecki`)
* [34ccb24] [refactor] Remove watching code from `forever.Monitor` (`Maciej Małecki`)
* [0e6ea8f] [test] Basic tests for `Logger` plugin (`Maciej Małecki`)
* [f84634b] [refactor] Add `Logger` plugin (`Maciej Małecki`)
* [ab0f8e9] [refactor] Remove logging from `forever.Monitor` (`Maciej Małecki`)
* [8a9af6b] [refactor] Inherit from `broadway.App` (`Maciej Małecki`)
* [d945bb2] [dist] Depend on `broadway` and `eventemitter2` (dev dep) (`Maciej Małecki`)
* [cdb355f] [test] Add useful mocks (`Maciej Małecki`)
* [ed75bd4] [dist] Ignore vim swap files (`Maciej Małecki`)
v0.7.6 / Fri, 23 Dec 2011
=========================
* [2ac0459] [dist] Version bump. 0.7.6. 0.4.x only. `forever >= 0.8.0` will be 0.6.x compatible (`indexzero`)
* [88d9c20] [dist] Remove clip dependency (`indexzero`)
* [2815f71] [fix] Break apart cli.logs to support `forever logs` and `forever logs <script|index>` correctly (`indexzero`)
* [72f4d14] [test] Update test fixture pathing mistake (`indexzero`)
* [c6072f5] [dist] Remove console.error/log statements (`indexzero`)
* [ed0d1e8] [fix minor] Fix 2 typos in forever service CLI (`Maciej Małecki`)
* [079137c] [refactor] Refactor Forever service CLI (`Maciej Małecki`)
* [c01abef] [api] Export `cli.getOptions` (`Maciej Małecki`)
* [13e8db8] [api] Expose `argvOptions` (`Maciej Małecki`)
* [ee9f98b] [doc fix] `--pidfile` is now called `--pidFile` (`Maciej Małecki`)
* [1d1656c] [test refactor] `test/{helpers.js => helpers/macros.js}` (`Maciej Małecki`)
* [ce7d5a1] [fix] Fix option parsing for starting actions (`Maciej Małecki`)
* [afccdb4] Merge pull request #190 from muloka/patch-1 (`Marak Squires`)
* [fc4dec5] Fixed broken link, replaced indexzero with nodejitsu in url. (`Louis Galipeau`)
* [0812449] [fix] Respect `-c` on restart. Fixes #159 (`indexzero`)
* [0e7873b] [fix] Improve the ordering of options parsing and include some options missed on the reparse. Fixes #139 (`indexzero`)
v0.7.5 / Fri, 2 Dec 2011
========================
* [76b4d96] [dist] Version bump. 0.7.5 (`indexzero`)
* [d6c7590] [minor] Always try to parse the response before calling next() (`indexzero`)
* [dcbfc70] [dist] Various small esoteric changes. Fixes #179 (`indexzero`)
* [061d14f] [fix doc] Fix README to match flatiron refactor (`Maciej Małecki`)
* [517d31b] [fix] Make option aliases work again (`Maciej Małecki`)
* [63d91b2] [fix] Fix for pass-through parameters (`nconf@0.5`) (`Maciej Małecki`)
* [e7e8fdf] prevent leading dashes in autogenerated log/pid filenames (`Brian Mount`)
* [76bea57] [fix] Fix `require`s in `foreverd` (`Maciej Małecki`)
* [7cdca07] [fix] Make it compatible with `broadway@0.1.1` (`nconf@0.5`) (`Maciej Małecki`)
* [791c123] [dist] Locked in nconf to v0.4.x. Bumped to v0.7.4. Should close #172 (`Marak Squires`)
* [4ae63d0] [merge] A few random missed conflicts from `git cherry-pick` on 22 commits. oops. (`indexzero`)
* [60a576a] [test fix] Since forever.kill is async, use `async.forEach`. Update test/cli-test.js to rimraf ~/.forever temporarily (`indexzero`)
* [1a04002] [fix] Make `--help` work (`Maciej Małecki`)
* [58c251f] [fix] Make column operations work (`Maciej Małecki`)
* [b9c5f18] [refactor minor] Code formatting, unused variable (`Maciej Małecki`)
* [feade6c] [test] Basic CLI tests with some helpers (`Maciej Małecki`)
* [d6b6c58] [fix] Reset system store before reparsing argv (`Maciej Małecki`)
* [736fecb] [test] Clean up after tests are done (`Maciej Małecki`)
* [6b1a08d] [test] Add test for option parsing (`Maciej Małecki`)
* [a52ee8a] [refactor] Make `forever app.js` work (`Maciej Małecki`)
* [93359eb] [refactor doc] Document `cli.startDaemon` and `cli.cleanLogs` (`Maciej Małecki`)
* [93482cb] [refactor minor] Remove unused `tty` require (`Maciej Małecki`)
* [4d3958e] [refactor] Better option parsing (`Maciej Małecki`)
* [dde31b7] [refactor bin] Remove options parsing from bin (`Maciej Małecki`)
* [d793874] [api] Remove redudant `forever` options (`Maciej Małecki`)
* [c9ab4f0] [dist] Add `flatiron` dependency (`Maciej Małecki`)
* [8abe38d] [refactor] Implement pass-through options for child (`Maciej Małecki`)
* [b30316e] [refactor] Use `utile.randomString` (`Maciej Małecki`)
* [dbf46c3] [refactor fix] Pass options to `forever.start` (`Maciej Małecki`)
* [3d262df] [refactor] Add `help` command (`Maciej Małecki`)
* [1da249c] [fix] Fix `cli.start` regex to match .* instead of .+ (`Maciej Małecki`)
* [89969ef] [refactor] First pass on flatiron refactor (`Maciej Małecki`)
* [8b05686] [dist] Depend on `utile` (`Maciej Małecki`)
* [71cf0de] [test fix] Kill child in `forever-test.js` (`Maciej Małecki`)
v0.7.3 / Thu, 17 Nov 2011
=========================
* [865a8fd] [dist] Version bump. 0.7.3 (`indexzero`)
* [7ab97bd] always killTree (`Fabian Jakobs`)
* [e4f2b09] [dist] Update `watch` dependency. Fixes #155 (`indexzero`)
* [5f20181] [fix] give sigkills after a timeout given by options.killTTL in MS (`bradleymeck`)
* [8c8d670] Merge pull request #157 from mmalecki/assert-lengthof (`Maciej Małecki`)
* [3f1ed35] [test minor] Change `assert.length` to `assert.lengthOf` (`Maciej Małecki`)
v0.7.2 / Sat, 22 Oct 2011
=========================
* [382f8e7] [dist] Version bump. 0.7.2 (`indexzero`)
* [9131af7] [fix] Return when no index or script is passed to `forever logs`. Fixes #141 (`indexzero`)
* [8176f9f] Make sure all data is streamed before we try to parse it. (`Mariusz Nowak`)
* [4ca2862] [dist] Remove unnecessary eyes dependency (`indexzero`)
* [74f3140] [fix] Prefer `-` to `$` in `forever.randomString` (`indexzero`)
* [684296a] [test] Test `checkProcess` (`Maciej Małecki`)
* [c17d004] [refactor] Make `forever.checkProcess` synchronous (`Maciej Małecki`)
* [f820056] [fix] Use `process.kill` to check if process is alive (`Maciej Małecki`)
v0.7.1 / Sun, 9 Oct 2011
========================
* [d791422] [dist] Verion bump. 0.7.1 (`indexzero`)
* [0d4f68e] [fix] Pass proc.spawnWith to `forever.restart`. Fixes #116 (`indexzero`)
v0.7.0 / Sat, 8 Oct 2011
========================
* [39f8b5a] [dist] Version bump. 0.7.0 (`indexzero`)
* [0baaccf] [dist] Updated CHANGELOG.md (`indexzero`)
* [91dbd32] [api test] Expose `this.spawnWith` in Monitor.data (`indexzero`)
* [14c82fd] [dist] Update daemon to >= 0.3.2 (`indexzero`)
* [e740fb6] [doc] Update README.md for `forever logs *` commands (`indexzero`)
* [0d6f85f] [api test] Added `forever logs` CLI commands and `forever.tail()` method with appropriate tests. Fixes #123, #93 (`indexzero`)
* [3d23311] [minor] Minor whitespace fix (`indexzero`)
* [02f7b0f] [dist] Update `test` command in package.json (`indexzero`)
* [fa03117] [fix] Add the child PID to the list from `psTree` not remove it (`indexzero`)
* [7ae3d1d] [doc] Updated CHANGELOG.md (`indexzero`)
* [7c82d4b] [dist] Update contributors in package.json (`indexzero`)
* [067d50c] [minor] Remove file headers in examples/* (`indexzero`)
* [a942985] [dist] Update Copyright to Nodejitsu Inc. (`indexzero`)
* [877ef3b] [minor] Update file headers (`indexzero`)
* [a61e6be] [dist] Updates for JSHint in bin/* (`indexzero`)
* [f7575f9] [dist] Update for JSHint (`indexzero`)
* [4e27e3d] [api] Expose `Monitor.killTree` for killing process trees for processes spawned by forever (`indexzero`)
* [a83a1e1] kill all children of a monitored process. (`Dominic Tarr`)
* [89be252] [refactor test dist] Refactor /lib/foreverd/ into /lib/forever/service/ (`indexzero`)
* [36e0b9b] [minor] Updated foreverd for JSHint (`indexzero`)
* [3525130] [minor] Update lib/forever* for JSHint (`indexzero`)
* [1390910] [fix] forgot to add adapters (`bradleymeck`)
* [bad47f6] [fix][WIP] basic working order, starting CLI cleanup (`bradleymeck`)
* [6f68823] [API][WIP] Moved service manager out to its own system (`bradleymeck`)
* [61651a7] [fix] daemonize ourselve on startup rather than rely on OS function (TODO exit codes) (`bradleymeck`)
* [782cca7] [fix] services should be added to run levels during install (`bradleymeck`)
* [f2026b3] [fix] service process listing (`bradleymeck`)
* [1bfdcdb] [fix] Use lsb functions for starting up a daemon (`bradleymeck`)
* [60d4329] [fix] make services use hyphenated commands (`bradleymeck`)
* [93053d6] [api] Revive the service api stubs (`bradleymeck`)
v0.6.9 / Tue, 4 Oct 2011
========================
* [620a362] [dist] Version bump. 0.6.9 (`indexzero`)
* [2b8cf71] [doc] Add `--plain` option to README (`Maciej Małecki`)
* [4b08542] [bin] Add `--plain` option disabling CLI colors (`Maciej Małecki`)
v0.6.8 / Sat, 1 Oct 2011
========================
* [dfb12a6] [dist] Version bump. 0.6.8 (`indexzero`)
* [7d7398b] [doc] Update README.md with watch file options (`indexzero`)
* [8c8f0e0] [fix minor] A couple of small changes to merge in watch from @mmalecki (`indexzero`)
* [d891990] [test] Add tests for watch (`Maciej Małecki`)
* [f636447] [test] Add fixtures for watch test (`Maciej Małecki`)
* [836ea31] [fix minor] Use `path.join` (`Maciej Małecki`)
* [b9b3129] [fix refactor] Use `watch.watchTree` function (`Maciej Małecki`)
* [1b02785] [fix minor] Remove stupid `options.watch || false` (`Maciej Małecki`)
* [7ababd6] [bin] Add --watch/-w command line option (`Maciej Małecki`)
* [e2b3565] [api] Add watchDirectory option (`Maciej Małecki`)
* [b9d9703] [api] Complete file watching with .foreverignore (`Maciej Małecki`)
* [28a7c16] [dist] Add minimatch dependency (`Maciej Małecki`)
* [fff672d] [api] simplest possible file watcher (ref #41) (`Maciej Małecki`)
* [d658ee3] [dist] add watch dependency (`Maciej Małecki`)
v0.6.7 / Mon, 12 Sep 2011
=========================
* [c87b4b3] [dist] Version bump. 0.6.7 (`indexzero`)
* [1170362] Merge pull request #113 from mmalecki/replace-sys-usages (`Charlie Robbins`)
* [227b158] [refactor] replace sys module usages in examples with util (`Maciej Małecki`)
* [8ae06c0] [refactor test] replace sys module usages in tests with util (`Maciej Małecki`)
* [72eba1f] [refactor] replace sys module usages with util (`Maciej Małecki`)
* [00628c2] [dist] Update winston version (`indexzero`)
v0.6.6 / Sun, 28 Aug 2011
=========================
* [3f3cd17] [dist] Version bump. 0.6.6 (`indexzero`)
* [735fc95] [minor test] Update to the `hideEnv` implementation from @bmeck. Added tests appropriately (`indexzero`)
* [52c0529] [style] cleanup unused variable (`Bradley Meck`)
* [03daece] [api] Add options.hideEnv {key:boolean_hide,} to hide default env values (`Bradley Meck`)
v0.6.5 / Fri, 12 Aug 2011
=========================
* [a3f0df5] [dist] Version bump. 0.6.5 (`indexzero`)
* [fdf15a0] [api test] Update `forever.Monitor.prototype.restart()` to allow force restarting of processes in less than `.minUptime` (`indexzero`)
v0.6.4 / Thu, 11 Aug 2011
=========================
* [f308f7a] [dist] Version bump. 0.6.4 (`indexzero`)
* [9dc7bad] [doc] Added example about running / listing multiple processes programmatically (`indexzero`)
* [c3fe93a] [fix] Update forever.startServer() to support more liberal arguments (`indexzero`)
v0.6.3 / Sat, 23 Jul 2011
=========================
* [fa3b225] [dist] Version bump. 0.6.3 (`indexzero`)
* [e47af9c] [fix] When stopping only respond with those processes which have been stopped. Fixes #87 (`indexzero`)
* [e7b9e58] [fix] Create `sockPath` if it does not exist already. Fixes #92 (`indexzero`)
v0.6.2 / Tue, 19 Jul 2011
=========================
* [845ce2c] [dist] Version bump. 0.6.2 (`indexzero`)
* [f756e62] [fix] Display warning / error messages to the user when contacting UNIX sockets. Fixes #88 (`indexzero`)
v0.6.1 / Fri, 15 Jul 2011
=========================
* [72f200b] [dist] Version bump. 0.6.1 (`indexzero`)
* [1c0792e] Process variables are not always available, for example if you execute forever with a different process like monit. (`Arnout Kazemier`)
* [7ff26de] Fixed a bug where numbers in the file path caused forever to think that it should stop the script based on index instead of stopping it based on script. (`Arnout Kazemier`)
v0.6.0 / Mon, 11 Jul 2011
=========================
* [df54bc0] [dist] Version bump. 0.6.0 (`indexzero`)
* [8a50cf6] [doc] Minor updates to README.md (`indexzero`)
* [1dac9f4] [doc] Updated README.md (`indexzero`)
* [9d35315] [fix minor] Update how forever._debug works. Use updated CLI options in `forever restart` (`indexzero`)
* [da86724] [doc] Regenerate docco docs (`indexzero`)
* [ad40a95] [doc] Added some code docs (`indexzero`)
* [221c170] [doc] Update help in bin/forever (`indexzero`)
* [091e949] [api] Finished fleshing out `forever columns *` commands (`indexzero`)
* [581a132] [fix] Update `forever cleanlogs` for 0.6.x (`indexzero`)
* [a39fee1] [api] Began work on `forever columns *` (`indexzero`)
* [381ecaf] [api] Expose `forever.columns` and update `forever.format` to generate results dynamically (`indexzero`)
* [bc8153a] [minor] Trim whitespace in lib/* (`indexzero`)
* [2a163d3] [dist] Add `portfinder` dependency to package.json (`indexzero`)
* [57a5600] [doc] Remove references to *.fvr files in README.md (`indexzero`)
* [ef59672] [test] Updated tests for refactor in previous commit (`indexzero`)
* [7ae870e] [refactor] **Major awesome breaking changes** 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()` (`indexzero`)
* [a26cf9d] [minor] Catch `uncaughtException` slightly more intelligently (`indexzero`)
* [4446215] [api] Include uids in `forever list` (`indexzero`)
* [57bc396] [minor] Create `options.uid` by default in `.startDaemon()` if it is already not provided (`indexzero`)
* [dbf4275] [api] Default `minUptime` to 0 (`indexzero`)
* [079ca20] [doc] Small update to README.md (`indexzero`)
* [aaefc95] [fix] use default values for log file and pid file (prevents a process from being nuked by being daemonized) (`Bradley Meck`)
* [76be51e] [fix] Quick fix for the last commit (`indexzero`)
* [6902890] [api test] Added generic hooks for forever.Monitor (`indexzero`)
* [c7ff2d9] [doc] Update the help in the forever CLI and README.md (`indexzero`)
* [725d11d] [doc] Update README.md (`indexzero`)
* [5a8b32e] [doc] Regenerated docco docs (`indexzero`)
* [dfb54be] [api test doc] Remove deprecated `forever.Forever` from samples and tests. Added `env` and `cwd` options and associated tests. Some additional code docs and minor style changes (`indexzero`)
* [c5c9172] [api] Update `forever list` to use cliff (`indexzero`)
* [d2aa52b] [dist] Drop eyes in favor of cliff (`indexzero`)
* [bc5995f] [fix minor] Keep processes silent on `forever restart` if requested. A couple of minor log formatting updates (`indexzero`)
* [f11610e] [minor api] Update to optional debugging. Various small style updates (`indexzero`)
* [686d009] [minor api] Added forever.debug for debugging purposes (`indexzero`)
* [abed353] [doc] Updated README.md with newer options and events (`indexzero`)
* [da44ad0] [doc] Kill some ancient stuff in README.md (`indexzero`)
* [3ef90c1] [doc] Add a little more color to documentation for `forever.load()` (`indexzero`)
* [3d6018f] [doc] Update documentation on forever.load(). Fixes #72 (`indexzero`)
* [3c8e6eb] [api fix] When executing stopall, dont kill the current process. Refactor flow-control of forever.cleanUp() (`indexzero`)
* [d681cb7] [fix] Dont allow `-` in uuids generated by forever. Fixes #66. (`indexzero`)
* [e0c3dcf] [dist] Minor style updates. Update to use pkginfo (`indexzero`)
v0.5.6 / Tue, 7 Jun 2011
========================
* [de0d6d2] [dist] Version bump. 0.5.6 (`indexzero`)
v0.5.5 / Tue, 31 May 2011
=========================
* [4c5b73a] [dist] Version bump. 0.5.5 (`indexzero`)
* [1af1fe3] [fix] Remove .fvr file when a forever.Monitor child exits (`indexzero`)
v0.5.4 / Mon, 30 May 2011
=========================
* [4e84d71] [dist] Version bump. 0.5.4 (`indexzero`)
* [5b2bf74] [test] Update test/multiple-processes-test.js so that it doesnt leave zombie processes behind (`indexzero`)
* [6d93dcc] Add --spinSleepTime to throttle instead of killing spinning scripts (`Dusty Leary`)
v0.5.3 / Sun, 29 May 2011
=========================
* [7634248] [dist] Version bump. 0.5.3 (`indexzero`)
* [d6b0d0e] [test] Update tests to be consistent with new functionality (`indexzero`)
* [921966a] [api] Improve forever when working with `-c` or `--command` (`indexzero`)
* [349085d] [dist] Minor update to dependencies (`indexzero`)
* [96c3f08] [dist] Update .gitignore for npm 1.0 (`indexzero`)
* [f4982cd] [doc] Update README.md to still use -g (`indexzero`)
* [86fc40a] Merge branch 'master' of https://github.com/ded/forever (`indexzero`)
* [3feb0bc] [dist] Update package.json dependencies (`indexzero`)
* [270d976] preferGlobal (`Dustin Diaz`)
* [de90882] [doc] Update installation instructions with `-g` for npm 1.0 (`indexzero`)
v0.5.2 / Fri, 13 May 2011
=========================
* [2c99741] [dist] Version bump. 0.5.2 (`indexzero`)
* [eab1c04] [fix] Check if processes exist before returning in `.findByScript()`. Fixes #50 (`indexzero`)
* [e18a256] [fix] Batch the cleaning of *.fvr and *.pid files to avoid file descriptor overload. Fixes #53 (`indexzero`)
* [828cd48] [minor] *print help when a valid action isn't given (`nlco`)
v0.5.1 / Sun, 1 May 2011
========================
* [f326d20] [dist] Version bump. 0.5.1. Add `eyes` dependency (`indexzero`)
v0.5.0 / Sun, 1 May 2011
========================
* [7b451d9] [dist] Version bump. 0.5.0 (`indexzero`)
* [1511179] [doc] Regenerated docco docs (`indexzero`)
* [0fb8abe] [minor] Small require formatting updates. Try to be more future-proof. (`indexzero`)
* [3112380] [fix] Small fixes found from some upstream integrations (`indexzero`)
* [9788748] [fix] Better handling of bookkeeping of *.fvr and *.pid files. Closes #47 (`indexzero`)
* [864b1d1] [minor] Small fixes (`indexzero`)
* [9b56c41] [api] Allow for forced exit if scripts restart in less than `minUptime` (`indexzero`)
* [650f874] [minor] Add docs for `forever clear <key>` (`indexzero`)
* [396b9a1] [doc] Regenerate docco docs (`indexzero`)
* [a49483d] [doc] Updated README.md (`indexzero`)
* [f0ba253] [bin api minor] Update Copyright headers. Refactor bin/forever into lib/forever/cli.js. Add `forever config`, `forever set <key> <value>`, and `forever clear <key>` (`indexzero`)
* [dffd0d1] [minor dist api] Small updates for storing a forever global config file. Update package.json using require-analyzer (`indexzero`)
* [6741c3a] [minor] More work for multiple processes from a single programmatic usage (`indexzero`)
* [6e52e03] [minor test] Added tests for multiple processes from a single node process (`indexzero`)
* [1c16e81] [api test] Update to use nconf for forever configuration. Use uids for filenames instead of forever* and forever pids (more defensive + support for multiple monitors from a single `forever` process). (`indexzero`)
* [be6de72] [minor] Small updates after merging from kpdecker (`indexzero`)
* [3beb6da] Merge branch 'master' of https://github.com/kpdecker/forever into v0.5.x (`indexzero`)
* [95434b3] Proper pid lookup in getForeverId (`kpdecker`)
* [13bf645] Add custom root directory to the initd-example (For cases where /tmp is removed) (`kpdecker`)
* [b181dd7] Init.d Example script (`kpdecker`)
* [51bc6c0] Append log implementation (`kpdecker`)
* [588b2bf] Append log CLI (`kpdecker`)
* [ab497f4] forever.stat append flag (`kpdecker`)
* [dca33d8] CLI pidfile argument (`kpdecker`)
* [52184ae] forever.pidFilePath implementation (`kpdecker`)
* [e9b2cd3] forever.logFilePath utility. Treat paths that start with / as paths relative to the root, not the forever root. (`kpdecker`)
* [8e323ca] Pass cwd to spawn (`kpdecker`)
* [b29a258] Return non-zero error code on tryStart failure (`kpdecker`)
* [11ffce8] Load the forever lib relative to the binary rather than using module notation. (`kpdecker`)
v0.4.2 / Wed, 13 Apr 2011
=========================
* [7089311] [dist] Version bump. 0.4.2 (`indexzero`)
v0.4.1 / Sat, 19 Feb 2011
=========================
* [f11321f] [dist] Version bump. 0.4.1 (`indexzero`)
* [987d8ed] [fix] Update sourceDir option to check for file paths relative to root (`indexzero`)
v0.4.0 / Wed, 16 Feb 2011
=========================
* [b870d47] [dist] Version bump. 0.4.0 (`indexzero`)
* [d9911dd] [doc] Update docs for v0.4.0 release (`indexzero`)
* [6862ad5] [api] Expose options passed to child_process.spawn (`indexzero`)
* [4b25241] [doc] Added example for chroot (`indexzero`)
* [9d2eefa] [fix] Dont slice off arguments after [SCRIPT] if it is not passed to the CLI (e.g. forever list) (`indexzero`)
* [7c0c3b8] [api] Refactor to use winston instead of pure sys.puts() for logging (`indexzero`)
* [cc3d465] [api] Make forever.load() sync and not required for default configurations. Grossly simplifies saving / reloading semantics (`indexzero`)
* [fd1b9a6] [api] Added `restart` command to both forever.Monitor and CLI (`indexzero`)
* [c073c47] [api] First pass at "restart" functionality, not 100% yet (`indexzero`)
* [7b9b4be] [docs] Updated docs from docco (`indexzero`)
* [ea89def] [minor] Small formatting update to package.json (`indexzero`)
* [85b0a02] [api] Added ctime property to forever instances to track uptime (`indexzero`)
* [bc07f95] [docs refactor] Refactor forever.Forever into lib/forever/monitor.js (`indexzero`)
v0.3.5 / Fri, 11 Feb 2011
=========================
* [884037a] [dist] Version bump. 0.3.5. depends on daemon > 0.3.0 & node > 0.4.0 (`indexzero`)
* [7b31da2] [api minor] Updates for daemon.node 0.2.0. Fix randomString so it doesnt generate strings with "/" (`indexzero`)
* [a457ab7] [doc] Add docs from docco (`indexzero`)
* [4a0ca64] expose command to bin/forever as an option (`Adrien Friggeri`)
v0.3.1 / Fri, 24 Dec 2010
=========================
* [3c7e4a7] [dist doc] Version bump 0.3.1. Added CHANGELOG.md (`indexzero`)
* [38177c4] [bin] Ensure both daemons and long running processes get the same stat checking (`indexzero`)
* [ea6849d] [api] Make it the responsibility of the programmer to save/re-save the Forever information on start or restart events (`indexzero`)
* [14c7aa8] [api test bin doc] Added stop by script name feature. Improved the cleanlogs functionality. Made event emission consistent. Added to docs (`indexzero`)
* [b7f792b] [minor] Small update to how forever works with pid files (`indexzero`)
* [57850e9] [api fix] Improved the way forever manages pid / fvr files. Added cleanlogs command line option (`indexzero`)
* [070313e] [api] Push options hierarchy up one level. e.g. Forever.options.silent is now Forever.silent (`indexzero`)
* [124cc25] [fix api bin test] Check for scripts with fs.stat() before running them. Use process.kill instead of exec('kill'). Clean logs from command line. Display log file in forever list. Emit save event. (`indexzero`)
* [57273ea] updated the readme with non-node usage and an example (`James Halliday`)
* [cc33f06] passing test for non-node array usage (`James Halliday`)
* [761b31b] file array case shortcut to set the command and options (`James Halliday`)
* [02de53f] "command" option to spawn() with, defaults to "node" (`James Halliday`)
* [6feedc1] [minor] Remove unnecessary comma in package.json (`indexzero`)
v0.3.0 / Tue, 23 Nov 2010
=========================
* [5d6f8da] [dist] Version bump. 0.3.0 (`indexzero`)
* [29bff87] [doc] Updated formatting in README.md (`indexzero`)
* [00fc643] [api bin doc test] Added stop, stopall, and list command line functionality. Forever now tracks all daemons running on the system using *.fvr files (`indexzero`)
* [d084ad1] [minor] Make samples/server.js listen on 8000 (`indexzero`)
v0.2.7 / Tue, 16 Nov 2010
=========================
* [29bc24f] [minor] Version bump. Fix small bug in 0.2.6 (`indexzero`)
v0.2.6 / Mon, 15 Nov 2010
=========================
* [2bcc53d] [bin dist] Version bump. Small fixes from 0.2.5 (`indexzero`)
* [faacc0f] [doc] Typo (`indexzero`)
v0.2.5 / Sun, 14 Nov 2010
=========================
* [0d5a789] [dist] Version bump. (`indexzero`)
* [04705ed] [api test bin dist] Update to use daemon.node (`indexzero`)
* [65a91fb] [minor] Added .gitignore (`indexzero`)
v0.2.0 / Mon, 27 Sep 2010
=========================
* [f916359] [minor dist] Added LICENSE. Refactor forever.js to be more DRY (`indexzero`)
* [9243dee] Removed repeating function and replaced it by template generator (`Fedor Indutny`)
* [347dcaa] [minor] Updated contributors (`indexzero`)
* [a4f1700] [api test doc dist] Version bump. Merged from donnerjack. Added ability to log to file(s). Updated docs. (`indexzero`)
* [d5d2f1d] New-line at the end of file (`Fedor Indutny`)
* [73b52a4] Added chaining to run, simplyfied exports.run (`Fedor Indutny`)

19
node_modules/forever/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (C) 2010 Charlie Robbins & the 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.

175
node_modules/forever/README.md generated vendored Normal file
View File

@@ -0,0 +1,175 @@
# forever [![Build Status](https://api.travis-ci.org/foreverjs/forever.svg)](https://travis-ci.org/foreverjs/forever) [![Inline docs](http://inch-ci.org/github/foreverjs/forever.svg?branch=master)](http://inch-ci.org/github/foreverjs/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 _programmatically_ 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 by Id|Uid|Pid|Index|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 <key> <val> Sets the specified forever config <key>
clear <key> Clears the specified forever config <key>
logs Lists log files for all forever processes
logs <script|index> Tails the logs for <script|index>
columns add <col> Adds the specified column to the output in `forever list`
columns rm <col> Removed the specified column from the output in `forever list`
columns set <cols> 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
--uid Process uid, useful as a namespace for processes (must wrap in a string)
e.g. forever start --uid "production" app.js
forever stop production
--sourceDir The source directory for which SCRIPT is relative to
--workingDir The working directory in which SCRIPT will execute
--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 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
--watchIgnore To ignore pattern when watch is enabled (multiple option is allowed)
--killSignal Support exit signal customization (default is SIGKILL),
used for restarting script gracefully e.g. --killSignal=SIGTERM
-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
```
### Changing where forever writes files
By default `forever` places all of the files it needs into `/$HOME/.forever`. If you would like to change that location just set the `FOREVER_ROOT` environment variable when you are running forever:
```
FOREVER_ROOT=/etc/forever forever start index.js
```
Make sure that the user running the process has the appropriate privileges to read & write to this directory.
## 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);
```
This method takes multiple `forever.Monitor` instances which are defined in the `forever-monitor` dependency.
### forever.load (config)
_Synchronously_ sets the specified configuration (config) for the forever module. There are two important options:
Option | Description   | Default
------- | ------------------------------------------------- | ---------
root | Directory to put all default forever log files | `forever.root`
pidPath | Directory to put all forever *.pid files | `[root]/pids`
sockPath | Directory for sockets for IPC between workers | `[root]/sock`
loglength | Number of logs to return in `forever tail` | 100
columns | Array of columns to display when `format` is true | `forever.config.get('columns')`
debug | Boolean value indicating to run in debug mode | false
stream | Boolean value indicating if logs will be streamed | false
### forever.start (file, options)
Starts a script with forever. The `options` object is what is expected by the `Monitor` of `forever-monitor`.
### forever.startDaemon (file, options)
Starts a script with forever as a daemon. WARNING: Will daemonize the current process. The `options` object is what is expected by the `Monitor` of `forever-monitor`.
### 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.
The `format` parameter is a boolean value indicating whether the returned values should be formatted according to the configured columns which can set with `forever columns` or programmatically `forever.config.set('columns')`.
### forever.list (format, callback)
Returns a list of metadata objects about each process that is being run using forever. This method will return the list of metadata as such. Only processes which have invoked `forever.startServer()` will be available from `forever.list()`
The `format` parameter is a boolean value indicating whether the returned values should be formatted according to the configured columns which can set with `forever columns` or programmatically `forever.config.set('columns')`.
### forever.tail (target, options, callback)
Responds with the logs from the target script(s) from `tail`. There are two 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. Processes are the value returned from `Monitor.data` in `forever-monitor`.
### forever.startServer (monitor0, monitor1, ..., monitorN)
Starts the `forever` HTTP server for communication with the forever CLI. **NOTE:** This will change your `process.title`. This method takes multiple `forever.Monitor` instances which are defined in the `forever-monitor` dependency.
## Run Tests
``` bash
$ npm test
```
#### License: MIT
#### Author: [Charlie Robbins](https://github.com/indexzero)
#### Contributors: [Fedor Indutny](https://github.com/indutny), [James Halliday](http://substack.net/), [Charlie McConnell](https://github.com/avianflu), [Maciej Malecki](https://github.com/mmalecki), [John Lancaster](http://jlank.com)
[0]: https://github.com/foreverjs/forever-monitor
[1]: https://github.com/foreverjs/forever-monitor/tree/master/examples
[2]: https://github.com/foreverjs/forever/blob/master/lib/forever/cli.js

3
node_modules/forever/bin/forever generated vendored Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env node
require('../lib/forever').cli.start();

87
node_modules/forever/bin/monitor generated vendored Executable file
View File

@@ -0,0 +1,87 @@
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());
// inherits configuration from parent process if exists.
options && options._loadedOptions && (forever.load(options._loadedOptions), delete options._loadedOptions);
if (!started) {
started = true;
start(options);
}
});

1041
node_modules/forever/lib/forever.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

593
node_modules/forever/lib/forever/cli.js generated vendored Normal file
View File

@@ -0,0 +1,593 @@
/*
* cli.js: Handlers for the forever CLI commands.
*
* (C) 2010 Charlie Robbins & the Contributors
* 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 by Id|Uid|Pid|Index|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 <key> <val> Sets the specified forever config <key>',
' clear <key> Clears the specified forever config <key>',
' logs Lists log files for all forever processes',
' logs <script|index> Tails the logs for <script|index>',
' columns add <col> Adds the specified column to the output in `forever list`',
' columns rm <col> Removed the specified column from the output in `forever list`',
' columns set <cols> Set all columns for the output in `forever list`',
' columns reset Resets all columns to defaults 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',
' --uid Process uid, useful as a namespace for processes (must wrap in a string)',
' e.g. forever start --uid "production" app.js',
' forever stop production',
' --sourceDir The source directory for which SCRIPT is relative to',
' --workingDir The working directory in which SCRIPT will execute',
' --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)',
' --killSignal Support exit signal customization (default is SIGKILL)',
' used for restarting script gracefully e.g. --killSignal=SIGTERM',
' -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',
'stopbypid',
'stopall',
'restart',
'restartall',
'list',
'config',
'set',
'clear',
'logs',
'columns',
'cleanlogs'
];
var argvOptions = cli.argvOptions = {
'command': {alias: 'c'},
'errFile': {alias: 'e'},
'logFile': {alias: 'l'},
'killTree': {alias: 't', boolean: true},
'append': {alias: 'a', boolean: true},
'fifo': {alias: 'f', boolean: true},
'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},
'uid': {alias: 'u'}
};
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);
forever.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.args = 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', 'workingDir', 'uid', 'watchDirectory', 'watchIgnore',
'killTree', 'killSignal', 'id'
].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() : '/');
options.workingDir = options.workingDir || options.sourceDir;
options.spawnWith = { cwd: options.workingDir };
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:' + '\n' + process);
});
runner.on('error', function (err) {
forever.log.error('Forever cannot find process with id: ' + file);
process.exit(1);
});
});
//
// ### function stopbypid (pid)
// Stops running forever process by pid.
//
app.cmd(/stopbypid (.+)/, cli.stopbypid = function (pid) {
forever.log.warn('Deprecated, try `forever stop ' + pid + '` instead.');
cli.stop(pid);
});
//
// ### 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');
});
});
//
// ### 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();
});
app.cmd('columns reset', cli.resetColumns = function () {
var columns = 'uid command script forever pid logfile uptime';
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.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();
});
};

165
node_modules/forever/lib/forever/worker.js generated vendored Normal file
View File

@@ -0,0 +1,165 @@
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.args);
monitor.start();
monitor.on('start', function () {
socket.send(['spawn', 'start'], monitor.data);
});
});
socket.data(['stop'], function () {
function onStop(err) {
var args = [];
if (err && err instanceof Error) {
args.push(['stop', 'error'], { message: err.message, stack: err.stack });
self.monitor.removeListener('stop', onStop);
}
else {
args.push(['stop', 'ok']);
self.monitor.removeListener('error', onStop);
}
socket.send.apply(socket, args);
if (self.exitOnStop) {
process.exit();
}
}
self.monitor.once('stop', onStop);
self.monitor.once('error', onStop);
if (process.platform === 'win32') {
//
// On Windows, delete the 'symbolic' sock file. This
// file is used for exploration during `forever list`
// as a mapping to the `\\.pipe\\*` "files" that can't
// be enumerated because ... Windows.
//
fs.unlink(self._sockFile);
}
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');
if (callback) {
callback(null, self._sockFile);
}
});
self._socket.on('error', function (err) {
if (err.code === 'EADDRINUSE') {
return findAndStart();
}
else if (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('.'));
if (process.platform === 'win32') {
//
// Create 'symbolic' file on the system, so it can be later
// found via "forever list" since the `\\.pipe\\*` "files" can't
// be enumerated because ... Windows.
//
fs.openSync(sock, 'w');
//
// It needs the prefix, otherwise EACCESS error happens on Windows
// (no .sock extension, only named pipes with .pipe prefixes)
//
sock = '\\\\.\\pipe\\' + sock;
}
self._socket.listen(sock);
}
//
// Attempt to start the server the first time
//
findAndStart();
return this;
};

1
node_modules/forever/node_modules/.bin/flatiron generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../flatiron/bin/flatiron

2
node_modules/forever/node_modules/cliff/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules
npm-debug.log

19
node_modules/forever/node_modules/cliff/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2010 Charlie Robbins & the 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.

227
node_modules/forever/node_modules/cliff/README.md generated vendored Normal file
View File

@@ -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

BIN
node_modules/forever/node_modules/cliff/assets/inspect.png generated vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
node_modules/forever/node_modules/cliff/assets/put-object.png generated vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
node_modules/forever/node_modules/cliff/assets/put-rows.png generated vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,24 @@
/*
* put-object.js: Example usage for `cliff.putObject`.
*
* (C) 2010, Charlie Robbins & the Contributors
*
*/
var cliff = require('../lib/cliff');
console.log(cliff.inspect({
literal: "bazz",
arr: [
"one",
2,
],
obj: {
host: "localhost",
port: 5984,
auth: {
username: "admin",
password: "password"
}
}
}));

View File

@@ -0,0 +1,23 @@
/*
* put-object-rows.js: Example usage for `cliff.putObjectRows`.
*
* (C) 2010, Charlie Robbins & the Contributors
*
*/
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']);

View File

@@ -0,0 +1,24 @@
/*
* put-object.js: Example usage for `cliff.putObject`.
*
* (C) 2010, Charlie Robbins & the Contributors
*
*/
var cliff = require('../lib/cliff');
cliff.putObject({
literal: "bazz",
arr: [
"one",
2,
],
obj: {
host: "localhost",
port: 5984,
auth: {
username: "admin",
password: "password"
}
}
});

View File

@@ -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']);

View File

@@ -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']);

View File

@@ -0,0 +1,23 @@
/*
* put-object-rows.js: Example usage for `cliff.putObjectRows`.
*
* (C) 2010, Charlie Robbins & the Contributors
*
*/
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']));

View File

@@ -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']));

287
node_modules/forever/node_modules/cliff/lib/cliff.js generated vendored Normal file
View File

@@ -0,0 +1,287 @@
/*
* cliff.js: CLI output formatting tools: "Your CLI Formatting Friend".
*
* (C) 2010, Charlie Robbins & the Contributors
*
*/
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, options) {
var lengths, columns, output = [], headers;
options = options || {};
options.columnSpacing = options.columnSpacing || 2;
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]);
if(colorize) {
item = item[colors[i]] || item[colors[colors.length -1]] || item;
}
length = realLength(item);
padding = length < lengths[i] ? lengths[i] - length + options.columnSpacing : options.columnSpacing ;
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, options) {
var rows = [properties].concat(objs.map(function (obj) {
return cliff.extractFrom(obj, properties);
}));
return cliff.stringifyRows(rows, colors, options);
};
//
// ### 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;
}

View File

@@ -0,0 +1,6 @@
language: node_js
node_js:
- "0.11"
- "0.10"
- "0.8"
- "0.6"

View File

@@ -0,0 +1,23 @@
Original Library
- Copyright (c) Marak Squires
Additional Functionality
- Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.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.

View File

@@ -0,0 +1,167 @@
# colors.js
## get color and style in your node.js console
<img src="https://github.com/Marak/colors.js/raw/master/screenshots/colors.png"/>
## Installation
npm install colors
## colors and styles!
### text colors
- black
- red
- green
- yellow
- blue
- magenta
- cyan
- white
- gray
- grey
### background colors
- bgBlack
- bgRed
- bgGreen
- bgYellow
- bgBlue
- bgMagenta
- bgCyan
- bgWhite
### styles
- reset
- bold
- dim
- italic
- underline
- inverse
- hidden
- strikethrough
### extras
- rainbow
- zebra
- america
- trap
- random
## Usage
By popular demand, `colors` now ships with two types of usages!
The super nifty way
```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
console.log('Run the trap'.trap); // Drops the bass
```
or a slightly less nifty way which doesn't extend `String.prototype`
```js
var colors = require('colors/safe');
console.log(colors.green('hello')); // outputs green text
console.log(colors.red.underline('i like cake and pies')) // outputs red underlined text
console.log(colors.inverse('inverse the color')); // inverses the color
console.log(colors.rainbow('OMG Rainbows!')); // rainbow
console.log(colors.trap('Run the trap')); // Drops the bass
```
I prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way.
If you are writing good code you will never have an issue with the first approach. If you really don't want to touch `String.prototype`, the second usage will not touch `String` native object.
## Disabling Colors
To disable colors you can pass the following arguments in the command line to your application:
```bash
node myapp.js --no-color
```
## Console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data)
```js
var name = 'Marak';
console.log(colors.green('Hello %s'), name);
// outputs -> 'Hello Marak'
```
## Custom themes
### Using standard API
```js
var colors = 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);
```
### Using string safe API
```js
var colors = require('colors/safe');
// set single property
var error = colors.red;
error('this is red');
// set theme
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(colors.error("this is an error"));
// outputs yellow text
console.log(colors.warn("this is a warning"));
```
*Protip: There is a secret undocumented style in `colors`. If you find the style you can summon him.*

View File

@@ -0,0 +1,74 @@
var colors = require('../lib/index');
console.log("First some yellow text".yellow);
console.log("Underline that text".yellow.underline);
console.log("Make it bold and red".red.bold);
console.log(("Double Raindows All Day Long").rainbow)
console.log("Drop the bass".trap)
console.log("DROP THE RAINBOW BASS".trap.rainbow)
console.log('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported
console.log('So '.green + 'are'.underline + ' ' + 'inverse'.inverse + ' styles! '.yellow.bold); // styles not widely supported
console.log("Zebras are so fun!".zebra);
//
// Remark: .strikethrough may not work with Mac OS Terminal App
//
console.log("This is " + "not".strikethrough + " fun.");
console.log('Background color attack!'.black.bgWhite)
console.log('Use random styles on everything!'.random)
console.log('America, Heck Yeah!'.america)
console.log('Setting themes is useful')
//
// Custom themes
//
console.log('Generic logging theme as JSON'.green.bold.underline);
// Load theme with JSON literal
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);
// outputs grey text
console.log("this is an input".input);
console.log('Generic logging theme as file'.green.bold.underline);
// Load a theme from file
colors.setTheme(__dirname + '/../themes/generic-logging.js');
// outputs red text
console.log("this is an error".error);
// outputs yellow text
console.log("this is a warning".warn);
// outputs grey text
console.log("this is an input".input);
//console.log("Don't summon".zalgo)

View File

@@ -0,0 +1,76 @@
var colors = require('../safe');
console.log(colors.yellow("First some yellow text"));
console.log(colors.yellow.underline("Underline that text"));
console.log(colors.red.bold("Make it bold and red"));
console.log(colors.rainbow("Double Raindows All Day Long"))
console.log(colors.trap("Drop the bass"))
console.log(colors.rainbow(colors.trap("DROP THE RAINBOW BASS")));
console.log(colors.bold.italic.underline.red('Chains are also cool.')); // styles not widely supported
console.log(colors.green('So ') + colors.underline('are') + ' ' + colors.inverse('inverse') + colors.yellow.bold(' styles! ')); // styles not widely supported
console.log(colors.zebra("Zebras are so fun!"));
console.log("This is " + colors.strikethrough("not") + " fun.");
console.log(colors.black.bgWhite('Background color attack!'));
console.log(colors.random('Use random styles on everything!'))
console.log(colors.america('America, Heck Yeah!'));
console.log('Setting themes is useful')
//
// Custom themes
//
//console.log('Generic logging theme as JSON'.green.bold.underline);
// Load theme with JSON literal
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(colors.error("this is an error"));
// outputs yellow text
console.log(colors.warn("this is a warning"));
// outputs grey text
console.log(colors.input("this is an input"));
// console.log('Generic logging theme as file'.green.bold.underline);
// Load a theme from file
colors.setTheme(__dirname + '/../themes/generic-logging.js');
// outputs red text
console.log(colors.error("this is an error"));
// outputs yellow text
console.log(colors.warn("this is a warning"));
// outputs grey text
console.log(colors.input("this is an input"));
// console.log(colors.zalgo("Don't summon him"))

View File

@@ -0,0 +1,176 @@
/*
The MIT License (MIT)
Original Library
- Copyright (c) Marak Squires
Additional functionality
- Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.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.
*/
var colors = {};
module['exports'] = colors;
colors.themes = {};
var ansiStyles = colors.styles = require('./styles');
var defineProps = Object.defineProperties;
colors.supportsColor = require('./system/supports-colors');
if (typeof colors.enabled === "undefined") {
colors.enabled = colors.supportsColor;
}
colors.stripColors = colors.strip = function(str){
return ("" + str).replace(/\x1B\[\d+m/g, '');
};
var stylize = colors.stylize = function stylize (str, style) {
return ansiStyles[style].open + str + ansiStyles[style].close;
}
var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
var escapeStringRegexp = function (str) {
if (typeof str !== 'string') {
throw new TypeError('Expected a string');
}
return str.replace(matchOperatorsRe, '\\$&');
}
function build(_styles) {
var builder = function builder() {
return applyStyle.apply(builder, arguments);
};
builder._styles = _styles;
// __proto__ is used because we must return a function, but there is
// no way to create a function with a different prototype.
builder.__proto__ = proto;
return builder;
}
var styles = (function () {
var ret = {};
ansiStyles.grey = ansiStyles.gray;
Object.keys(ansiStyles).forEach(function (key) {
ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
ret[key] = {
get: function () {
return build(this._styles.concat(key));
}
};
});
return ret;
})();
var proto = defineProps(function colors() {}, styles);
function applyStyle() {
var args = arguments;
var argsLen = args.length;
var str = argsLen !== 0 && String(arguments[0]);
if (argsLen > 1) {
for (var a = 1; a < argsLen; a++) {
str += ' ' + args[a];
}
}
if (!colors.enabled || !str) {
return str;
}
var nestedStyles = this._styles;
var i = nestedStyles.length;
while (i--) {
var code = ansiStyles[nestedStyles[i]];
str = code.open + str.replace(code.closeRe, code.open) + code.close;
}
return str;
}
function applyTheme (theme) {
for (var style in theme) {
(function(style){
colors[style] = function(str){
return colors[theme[style]](str);
};
})(style)
}
}
colors.setTheme = function (theme) {
if (typeof theme === 'string') {
try {
colors.themes[theme] = require(theme);
applyTheme(colors.themes[theme]);
return colors.themes[theme];
} catch (err) {
console.log(err);
return err;
}
} else {
applyTheme(theme);
}
};
function init() {
var ret = {};
Object.keys(styles).forEach(function (name) {
ret[name] = {
get: function () {
return build([name]);
}
};
});
return ret;
}
var sequencer = function sequencer (map, str) {
var exploded = str.split(""), i = 0;
exploded = exploded.map(map);
return exploded.join("");
};
// custom formatter methods
colors.trap = require('./custom/trap');
colors.zalgo = require('./custom/zalgo');
// maps
colors.maps = {};
colors.maps.america = require('./maps/america');
colors.maps.zebra = require('./maps/zebra');
colors.maps.rainbow = require('./maps/rainbow');
colors.maps.random = require('./maps/random')
for (var map in colors.maps) {
(function(map){
colors[map] = function (str) {
return sequencer(colors.maps[map], str);
}
})(map)
}
defineProps(colors, init());

View File

@@ -0,0 +1,45 @@
module['exports'] = function runTheTrap (text, options) {
var result = "";
text = text || "Run the trap, drop the bass";
text = text.split('');
var trap = {
a: ["\u0040", "\u0104", "\u023a", "\u0245", "\u0394", "\u039b", "\u0414"],
b: ["\u00df", "\u0181", "\u0243", "\u026e", "\u03b2", "\u0e3f"],
c: ["\u00a9", "\u023b", "\u03fe"],
d: ["\u00d0", "\u018a", "\u0500" , "\u0501" ,"\u0502", "\u0503"],
e: ["\u00cb", "\u0115", "\u018e", "\u0258", "\u03a3", "\u03be", "\u04bc", "\u0a6c"],
f: ["\u04fa"],
g: ["\u0262"],
h: ["\u0126", "\u0195", "\u04a2", "\u04ba", "\u04c7", "\u050a"],
i: ["\u0f0f"],
j: ["\u0134"],
k: ["\u0138", "\u04a0", "\u04c3", "\u051e"],
l: ["\u0139"],
m: ["\u028d", "\u04cd", "\u04ce", "\u0520", "\u0521", "\u0d69"],
n: ["\u00d1", "\u014b", "\u019d", "\u0376", "\u03a0", "\u048a"],
o: ["\u00d8", "\u00f5", "\u00f8", "\u01fe", "\u0298", "\u047a", "\u05dd", "\u06dd", "\u0e4f"],
p: ["\u01f7", "\u048e"],
q: ["\u09cd"],
r: ["\u00ae", "\u01a6", "\u0210", "\u024c", "\u0280", "\u042f"],
s: ["\u00a7", "\u03de", "\u03df", "\u03e8"],
t: ["\u0141", "\u0166", "\u0373"],
u: ["\u01b1", "\u054d"],
v: ["\u05d8"],
w: ["\u0428", "\u0460", "\u047c", "\u0d70"],
x: ["\u04b2", "\u04fe", "\u04fc", "\u04fd"],
y: ["\u00a5", "\u04b0", "\u04cb"],
z: ["\u01b5", "\u0240"]
}
text.forEach(function(c){
c = c.toLowerCase();
var chars = trap[c] || [" "];
var rand = Math.floor(Math.random() * chars.length);
if (typeof trap[c] !== "undefined") {
result += trap[c][rand];
} else {
result += c;
}
});
return result;
}

View File

@@ -0,0 +1,104 @@
// please no
module['exports'] = function zalgo(text, options) {
text = text || " he is here ";
var soul = {
"up" : [
'̍', '̎', '̄', '̅',
'̿', '̑', '̆', '̐',
'͒', '͗', '͑', '̇',
'̈', '̊', '͂', '̓',
'̈', '͊', '͋', '͌',
'̃', '̂', '̌', '͐',
'̀', '́', '̋', '̏',
'̒', '̓', '̔', '̽',
'̉', 'ͣ', 'ͤ', 'ͥ',
'ͦ', 'ͧ', 'ͨ', 'ͩ',
'ͪ', 'ͫ', 'ͬ', 'ͭ',
'ͮ', 'ͯ', '̾', '͛',
'͆', '̚'
],
"down" : [
'̖', '̗', '̘', '̙',
'̜', '̝', '̞', '̟',
'̠', '̤', '̥', '̦',
'̩', '̪', '̫', '̬',
'̭', '̮', '̯', '̰',
'̱', '̲', '̳', '̹',
'̺', '̻', '̼', 'ͅ',
'͇', '͈', '͉', '͍',
'͎', '͓', '͔', '͕',
'͖', '͙', '͚', '̣'
],
"mid" : [
'̕', '̛', '̀', '́',
'͘', '̡', '̢', '̧',
'̨', '̴', '̵', '̶',
'͜', '͝', '͞',
'͟', '͠', '͢', '̸',
'̷', '͡', ' ҉'
]
},
all = [].concat(soul.up, soul.down, soul.mid),
zalgo = {};
function randomNumber(range) {
var 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) {
var result = '', counts, l;
options = options || {};
options["up"] = options["up"] || true;
options["mid"] = options["mid"] || true;
options["down"] = options["down"] || true;
options["size"] = options["size"] || "maxi";
text = text.split('');
for (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;
}
// don't summon him
return heComes(text);
}

View File

@@ -0,0 +1,118 @@
var colors = require('./colors'),
styles = require('./styles');
module['exports'] = function () {
//
// Extends prototype of native string object to allow for "foo".red syntax
//
var addProperty = function (color, func) {
String.prototype.__defineGetter__(color, func);
};
var sequencer = function sequencer (map, str) {
return function () {
var exploded = this.split(""), i = 0;
exploded = exploded.map(map);
return exploded.join("");
}
};
var stylize = function stylize (str, style) {
return styles[style].open + str + styles[style].close;
}
addProperty('strip', function () {
return colors.strip(this);
});
addProperty('stripColors', function () {
return colors.strip(this);
});
addProperty("trap", function(){
return colors.trap(this);
});
addProperty("zalgo", function(){
return colors.zalgo(this);
});
addProperty("zebra", function(){
return colors.zebra(this);
});
addProperty("rainbow", function(){
return colors.rainbow(this);
});
addProperty("random", function(){
return colors.random(this);
});
addProperty("america", function(){
return colors.america(this);
});
//
// Iterate through all default styles and colors
//
var x = Object.keys(colors.styles);
x.forEach(function (style) {
addProperty(style, function () {
return stylize(this, style);
});
});
function applyTheme(theme) {
//
// Remark: This is a list of methods that exist
// on String that you should not overwrite.
//
var stringPrototypeBlacklist = [
'__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'charAt', 'constructor',
'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf', 'charCodeAt',
'indexOf', 'lastIndexof', 'length', 'localeCompare', 'match', 'replace', 'search', 'slice', 'split', 'substring',
'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight'
];
Object.keys(theme).forEach(function (prop) {
if (stringPrototypeBlacklist.indexOf(prop) !== -1) {
console.log('warn: '.red + ('String.prototype' + prop).magenta + ' is probably something you don\'t want to override. Ignoring style name');
}
else {
if (typeof(theme[prop]) === 'string') {
colors[prop] = colors[theme[prop]];
addProperty(prop, function () {
return colors[theme[prop]](this);
});
}
else {
addProperty(prop, function () {
var ret = this;
for (var t = 0; t < theme[prop].length; t++) {
ret = exports[theme[prop][t]](ret);
}
return ret;
});
}
}
});
}
colors.setTheme = function (theme) {
if (typeof theme === 'string') {
try {
colors.themes[theme] = require(theme);
applyTheme(colors.themes[theme]);
return colors.themes[theme];
} catch (err) {
console.log(err);
return err;
}
} else {
applyTheme(theme);
}
};
};

View File

@@ -0,0 +1,12 @@
var colors = require('./colors');
module['exports'] = colors;
// Remark: By default, colors will add style properties to String.prototype
//
// If you don't wish to extend String.prototype you can do this instead and native String will not be touched
//
// var colors = require('colors/safe);
// colors.red("foo")
//
//
var extendStringPrototype = require('./extendStringPrototype')();

View File

@@ -0,0 +1,12 @@
var colors = require('../colors');
module['exports'] = (function() {
return function (letter, i, exploded) {
if(letter === " ") return letter;
switch(i%3) {
case 0: return colors.red(letter);
case 1: return colors.white(letter)
case 2: return colors.blue(letter)
}
}
})();

View File

@@ -0,0 +1,13 @@
var colors = require('../colors');
module['exports'] = (function () {
var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta']; //RoY G BiV
return function (letter, i, exploded) {
if (letter === " ") {
return letter;
} else {
return colors[rainbowColors[i++ % rainbowColors.length]](letter);
}
};
})();

View File

@@ -0,0 +1,8 @@
var colors = require('../colors');
module['exports'] = (function () {
var available = ['underline', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta'];
return function(letter, i, exploded) {
return letter === " " ? letter : colors[available[Math.round(Math.random() * (available.length - 1))]](letter);
};
})();

View File

@@ -0,0 +1,5 @@
var colors = require('../colors');
module['exports'] = function (letter, i, exploded) {
return i % 2 === 0 ? letter : colors.inverse(letter);
};

View File

@@ -0,0 +1,77 @@
/*
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.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.
*/
var styles = {};
module['exports'] = styles;
var codes = {
reset: [0, 0],
bold: [1, 22],
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29],
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
gray: [90, 39],
grey: [90, 39],
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49],
// legacy styles for colors pre v1.0.0
blackBG: [40, 49],
redBG: [41, 49],
greenBG: [42, 49],
yellowBG: [43, 49],
blueBG: [44, 49],
magentaBG: [45, 49],
cyanBG: [46, 49],
whiteBG: [47, 49]
};
Object.keys(codes).forEach(function (key) {
var val = codes[key];
var style = styles[key] = [];
style.open = '\u001b[' + val[0] + 'm';
style.close = '\u001b[' + val[1] + 'm';
});

View File

@@ -0,0 +1,61 @@
/*
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.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.
*/
var argv = process.argv;
module.exports = (function () {
if (argv.indexOf('--no-color') !== -1 ||
argv.indexOf('--color=false') !== -1) {
return false;
}
if (argv.indexOf('--color') !== -1 ||
argv.indexOf('--color=true') !== -1 ||
argv.indexOf('--color=always') !== -1) {
return true;
}
if (process.stdout && !process.stdout.isTTY) {
return false;
}
if (process.platform === 'win32') {
return true;
}
if ('COLORTERM' in process.env) {
return true;
}
if (process.env.TERM === 'dumb') {
return false;
}
if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) {
return true;
}
return false;
})();

View File

@@ -0,0 +1,35 @@
{
"name": "colors",
"description": "get colors in your node.js console",
"version": "1.0.3",
"author": {
"name": "Marak Squires"
},
"homepage": "https://github.com/Marak/colors.js",
"bugs": {
"url": "https://github.com/Marak/colors.js/issues"
},
"keywords": [
"ansi",
"terminal",
"colors"
],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/Marak/colors.js.git"
},
"license": "MIT",
"scripts": {
"test": "node tests/basic-test.js && node tests/safe-test.js"
},
"engines": {
"node": ">=0.1.90"
},
"main": "./lib/index",
"readme": "# colors.js\n\n## get color and style in your node.js console\n\n<img src=\"https://github.com/Marak/colors.js/raw/master/screenshots/colors.png\"/>\n\n## Installation\n\n npm install colors\n\n## colors and styles!\n\n### text colors\n\n - black\n - red\n - green\n - yellow\n - blue\n - magenta\n - cyan\n - white\n - gray\n - grey\n\n### background colors\n\n\n\n - bgBlack\n - bgRed\n - bgGreen\n - bgYellow\n - bgBlue\n - bgMagenta\n - bgCyan\n - bgWhite\n\n### styles\n\n - reset\n - bold\n - dim\n - italic\n - underline\n - inverse\n - hidden\n - strikethrough\n\n### extras\n\n - rainbow\n - zebra\n - america\n - trap\n - random\n\n\n## Usage\n\nBy popular demand, `colors` now ships with two types of usages!\n\nThe super nifty way\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\nconsole.log('Run the trap'.trap); // Drops the bass\n\n```\n\nor a slightly less nifty way which doesn't extend `String.prototype`\n\n```js\nvar colors = require('colors/safe');\n\nconsole.log(colors.green('hello')); // outputs green text\nconsole.log(colors.red.underline('i like cake and pies')) // outputs red underlined text\nconsole.log(colors.inverse('inverse the color')); // inverses the color\nconsole.log(colors.rainbow('OMG Rainbows!')); // rainbow\nconsole.log(colors.trap('Run the trap')); // Drops the bass\n\n```\n\nI prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way. \n\nIf you are writing good code you will never have an issue with the first approach. If you really don't want to touch `String.prototype`, the second usage will not touch `String` native object.\n\n## Disabling Colors\n\nTo disable colors you can pass the following arguments in the command line to your application:\n\n```bash\nnode myapp.js --no-color\n```\n\n## Console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data)\n\n```js\nvar name = 'Marak';\nconsole.log(colors.green('Hello %s'), name);\n// outputs -> 'Hello Marak'\n```\n\n## Custom themes\n\n### Using standard API\n\n```js\n\nvar colors = 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### Using string safe API\n\n```js\nvar colors = require('colors/safe');\n\n// set single property\nvar error = colors.red;\nerror('this is red');\n\n// set theme\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(colors.error(\"this is an error\"));\n\n// outputs yellow text\nconsole.log(colors.warn(\"this is a warning\"));\n```\n\n*Protip: There is a secret undocumented style in `colors`. If you find the style you can summon him.*",
"readmeFilename": "ReadMe.md",
"_id": "colors@1.0.3",
"_shasum": "0433f44d809680fdeb60ed260f1b0c262e82a40b",
"_resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
"_from": "colors@>=1.0.3 <1.1.0"
}

View File

@@ -0,0 +1,9 @@
//
// Remark: Requiring this file will use the "safe" colors API which will not touch String.prototype
//
// var colors = require('colors/safe);
// colors.red("foo")
//
//
var colors = require('./lib/colors');
module['exports'] = colors;

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -0,0 +1,50 @@
var assert = require('assert'),
colors = require('../lib/index');
var s = 'string';
function a(s, code) {
return '\x1B[' + code.toString() + 'm' + s + '\x1B[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].strip, s);
assert.equal(s[color].strip, colors.strip(s));
}
function h(s, color) {
return '<span style="color:' + color + ';">' + s + '</span>';
}
var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow'];
var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']);
colors.mode = 'console';
assert.equal(s.bold, '\x1B[1m' + s + '\x1B[22m');
assert.equal(s.italic, '\x1B[3m' + s + '\x1B[23m');
assert.equal(s.underline, '\x1B[4m' + s + '\x1B[24m');
assert.equal(s.strikethrough, '\x1B[9m' + s + '\x1B[29m');
assert.equal(s.inverse, '\x1B[7m' + s + '\x1B[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.setTheme({error:'red'});
assert.equal(typeof("astring".red),'string');
assert.equal(typeof("astring".error),'string');

View File

@@ -0,0 +1,45 @@
var assert = require('assert'),
colors = require('../safe');
var s = 'string';
function a(s, code) {
return '\x1B[' + code.toString() + 'm' + s + '\x1B[39m';
}
function aE(s, color, code) {
assert.equal(colors[color](s), a(s, code));
assert.equal(colors.strip(s), s);
}
function h(s, color) {
return '<span style="color:' + color + ';">' + s + '</span>';
}
var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow'];
var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']);
colors.mode = 'console';
assert.equal(colors.bold(s), '\x1B[1m' + s + '\x1B[22m');
assert.equal(colors.italic(s), '\x1B[3m' + s + '\x1B[23m');
assert.equal(colors.underline(s), '\x1B[4m' + s + '\x1B[24m');
assert.equal(colors.strikethrough(s), '\x1B[9m' + s + '\x1B[29m');
assert.equal(colors.inverse(s), '\x1B[7m' + s + '\x1B[27m');
assert.ok(colors.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.setTheme({error:'red'});
assert.equal(typeof(colors.red("astring")), 'string');
assert.equal(typeof(colors.error("astring")), 'string');

View File

@@ -0,0 +1,12 @@
module['exports'] = {
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
};

View File

@@ -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.

View File

@@ -0,0 +1,4 @@
test:
@@node test/eyes-test.js
.PHONY: test

View File

@@ -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
});

View File

@@ -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;
}

View File

@@ -0,0 +1,42 @@
{
"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",
"_shasum": "62cf120234c683785d902348a800ef3e0cc20bc0",
"_resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
"_from": "eyes@>=0.1.8 <0.2.0"
}

View File

@@ -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 }));

44
node_modules/forever/node_modules/cliff/package.json generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,79 @@
/*
* log-test.js: Tests for cliff.
*
* (C) 2010, Charlie Robbins & the Contributors
*
*/
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);

View File

@@ -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.

77
node_modules/forever/node_modules/colors/ReadMe.md generated vendored Normal file
View File

@@ -0,0 +1,77 @@
# colors.js - get color and style in your node.js console ( and browser ) like what
<img src="http://i.imgur.com/goJdO.png" border = "0"/>
## 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 colors = 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)

342
node_modules/forever/node_modules/colors/colors.js generated vendored Normal file
View File

@@ -0,0 +1,342 @@
/*
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) {
exports[color] = function (str) {
return func.apply(str);
};
String.prototype.__defineGetter__(color, func);
};
function stylize(str, style) {
var styles;
if (exports.mode === 'console') {
styles = {
//styles
'bold' : ['\x1B[1m', '\x1B[22m'],
'italic' : ['\x1B[3m', '\x1B[23m'],
'underline' : ['\x1B[4m', '\x1B[24m'],
'inverse' : ['\x1B[7m', '\x1B[27m'],
'strikethrough' : ['\x1B[9m', '\x1B[29m'],
//text colors
//grayscale
'white' : ['\x1B[37m', '\x1B[39m'],
'grey' : ['\x1B[90m', '\x1B[39m'],
'black' : ['\x1B[30m', '\x1B[39m'],
//colors
'blue' : ['\x1B[34m', '\x1B[39m'],
'cyan' : ['\x1B[36m', '\x1B[39m'],
'green' : ['\x1B[32m', '\x1B[39m'],
'magenta' : ['\x1B[35m', '\x1B[39m'],
'red' : ['\x1B[31m', '\x1B[39m'],
'yellow' : ['\x1B[33m', '\x1B[39m'],
//background colors
//grayscale
'whiteBG' : ['\x1B[47m', '\x1B[49m'],
'greyBG' : ['\x1B[49;5;8m', '\x1B[49m'],
'blackBG' : ['\x1B[40m', '\x1B[49m'],
//colors
'blueBG' : ['\x1B[44m', '\x1B[49m'],
'cyanBG' : ['\x1B[46m', '\x1B[49m'],
'greenBG' : ['\x1B[42m', '\x1B[49m'],
'magentaBG' : ['\x1B[45m', '\x1B[49m'],
'redBG' : ['\x1B[41m', '\x1B[49m'],
'yellowBG' : ['\x1B[43m', '\x1B[49m']
};
} else if (exports.mode === 'browser') {
styles = {
//styles
'bold' : ['<b>', '</b>'],
'italic' : ['<i>', '</i>'],
'underline' : ['<u>', '</u>'],
'inverse' : ['<span style="background-color:black;color:white;">', '</span>'],
'strikethrough' : ['<del>', '</del>'],
//text colors
//grayscale
'white' : ['<span style="color:white;">', '</span>'],
'grey' : ['<span style="color:gray;">', '</span>'],
'black' : ['<span style="color:black;">', '</span>'],
//colors
'blue' : ['<span style="color:blue;">', '</span>'],
'cyan' : ['<span style="color:cyan;">', '</span>'],
'green' : ['<span style="color:green;">', '</span>'],
'magenta' : ['<span style="color:magenta;">', '</span>'],
'red' : ['<span style="color:red;">', '</span>'],
'yellow' : ['<span style="color:yellow;">', '</span>'],
//background colors
//grayscale
'whiteBG' : ['<span style="background-color:white;">', '</span>'],
'greyBG' : ['<span style="background-color:gray;">', '</span>'],
'blackBG' : ['<span style="background-color:black;">', '</span>'],
//colors
'blueBG' : ['<span style="background-color:blue;">', '</span>'],
'cyanBG' : ['<span style="background-color:cyan;">', '</span>'],
'greenBG' : ['<span style="background-color:green;">', '</span>'],
'magentaBG' : ['<span style="background-color:magenta;">', '</span>'],
'redBG' : ['<span style="background-color:red;">', '</span>'],
'yellowBG' : ['<span style="background-color:yellow;">', '</span>']
};
} 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];
}
function applyTheme(theme) {
//
// Remark: This is a list of methods that exist
// on String that you should not overwrite.
//
var stringPrototypeBlacklist = [
'__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'charAt', 'constructor',
'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf', 'charCodeAt',
'indexOf', 'lastIndexof', 'length', 'localeCompare', 'match', 'replace', 'search', 'slice', 'split', 'substring',
'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight'
];
Object.keys(theme).forEach(function (prop) {
if (stringPrototypeBlacklist.indexOf(prop) !== -1) {
console.log('warn: '.red + ('String.prototype' + prop).magenta + ' is probably something you don\'t want to override. Ignoring style name');
}
else {
if (typeof(theme[prop]) === 'string') {
addProperty(prop, function () {
return exports[theme[prop]](this);
});
}
else {
addProperty(prop, function () {
var ret = this;
for (var t = 0; t < theme[prop].length; t++) {
ret = exports[theme[prop][t]](ret);
}
return ret;
});
}
}
});
}
//
// Iterate through all default styles and colors
//
var x = ['bold', 'underline', 'strikethrough', 'italic', 'inverse', 'grey', 'black', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta', 'greyBG', 'blackBG', 'yellowBG', 'redBG', 'greenBG', 'blueBG', 'whiteBG', 'cyanBG', 'magentaBG'];
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(""), 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.themes = {};
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) {
if (typeof theme === 'string') {
try {
exports.themes[theme] = require(theme);
applyTheme(exports.themes[theme]);
return exports.themes[theme];
} catch (err) {
console.log(err);
return err;
}
} else {
applyTheme(theme);
}
};
addProperty('stripColors', function () {
return ("" + this).replace(/\x1B\[\d+m/g, '');
});
// please no
function zalgo(text, options) {
var soul = {
"up" : [
'̍', '̎', '̄', '̅',
'̿', '̑', '̆', '̐',
'͒', '͗', '͑', '̇',
'̈', '̊', '͂', '̓',
'̈', '͊', '͋', '͌',
'̃', '̂', '̌', '͐',
'̀', '́', '̋', '̏',
'̒', '̓', '̔', '̽',
'̉', 'ͣ', 'ͤ', 'ͥ',
'ͦ', 'ͧ', 'ͨ', 'ͩ',
'ͪ', 'ͫ', 'ͬ', 'ͭ',
'ͮ', 'ͯ', '̾', '͛',
'͆', '̚'
],
"down" : [
'̖', '̗', '̘', '̙',
'̜', '̝', '̞', '̟',
'̠', '̤', '̥', '̦',
'̩', '̪', '̫', '̬',
'̭', '̮', '̯', '̰',
'̱', '̲', '̳', '̹',
'̺', '̻', '̼', 'ͅ',
'͇', '͈', '͉', '͍',
'͎', '͓', '͔', '͕',
'͖', '͙', '͚', '̣'
],
"mid" : [
'̕', '̛', '̀', '́',
'͘', '̡', '̢', '̧',
'̨', '̴', '̵', '̶',
'͜', '͝', '͞',
'͟', '͠', '͢', '̸',
'̷', '͡', ' ҉'
]
},
all = [].concat(soul.up, soul.down, soul.mid),
zalgo = {};
function randomNumber(range) {
var 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) {
var result = '', counts, l;
options = options || {};
options["up"] = options["up"] || true;
options["mid"] = options["mid"] || true;
options["down"] = options["down"] || true;
options["size"] = options["size"] || "maxi";
text = text.split('');
for (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);
}
// don't summon zalgo
addProperty('zalgo', function () {
return zalgo(this);
});

76
node_modules/forever/node_modules/colors/example.html generated vendored Normal file
View File

@@ -0,0 +1,76 @@
<!DOCTYPE HTML>
<html lang="en-us">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Colors Example</title>
<script src="colors.js"></script>
</head>
<body>
<script>
var test = colors.red("hopefully colorless output");
document.write('Rainbows are fun!'.rainbow + '<br/>');
document.write('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported
document.write('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported
//document.write('zalgo time!'.zalgo);
document.write(test.stripColors);
document.write("a".grey + " b".black);
document.write("Zebras are so fun!".zebra);
document.write(colors.rainbow('Rainbows are fun!'));
document.write("This is " + "not".strikethrough + " fun.");
document.write(colors.italic('So ') + colors.underline('are') + colors.bold(' styles! ') + colors.inverse('inverse')); // styles not widely supported
document.write(colors.bold(colors.italic(colors.underline(colors.red('Chains are also cool.'))))); // styles not widely supported
//document.write(colors.zalgo('zalgo time!'));
document.write(colors.stripColors(test));
document.write(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))]];
};
})());
document.write("AMERICA! F--K YEAH!".america);
document.write("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
document.write("this is an error".error);
// outputs yellow text
document.write("this is a warning".warn);
</script>
</body>
</html>

77
node_modules/forever/node_modules/colors/example.js generated vendored Normal file
View File

@@ -0,0 +1,77 @@
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('background color attack!'.black.whiteBG)
//
// Remark: .strikethrough may not work with Mac OS Terminal App
//
console.log("This is " + "not".strikethrough + " fun.");
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
//
// Load theme with JSON literal
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);
// outputs grey text
console.log("this is an input".input);
// Load a theme from file
colors.setTheme('./themes/winston-dark.js');
console.log("this is an input".input);

31
node_modules/forever/node_modules/colors/package.json generated vendored Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "colors",
"description": "get colors in your node.js console like what",
"version": "0.6.2",
"author": {
"name": "Marak Squires"
},
"homepage": "https://github.com/Marak/colors.js",
"bugs": {
"url": "https://github.com/Marak/colors.js/issues"
},
"keywords": [
"ansi",
"terminal",
"colors"
],
"repository": {
"type": "git",
"url": "git+ssh://git@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<img src=\"http://i.imgur.com/goJdO.png\" border = \"0\"/>\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 colors = 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",
"_id": "colors@0.6.2",
"_shasum": "2423fe6678ac0c5dae8852e5d0e5be08c997abcc",
"_resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
"_from": "colors@>=0.6.2 <0.7.0"
}

70
node_modules/forever/node_modules/colors/test.js generated vendored Normal file
View File

@@ -0,0 +1,70 @@
var assert = require('assert'),
colors = require('./colors');
var s = 'string';
function a(s, code) {
return '\x1B[' + code.toString() + 'm' + s + '\x1B[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 '<span style="color:' + color + ';">' + s + '</span>';
}
var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow'];
var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']);
colors.mode = 'console';
assert.equal(s.bold, '\x1B[1m' + s + '\x1B[22m');
assert.equal(s.italic, '\x1B[3m' + s + '\x1B[23m');
assert.equal(s.underline, '\x1B[4m' + s + '\x1B[24m');
assert.equal(s.strikethrough, '\x1B[9m' + s + '\x1B[29m');
assert.equal(s.inverse, '\x1B[7m' + s + '\x1B[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.setTheme({error:'red'});
assert.equal(typeof("astring".red),'string');
assert.equal(typeof("astring".error),'string');
colors.mode = 'browser';
assert.equal(s.bold, '<b>' + s + '</b>');
assert.equal(s.italic, '<i>' + s + '</i>');
assert.equal(s.underline, '<u>' + s + '</u>');
assert.equal(s.strikethrough, '<del>' + s + '</del>');
assert.equal(s.inverse, '<span style="background-color:black;color:white;">' + s + '</span>');
assert.ok(s.rainbow);
stylesColors.forEach(function (color) {
assert.equal(s[color], h(s, color));
assert.equal(colors[color](s), h(s, color));
});
assert.equal(typeof("astring".red),'string');
assert.equal(typeof("astring".error),'string');
colors.mode = 'none';
stylesAll.forEach(function (style) {
assert.equal(s[style], s);
assert.equal(colors[style](s), s);
});
assert.equal(typeof("astring".red),'string');
assert.equal(typeof("astring".error),'string');

View File

@@ -0,0 +1,12 @@
module['exports'] = {
silly: 'rainbow',
input: 'black',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
};

View File

@@ -0,0 +1,12 @@
module['exports'] = {
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
};

View File

@@ -0,0 +1,2 @@
node_modules
npm-debug.log

12
node_modules/forever/node_modules/flatiron/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,12 @@
language: node_js
branches:
only:
- master
node_js:
- 0.8
notifications:
email:
- travis@nodejitsu.com
irc: "irc.freenode.org#nodejitsu"

19
node_modules/forever/node_modules/flatiron/LICENSE generated vendored Normal file
View File

@@ -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.

482
node_modules/forever/node_modules/flatiron/README.md generated vendored Normal file
View File

@@ -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 = flatiron.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, <host>, <callback(err)>)`
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 <person>',
'',
' This will print "hello <person>"'
]
});
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 <person>
help:
help: This will print "hello <person>"
```
### 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

30
node_modules/forever/node_modules/flatiron/bin/flatiron generated vendored Executable file
View File

@@ -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();

View File

@@ -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 <msg> - 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();

View File

@@ -0,0 +1,5 @@
var print = module.exports = function print(msg) {
console.log(msg);
}
print.usage = 'Print out a <msg>';

View File

@@ -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);

View File

@@ -0,0 +1,8 @@
var flatiron = require('../../lib/flatiron'),
app = module.exports = flatiron.app;
app.use(flatiron.plugins.resourceful, {
root: __dirname,
engine: 'memory'
});

View File

@@ -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);
};

View File

@@ -0,0 +1,15 @@
{
"name": "resourceful-app",
"description": "An example flatiron app using resourceful",
"version": "0.1.0",
"author": "Nodejitsu Inc. <info@nodejitsu.com>",
"dependencies": {
"flatiron": "0.3.x",
"resourceful": "0.3.x"
},
"main": "./app",
"engines": {
"node": ">= 0.6.4"
}
}

View File

@@ -0,0 +1,8 @@
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>

View File

@@ -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);
});
});

View File

@@ -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;

View File

@@ -0,0 +1 @@
body { color: lime; background-color: black; }

View File

@@ -0,0 +1 @@
document.write('Hello World!');

View File

@@ -0,0 +1,15 @@
{
"name": "static-app",
"description": "An example flatiron app using static plugin",
"version": "0.1.0",
"author": "Nodejitsu Inc. <info@nodejitsu.com>",
"dependencies": {
"flatiron": "0.3.x",
"st": "0.1.0"
},
"main": "./app",
"engines": {
"node": ">= 0.6.4"
}
}

View File

@@ -0,0 +1,71 @@
/*
* flatiron.js: An elegant blend of convention and configuration for building apps in Node.js and the browser.
*
* Copyright(c) 2011 Nodejitsu Inc. <info@nodejitsu.com>
* MIT LICENCE
*
*/
var fs = require('fs'),
path = require('path'),
broadway = require('broadway');
var flatiron = exports,
_app;
//
// ### Export core `flatiron` modules
//
flatiron.common = require('./flatiron/common');
flatiron.constants = require('./flatiron/constants');
flatiron.formats = broadway.formats;
flatiron.App = require('./flatiron/app').App;
flatiron.version = require('../package.json').version;
//
// ### 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);
};

View File

@@ -0,0 +1,21 @@
/*
* 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');
var App = exports.App = function (options) {
broadway.App.call(this, options);
};
//
// Inherit from `broadway.App`.
//
util.inherits(App, broadway.App);

View File

@@ -0,0 +1,105 @@
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';
name = name || '';
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(err) {
if (err) {
if (err.message === 'canceled') {
// Start a new line to make the cancel look pretty.
return process.stdout.write('\n');
}
throw err;
}
app.log.info('Application ' + info.name.magenta + ' is now ready');
callback();
}
);
}
module.exports.usage = [
'Generates a flatiron skeleton application. If no <type>',
'is specified an HTTP application will be created.',
'<type> can currently be either cli or http',
'',
'create <app-name> <type>',
];

View File

@@ -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 `<app>` 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(/\<app\>/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 [] }
};

View File

@@ -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"
};

View File

@@ -0,0 +1,454 @@
/*
* 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];
var usage = app.usage || [
name
? 'Cannot find commands for ' + name.magenta
: 'Cannot find commands'
];
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(usage)
}
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(usage);
}
}
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;
});
};

View File

@@ -0,0 +1,104 @@
/*
* 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,
spdy: app.http.spdy
});
};
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);
};
};

View File

@@ -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.get('database') || {}
);
app.config.set('resourceful', options);
//
// Remark: Should we accept the autoMigrate option?
//
if (options.engine) {
resourceful.use(options.engine, options);
}
done();
};

View File

@@ -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);
}
}

View File

@@ -0,0 +1,4 @@
node_modules
npm-debug.log
.DS_Store

View File

@@ -0,0 +1,10 @@
language: node_js
node_js:
- "0.8"
- "0.10"
notifications:
email:
- travis@nodejitsu.com
irc: "irc.freenode.org#nodejitsu"

View File

@@ -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.

View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More