{"_id":"args-command-router","_rev":"29-eb69cbd46e117456d5cf02c120d0a7a9","name":"args-command-router","dist-tags":{"latest":"4.0.1","next":"4.0.1-beta"},"versions":{"1.0.0":{"name":"args-command-router","version":"1.0.0","description":"Nodejs command line argument router","main":"index.js","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"echo \"Error: no test specified\" && exit 1","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"license":"MIT","devDependencies":{"@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.3.2","@typescript-eslint/parser":"^2.3.2","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","prettier":"^1.18.2","typescript":"^3.6.3"},"dependencies":{"args-command-parser":"^1.0.6"},"gitHead":"31b48a67ac806b00625d2002b6e40e382db99cc2","_id":"args-command-router@1.0.0","_nodeVersion":"10.16.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-yxJHLBv/PNvHNwX+cTSHX8PeiuP7qyrbUfOjYxcoFwuuSwLNPtubCvtf8M1RKfOnkSq0rOgKWwk/sY6QD+kf8g==","shasum":"b95bc16b7d46b4368f09de55025c2a0fd1c99655","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.0.tgz","fileCount":2,"unpackedSize":1233,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdnYi8CRA9TVsSAnZWagAAoAQP/RqDYyuyWCRf6TDDFD8j\nB0l3OjBG1YKfGbBkiPlELPY0b1ZimcgQgPhe2dOSk1d6ugDw8bisasIZ1Z/g\nIjaDL1rHcsRysGmR4Xs2dMvCguemhctWpf5UbM/1aMJcXx40SLipjXXH2GKo\n3ZEqtc6AkTPQ8OGCcuhBRv8sYIVdW/Bbcb/YI1F8nbWLdpuy0z2Rn8F9NisV\n5KeQcehUDn4Sl+w0JSxNjr5hNRbyvehKbs/847ke47ggFw5LU0i5UQclkl+L\nvizIssQ5+nNXS0Wx9BC9cbaTQw6gahcRG9rutJ/6PCUP74SQi6+KhIyMOPMP\nYFmK2FcpvOZ7/CvlXaakcID72laiKioJJaiz49ZXcs9PJ2W6+uSoHRSK5xl/\nzDp0tgnCA/AaVOg8gcV2+Gy3pxJ20k4v8lAIS1MZCG2vWio5kJErZQv4sdBQ\nfnJIYApcuo5RDuY3stXlYb+Y5exuuGOZ9Rb0mDfFPnPFQHSeWJ+jXB6JhDy3\n2HAvwuyyEQgJe7bQJZBEzOydDqOgEBHXnZ2QsXlzrTMIWRZszQxPYd1K/Xbb\nH+4+5rr2dNAn6kzG7yaqvhTVkxojwLeBTXTXIPC6Q0Ee+5jcwhxymavczaKR\nSr7m1uzTVw/NXzXVcjrMPtrKHXl+qLZl3g+DNavjhEKYDOl3fPjIiKgIhQcC\nJikE\r\n=CZZD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBFN4ikVndnazFx041oEo1ProqsNTx+Za1wDQoCu3NADAiALaFFnLXFaEI1w/SNPIEHYX6oU85nCK8xGk/9/phfgeQ=="}]},"maintainers":[{"name":"xx007","email":"sahand.javid@gmail.com"}],"_npmUser":{"name":"xx007","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.0_1570605244019_0.1659443424430087"},"_hasShrinkwrap":false},"1.0.1":{"name":"args-command-router","version":"1.0.1","description":"Nodejs command-line argument router","main":"index.js","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"echo \"Error: no test specified\" && exit 1","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"license":"MIT","devDependencies":{"@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","prettier":"^1.18.2","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"5089cdd393c8507579375cea6f4072a0636b4afc","_id":"args-command-router@1.0.1","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-7N43JfjMUlcxFeHJ9jr6c4VHEHgG5nepc9NTlUDakG4DHxYITTqGBj5v1mV3lpEibVkM25HyAy0kCOuyWlubtQ==","shasum":"752d37003acd3dedb1b06e3d562a9808a33b4f54","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.1.tgz","fileCount":69,"unpackedSize":155776,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdq372CRA9TVsSAnZWagAAmuYP/AtFkXz0FYgpeWyRygrM\nUiSb0KmHkJCaV3xqeda5bB59t+d4CE0Ha8dHru/U0zES0EpI+y7KPV2NhZRC\n9Y6Tptk/EvqQhTCVN+FkGfXpTetwSCl8ah/tcLPMGm5/Us0fKknXxxaz98yY\n3nClnXX0AszYrz1rRc2qvvJsr38wGIiVpzB313pDmKAGwV2uc84FgNZvMgFp\nqSMocLiaEb+lsr2VdaMQgGycLdWVAmcC0n74nYTFti6w4I0xN5pedQ8bIn3+\n59FLOFCvP3BBueqB0RLN7OsfHcTtua+4BWCyDGYT/spv0AH5+ftmno/WjC7L\np9fv7GYq/03J3iC2ez2bx6bK/p4W4FrKz064o+iipcxUzJxoEnscuXQfZ3AR\njWV6Tu07EYc1sV5ZSn/PpJntPNZQinxF6hWpdNVsbi5Ms+++PfewtOkGekYI\n2MGedhkuop5RmIv+ZPdZh9gc0WdqFT0sjvU0u4NR8d4SNaopswCSyhiLlKyW\nMAde3Vz/c+wWaZRPp+eauEp9QAOTf6/0ly5nZfPh3Lv5W2DycxkbXyW1En1d\n2PGDqESarSnxWrWrl/WtMmKQNdkUjtUTbn6bKWXtUyG9AXzCS7RorFZXyQCK\nmJf0MfPnbUfstZ7irCODUlHJUlxKCKsVTtmn7lEXHS1soevUg8cy9i9gWe0e\n86AN\r\n=BSYP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD9codyFYOjPKE3vMsDgSv7TP/ETr3xTu3gzDCbt9Q4XwIhAOXoLJnzUr6+1Kd66EgcTclWkNr0KolS3PZNjlGCwUHN"}]},"maintainers":[{"name":"xx007","email":"sahand.javid@gmail.com"}],"_npmUser":{"name":"xx007","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.1_1571520245704_0.9390341757412564"},"_hasShrinkwrap":false},"1.0.2":{"name":"args-command-router","version":"1.0.2","description":"Nodejs command-line argument router","main":"index.js","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"echo \"Error: no test specified\" && exit 1","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"license":"MIT","devDependencies":{"@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","prettier":"^1.18.2","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"aba2e2d9cfd0a9ba2b68c19a03e7056ff8fdde93","_id":"args-command-router@1.0.2","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-2JIJqkUKFo3Fe5obbM+jjEj7gt5230l7pppF83Lgknt9QyoO38QNLb8lkwz+X8I1X+9kHUr6HV3w2be04ynCyw==","shasum":"8b3325f3bde26a71c5978ee925f7c9573c54627c","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.2.tgz","fileCount":69,"unpackedSize":155776,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdq3+2CRA9TVsSAnZWagAAqkgP/01ou1kTmrpOY9Ky3dbN\noHiya5v4f5fSKPx+PlPDCYQPjxzwShWW/eEkCMtjhDJaxZqyS3BF3sZZqQq7\nhPZ0GahndOMQS6sjeo4j0oakQrbUDSwmhK6wxo4w+rEXI6AkI6eTlrdI8eWO\n6S1Rcc3e1ZZNPOZWYEGfxEjzqj6qMGEZPcYm2bB5rX6NNPUZeYeNO8L1UwzR\nEZMOI2bJjhVVCUgFYvM0nHqQL2cs+GR1yecTMsZ/4KnkBQQ2elzEk2UZahR/\nLPzyakQnJL9Sa5ZHwbHPp5Hu3OTEWP4YFK66KV1qCqW4YX70w7yC7PCct58z\nnAPfrTPqkxl7qYjoQkb5/PzQoumDZ5jc/pZraydG60CwYr5rZd/s2X19LXfi\nkN80d6yk/tE1SFeMkhhjXnufYDlPzIVJiZaHUwVI0dVt+7rc+wNQ96f8twkM\nqap2x5WXhuHkaEreBaBwBNonV7NruiSlEbozm1+OwFgiDNEIUnEnd54/F3Zx\nJx2pjIJonh26gDY/P6Dc714Kjh3hrkX72mzuEWLEvUfV2brJWfeY0gUn3SHg\nrvtrxizAnpn/u/VaBRc3nUmyL62gny0oWxLi8jqM3VR4TOc5sisEpQz0WjgF\nRgAkYLQDYiCqKBvFvnlBmRvxwmK/mvjHJGF36yzwimSYdEXvtaH3qr8x67x/\naO75\r\n=DO4f\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCqFphgtiT+33vgoxDJmnZYo+7rIF45pSmK868IYCU7OQIgab9rEn8xuGdqCJifjjZa+3N2ft9G27TaX/05Fv8OLD4="}]},"maintainers":[{"name":"xx007","email":"sahand.javid@gmail.com"}],"_npmUser":{"name":"xx007","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.2_1571520438122_0.6697469412553214"},"_hasShrinkwrap":false},"1.0.3":{"name":"args-command-router","version":"1.0.3","description":"Nodejs command-line argument router","main":"index.js","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"echo \"Error: no test specified\"","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"license":"MIT","devDependencies":{"@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","prettier":"^1.18.2","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"5817313f1809440bcbe0e6348e1ae92607915b7a","_id":"args-command-router@1.0.3","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-nJYvgD4uvvnrw9D2oltZjwX92bEm0s6otAxKCaeW7Oqfx6lP4qTd0xGe1Nh/+bQmezjWOY4iPyIrjT1NtUFfGQ==","shasum":"d99dcddfca6354f60af35fd77b5a65522764a6f4","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.3.tgz","fileCount":69,"unpackedSize":155766,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdq4AKCRA9TVsSAnZWagAA8NwQAJ0nkq1zlJwl5imNWGh2\nT33Kly0G+dqdjSxevcxfhckdNRj6mX4v5PGYJ5qkLGr6SxthxaDcXAviUGQZ\nQJ0ewGg2R2JZElrU8GXIUK/RsKqXeUfHtzWe6BS+CdUZEjNzWBqCvhOLfpo/\nm9Gc41i5oSsLKxj0bN7LJFZA7pFB18Wstx2NlLOwYNzRRNQQaRnYWtqWBNxs\nvLsbX3hF+gVIxfAXCpjzanFNiet91uhjpmMBP8Ta+mNcCVjNU75xbf/ZcIxM\nLSjM13iVLiINrR168zwdU5D2FGC1jO1YhqHNT5+a5P5Pcs+Dclrff9yrt2oq\n8fM7AMEO2AcmsfIg411H3T8MJaxWGl6IKxemAhM2bjYeaT1D7bot59F8yJ4o\ny2MucFg73gjyYSMSmLruyeOj1m5t+bFISzA/bZjEzPKIhbw50uNtqJ09W8/j\nJAJ96nrueRreYoR2N6b+timDapHcZ9OovmISnv+cxXc1rAdnmLJoBrgArJFt\n8xT9DlzJz3hmVAQpDBmefvBKKj7NWUgifHsU0NVF/Kc8+Vmdn1QsoCl2Qxco\nd8CWcp8Ym43cizlTEQr6ntfg06R1DcA02rXWUQhscdtnZ/pWMx1TZFPnIwOw\n4iVYLemDcKu5lbXekQ0g4W6ZEFezOCwSx5KsOrKiKDtK+5lnrBsz8Iq8CmYt\nnT4j\r\n=6gvi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHECfO1UYrYNLgpSvTW/rVSGFMeCSDMCsse9QMeRgeMdAiADbmmEACSU9szRxENF93EVYi5aM2okuaxNWwxYrEsrkw=="}]},"maintainers":[{"name":"xx007","email":"sahand.javid@gmail.com"}],"_npmUser":{"name":"xx007","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.3_1571520521802_0.23834198330046164"},"_hasShrinkwrap":false},"1.0.4-0":{"name":"args-command-router","version":"1.0.4-0","description":"Nodejs command-line argument router","main":"index.js","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"echo \"Error: no test specified\"","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","prettier":"^1.18.2","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"readme":"# args-command-parser\n\nNodejs opinionated command-line argument router\n\n## Installation\n\n```bash\nnpm install args-command-router\n```\n\n## Usage\n\n### Scenario\n\nLet's say we want to create a nodejs application called _Fetcher_. It can download a file, crawl a website, and so more.\n\nOn the CLI, you've decided that your application should work like this:\n\n```bash\nnode fetcher.js version\nnode fetcher.js check file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\nnode fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\nnode fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg --output ~/Downloads\nnode fetcher.js download folder https://nodejs.org/dist/ --depth 2\n```\n\nLet's try to route `version` path to its implementation:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\nconst app = argsCommandRouter()\n\nconst APP_VERSION = '1.0.1'\n\n// node fetcher.js version\napp.route('version', () => {\n  console.log(APP_VERSION)\n})\n\napp.run()\n```\n\nFor the next one, let's do the `check file <file_url>` and `download file <file_url>`:\n\n```js\n// initializing app constant like above...\n\n// node fetcher.js check file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\napp.route('check/file/:file_url', inputs => {\n  const fileUrl = inputs.params.file_url\n\n  console.log('Check whether the file ' + fileURL + 'exists.')\n})\n\n// node fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\napp.route('download/file/:file_url', inputs => {\n  const fileUrl = inputs.params.file_url\n\n  console.log('Download the file ' + fileURL + ' to the Desktop')\n})\n```\n\nNow let's add a condition that if the `download file <file_url>` has an `--output` switch route to another implementation:\n\n```js\n// node fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg --output ~/Downloads\napp.route('download/file/:file_url[output]', inputs => {\n  const fileUrl = inputs.params.file_url\n  const outputDir = inputs.switches.output\n\n  console.log('Download the file ' + fileURL + ' to ' + outputDir)\n})\n```\n\nNow let's try to route `download folder <folder_url>` with switch `--depth`. Let's say for different depths, we want to have different implementations:\n\n```js\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 1\napp.route('download/folder/:folder_url[depth==\"1\"]', inputs => {\n  const folderUrl = inputs.params.folder_url\n\n  console.log('Download only the files inside ' + folderUrl + ' url folder')\n})\n\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 0\napp.route('download/folder/:folder_url[depth < \"1\"]', inputs => {\n  console.log('There is nothing to download')\n})\n\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 3\napp.route('download/folder/:folder_url[depth]', inputs => {\n  const folderUrl = inputs.params.folder_url\n  const depth = inputs.params.depth\n\n  console.log(\n    'Crawl and download to maximum ' + depth + ' levels in ' + folderUrl\n  )\n})\n\napp.route('download/folder/:folder_url', inputs => {\n  const folderUrl = inputs.params.folder_url\n\n  console.log('Crawl and download eveything inside ' + folderUrl)\n})\n```\n\n## More Details on the Format\n\n**args-command-router** is opinionated command-line router based on the package [args-command-parser](https://www.npmjs.com/package/args-command-parser). The idea is that the command is in the format below:\n\n```\nnode <file.js> [command1 [command2 [...]]] [switches]\n```\n\n### Command\n\nCommands are the first arguments showing up. These are names without `-` or `--`. As soon as a switch seen, the sequence of commands is considered finished.\n\n### Switch\n\nSwitches can be in short or long format.\n\n#### Short Switch\n\nShort Switches are prefixed with `-` followed by one or more single-character switch. If more than one character is specified, each character is considered a Short Switch. Short Switches can be followed by zero to any number of values.\n\n#### Long Switch\n\nLong Switches are prefixed with `--` followed by the switch name. Long Switches can be followed by zero to any number of values.\n\n## More Details on Routes\n\n**Becareful about order of the routes you're defining.**\n\nIf there are multiple matches, the latest matched route callback will be triggered.\n\nThe `noroute()` method can be used for when no routes are matched:\n\n```js\napp.noroute(inputs => {\n  console.log('No routes matched.')\n})\n```\n\nAfter defining all your routes, you need to call the `run()` method on the application instance.\n\n```\napp.run()\n```\n\nThe `run()` method use currently passed arguments to find the route match, but you can pass an array of strings to `run()`, and args-command-router will use those instead of the currently passed arguments.\n\n## More Details on Commands and Switches\n\nRoutes are consist of two parts:\n\n- Commands\n- Condition\n\n### Commands\n\nCommands are specifying an argument path to the user's implementation. Command path can be specified in string in `route()` or by creating a `Command` object.\n\nCommand _string_ items (fixed or parameter) are separated by a slash (`/`), and parameters are prefixed by a colon (`:`).\n\nThe _Command_ objects give you better control over organizing and externalizing routes and code.\n\n```js\nconst { argsCommandRouter, Command } = require('args-command-router')\nconst downloadFile = require('./downloadFile.js')\nconst app = argsCommandRouter()\n\nconst downloadFileCommand = new Command('download/file')\napp.route(downloadFileCommand, downloadFile)\n```\n\nBy having a reference to the Command, you can set additional properties for documentation and control.\n\nJust remember that when you are creating a `Command` object, the command path string shouldn't contain any brackets and conditions.\n\n```\nconst downloadFileCommand = new Command('download/file')\ndownloadFileCommand\n  .description('Downloads a specific file given by its url')\n  .valuedSwitch('o', 'output', null, 'Destination file local path')\n  .booleanSwitch('p', 'progress', 'Show download progress bar')\n  .requiredSwitch('f', 'force', 'This is just to a show required switch feature')\n```\n\nThe other thing is, each Command item comes with a fixed Command child `help` to display a help message for that command. So you can do:\n\n```bash\nnode fetcher.js help\nnode fetcher.js download help\nnode fetcher.js download file help\n...\n```\n\nI'm generating help outputs using the [command-line-usage](https://www.npmjs.com/package/command-line-usage) package.\n\nYou can override the `help` command in the same way that you defined a new route:\n\n```js\napp.route('download/file/:file_url/help', inputs => {\n  console.log('I want my own help message')\n})\n```\n\n### Condition\n\nConditions add extra control over routing the command arguments. They can be specified inside the route path or by creating a `Condition` object.\n\nYou can use _Command Parameters_ and _switches that passed at runtime_ in your conditions.\n\nWe have already seen conditions inside route (using brackets `[]`). Let's have an example of `Condition` objects.\n\n```js\nconst { argsCommandRouter, Command } = require('args-command-router')\nconst downloadFile = require('./downloadFile.js')\nconst app = argsCommandRouter()\n\nconst downloadFileCommand = new Command('download/folder/:folder_url')\nconst downloadFileDepthOneCondition = new Condition('depth==1')\napp.route(downloadFileCommand, downloadFileDepthOneCondition, downloadFile)\n```\n\nOr you can specify each of them in the route separately by route string path:\n\n```\napp.route('download/folder/:folder_url', downloadFileDepthOneCondition, downloadFile)\napp.route(downloadFileCommand, 'depth==1', downloadFile)\napp.route('download/folder/:folder_url', 'depth==1', downloadFile)\napp.route('download/folder/:folder_url[depth==1]', downloadFile)\n```\n\nThe condition string follows the extended [expr-eval](https://www.npmjs.com/package/expr-eval) conditional syntax and doesn't follow the JavaScript syntax.\n\n| Operator | Description         | Example                            | Example explained                           |\n| -------- | :------------------ | :--------------------------------- | :------------------------------------------ |\n| ==       | equal               | a == \"2\"                           | a is equal to 2                             |\n| !=       | not equal           | a != \"2\"                           | a is not equal to 2                         |\n| >=       | greater or equal    | a >= \"2\"                           | a is greater or equal 2                     |\n| <=       | lesser or equal     | a <= \"2\"                           | a is lesser or equal 2                      |\n| >        | greater             | a > \"2\"                            | a is greater 2                              |\n| <        | lesser              | a < \"2\"                            | a is lesser 2                               |\n| and      | logical AND         | b and a == \"2\"                     | b is present and a is equal to 2            |\n| or       | logical OR          | b or a == \"2\"                      | b is present or a is equal to 2             |\n| not      | logical Not         | not a                              | a is not present                            |\n| (...)    | Grouping conditions | (a and b) or ((not a) and (not b)) | both a and b is present or both not present |\n\n## License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n","readmeFilename":"README.md","gitHead":"563c96a292e65b620d606641b262744cd714ea0b","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@1.0.4-0","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-23Kysh6qOPKq+VVSycW8/XF5EvxtJcO2EhN+ixjvzg9PS9wLFCkEuhsvcShitAU8uQclRLw4dr7rg52XM5rgwg==","shasum":"3cf6a681cebedf9cbb285f21cc71686656b188e3","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.4-0.tgz","fileCount":69,"unpackedSize":155875,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdq4HJCRA9TVsSAnZWagAAvbMQAIbla3sU9by6EZ6uaWKJ\nD7dnL6CigEfthV6MpCnFSRcn6VTqIntT9CzaNaKWhgz1/YaCzjimqOyY1lJK\njLL7eOKc3ol6hAhAFQ6KVujF6/2yPPs32M4Yo1iVg/Q6guTlwUHA0d5kqx1k\nDyHGPt1XUWzuIbf2w+UZ048PG4PRQf3C9EiHrLtcL4mzu5KvVckt5hkcb8Ko\nIDQd65LUq/4sbYoxPUAJd77fwoaX9H3oAXp/JBMM25QOFU2w7R2l683HduzY\nio5K/Z4anj3qCfQ8VL+7rycLVOGcnqi0SMvTooZ7YC9rbhmd9QZ9v1TGYjbT\nNNJSgm/4z/s8Fki+ryhJV69HuNv3wHcBQbY8xNIJZbWTrkIhH871yZDIOiGz\nT2cldVqlY4E7HrcF5iwNMoq8SAupT8cZQn8MiSTViobOc+XARlqTksxsJz0r\nG7bC6UaotAs2gx9YUJJQf+4A5rr66WzWBws+LW89try4TGU/VasobyI99oI9\nZaHL4h8vozt72kviaK9VgJ5azSjt1ZeRSgDiBOHKLfcVHl/+YlnymCnbb/ee\nbPlVnf5VXlns1fxxNYhnlKeb/uNNuLzxqlikys3fQeA7FbuGM4YPGP12Ke0b\n7vHJuDFV74zomeftCJ+8rgPbXWGkvNOm2qYXLjoVUbm+C4KhXfeF5Eib//IW\n7NT1\r\n=ALti\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCXo+g81FmM12Kc9bdFNNovkHtP8nL1unF8lHpLbgH5AIgNNSVhZFAcrzDzYDdhdYcdlNgGrIXm7EfCpfb0+pcgdk="}]},"maintainers":[{"name":"xx007","email":"sahand.javid@gmail.com"}],"_npmUser":{"name":"xx007","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.4-0_1571520968735_0.003225044134914201"},"_hasShrinkwrap":false},"1.0.4-1":{"name":"args-command-router","version":"1.0.4-1","description":"Nodejs command-line argument router","main":"index.js","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"echo \"Error: no test specified\"","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","prettier":"^1.18.2","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"readme":"# args-command-parser\n\nNodejs opinionated command-line argument router\n\n## Installation\n\n```bash\nnpm install args-command-router\n```\n\n## Usage\n\n### Scenario\n\nLet's say we want to create a nodejs application called _Fetcher_. It can download a file, crawl a website, and so more.\n\nOn the CLI, you've decided that your application should work like this:\n\n```bash\nnode fetcher.js version\nnode fetcher.js check file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\nnode fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\nnode fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg --output ~/Downloads\nnode fetcher.js download folder https://nodejs.org/dist/ --depth 2\n```\n\nLet's try to route `version` path to its implementation:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\nconst app = argsCommandRouter()\n\nconst APP_VERSION = '1.0.1'\n\n// node fetcher.js version\napp.route('version', () => {\n  console.log(APP_VERSION)\n})\n\napp.run()\n```\n\nFor the next one, let's do the `check file <file_url>` and `download file <file_url>`:\n\n```js\n// initializing app constant like above...\n\n// node fetcher.js check file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\napp.route('check/file/:file_url', inputs => {\n  const fileUrl = inputs.params.file_url\n\n  console.log('Check whether the file ' + fileURL + 'exists.')\n})\n\n// node fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\napp.route('download/file/:file_url', inputs => {\n  const fileUrl = inputs.params.file_url\n\n  console.log('Download the file ' + fileURL + ' to the Desktop')\n})\n```\n\nNow let's add a condition that if the `download file <file_url>` has an `--output` switch route to another implementation:\n\n```js\n// node fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg --output ~/Downloads\napp.route('download/file/:file_url[output]', inputs => {\n  const fileUrl = inputs.params.file_url\n  const outputDir = inputs.switches.output\n\n  console.log('Download the file ' + fileURL + ' to ' + outputDir)\n})\n```\n\nNow let's try to route `download folder <folder_url>` with switch `--depth`. Let's say for different depths, we want to have different implementations:\n\n```js\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 1\napp.route('download/folder/:folder_url[depth==\"1\"]', inputs => {\n  const folderUrl = inputs.params.folder_url\n\n  console.log('Download only the files inside ' + folderUrl + ' url folder')\n})\n\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 0\napp.route('download/folder/:folder_url[depth < \"1\"]', inputs => {\n  console.log('There is nothing to download')\n})\n\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 3\napp.route('download/folder/:folder_url[depth]', inputs => {\n  const folderUrl = inputs.params.folder_url\n  const depth = inputs.params.depth\n\n  console.log(\n    'Crawl and download to maximum ' + depth + ' levels in ' + folderUrl\n  )\n})\n\napp.route('download/folder/:folder_url', inputs => {\n  const folderUrl = inputs.params.folder_url\n\n  console.log('Crawl and download eveything inside ' + folderUrl)\n})\n```\n\n## More Details on the Format\n\n**args-command-router** is opinionated command-line router based on the package [args-command-parser](https://www.npmjs.com/package/args-command-parser). The idea is that the command is in the format below:\n\n```\nnode <file.js> [command1 [command2 [...]]] [switches]\n```\n\n### Command\n\nCommands are the first arguments showing up. These are names without `-` or `--`. As soon as a switch seen, the sequence of commands is considered finished.\n\n### Switch\n\nSwitches can be in short or long format.\n\n#### Short Switch\n\nShort Switches are prefixed with `-` followed by one or more single-character switch. If more than one character is specified, each character is considered a Short Switch. Short Switches can be followed by zero to any number of values.\n\n#### Long Switch\n\nLong Switches are prefixed with `--` followed by the switch name. Long Switches can be followed by zero to any number of values.\n\n## More Details on Routes\n\n**Becareful about order of the routes you're defining.**\n\nIf there are multiple matches, the latest matched route callback will be triggered.\n\nThe `noroute()` method can be used for when no routes are matched:\n\n```js\napp.noroute(inputs => {\n  console.log('No routes matched.')\n})\n```\n\nAfter defining all your routes, you need to call the `run()` method on the application instance.\n\n```\napp.run()\n```\n\nThe `run()` method use currently passed arguments to find the route match, but you can pass an array of strings to `run()`, and args-command-router will use those instead of the currently passed arguments.\n\n## More Details on Commands and Switches\n\nRoutes are consist of two parts:\n\n- Commands\n- Condition\n\n### Commands\n\nCommands are specifying an argument path to the user's implementation. Command path can be specified in string in `route()` or by creating a `Command` object.\n\nCommand _string_ items (fixed or parameter) are separated by a slash (`/`), and parameters are prefixed by a colon (`:`).\n\nThe _Command_ objects give you better control over organizing and externalizing routes and code.\n\n```js\nconst { argsCommandRouter, Command } = require('args-command-router')\nconst downloadFile = require('./downloadFile.js')\nconst app = argsCommandRouter()\n\nconst downloadFileCommand = new Command('download/file')\napp.route(downloadFileCommand, downloadFile)\n```\n\nBy having a reference to the Command, you can set additional properties for documentation and control.\n\nJust remember that when you are creating a `Command` object, the command path string shouldn't contain any brackets and conditions.\n\n```\nconst downloadFileCommand = new Command('download/file')\ndownloadFileCommand\n  .description('Downloads a specific file given by its url')\n  .valuedSwitch('o', 'output', null, 'Destination file local path')\n  .booleanSwitch('p', 'progress', 'Show download progress bar')\n  .requiredSwitch('f', 'force', 'This is just to a show required switch feature')\n```\n\nThe other thing is, each Command item comes with a fixed Command child `help` to display a help message for that command. So you can do:\n\n```bash\nnode fetcher.js help\nnode fetcher.js download help\nnode fetcher.js download file help\n...\n```\n\nI'm generating help outputs using the [command-line-usage](https://www.npmjs.com/package/command-line-usage) package.\n\nYou can override the `help` command in the same way that you defined a new route:\n\n```js\napp.route('download/file/:file_url/help', inputs => {\n  console.log('I want my own help message')\n})\n```\n\n### Condition\n\nConditions add extra control over routing the command arguments. They can be specified inside the route path or by creating a `Condition` object.\n\nYou can use _Command Parameters_ and _switches that passed at runtime_ in your conditions.\n\nWe have already seen conditions inside route (using brackets `[]`). Let's have an example of `Condition` objects.\n\n```js\nconst { argsCommandRouter, Command } = require('args-command-router')\nconst downloadFile = require('./downloadFile.js')\nconst app = argsCommandRouter()\n\nconst downloadFileCommand = new Command('download/folder/:folder_url')\nconst downloadFileDepthOneCondition = new Condition('depth==1')\napp.route(downloadFileCommand, downloadFileDepthOneCondition, downloadFile)\n```\n\nOr you can specify each of them in the route separately by route string path:\n\n```\napp.route('download/folder/:folder_url', downloadFileDepthOneCondition, downloadFile)\napp.route(downloadFileCommand, 'depth==1', downloadFile)\napp.route('download/folder/:folder_url', 'depth==1', downloadFile)\napp.route('download/folder/:folder_url[depth==1]', downloadFile)\n```\n\nThe condition string follows the extended [expr-eval](https://www.npmjs.com/package/expr-eval) conditional syntax and doesn't follow the JavaScript syntax.\n\n| Operator | Description         | Example                            | Example explained                           |\n| -------- | :------------------ | :--------------------------------- | :------------------------------------------ |\n| ==       | equal               | a == \"2\"                           | a is equal to 2                             |\n| !=       | not equal           | a != \"2\"                           | a is not equal to 2                         |\n| >=       | greater or equal    | a >= \"2\"                           | a is greater or equal 2                     |\n| <=       | lesser or equal     | a <= \"2\"                           | a is lesser or equal 2                      |\n| >        | greater             | a > \"2\"                            | a is greater 2                              |\n| <        | lesser              | a < \"2\"                            | a is lesser 2                               |\n| and      | logical AND         | b and a == \"2\"                     | b is present and a is equal to 2            |\n| or       | logical OR          | b or a == \"2\"                      | b is present or a is equal to 2             |\n| not      | logical Not         | not a                              | a is not present                            |\n| (...)    | Grouping conditions | (a and b) or ((not a) and (not b)) | both a and b is present or both not present |\n\n## License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n","readmeFilename":"README.md","gitHead":"82b47354398f6e03c373cbfd2080a1de4906fdaa","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@1.0.4-1","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-MWtp76AXmXI61oMcLR6o2HlVfJCJMILhxZ2cqzyR9nyZGaUCgns58vcbm+UwFfVxkSMGp33QYAvtQzld5rctFA==","shasum":"99b582aef285acd5f2286eeda455e9c367827f36","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.4-1.tgz","fileCount":69,"unpackedSize":155871,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdq4JGCRA9TVsSAnZWagAAT+MP/RSL06nVzh3Gzf5zrJB6\nVO6ZfFehWsdIC6MGl+/i/ETMnnVGkDlM39pICL5+wuk5Wh0nsRB564+/vfok\n1UWBhTRcH3bMntflFRT8JnnfK8DeXlLzO8qneWMcLhJAiMIrFVUH0M+8p1sL\nTsvwqrx+RJYCi160RJSXh06Kc9VvPjLJNVNlrBQC29TF+8SRh6GsZ3hHPUio\no3wKUvipjvbbzY2iT+BsOO2ZFb95+ngbdmycRjVuo6StzJ2B5+Fru/ud5uG6\ng0kqzapbOXDr8HEMG8KfhgU/IY5EKsXcxw13otP6d3Gnv1zoHRwiqKI8FbdS\nlGtL8UuquRa2RUgQgU5o0qkbDa/2XHZWAJz0JDvz0zOvVVSF5JXvfDAQs0mH\n2gpLFzrpi2uqeMH6rlgGKZiEWhTey8Ea8MWeM/H0nclz181afn/LissrpWoh\nTsH7kidhXFLK9wmpKtNYyRSkzQn7STiP+x9Ex1vleP5zpsJhadgIk8Bp5aPi\n70P+CMISQeoj3b4JoIGkNO/5UoDZJJ7o7N77PuOZjbjS8nxgcQsRYMULECfm\n4cRRyPIOcoxCmU392xjsyg/avIP1yICv9vt0kIwOk93y0PnikqZnWZcO8z6d\nFyQvvTCTyuZtpos8eUltZwcwskkMNUvH8vByVuZvip8xiNdZxeOMmR/JWbkY\n5KSM\r\n=t9TY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDp2YJ/abwTAnmkgWr75lUzTb32b5zPpuHIuW0xkUI86AiEA5V0A7jQb3U5KP4jb+O2Emjkiqll0nFASxKQQ3xrKs2Q="}]},"maintainers":[{"name":"xx007","email":"sahand.javid@gmail.com"}],"_npmUser":{"name":"xx007","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.4-1_1571521094250_0.0004169763687373873"},"_hasShrinkwrap":false},"1.0.4-2":{"name":"args-command-router","version":"1.0.4-2","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.3","@types/mocha":"^5.2.7","@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","chai":"^4.2.0","coveralls":"^3.0.7","cross-env":"^6.0.3","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","mocha":"^6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","ts-node":"^8.4.1","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"readme":"# args-command-parser\n\nNodejs opinionated command-line argument router\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install args-command-router\n```\n\n## Usage\n\n### Scenario\n\nLet's say we want to create a nodejs application called _Fetcher_. It can download a file, crawl a website, and so more.\n\nOn the CLI, you've decided that your application should work like this:\n\n```bash\nnode fetcher.js version\nnode fetcher.js check file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\nnode fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\nnode fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg --output ~/Downloads\nnode fetcher.js download folder https://nodejs.org/dist/ --depth 2\n```\n\nLet's try to route `version` path to its implementation:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\nconst app = argsCommandRouter()\n\nconst APP_VERSION = '1.0.1'\n\n// node fetcher.js version\napp.route('version', () => {\n  console.log(APP_VERSION)\n})\n\napp.run()\n```\n\nFor the next one, let's do the `check file <file_url>` and `download file <file_url>`:\n\n```js\n// initializing app constant like above...\n\n// node fetcher.js check file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\napp.route('check/file/:file_url', inputs => {\n  const fileUrl = inputs.params.file_url\n\n  console.log('Check whether the file ' + fileURL + 'exists.')\n})\n\n// node fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg\napp.route('download/file/:file_url', inputs => {\n  const fileUrl = inputs.params.file_url\n\n  console.log('Download the file ' + fileURL + ' to the Desktop')\n})\n```\n\nNow let's add a condition that if the `download file <file_url>` has an `--output` switch route to another implementation:\n\n```js\n// node fetcher.js download file https://nodejs.org/dist/v10.16.3/node-v10.16.3.pkg --output ~/Downloads\napp.route('download/file/:file_url[output]', inputs => {\n  const fileUrl = inputs.params.file_url\n  const outputDir = inputs.switches.output\n\n  console.log('Download the file ' + fileURL + ' to ' + outputDir)\n})\n```\n\nNow let's try to route `download folder <folder_url>` with switch `--depth`. Let's say for different depths, we want to have different implementations:\n\n```js\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 1\napp.route('download/folder/:folder_url[depth==\"1\"]', inputs => {\n  const folderUrl = inputs.params.folder_url\n\n  console.log('Download only the files inside ' + folderUrl + ' url folder')\n})\n\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 0\napp.route('download/folder/:folder_url[depth < \"1\"]', inputs => {\n  console.log('There is nothing to download')\n})\n\n// node fetcher.js download folder https://nodejs.org/dist/ --depth 3\napp.route('download/folder/:folder_url[depth]', inputs => {\n  const folderUrl = inputs.params.folder_url\n  const depth = inputs.params.depth\n\n  console.log(\n    'Crawl and download to maximum ' + depth + ' levels in ' + folderUrl\n  )\n})\n\napp.route('download/folder/:folder_url', inputs => {\n  const folderUrl = inputs.params.folder_url\n\n  console.log('Crawl and download eveything inside ' + folderUrl)\n})\n```\n\n## More Details on the Format\n\n**args-command-router** is opinionated command-line router based on the package [args-command-parser](https://www.npmjs.com/package/args-command-parser). The idea is that the commands are in the format below:\n\n```\nnode <file.js> [command1 [command2 [...]]] [switches]\n```\n\n### Command\n\nCommands are the first arguments showing up. These are names without `-` or `--`. As soon as a switch is seen, the sequence of commands is considered finished.\n\n### Switch\n\nSwitches can be in short or long format.\n\n#### Short Switch\n\nShort Switches are prefixed with `-` followed by one or more single-character switch. If more than one character is specified, each character is considered a Short Switch. Short Switches can be followed by zero to any number of values.\n\n#### Long Switch\n\nLong Switches are prefixed with `--` followed by the switch name. Long Switches can be followed by zero to any number of values.\n\n## More Details on Routes\n\n**Becareful about order of the routes you're defining.**\n\nIf there are multiple matches, the latest matched route callback will be triggered.\n\nThe `noroute()` method can be used for when no routes are matched:\n\n```js\napp.noroute(inputs => {\n  console.log('No routes matched.')\n})\n```\n\nAfter defining all your routes, you need to call the `run()` method on the application instance.\n\n```\napp.run()\n```\n\nThe `run()` method use currently passed arguments to find the route match, but you can pass an array of strings to `run()`, and args-command-router will use those instead of the currently passed arguments.\n\n## More Details on Commands and Switches\n\nRoutes are consist of two parts:\n\n- Commands\n- Condition\n\n### Commands\n\nCommands are specifying an argument path to the user's implementation. Command path can be specified in string in `route()` or by creating a `Command` object.\n\nCommand _string_ items (fixed or parameter) are separated by a slash (`/`), and parameters are prefixed by a colon (`:`).\n\nThe _Command_ objects give you better control over organizing and externalizing routes and code.\n\n```js\nconst { argsCommandRouter, Command } = require('args-command-router')\nconst downloadFile = require('./downloadFile.js')\nconst app = argsCommandRouter()\n\nconst downloadFileCommand = new Command('download/file')\napp.route(downloadFileCommand, downloadFile)\n```\n\nBy having a reference to the Command, you can set additional properties for documentation and control.\n\nJust remember that when you are creating a `Command` object, the command path string shouldn't contain any brackets and conditions.\n\n```\nconst downloadFileCommand = new Command('download/file')\ndownloadFileCommand\n  .description('Downloads a specific file given by its url')\n  .valuedSwitch('o', 'output', null, 'Destination file local path')\n  .booleanSwitch('p', 'progress', 'Show download progress bar')\n  .requiredSwitch('f', 'force', 'This is just to a show required switch feature')\n```\n\nThe other thing is, each Command item comes with a fixed Command child `help` to display a help message for that command. So you can do:\n\n```bash\nnode fetcher.js help\nnode fetcher.js download help\nnode fetcher.js download file help\n...\n```\n\nI'm generating help outputs using the [command-line-usage](https://www.npmjs.com/package/command-line-usage) package.\n\nYou can override the `help` command in the same way that you defined a new route:\n\n```js\napp.route('download/file/:file_url/help', inputs => {\n  console.log('I want my own help message')\n})\n```\n\n### Condition\n\nConditions add extra control over routing the command arguments. They can be specified inside the route path or by creating a `Condition` object.\n\nYou can use _Command Parameters_ and _switches that passed at runtime_ in your conditions.\n\nWe have already seen conditions inside route (using brackets `[]`). Let's have an example of `Condition` objects.\n\n```js\nconst { argsCommandRouter, Command } = require('args-command-router')\nconst downloadFile = require('./downloadFile.js')\nconst app = argsCommandRouter()\n\nconst downloadFileCommand = new Command('download/folder/:folder_url')\nconst downloadFileDepthOneCondition = new Condition('depth==1')\napp.route(downloadFileCommand, downloadFileDepthOneCondition, downloadFile)\n```\n\nOr you can specify each of them in the route separately by route string path:\n\n```\napp.route('download/folder/:folder_url', downloadFileDepthOneCondition, downloadFile)\napp.route(downloadFileCommand, 'depth==1', downloadFile)\napp.route('download/folder/:folder_url', 'depth==1', downloadFile)\napp.route('download/folder/:folder_url[depth==1]', downloadFile)\n```\n\nThe condition string follows the extended [expr-eval](https://www.npmjs.com/package/expr-eval) conditional syntax and doesn't follow the JavaScript syntax.\n\n| Operator | Description         | Example                            | Example explained                           |\n| -------- | :------------------ | :--------------------------------- | :------------------------------------------ |\n| ==       | equal               | a == \"2\"                           | a is equal to 2                             |\n| !=       | not equal           | a != \"2\"                           | a is not equal to 2                         |\n| >=       | greater or equal    | a >= \"2\"                           | a is greater or equal 2                     |\n| <=       | lesser or equal     | a <= \"2\"                           | a is lesser or equal 2                      |\n| >        | greater             | a > \"2\"                            | a is greater 2                              |\n| <        | lesser              | a < \"2\"                            | a is lesser 2                               |\n| and      | logical AND         | b and a == \"2\"                     | b is present and a is equal to 2            |\n| or       | logical OR          | b or a == \"2\"                      | b is present or a is equal to 2             |\n| not      | logical Not         | not a                              | a is not present                            |\n| (...)    | Grouping conditions | (a and b) or ((not a) and (not b)) | both a and b is present or both not present |\n\n## License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n","readmeFilename":"README.md","gitHead":"e7c128cbb9742bf903c30dae9c4d20164a1f460d","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@1.0.4-2","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-TsadMsyCmJBs2G/5a6b584kse5hRkz+6CVdjyZRu6gBNfiM3ZbVyVZCfPFIRDdaNmtbFwpua655UevmPWrc1cQ==","shasum":"6e96e78c391677866acb60fb9658387344a736ba","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.4-2.tgz","fileCount":57,"unpackedSize":93948,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdsA9hCRA9TVsSAnZWagAA8DQP/1FNGOH9xvfEvfyGpt1X\ntaRQsGgSRuKC6gMWAzZpT7m/MTtk+kGI4DJ0qzb/wOkz4hnuNNFLAJqunXxt\nlhOejIK8Hm4hjKJaAg83Sgu0KkkEp4t8+pFLLp2uocQPWudiSNozsP2H+N6G\nV/rc1pasL8agp3xydUjp5ayuQkdrzMkLV8hG6hpKwrezMqLfZZ7ds7+GPoaD\n4XcKkxhPJAmu0FTy6F3F0m0VBUBwWdl2UrgXiwCCqn+XQTDMQvMgHxwOJ9gR\nvMDTOyfOES+iVUbhNe8sm8OlDEMvShooPnQDcORPMonrigz3XFv1flSKMRrx\nrQ/4mMnk1PZHIzxUX9eK2lI4U9yXmxBN1gd60l4SC7vAhiN6IclDSQiuOcKC\nO56GBUSTv4MQ+pYeZu9W8v/z24HAZJnDOm0mwvjylgqV2+iDL3TAX2vlKwK4\n0jKH+Q6HuivEctt8ZkyIO+EenflVGTJgYfkNCQ8MdkbCwVZMnVyG3EQso89f\nUL/RhxI2rF4fwojCEay8m0yLoRNiiTYXKa462Irt3MXBm9Za+pJGBH98Ohow\nYjfFC74UttSQ0vOW80fO8srTzW0P7yWPzxUZWrS9ccwzbLw+2wtqIRLCFW7d\nJ+xYUCcg8ChvQQad1nZhURLTPZAf3rzBGG0X0YlbxwTixAf4bHonAgc9rlzW\nxFDp\r\n=JC6R\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAcNO+3rr5QDFvWN/96xCvc24LPY0PFnOq8fkmvuafq/AiBjy0lGaJDRfmcJ1kHWeEusJX+ZtR2TkS1Y7Vkmu6nxZw=="}]},"maintainers":[{"email":"sahand.javid@gmail.com","name":"shnd"}],"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.4-2_1571819360597_0.474149773093115"},"_hasShrinkwrap":false},"1.0.4":{"name":"args-command-router","version":"1.0.4","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.3","@types/mocha":"^5.2.7","@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","chai":"^4.2.0","coveralls":"^3.0.7","cross-env":"^6.0.3","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","mocha":"^6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","ts-node":"^8.4.1","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"c930854b2a47cb48c0ee7a3e4b18607bb7a7987e","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@1.0.4","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-zf7R+Ri49vRTM/chJw9Lxsq7YRAD9PjPyRuOXDo2/2ufKfvKpuDmoNEcBkNI9VXBS86A4gFW6P7ClzYxRuE2Vw==","shasum":"a72920a44bf2c23af68e6a3f1e690acaca8565ce","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.4.tgz","fileCount":57,"unpackedSize":93946,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdsBaMCRA9TVsSAnZWagAAQVsP/iu26GQ7yeO+W0p/bDW3\nKR7H0aNmST9l4kEerFwNxrh4crtT8PjagC+8djmbo+gnhVT6h5011Msv7qQs\nwdxt4fjHfWjB6yGEXXJFWo/KQqkxxRvx7afu4RRm+CIspagUBT7K7LQM0Uo8\nr95vZmIaZ843RnInXPucjaxIkRi8lW2Ix/0Z1c2SmgsG4ZkrteutGq0wpJlT\nen+uwYqfjsKDIJy6l/D5iTNgdUj5gOtq0Zuqk7ktgTpmRWYgPV1VDEKOGNdE\nK2XibQBsLkritgMmMLLUZTqH5IBv20S+mEue9yhm+6wFvKTDRNd4B4Of00sZ\n0T/r8f/jhcaCx2wke8EoTayxCtg+KnB0eEXDtCK7BmnTemd6dkVMeouxgRu8\nBD2gNGwOxjDyDoZbNUZQPIz4a+mqxQrrSk6dHnznRZjRnSSYaKrRrKeY1C5C\nZ7aiShipgbCnp2ndfoZw6N6kDvKDAJhW+puZNOxM21MNoo92hmZ9Cut/jO5r\nEPwHGs/51sXElmxSbXnTY0VJZdA/BPZWXFji6+b7HYJ/NhzgLbhAAQrn4GMi\nATSO5g1W09bsJSoT6N6jEoZUNdfAP74i7cQEyWZFZXdo/oG81KnnzNfsA/fL\nT1z/Az3/8dKT8u9p+l4Nw+FC8AKBLIj6VJX3Wn7XnhinZLy6VpaYVYeI9DIF\nVRnY\r\n=+IOz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAKQcMRGdiRRwu1GPgxUwOU6O+DBeJGDol4hWcCpvmOjAiEAn0VC0g3VwGWD+pCNvqnq0AeMFAj02gr62kBfFLYtuL0="}]},"maintainers":[{"email":"sahand.javid@gmail.com","name":"shnd"}],"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.4_1571821195634_0.47781784724383747"},"_hasShrinkwrap":false},"1.0.5":{"name":"args-command-router","version":"1.0.5","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.3","@types/mocha":"^5.2.7","@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","chai":"^4.2.0","coveralls":"^3.0.7","cross-env":"^6.0.3","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","mocha":"^6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","ts-node":"^8.4.1","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"5c2b6ab63aa6c7c31f8d1b67a9aaada90e75753b","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@1.0.5","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-S0ULSk4nYODGDxbkXrJGX5tOqXLWrHaeiqf3jybVffIhoxFdXOXk3q7u+/4GMM1BbzSFozaoR8tFu/QRpY5s+A==","shasum":"be272294946ee4d719c196b6238b89c7df04dafc","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.5.tgz","fileCount":60,"unpackedSize":99211,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdsW9+CRA9TVsSAnZWagAAmjwQAJiJ1uMm+4oLznkkgzBA\nVDMkLfwCBIDW7/FkNlpuG/6r+gE7uczPLZDbRb4ctuqGSFiiVGUSm3K1r0BI\nYOOM2PxWrjn5Tko0pTdd6J2QzjAF0I/rQ/xxp9VRGau+20qqa90Swy1h3b64\nOQlDn6MCxaBlvbu61otULsHjbHGtLpzSsw4ORjCqpr7pYKft1FD+4HyYzZ4g\nKvJeEglmWcjtccaZSi5ogpuNZP0KXFo7qRcwKRdgfEPkN76PYqsYhR2Fs88b\nqwjTDqrHE7dZaYurDhJ1bpmfB13ehe+5fCrJ3NoyAhg0sHSBkGL5g6pC3/WW\nthWkn+sw+dYkZ3pQq/klto2IHceg2AjyppB3FHMrmeeQx+fkK6Ql4Ioq/79N\n6horso64npuJ9rz/MJ5Bh4x5pj3sclNaEGRUAfB0lr/rxjSHOc8GErY3O50e\n6H+ub1Fl7M39J2+xHAp6kPSJRc7goi3YuhGz4gZnRii6c2IcTOY5f0F9YT9N\n00P1pyg9stOFlAMkEhwnB6prEEtpU8tlVnWyqUyOpL//JzHXbc7ttk4Ddsv4\nwTymmi5bZXcDK/wEkS9r4qJl7OEwUKaaa2mYUEFzQ3KdLPLsoejJHWrZ0BRV\n2DJMquj/7jBrjJt18gxyH86KLTP29X8LXzDxHbKr4lT6WqLr+h1kMaeoi98Q\n5KER\r\n=4PfO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHAImuqCSsmxfILmFO4I5FrY1NplyhMvMBdAscKWV9uFAiBGKjo9QhTsvFJ7NxamqKbqyPwVIW4Fo2DZYn8E8b7QNg=="}]},"maintainers":[{"email":"sahand.javid@gmail.com","name":"shnd"}],"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.5_1571909501560_0.08101511505234327"},"_hasShrinkwrap":false},"1.0.6":{"name":"args-command-router","version":"1.0.6","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.3","@types/mocha":"^5.2.7","@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","chai":"^4.2.0","coveralls":"^3.0.7","cross-env":"^6.0.3","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","mocha":"^6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","ts-node":"^8.4.1","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"73dd3c7ff464262237148d7de528a4b2b5d69adf","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@1.0.6","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-wRZ5yADqkOsuENk3eIojsScfPxC0AYuBWTeeYU110Z0nmon2IiyAfaGtyP4VwzEztkVXJXes7fbXkz47+Xbs5A==","shasum":"e18ea5c659e6e9f2129536235d640ee11a22c6b9","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-1.0.6.tgz","fileCount":60,"unpackedSize":99412,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdsi+fCRA9TVsSAnZWagAA46kP/RH6oKXseaePZIWqNDGN\n+KvorA2s6RwhqK6ExA2kya8efT455I/octDyctSNL4gB2bKtn2fjhX3rGfIC\nUMAoB7ui4m2ktgKywqPeVsYCquDPcy9v/0wVHmx9dck1HLofbwr8cPb30Zrc\ndqgi9OBDswsW1cWsm/uNHnVWQ3WA2cUilRybIKdjJB8u+ioC3LT0slHGdUtM\neVWBn54dYzMSurLB7AMvrQR8BR3R/RMmDHQu9VAdFqohP1QITeCQDs1hnjR/\nM03NQDmeAB5ULic5VSDhw3N8Tns4bdNXeIpI+dunmvnTCajYMUo9iMO+K+U+\nDrmu19ndGvrOqXNjV6P/LJx0/WWh+5ZBEs9yDtO6ajN50yiqEpXUdblQpf7F\nv/KdH+jTxeN7m9dbpvM+3guQr4e2CrZg+2zwysM1Fb0owPs9dZxNAXJqlVT9\ndpsAvv6yjqq1qYCJpP3c78ctUWVV3D7peK4Ag0jlOfRsqCExDEdABzQ/BqAK\nsyOpj+cG1+WTMCOu3qxlgcMe8kAlWxUMGtw9ocOXLBVhx1Bt8UsYDBk9jiIQ\nk/q/aP2irngYCtKgQAZN0MQmI2caN2lKUyN/KdVQbwwgSiPvPMuSCVE6theP\nX9BuxFOK5wae1WqwGBhmkilgkLst1tB1KgNKp2q+1ZBpcoT8H0gThh4HvGcB\nkm3G\r\n=FKtk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHZpvTqo9zf7uqOgUpm0RPdhuHBik+GYkpRcOpYrBkgaAiEA7cBTW3YvufY5442yhP0Lmq9iCnmUvnUNjO60JufF7Qo="}]},"maintainers":[{"email":"sahand.javid@gmail.com","name":"shnd"}],"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_1.0.6_1571958687067_0.7861426170420027"},"_hasShrinkwrap":false},"2.0.1":{"name":"args-command-router","version":"2.0.1","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.3","@types/mocha":"^5.2.7","@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","chai":"^4.2.0","coveralls":"^3.0.7","cross-env":"^6.0.3","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","mocha":"^6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","ts-node":"^8.4.1","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"f0e861ad3a203d4821adce39a728170c0e893806","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@2.0.1","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-WyHBX02smxpzUhqN8kWqaBV5Vl0qmMU3wSThKEN58bHvcI0goDfAArCPkWxtSvggLVT979vugvaVaCHp/1PKqw==","shasum":"dd67893ccde8c6a5c3e770b497b0b319737cd700","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-2.0.1.tgz","fileCount":60,"unpackedSize":111736,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdtQ3UCRA9TVsSAnZWagAAaKoP/0NK6b9SpoEgULLo4ZVi\n+30/dzV5A9tp+BQR9z1As5OfNk0F8ite7KBO8CD5/+ItnohmB4nGHTFxVfek\nF4fVtTYTS+Pz3P87DVi7fCRQg90jY2eUNPT+gqTtRMud4+1g6LWbNAWWqFAu\n09xYKRs+JgTfVMRHg7mvxlpbS/UFdcI3dqYwOjLrsqszXEl6oxK3RLQyBdRr\n9haDolrIiHR34CZuvE+jpnOTDF1/m7c7Tp5nBHbMvBLKKqLrXSQ5nHq4wUEP\nzvwi1Te4s9y9zOP/hS+9Dn4F7V7iEwg76PeZgcGHBPaH77/L5z6ttWEWl9FC\nURs1nC7t//ldRux4UHxIs3UM3D1NX3KF8yFwpoD0s7s5/u+yqRH/VwjdruBG\nWCaa/xvzHSSlB5wHUvi5tXXdVSFQRUjP4Shmw/s3YTwg5b+W2y1OnUVQVGvA\nO8CJc79ReRfUiL6Cx8DbjsCB15jcMKfIYL61WEyThkP+y/CszVuICNFaTeqs\nNTLI8KX+anc9ktVkLzvDOlRIZKC/j4yWy7mIjgRRhGNVtUPpvZ089cEoWdZu\ncGc2vkhczmuilT+dIQP0QehFbBRGLlZJcmk4p04+35mY6MPHo9qmNdKIP0LJ\nNmIZ7cUtHGCoaRqGt+BlbBiC/TTwafGiv4Osg9zrnzLHvMW2YpswxELRvoRm\ngn/v\r\n=Scmd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDdvYYLuguTfsSB6Z2ZuKYuNEnim6RxIMVltgzOLHEi7QIgYVsnIXrApPdWFpESmwkCosQ/xAqtJlaT4VCayNR4abY="}]},"maintainers":[{"email":"sahand.javid@gmail.com","name":"shnd"}],"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_2.0.1_1572146644332_0.4630552422560055"},"_hasShrinkwrap":false},"2.0.2":{"name":"args-command-router","version":"2.0.2","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.3","@types/mocha":"^5.2.7","@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","chai":"^4.2.0","coveralls":"^3.0.7","cross-env":"^6.0.3","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","mocha":"^6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","ts-node":"^8.4.1","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"7ed1535164f62c2aa42d4d92b3447e4d0e476082","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@2.0.2","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-Z1dMfirX3Scwju/WTphHnvFwb0Jv+TZpJMGGfDVcxh49BWpk3CSL3UCxWYDV3MeSvliSkbsZr/S/eauSXRDWnQ==","shasum":"5ab6985fb3e7ba87482b40f96c9141a0a4dabfb4","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-2.0.2.tgz","fileCount":60,"unpackedSize":111581,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdtRAOCRA9TVsSAnZWagAA/c8P/A1WpCzusVwvBSZnpL/x\nelM3ewZ83qfP5iLYTT3qxpVaOGzVAwh6+/Ih6QEPlJHIE1fqVK8Md0Ru8Rdc\nE0bfAPu/x+P6AOWKKT1l+zbdywItOPMB0JIZFe94jEumGpdEo/cXzQsjK18S\nvl2C+X7VUbpDpLFdbWZEf4l1luI90Fpa3P6Qdm94kJENxu1MlieXK/IheXHa\nw+6kn7mUKkiOEzErvm8YOktgKAsEAn9v6WJJF66qB6zBFtCgwDLO73/A27Al\nZt+2nFotaHrFM0/1hEkz7Qw6qc9KsJEgk/AMNWoZgWrPHZtUfuMBrAq28UrR\nnyUTwSvUZi+A8HAboV80cy1Q8IeKAQFQn+k/5ROk5BQT3xTFqtv5+9KFht4D\nxWgqj/dgG2UuYeGJ+6B4J0iMSCw0fN/kfjK3zWFwmo9smC8rcVAcrovTg5o0\nsbUKd1Lx2rcp4pU31ZshzGDHLdXI5xs71Jpi1p+joHPjejfz2OrAR7x5z5Ta\noKTH6AVnBB1qWpTWfOgcS4EKKTY5xl2mpaBh0sCm+SmFG+xJBLAECN2XUajD\nDQAhMhGEG96fp98JVRqKO4xY92pcgDi5yVZGsu+gQ7Z7SLtXszLJM9ce4Sw7\ntPx+Q+SUMoYnZcUWdKpTM2YAYNMTaIScVpRrNABxqMhZ8+AcVhv+nwBfBf99\nKM3A\r\n=otAc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID0EcujDRrlP70H78ZJNYfnYn9Mox1U9mPjzfl8y9Vx1AiBQhWg07mo6B42KXD5xIXIgfAzlC3SFNFvZdFiwSp3tTA=="}]},"maintainers":[{"email":"sahand.javid@gmail.com","name":"shnd"}],"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_2.0.2_1572147213506_0.5300321287788208"},"_hasShrinkwrap":false},"2.0.3":{"name":"args-command-router","version":"2.0.3","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.3","@types/mocha":"^5.2.7","@types/node":"^12.7.11","@typescript-eslint/eslint-plugin":"^2.4.0","@typescript-eslint/parser":"^2.4.0","chai":"^4.2.0","coveralls":"^3.0.7","cross-env":"^6.0.3","eslint":"^6.5.1","eslint-config-prettier":"^6.4.0","eslint-plugin-prettier":"^3.1.1","mocha":"^6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","ts-node":"^8.4.1","typescript":"^3.6.4"},"dependencies":{"@types/command-line-usage":"^5.0.1","args-command-parser":"^1.0.9","command-line-usage":"^6.0.2","expr-eval":"^2.0.2"},"gitHead":"454ab3acc3faecebdb9a886cd0f3ca187a95fc46","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@2.0.3","_nodeVersion":"10.16.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-f8Y9Ho5yGDIc+LbpBbE6fmuB7VtV8kcptCM40vNynpL9JDR3GT0dBSBn5Mx9KJjqgcEPOKBqMv+vFgjtJw5Gtw==","shasum":"5dd6c54e70b958f8237ddfcf87a3b86eb107e90e","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-2.0.3.tgz","fileCount":60,"unpackedSize":111154,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdtouLCRA9TVsSAnZWagAAGf4QAKTQvV+XBiJlxYFHUPVu\nfau9zqFpVWGMVFU+hJyLzvkUNKpWpEGQ3aw4+F0eI/f1JxAZUP5Byh5V5df+\njCE76Vd4wQ1kwzaQ0/20q6HPaKKa7+4cMUeGpH4VcB/MllS2zSOCnIusGFrf\nz1g5w4VhheXavT6ExaBLgP9WUJ7510yZ5POaqS7szwMBGkWLBBv6V5dwrXY4\nsKJxZPisvqesmqqYSCba7/S2jcJ9Ogr5w5yzICXgmnd2dr1oD+fkknWDuYOY\nsLqbb8dl+yzKgh7iRxT7fozFEI66D2Ju9wRPCkyueAzeF7u2zrRxSmhPN+R6\n9qSxfZzcU++Noir1osr82MQ1p6hUGx7K7e0LUv4/cb8CMe4O9ZpHeDaG4HAt\nyA6v7eOWos8+A5WdIfO/yXUOc9/U5SV0hzzmwXFeFVOesgtOV8hKoP6BKxuN\nzvVJ3tlscVPh/rXfLvKhpQBN8+U+KFdr5iQu9kUfCC44LC/bX7pBpzn62wAa\nCD5+mB59fJzovOHFqvFxNBi+/Gzu47FLKlkOYFiH4F8EEF8lC/ckxToB6ZzF\nqBfYE0gfOV4YTl1iQIFXcaJkyC3YcwUO0Re9tZWszDUDnAM9uQtdcW+66Pqz\n/jSKZsx7Ok61xfRXFP6huWxXFll9XBfeYZ3RhkR/QchA/PC4wmqtq50sslDe\ngitk\r\n=Puw+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHfk4pyspxjLt18JuJESJYPvKrpt5ffnXwv8HM5vTSGpAiEA5iZA0GYU3t0aptbn2i2AawF5vmUf8e5kXv/fYeh9c+k="}]},"maintainers":[{"email":"sahand.javid@gmail.com","name":"shnd"}],"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_2.0.3_1572244362431_0.2025435527115964"},"_hasShrinkwrap":false},"3.0.0-alpha.1":{"name":"args-command-router","version":"3.0.0-alpha.1","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add .\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { Application } = require('args-command-router')\n\nconst app = new Application({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/:filename')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method on the Application instance specifies for each series of commands and switches (path), what routine (callback) should be called.\n\nIt receives a series of names separated by `/` and series of optional switches at the end of the path each inside `[]`.\n\n```js\napp.route('/cmd1/:cmd2[switch1=123][s]\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP cmd1 hi --switch1 123 -s\n$ APP cmd1 hello -s --switch1 123\n$ APP cmd1 'hey all' -s --switch1 123\n```\n\nEach `cmd1`, `:cmd2` and `[switch1=123][s]` are called **PathItem**.\n\n- `cmd1` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:cmd2` is a **Dynamic PathItem**, and it can be matched to any value in its place.\n\n- `[switch1=123][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--switch1` with the exact value of _123_. If you have special characters in the value, you can put that value in single or double quotes.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/call/my/callback').callback(function(inputs) {\n  const { commands, pathParams, shortSwitches, longSwitches, switches } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are passed with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic pathItem names and values that are passed to your application.\n- **shortSwitches** is an object of short switch names and array of values that are passed to your application.\n- **longSwitches** is an object of long switch names and array of values that are passed to your application.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches must to be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string.\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequired('k', 'key', 'Api key', ['key'])\n  .commonOptional('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application.\n\nCurrently, there are three different hooks:\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.hello)\n})\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  verifySwitches: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `verifySwitches`: Verify if the passed switches are matched with switches defined on the found pathItem.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `verifySwitches` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when `helpType` is `switch` and `helpShortSwitch` is passed.\n","readmeFilename":"README.md","gitHead":"a2608348599a569610d4d00f00136c57a6b233c8","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.0.0-alpha.1","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-vU13D6MeCqF143vBV620yYMcgER8fyrNcyDXuW3UOGZVQZKR4hpuvvXS8HYUBrjFrTADg8nQz3+d0+f51wzMmQ==","shasum":"e3d71602efa302ee3a3e37ff198b109233541ca1","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.0.0-alpha.1.tgz","fileCount":102,"unpackedSize":253066,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfqCPQCRA9TVsSAnZWagAA2SQP/130nu65aF68uNXxrxhE\nWI+cp6C7Y261mL2zGc/3BKh9TioKps1MjULovoh5w/6VNv2O6WPl8pSKE6JO\nN3kT18SVXFlv0w53iuYLAsJr4bcv/zIRxZWL03SS+PrWwELbOxwoeuBSDlAb\ntmNsIaPy1S2FLbKQ5YUnBXj25pdfNag2Rej413qcfIK1SH8Ecb/uL2ktRzga\nI1WsEfBFmFaiuOfKsbAiigjaH0pxVdqd3SvNljRCh94Slb0+FRImrUXllAjp\ndQLVoYFLMsnDd0eN/dMHmCK+L+ZxDO8D3oPwaIH3Rl+UQPai152LPuh/DrU1\ngJDq2p+zMThd0tFEzHMSImlvB9CHb640cTj2y6S++myp0w8ALu5xOIlSRkML\nUBkrS86gdSz7ydvON/5t8YFPICU09D9cROIHbfPzp3PaMry5Cxs+nSAlYQRm\nQdJXBMeOezm0+CK7+gpRmMLU4JlU9RwkvZ78EzGVy7LbSe3PMEw4DKF+RIll\nPcnxLcjL1W/y13K+7tHYrHRfHRJnEebkdD1qip0Y2+/m4veW9YWjdQzLFnq3\nQrpnZIwbIDJggImcm6/Gp7nmZcjmIMatnbvM3I3MRlX9XEQXYTQzonEwSm6O\nP23F8vrMymlmWnBPvwE5q/BtN3uLURxUIX8y0cS5V/2uCjd+3m5bu36F3nzz\nioIF\r\n=q4Rq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH87YtZAVFyqSEPzOExw7/EFqlxDRWmefLsoavnGxLXzAiEA1iqxl8FgsSmKeUgpxV9tvnx5aomnMuDpRd46Xtb2Y40="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.0.0-alpha.1_1604854736045_0.6819292847443685"},"_hasShrinkwrap":false},"3.0.0-alpha.2":{"name":"args-command-router","version":"3.0.0-alpha.2","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router@next\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add .\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/:filename')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method on the Application instance specifies, what routine (callback) should be called for each series of commands and switches.\n\nIt receives a series of names separated by `/` and series of optional switches at the end of the path each inside `[]`.\n\n```js\napp.route('/cmd1/:cmd2[switch1=123][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP cmd1 hi --switch1 123 -s\n$ APP cmd1 hello -s --switch1 123\n$ APP cmd1 'hey all' -s --switch1 123\n```\n\nEach `cmd1`, `:cmd2` and `[switch1=123][s]` are called **PathItem**.\n\n- `cmd1` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:cmd2` is a **Dynamic PathItem**, and it can be matched to any value in its place.\n\n- `[switch1=123][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--switch1` with the exact value of _123_. If you have special characters in the value, you can put that value in single or double quotes.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/call/my/callback').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic pathItem names and values that are passed to your application.\n- **shortSwitches** is an object of short switch names and array of values that are passed to your application.\n- **longSwitches** is an object of long switch names and array of values that are passed to your application.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `verifySwitches`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequired('k', 'key', 'Api key', ['key'])\n  .commonOptional('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  verifySwitches: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `verifySwitches`: Verify if the passed switches are matched with switches defined on the found pathItem.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `verifySwitches` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when user pass `-h`.\n","readmeFilename":"README.md","gitHead":"b94657dfe2330a6ab738bef3b779bfc4b39b1095","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.0.0-alpha.2","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-wPJpWK1TVWc5tDGB/gjUlcK8x418LlGgHByJIcQ/LMKn79vFP0uMmwBkkL7LWY8Z+IRE7ofKSf1JHTMzzZl+Cg==","shasum":"194052f72dfbfa7ef9f641b9b3a5f53d16baf87a","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.0.0-alpha.2.tgz","fileCount":102,"unpackedSize":253318,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfqDvaCRA9TVsSAnZWagAADV4P/3zTeg9o7h4/yRlv/7wR\nz0m81u0GGngjY5Q8gguZFDQobEYnaxPOvt74HWkGfMUS4tHtYIwUPxnUzvZL\nsnOA49nMHM+LKSMtXSPsuPd5xPanBBsR+g+JuvT0inaQdqpu6jNMyzF1pVbK\nAOdHbXK+u1PPAUfMSfzcO2/QI7DTEElYTMvUhu+pgmMNn3WfiHtH95OVoQpU\nRFMSNjv1TYrjKRmMWcuIAJ5O2/Pb5/iT8HLdBGltOqHp27u4OgLIdMn18Zt6\nO0QGg5MX4mIr9YREYRruyx4IcS79AVjybuPRigy7qyyai1J6yS1Gn6HjpIRi\nxir/T8wmNRpCU+CLTy1wyUeIG3vLazR0E0GfUoHtHJuQt4dG6mbi3TcfpFjA\nXwHmt3ZW0vXILXa4I0d/z6Qc0pJMcrF364XZG6jY0/saGASwB3HadL+lnZOJ\nvjEYKOF0TGBJ/ry7CnUUTZw40yQDW1oyvuAXmajEHlICKhVvkhHU8kUkbXF5\naZGFpkBGMEk6nvauCyaZt9YX1qrL0Pkf0SrxZWTcAlIqLbNJnB6GmdEDaqav\n92bhJCzxP00Q+lD1CobU0D3YJsns4NzIZstiby6PU6CWaGFHLg9okxNfTWSn\nDjE0c7gJGwAJ/3rxlbor/qKg6RzhMXzjoXvC6u0xIQLmszONqXb6NX/DnoY5\n6B21\r\n=yq66\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC1hVHU0usyGPWK55NnnhKWSd2TIZ/ZoiZvWG6zK+mNVAiAsS0brAS+aqQdEbVURFz5TXB2cuSlvV+NCj9gRl7pNTw=="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.0.0-alpha.2_1604860890205_0.8359925181067391"},"_hasShrinkwrap":false},"3.0.0-alpha.3":{"name":"args-command-router","version":"3.0.0-alpha.3","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router@next\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add .\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/:filename')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method on the Application instance specifies, what routine (callback) should be called for each series of commands and switches.\n\nIt receives a series of names separated by `/` and series of optional switches at the end of the path each inside `[]`.\n\n```js\napp.route('/cmd1/:cmd2[switch1=123][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP cmd1 hi --switch1 123 -s\n$ APP cmd1 hello -s --switch1 123\n$ APP cmd1 'hey all' -s --switch1 123\n```\n\nEach `cmd1`, `:cmd2` and `[switch1=123][s]` are called **PathItem**.\n\n- `cmd1` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:cmd2` is a **Dynamic PathItem**, and it can be matched to any value in its place.\n\n- `[switch1=123][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--switch1` with the exact value of _123_. If you have special characters in the value, you can put that value in single or double quotes.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/call/my/callback').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic pathItem names and values that are passed to your application.\n- **shortSwitches** is an object of short switch names and array of values that are passed to your application.\n- **longSwitches** is an object of long switch names and array of values that are passed to your application.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `verifySwitches`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequired('k', 'key', 'Api key', ['key'])\n  .commonOptional('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  verifySwitches: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `verifySwitches`: Verify if the passed switches are matched with switches defined on the found pathItem.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `verifySwitches` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when user pass `-h`.\n","readmeFilename":"README.md","gitHead":"12ec4a48df107f9809193e4e78a819ef9257e903","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.0.0-alpha.3","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-opDxjJRYF94W43Uw/tfgRBl1d+7BFL6zsCHijgSL1ERxkm5utwhhb3S5NbdXysjpL9zt1LmJeIwSWVvtEZb/yA==","shasum":"153251ff06f70a11dda04f2fe5ac859a3b4b3876","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.0.0-alpha.3.tgz","fileCount":102,"unpackedSize":245429,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfsaF4CRA9TVsSAnZWagAAO60QAIvfN860qO6ygEEvrlND\nXHD+gBk4uragtrmaxFkeRRb0LUPTTrrHBBvjarzTVpNd9xH5RELx2SCRQjSA\nszg83kaj3+iWiJhcHevxNkhJP2CEdx/p4mhMCN1hNm8aLkwcZrVizMn49gFw\nEMfYmZolitPANsXhgJVaB8HFKNZfYJzh2e/z/g6kAic5wVR0Ct2B3C7K1OFl\nKsPdGgcNpWT88An0biLaDaphiXKvFaPePs7s5C2yk+OFbMOHwJo7Wtsou7oz\nvOzvWwlyAV4dDkULFoI+qfzYwCKv3K3CDU9V6vFb2WjKX0UvRp3fRp9NSTsD\ny2Vpts7yVhutfd6inYNqKkTOeWiPLVkiZjNvcEDG/nH44GS4QL1fdyW5XIty\nmQHICDRJ43MpDcP5UPXVZsDqOPrYntpCsuYJhsn6vLn8YpPP/RrljlvTrL+n\nNYrnY4Sp8TdAP88nSzVcvXXgr2iSg0DTh+uuOJiecUta9/hV1D/xYBkFptvS\nNmD16L+NkYnPG9V6pZuDLcZ63+DnyDcmQKoW8RkprAIENe/smtxGrS8/Ab2V\ncBFiTQFJhf41EvgeaIciu9Lw2vf7sl2arZiM20bpMp5/62MPq+51XBuuTQB8\nj0u9AhqvF3wbbPb6gkjPWmx3sdcXyg+ki33n30CAkjMotctBbwO7k5ZP5+yo\nvvtm\r\n=/Rk8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC3Qu/HqJLDfHebh3y2hFAUcJj+QII6aXpzS7B9QiqCDgIgNigyPBjcMIxI4YXMKcHsAysC0HoGYsG7tPG5jkWBoFg="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.0.0-alpha.3_1605476727958_0.6335122093930556"},"_hasShrinkwrap":false},"3.1.0-alpha.0":{"name":"args-command-router","version":"3.1.0-alpha.0","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router@next\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add .\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/:filename')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method on the Application instance specifies, what routine (callback) should be called for each series of commands and switches.\n\nIt receives a series of names separated by `/` and series of optional switches at the end of the path each inside `[]`.\n\n```js\napp.route('/cmd1/:cmd2[switch1=123][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP cmd1 hi --switch1 123 -s\n$ APP cmd1 hello -s --switch1 123\n$ APP cmd1 'hey all' -s --switch1 123\n```\n\nEach `cmd1`, `:cmd2` and `[switch1=123][s]` are called **PathItem**.\n\n- `cmd1` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:cmd2` is a **Dynamic PathItem**, and it can be matched to any value in its place.\n\n- `[switch1=123][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--switch1` with the exact value of _123_. If you have special characters in the value, you can put that value in single or double quotes.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/call/my/callback').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic pathItem names and values that are passed to your application.\n- **shortSwitches** is an object of short switch names and array of values that are passed to your application.\n- **longSwitches** is an object of long switch names and array of values that are passed to your application.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `verifySwitches`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequired('k', 'key', 'Api key', ['key'])\n  .commonOptional('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  verifySwitches: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `verifySwitches`: Verify if the passed switches are matched with switches defined on the found pathItem.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `verifySwitches` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when user pass `-h`.\n","readmeFilename":"README.md","gitHead":"ed7421665c4707f1fc48c7bbdb2f7d530387a022","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.1.0-alpha.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-+iv1+2WSdARFTh3hHe3oZdPc5wu5C3oQ85eW4BHleyDHdLrIGJFUsiGLpRxU7mGPOZC3CgqtRc/sQYPKPQeDiQ==","shasum":"a9ba2e773b68dd4b40100acdb26277b5b9f3e720","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.1.0-alpha.0.tgz","fileCount":105,"unpackedSize":264247,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgTHv1CRA9TVsSAnZWagAA4i4P/0A4jcoy9ZsgKzrrNbRy\nC+D/zTOssaYHpA1jRwzECtmrjUwhXv9Xof9GRSl95F26N1iygG6mADCl2Dte\nbQX0ef5c4xL27qvSDInq/5Xsb0HGvXG1EB7YyRpDw4OGHD3Rly3wTYWVNLYk\naIq7RFXkRtyfmekJ52vRg83022RsVPkBkyLs2wpYvyfdvF6mlR9r/YRcdseE\ndV0HBV0tkwoETwAQm4J+UHa9aVTcZRoVwYYb6s2T98U1iXJroTrISOAW61MS\n2yaJx3MwmZFFPhVxZaciatmAwztdF4WXvr8olAw4wj9nbs+mDvG3+WvAcBnW\nbum7QpCPWThE5R61QDn224WWPodbpcDbVSMkRXQKPH1seZbevytHBLQ2/ISF\nkUrYqwjlWju1znvdYswW6NmhJ50ilnbhwoTdUQjth0knqLE5uBdr5vviRvo6\nqDhBrLmiRKNJAccWhgmL7t4nXwK71j/W6pjM6e4eKGedY/pLol3LGD6QJPeG\nOuxZeHvzv1lvk366ZbW/4b+hymGjbeVVyTSDIva36XPG/Jo9uVDfgybjn9XB\npCri2ueusuY+fdZKhC+mBLwLP6+1aCd7vFr6GL1jHnXptnv09oASpXGaRoEk\n3mXDeMnjtt8/hkhGAnJu5+zHeA6e6Exb5z/4ijvPIketRxeW29YxwYuU7XHI\nRSwA\r\n=2d1w\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE9QjR9KfviM/mpSJfo3lrka4N3391xOwTeIJrtt1qphAiB+FIAtidycz/V099E4EVKmpW4+MrXU4a99x3bgZokPUQ=="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.1.0-alpha.0_1615625204830_0.3188594270358154"},"_hasShrinkwrap":false},"3.1.0-alpha.4":{"name":"args-command-router","version":"3.1.0-alpha.4","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router@next\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add .\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/:filename')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method on the Application instance specifies, what routine (callback) should be called for each series of commands and switches.\n\nIt receives a series of names separated by `/` and series of optional switches at the end of the path each inside `[]`.\n\n```js\napp.route('/cmd1/:cmd2[switch1=123][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP cmd1 hi --switch1 123 -s\n$ APP cmd1 hello -s --switch1 123\n$ APP cmd1 'hey all' -s --switch1 123\n```\n\nEach `cmd1`, `:cmd2` and `[switch1=123][s]` are called **PathItem**.\n\n- `cmd1` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:cmd2` is a **Dynamic PathItem**, and it can be matched to any value in its place.\n\n- `[switch1=123][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--switch1` with the exact value of _123_. If you have special characters in the value, you can put that value in single or double quotes.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/call/my/callback').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic pathItem names and values that are passed to your application.\n- **shortSwitches** is an object of short switch names and array of values that are passed to your application.\n- **longSwitches** is an object of long switch names and array of values that are passed to your application.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `verifySwitches`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequired('k', 'key', 'Api key', ['key'])\n  .commonOptional('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  verifySwitches: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `verifySwitches`: Verify if the passed switches are matched with switches defined on the found pathItem.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `verifySwitches` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when user pass `-h`.\n","readmeFilename":"README.md","gitHead":"7dbbe03d03da07474eb8762112ec1cf8f1f81e1a","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.1.0-alpha.4","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-TfF/8Lke6Q5RMKbsixCPFyBo9Lg6SbPAjJwba2IZZD/otPhWbSToUevKPsy2gje03s/sudWNxBRtJDXsTyGa0A==","shasum":"6b542665111c75a9c09c72c280f7594477c0e552","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.1.0-alpha.4.tgz","fileCount":105,"unpackedSize":264247,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgTIB1CRA9TVsSAnZWagAAfzQQAIQX6AkPyMtO+bQWuXUT\n/kZT+j+lP3ZYwo1oIOn5csNMME6vVw7gaUp8WJI1fczOFNeITDtgXY8qese2\nj67gRSMLnCRphvlPpNMUXtH5Xp0Xhk4Y6YtuzEy22zs9J0yJS3imv0HfsGit\nx9xcKQ4/tlold2LPyq8ONCqT4OCe4h4E0JGPDtf33r/bY83gVc6hrbqwzeHj\nkz+vSenx9eLqILZdPks7jdPbwQWQSyBRv0GxzvZTxCOl6SlLvLGNPP95sT0f\n7TzL4WFSnnLqUeveTWR2ffmg6ek8sAWd0SEjL25/AhuaRoWo9ACEaxN/cuwy\nRsCsWx43mhZq1iq5Lf+OlK6xO5Kb6oSM6cl7ap0V6uJHG9MamxDntx5ZJLEP\nncEs4fKJAkn2muJAS5IEKGTbXBFWk1sl/JS+/4LqRbvxpXS7BYEfqUG2NzpK\n4TeWSw20KC3zXCgLZt7QOrbFQY9/YkRUc/I3fb48enPWkeD4qk96rG/DKSmC\n8sH4ob6h1Mc2bVczYS7d5WSGGpWhjWpjDo04E7WtLmQneiyQehZJH5/nfvEm\n5Tr7l5mI+Tl/PTbmhVkxFmnjYJQHLlr0jzBhyy9JtHosstSvTNJYMkZ51+D/\naO9jCbqSlFqjnhmzvDFBsB1A5BTWbhcWpi1YjwpHyS0NSocvna3AmbRxH3oY\nlWAZ\r\n=jBQr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAj829GvY2KYjxPXvOhtkbQ9d++IynuYUPUVrD/GPL18AiAXv7z8GJug2UOuCk5rHgr5w16cKtuw/jZ/2byx+02Qig=="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.1.0-alpha.4_1615626357397_0.8742458861898355"},"_hasShrinkwrap":false},"3.1.0-alpha.5":{"name":"args-command-router","version":"3.1.0-alpha.5","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router@next\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add ./files1 ./file2\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/...files')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method maps patterns to callbacks. It receives a series of names separated by `/` and series of optional switch patterns at the end of the path each inside `[]`.\n\n```js\napp.route('/say/:greet/...names[age=21][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP say hi john --age 21 -s\n$ APP say hey john marry -s --age 123\n$ APP say hello 'everyone here' -s --age 123\n```\n\nThe `say`, `:greet`, `...names` and `[age=21][s]` are called **PathItem**.\n\n- `say` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:greet` is a **Dynamic PathItem**, and it matches to any value in its place.\n\n- `...names` is a **Spread PathItem**, and it matches to one to any number of values in its place.\n\n- `[age=21][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--age` with the exact value of _21_.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/say/:greet/...names[age=21][s]').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic and spread pathItem names and values passed for those.\n- **shortSwitches** is an object of short switch names with values passed to those switches.\n- **longSwitches** is an object of long switch names with values passed to those switches.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\nConsidering our example for `route('/say/:greet/...names[age=21][s]')` and execution `$APP say hey john marry -s --age 21` the `inputs` parameter will be:\n\n```js\n{\n  commands: [ 'say', 'hey', 'john', 'marry' ],\n  pathParams: { greet: 'hey', names: [ 'john', 'marry' ] },\n  shortSwitches: { s: [] },\n  longSwitches: { age: [ '21' ] },\n  switches: { s: [], age: [ '21' ] },\n  context: {}\n}\n```\n\nRemember if you mention switches in your route patterns, you need to define them as `requiredSwitch` on your routes otherwise they won't get matched.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `strictSwitchMatching`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequiredSwitch('k', 'key', 'Api key', ['key'])\n  .commonOptionalSwitch('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Context\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties. Those will be available in the following hooks and callbacks in the context object.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  strictSwitchMatching: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `strictSwitchMatching`: Verify if the passed switches are matched with switches defined on the found pathItem. If it's set to false, the requiredSwitches won't be enforced, and switched that are not defined are accepted.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `strictSwitchMatching` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when user pass `-h`.\n","readmeFilename":"README.md","gitHead":"112968b156cf6d2ffdfd380c482753d248950aec","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.1.0-alpha.5","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-rzJI40nCf9B7j73z6JnMqEkkOFQV9B0qTtPp1c61ddzZa5V8QcANujuX+BUOLRoggCdsELjukQGHkBkvbOKvMQ==","shasum":"fbaf8a0eca71fadcdcd1eba1b7e6f8050448892d","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.1.0-alpha.5.tgz","fileCount":57,"unpackedSize":188216,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgTco8CRA9TVsSAnZWagAAKqwP/01TAMc53+XePVGYcVo6\nnbVZIjGlyPA4ceXSEWtjcFT7iM8f0czyfOa9U4BfujJVgZ7cy/WonE+sXaJl\nlJYHszBtHjKmnE8KYrJYZsCoIXeCrcOuUOaQQH5NYn5WV14sXBoC9LImJ3MK\nzUP85UYZOgChnotTIgXOaRWoHC0MFSK5J4eca2rvVoDPOsTab9UJchSWAzhu\nqTEOmz4TmAORBhs0gTFq8ZD+RT8YJGuy02caSYym5rvJY23Ae4dS60G3xRoi\nMtHtUIDWBcI4NiG7rkOLZD0+gPR11usbYLKz8oAzQu6HN/AWausXaa043Ira\n20HCGfXPxywEp6h2XVClff5WtsARro4uAXlYABKZ0kr31tva6ir7sr/zuY2R\n50rkbGZ4Cm8/5V4B/KQMaDpmQvJI6R+FPOBdID/SEyfX66e/4S6bvZWicum6\nnDSG7yBtnzur9fW//AR10nJ4jLdNA0aw8SqQ42b6D9Py2hx4+BC7ek0UqXHp\n0KRAIGzXfe8HV/04vPIPH8DRlupwtiiQTtZhiFzCKn6EKzvcV6wUt9BnXncd\nU8OO8kFO/7D5Tr6ueUUfUEBTsvg1NlT8wUtdoWRwa8S2DhaMrKoPKStAOjf4\n6FoUmO8Mqttql8RBBDoRzziLRkyofjsOggNo5HmiR1DNJ6jqR/Gum6zA0qsQ\nBLLr\r\n=8fu0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+eCyhecSBnrOUPTKkVesWfx6y6eJ+HMXiXMa60d2fWwIhAIOc1Gf/ZkN7ziddqV7yyC4cYEIcnVlf/X9QPInm/fxt"}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.1.0-alpha.5_1615710779597_0.9310405584169907"},"_hasShrinkwrap":false},"3.2.0-alpha.6":{"name":"args-command-router","version":"3.2.0-alpha.6","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router@next\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add ./files1 ./file2\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/...files')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method maps patterns to callbacks. It receives a series of names separated by `/` and series of optional switch patterns at the end of the path each inside `[]`.\n\n```js\napp.route('/say/:greet/...names[age=21][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP say hi john --age 21 -s\n$ APP say hey john marry -s --age 123\n$ APP say hello 'everyone here' -s --age 123\n```\n\nThe `say`, `:greet`, `...names` and `[age=21][s]` are called **PathItem**.\n\n- `say` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:greet` is a **Dynamic PathItem**, and it matches to any value in its place.\n\n- `...names` is a **Spread PathItem**, and it matches to one to any number of values in its place.\n\n- `[age=21][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--age` with the exact value of _21_.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/say/:greet/...names[age=21][s]').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic and spread pathItem names and values passed for those.\n- **shortSwitches** is an object of short switch names with values passed to those switches.\n- **longSwitches** is an object of long switch names with values passed to those switches.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\nConsidering our example for `route('/say/:greet/...names[age=21][s]')` and execution `$APP say hey john marry -s --age 21` the `inputs` parameter will be:\n\n```js\n{\n  commands: [ 'say', 'hey', 'john', 'marry' ],\n  pathParams: { greet: 'hey', names: [ 'john', 'marry' ] },\n  shortSwitches: { s: [] },\n  longSwitches: { age: [ '21' ] },\n  switches: { s: [], age: [ '21' ] },\n  context: {}\n}\n```\n\nRemember if you mention switches in your route patterns, you need to define them as `requiredSwitch` on your routes otherwise they won't get matched.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `strictSwitchMatching`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequiredSwitch('k', 'key', 'Api key', ['key'])\n  .commonOptionalSwitch('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Context\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties. Those will be available in the following hooks and callbacks in the context object.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  checkForSwitchConflicts: true,\n  strictSwitchMatching: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `checkForSwitchConflicts`: Verify Switch names are not conflicting in your Application. You can disable this after you're done with your application development to improve performance.\n- `strictSwitchMatching`: Verify if the passed switches are matched with switches defined on the found pathItem. If it's set to false, the requiredSwitches won't be enforced, and switched that are not defined are accepted.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `strictSwitchMatching` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when user pass `-h`.\n","readmeFilename":"README.md","gitHead":"8125a28d108eeb1dedbd6bd9a335fa989300b085","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.2.0-alpha.6","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-Zo0N00sZIixgyWCDSRV4po5kuXVxUcK2mRl/4EAkKRsffpHUDW4ePjA9D4f9cA7aBxd59AYgfV5I5qk7fM8T2Q==","shasum":"deb7136ad400aaeb617dfb90c88578bdad2be969","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.2.0-alpha.6.tgz","fileCount":57,"unpackedSize":191805,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgWt6ECRA9TVsSAnZWagAA/7wQAItaXbxSqDroBxkUgb+f\nJVyhW3es+g5u0K8UoEFmvsjvoNvhDb/uyiWMEYrXeSA7dVRNTEsP7Or7r+Kk\nki57f+q9OO49dDMRCYFRy7P/Gik2H/EBNLobYSATtDtO4cdiVSTr7gsdyPma\nijoF8MPylkPXPQVcat6Pmp/80qtLegObZX+1VGZCnwlsThjGlYN936mooc5k\nGLlczOMYpNvzcgmOG0Rdi4k1T6ge/ViztMI6LPNWnRcy8mkFVcqr194XOCXj\n6OXvMqQhWar34icjnvIlJJMTEA6Te2r9NbaYQCAmNBeNZDtEQJDcmqlNBV7n\nTiW0SRymsvkhkEKgM8JHga5YurAv3UC8+umS4OSBpUx6Qq3grPak86E9Ur28\n4nTU+kW4BgCzj8fY8PkdBX0qNcBwdYmbDLyRxVmvpR9b7ex0wESjLJvcMVyu\nsvrgghG5W/2aaDiqviy8vJ3HO03BKSIPwvGiwK+xQRTad0gd3gqrfwCqLp9O\nkq/Jx1LQtgK9n3dC30Y1hfYyKNJnEoO/ZGW5N+vkm96EpI1hOBLW9/+Mk8dB\nmD4Y41bE1EerRjg7zVH4EKtAx6oW3K8LURvhJFytTjgl4XxZN/X04NFCoSlL\nUl1CbicEdgvjYaho9d5wCBubAd/bKdZFFpwPSSVsWTkw+1dNfY++fe99VkPi\nobJl\r\n=OpTF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGYko2ii8CwXhinuduOY+qvOIOiLjESU2ELbkk8o7JoyAiEA3UoeKJKHO4jeaNJsifMwZ5axhGLbdLhj1WV+G8v+zHM="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.2.0-alpha.6_1616567940369_0.43462723102817735"},"_hasShrinkwrap":false},"3.3.0-alpha.8":{"name":"args-command-router","version":"3.3.0-alpha.8","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router@next\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add ./files1 ./file2\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/...files')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method maps patterns to callbacks. It receives a series of names separated by `/` and series of optional switch patterns at the end of the path each inside `[]`.\n\n```js\napp.route('/say/:greet/...names[age=21][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP say hi john --age 21 -s\n$ APP say hey john marry -s --age 123\n$ APP say hello 'everyone here' -s --age 123\n```\n\nThe `say`, `:greet`, `...names` and `[age=21][s]` are called **PathItem**.\n\n- `say` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:greet` is a **Dynamic PathItem**, and it matches to any value in its place.\n\n- `...names` is a **Spread PathItem**, and it matches to one to any number of values in its place.\n\n- `[age=21][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--age` with the exact value of _21_.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/say/:greet/...names[age=21][s]').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic and spread pathItem names and values passed for those.\n- **shortSwitches** is an object of short switch names with values passed to those switches.\n- **longSwitches** is an object of long switch names with values passed to those switches.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\nConsidering our example for `route('/say/:greet/...names[age=21][s]')` and execution `$APP say hey john marry -s --age 21` the `inputs` parameter will be:\n\n```js\n{\n  commands: [ 'say', 'hey', 'john', 'marry' ],\n  pathParams: { greet: 'hey', names: [ 'john', 'marry' ] },\n  shortSwitches: { s: [] },\n  longSwitches: { age: [ '21' ] },\n  switches: { s: [], age: [ '21' ] },\n  context: {}\n}\n```\n\nRemember if you mention switches in your route patterns, you need to define them as `requiredSwitch` on your routes otherwise they won't get matched.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `strictSwitchMatching`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequiredSwitch('k', 'key', 'Api key', ['key'])\n  .commonOptionalSwitch('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Aliases\n\nStatic pathItems along with their name can also have aliases.\n\n```js\napp\n  .route('/say')\n  .alias('shout')\n  .alias('whisper')\n```\n\nNow calling the route `/say/:greet` can be done using any lines below:\n\n```bash\n$ App say 'my name'\n$ App shout 'my name'\n$ App whisper 'my name'\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Context\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties. Those will be available in the following hooks and callbacks in the context object.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  checkForSwitchConflicts: true,\n  strictSwitchMatching: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `checkForSwitchConflicts`: Verify Switch names are not conflicting in your Application. You can disable this after you're done with your application development to improve performance.\n- `strictSwitchMatching`: Verify if the passed switches are matched with switches defined on the found pathItem. If it's set to false, the requiredSwitches won't be enforced, and switched that are not defined are accepted.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `strictSwitchMatching` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when user pass `-h`.\n","readmeFilename":"README.md","gitHead":"8b993038b04c8c4d0e298a909c14cfc377e0291e","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.3.0-alpha.8","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-Y7L6W+WsUQG33uFZ270bJcApyneYHyEZydrbyfRH4ikDlhCeVsrT4bpD8n1k1sKVTQnzI424Y4zTmYafsAXyBg==","shasum":"c11ffd47bdb32b573f888223b554166b63936824","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.3.0-alpha.8.tgz","fileCount":57,"unpackedSize":189380,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgX9MgCRA9TVsSAnZWagAAx1QQAJIrbY70VKwhBKmj3Sox\n0L3vGczVBUXLijsMFE6H5FL0vMYVCsuRAtskbKbTt3lHQXN14A5VFMQvGXiM\nP+0U7kLfE29TlwwI9ogno/Bb/8RJyIbI0C78xNFw1IhlzSNWZq8zjhLnsRaG\nXGk0qJAm957ygTw6tw6pn+E1ATc0ZqMWtFefC4JkcBMawaruIm2rjRzcV6Rz\nNQn3+DrUhEezuuos+n/eil9Ix3KOeebpHx7EQN/P9MY3mfdhLkUPlYkJDf8S\nyr9aO+3T5mt97eWi17k9DyGysz4zbh4aUH5vXyxXdf56jujzxgk6YMTYZC8N\nWhZQCgOYY6H1WtJKBnkUgBeZaGl72FqXAfkRURI6ReSUJEFsJu7GWcdYKUT/\nk2czvajIp6d0p8B7FywRTbG0xoC6RBupHgcphBI7mKZpxkp1ZJtYso3QMhWp\nVs/ahCgPE8n6SLJ72MWk8fgiEV+/FS/9ehTikOXPzV21fU5Dp7hSdud/xpK+\nbCMDVAxw7ws9451F1p3rIqmbCnbpqnEp+xWNfcM2rv9n6b7DW7LZCxgc+9yK\n1xiCz7fHzQrtfK7sPlchU/mD/KhMuV7Xfd84iWVJJY3vl1Lo7ILpDa+G64tK\nPziTkZfdy7hxouDKm29ZK5rcHV4axqriOO+FpVacNXdesssLagE6NhTrMyNi\npv+d\r\n=M/EV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD1MbslpkAl+Ig0tWQI7g5EdxYCtW1UvDxiFJT1kceDdQIhAOzLvfEsZqrPKN+JAQGvYllcLQPaGYA2A3gIgTRDzTwG"}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.3.0-alpha.8_1616892704019_0.29319771046874865"},"_hasShrinkwrap":false},"3.3.1-alpha.10":{"name":"args-command-router","version":"3.3.1-alpha.10","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```bash\nnpm install --save args-command-router@next\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add ./files1 ./file2\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/...files')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n## Routes\n\nThe `route()` method maps patterns to callbacks. It receives a series of names separated by `/` and series of optional switch patterns at the end of the path each inside `[]`.\n\n```js\napp.route('/say/:greet/...names[age=21][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP say hi john --age 21 -s\n$ APP say hey john marry -s --age 123\n$ APP say hello 'everyone here' -s --age 123\n```\n\nThe `say`, `:greet`, `...names` and `[age=21][s]` are called **PathItem**.\n\n- `say` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:greet` is a **Dynamic PathItem**, and it matches to any value in its place.\n\n- `...names` is a **Spread PathItem**, and it matches to one to any number of values in its place.\n\n- `[age=21][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--age` with the exact value of _21_.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/say/:greet/...names[age=21][s]').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic and spread pathItem names and values passed for those.\n- **shortSwitches** is an object of short switch names with values passed to those switches.\n- **longSwitches** is an object of long switch names with values passed to those switches.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\nConsidering our example for `route('/say/:greet/...names[age=21][s]')` and execution `$APP say hey john marry -s --age 21` the `inputs` parameter will be:\n\n```js\n{\n  commands: [ 'say', 'hey', 'john', 'marry' ],\n  pathParams: { greet: 'hey', names: [ 'john', 'marry' ] },\n  shortSwitches: { s: [] },\n  longSwitches: { age: [ '21' ] },\n  switches: { s: [], age: [ '21' ] },\n  context: {}\n}\n```\n\nRemember if you mention switches in your route patterns, you need to define them as `requiredSwitch` on your routes otherwise they won't get matched.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `strictSwitchMatching`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequiredSwitch('k', 'key', 'Api key', ['key'])\n  .commonOptionalSwitch('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\n## Aliases\n\nStatic pathItems along with their name can also have aliases.\n\n```js\napp\n  .route('/say')\n  .alias('shout')\n  .alias('whisper')\n```\n\nNow calling the route `/say/:greet` can be done using any lines below:\n\n```bash\n$ App say 'my name'\n$ App shout 'my name'\n$ App whisper 'my name'\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Context\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties. Those will be available in the following hooks and callbacks in the context object.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\n## Help\n\nArgs Command Router generates help (usage) output out of the box for you. By including `-h` or `--help` the help (usage) will be display on the console.\n\nHelp switches are configurable when instantiating the Application.\n\nIn case you want to disable default help set the configuration option `helpType` to `null`.\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  checkForSwitchConflicts: true,\n  strictSwitchMatching: true,\n  helpType: 'switch',\n  helpShortSwitch: 'h',\n  helpLongSwitch: 'help',\n  helpOnNoTarget: true,\n  helpOnNoCallback: true,\n  helpOnVerifySwitchFailure: true,\n  helpOnAskedForHelp: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `checkForSwitchConflicts`: Verify Switch names are not conflicting in your Application. You can disable this after you're done with your application development to improve performance.\n- `strictSwitchMatching`: Verify if the passed switches are matched with switches defined on the found pathItem. If it's set to false, the requiredSwitches won't be enforced, and switched that are not defined are accepted.\n- `helpType`: If you want to disable the help functionality, set this to `null`.\n- `helpShortSwitch`: The short switch name for showing help (usage) output.\n- `helpLongSwitch`: The long switch name for showing help (usage) output.\n- `helpOnNoTarget`: Show help when no PathItem found for the passed commands.\n- `helpOnNoCallback`: Show help when PathItem is found but no callbacks are defined on that pathItem.\n- `helpOnVerifySwitchFailure`: Show help if the `strictSwitchMatching` config is set to true but switches for that pathItem not matched.\n- `helpOnAskedForHelp`: Show help when user deliberatly asks for help. e.g. when user pass `-h`.\n","readmeFilename":"README.md","gitHead":"1c98c006e78a2977f799a1f32ee8ee32087b65d2","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.3.1-alpha.10","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-42FpkjTdqHddKatLEGvRG8Lp4Gd5UGXcmbOjPdlHYTZgK4HswddhxlXl8ngCBm1LCqhEDBHYsiLzmm6fuDn4JQ==","shasum":"bd9c8bfe411caffd07d2c5f8d019300cedaf953b","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.3.1-alpha.10.tgz","fileCount":57,"unpackedSize":189393,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgYAcRCRA9TVsSAnZWagAA8ZkP/1CZZ4W3JlQJx/MGHdwF\nJcMsIqWQMm80grktyoV1T3hGIOyBCH3+NMbvK68UOKX1qg+JA8ZJtZnUzCIE\nDYs31vAoaWDbZr2fp3zxC/sL0R+1sj2lYyAbgUpZZ2HFOilrXI4KFWlqMQI0\nk2bNMX9DAj5cWUw7CDOTMhzmghE7zxSF58GhO4pN+08DOTtTTL1lmBzDkl1A\ndgbKBiS75zNBWQYuKP7syrPXQ4XjGxqXjk3xufgzmmH36GansvVscB4gH//d\nSczbywWxIg1Cy/B7kX8nhSnlAX0t1JiYkXE95hq5OqPG83g5QXPJ6cyzh0+J\nxAY7KKlrHpFlVfG4GFhHaVlpjsvgpo0T896mpmEtlAO981GWgq8c7Cf/EKa9\nsO4k2FOzeizQweQhrbe5ncht9ikNN65tYp589xp5AdMnP4LtFnSBZuwkeLQ6\nrZdLG2roExp3SbkGbD6n9mlCU5zcS6wXY6mLADR3FXpXNDfOBH6Ae094eQbq\nfft8RaSIIkodZ/WWK2EEfm8/uiTvRx3jY083D+MB309/q1bjl4xhCSRmkEEr\nD6qwLsUdJASJeiGnW0Yiuugn8CLkzcoJorWw1s3q5pbvf61xJ8fzzAkI9EOI\n/Q+XLPiXSgDXYWlblq2bJF7f+PxSObVrY8VPicEE+L+Wd1LYGOlFAGLMe8v+\nj5ov\r\n=Y+hE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGexq/lh3pcwSuVtN0rXjdRfzVU6Qm67bsyOXd/PPhrkAiAE8O4mwxNPYg6TrJqZc8t5Ggr1LYejjVGCiojwYDHQRA=="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.3.1-alpha.10_1616906001158_0.7401261043056664"},"_hasShrinkwrap":false},"3.4.0":{"name":"args-command-router","version":"3.4.0","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"gitHead":"2c6347d3fc440d820de8bf10578fa25a6a130623","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.4.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-D1xsrNLU///lT1ubac2QE0QEnuHLo66qm+c3HsJDswcaZjyCfwkNEl7+pZ3HLo5SgTme8H5AO+18fziKYsloOw==","shasum":"5f38859b7ae750377d392e6b7efa833df067a58a","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.4.0.tgz","fileCount":58,"unpackedSize":203370,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgYX2PCRA9TVsSAnZWagAAR4MP/0ZN6GDxknt4nwnOjCoL\nhis07W+IXj+AiEHu+fo7X2bX5MIq+dgYUVe1E8tNLDH3udmNXhPH/qbq2pP8\n2F+qc8i/aY0M2IVJeEBOO+OJFrxVT/GG+0ND9FIZo4XP1lxiRaxY9uR4MD5a\nwXbVfqq1wi+rv/Ilz1I4roBNjvxf+jvrlz1WoHfSXBKa85HblL6BVvBDdiR0\nS+MEt4mgztU7oV1HBUA5XIXkwaU0+p3zaumfb05MBhW2/uenIwJwY0V7Ioth\nuKiR96tRJrzEP0uz4A9SA3H4DGTktsiHOSjNjbgeJihN3hEVbE/vpUfygQle\n1osGwk+SMi8atnKfd990H1xjoSGWmluEMmd+RF1NacfR2rzzFzOef2jS226u\naQvF0+tCNXjDssAKlgS812P0Uj0DJntRlqADKZf37zPU7EF9dD5oCnZNi5bL\nphrPa+eEyNsaVlkAwbWouEpT4pHTOET/36h5UmccnV5ZUqBhKQS7z8rDP4X+\nB3/YHXKBHQJr3XZ0d/v7hPLXFSJL3nSPYQJc6Zmp2CnoPbVx9acu4SVQZtVK\no+Fxx1bI5iPV8tdDFuWvJtOex33E+eGF5Pxjx/bdU0QuHQ3/CeUlnbWPNhhn\nSkbEZGB3+xvRb54SkiG0ORYlfK9wqdWfP9LAE/U4gyHOfCdC3bLvUQTRlzmV\nWbmp\r\n=iTX9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCjMA4OankinB796k9JG7x66siK36f8bjcPUSAekns24QIhAPAPi1jFDSPwoLguJphfyTEdJlKW/k+PRwF+ieNJ/Rtd"}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.4.0_1617001871144_0.5853194114036258"},"_hasShrinkwrap":false},"3.4.1":{"name":"args-command-router","version":"3.4.1","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"gitHead":"1102c9b22d39a6c70d06ec956deac6d8ec90aae3","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.4.1","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-GW3aSynpvqfd2y1zk2eQrHVjtRAK5XT/xCG7wZNgIZp3AwpPqyfuVr+WNkxwChJW4s6C9sGFfKInOdfL/C4F0A==","shasum":"fc6db7d28e8dc5aeed7db96a387bc7466cc68141","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.4.1.tgz","fileCount":58,"unpackedSize":203365,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgYX5TCRA9TVsSAnZWagAAILcP/AkJf8pWHVkaQ7fTQwl8\nnftJj6puhQ68V2ix90NQ5/Uvl4Eg/KqdYHJvMw4EXgxpVg46bU/twZk7HRKy\nzvv96NJak5ccZDTnJH9OMMjuZrDY4UbuTYEFmBcioBb3iyi/9MVshdb/3NU4\nT5A55Md+2dBPbOmop+ugS/IRWNlFce/UAE66pMyIDGL7zzyBGMBesoHB8mrc\nVc6K+zY1jimrY8fYgBWJpe5VNwIuc9lgTVHHPuV2eTvlQVLggKAPysQY95nX\nRcQWaMzg9cDDqGoetCPtviVQ+OWsvkCHMwHTjhRQDdj7K4vFwovU6X+GYDNd\nv4sWKZCsSg4i14BtI6mcsh1xYNlv9gWvucHQc1b+/ag0rq4RdVG5KIsKvrsv\nTRq0PaZYKol5rt4f4bgZyLzeeSNv0EGoZYBiXx7VllweZpKFVO+rH+zS83lO\nL8c1iZxmdTFtFHoGByM/7jCyjl4cuKtzYISGAzH4Rq5NbTsKPTWAVKBB7VF0\nwDbptFmgerORgrR4eV2VfApkTYjKa8eSDxh5TzejJaVYf7koUuk6CbRmF95u\nMTlHkefISzxQeQAoFPgIbwwOkwCqByVnXVsFpg016T2IEefAaxZW5uRMUe2Q\nHi4dEymUexncaKOAWH1qBmlwOUsbE5ONNHvfdkcL6Pi11wtbXxS3f+TqcjCE\nYvxh\r\n=ki7R\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDTMtuV/ydA++8aseZXZ4MwImEhzesj3Een1OSotmN/xAIgVphLnsdNOmduLjS2F+y+oc9f0+pAne7sBSo5pKQgX1Q="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.4.1_1617002066781_0.6475224632060592"},"_hasShrinkwrap":false},"3.6.0":{"name":"args-command-router","version":"3.6.0","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.11","command-line-usage":"^6.1.1"},"gitHead":"ed9b223a26f9d9c0d1925a76a92e174e0917fbc3","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.6.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-41XOnyYfjiwuTATS0Jvll6nZnJ7f36naadDfJwgkLCQnBYOJibbJaKNCNY37xJbODgJgZHa/p4o64w/jHSp6hA==","shasum":"6833c1cb5578fd2002d1edd10925a67166ff75d0","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.6.0.tgz","fileCount":68,"unpackedSize":217200,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgc+WgCRA9TVsSAnZWagAA5N8QAIfh6A9pHQ1RgUw3dUcY\nRpBkja50SX+aCtIUL/4r3miBzA0oYmGMpLiZW6Ld6R5L3BPtiLZEh56Fdd3M\nV62WKaZ4A4d3zuJZctFl8xS7XUlbY+UKJM7qoL3wmHMvNEc+EPPKgmJzkuEq\nV/64l5yu9lpJ9ygOMh8yt1KIfRfpCRzXJgHKruZgPcdpaRsFGBr2XQNR9bGr\nV332zBPVLdLt4RLVwX8a2YGDimsyQPxVEZZ0ea+KiLOzeJWmqO7I4gSH8Qau\nahU6vTDIHW3xKK0+uI2mJvC0leraRd/cu6c+kjmkDo4X1+sAskH0dpm+1Siz\nJaI5LlUb2pKItbGu8MliXhpPnW3u9eAGH0GLYRwDWqztPVzOSu715D9NHZ1y\npt7BRYKGvwejk485RSljoya+gxoUdAFYkQ3fg4Bgb+yKUaPPFivfLfcFFkYu\n1qhzLnAdnaq1rn9dW97QwOTy7bbkrP3m35F2NJ8io8lUw3DUMugVEDKhLKx9\nWgAQplv+1CX7IyRcZhVKftcvFge6UDKbOcXZBPWvzQVyx4iH2oGgYPb6LSb8\n43O9sZOvBxullrSeFhGGWfZsgTsbGpmxGn3wlUjiua6WmclwQDG3ULmmKvfW\nU/BftG1QHIdS00HZx2i0fAw1MuOVuP3YdAF18lgjWNawAgjluq7RWgc6uAMx\nJ33S\r\n=IWQz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC06KXI4wwVada20OjxF9WKvMIRfUPPlMJkAZUwDbJ/mgIhAOnanJmZY745iOsB+5lBEjUipjs4D0e8GUoqghWcShLA"}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.6.0_1618208160056_0.13477077112615365"},"_hasShrinkwrap":false},"3.6.2":{"name":"args-command-router","version":"3.6.2","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors test/*.test.ts test/**/*.test.ts","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.13","command-line-usage":"^6.1.1"},"gitHead":"3d9e9c0fd3a99cb1f9938479df8b6e48af934513","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@3.6.2","_nodeVersion":"14.4.0","_npmVersion":"7.11.2","dist":{"integrity":"sha512-KTR9pH3WWDEOTfkCBGWjL8uKTwZ3YtG+bX1AmgDKbvgYErv0NI6Cuehgjs0e/6aLoBfUkQ0KfTt2Vr2QsLMzEw==","shasum":"5b41e6e6cdb4333e754cb987601b412f8438a1fa","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-3.6.2.tgz","fileCount":68,"unpackedSize":217200,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg0ZUaCRA9TVsSAnZWagAA0kQP/075tLfH/0pjuYk1w4th\ngZRIGODOuaLIxx43DtRDRkZ8XEwPAFgaZsez06IVUMGgaEO33h+h14eTg8g+\n8qXhdSbeEtqMgsbqx7SBgcdyVt9mou/sJhw0Afk1u4lqJvgaFiYqtrYVjPNL\n3f9CI6cRhvMZjWJvFP+jqQ4xj60rrrgFoOY7g9+Zwp3YsfJJpGGJXjMQh9ht\n80Ionj1uX6CL9xws+tjG/mj2GJEg/xGiqrXQN0ddidkUZC9AnSikIVLhWMyZ\n1+PFYcuz5wDDRjH/43W5JbvUnzyJbjlOWBgRTPjHO8dRuWevHL5OURxvxZPn\nRT47u+9TXyw3+TfGkqbei4UQGbItflSBpu5IvQbo/o1iRcMv98W/xQSwl9Tq\nDpnRfX716FfHtKvXmt0IT/OrtUbl0Z8eUXs/ebiWTjJ3UhU5pZVJ1bF1JMml\nWQ5jWj3gUxx8Tg9ooQBjvSbCAz3P46a1jBTJq8R0ovzgobNr3qMtVbH0yif8\nalK4NUGlDeJhLNKQiX6RMpThPwZ1sQ/+xDEgDzzFtRcjEgeqq9BYxHLpws/j\nSv4D9avEoTZpKPwq/d50U4dRA4cJNwC2OThM9nldEkuA6wqaLoq7pJ6W8UVX\nXt1tFiMXiOrBI/Tj/fBzJwcFWm7SF71d5w8blbKOiBHJ9ofdBUzZFH1CgZXP\n2ln8\r\n=P6me\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEm4sLQz8C0LEkXSVxI+iog2ekHrNzVH5OrZP7P00HvKAiAvkRiUDoP7WLvyWerrL/56kJLSmRtYr9RSlbeVyJcB+g=="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_3.6.2_1624347929901_0.4757248077863865"},"_hasShrinkwrap":false},"4.0.1-beta":{"name":"args-command-router","version":"4.0.1-beta","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors \"test/**/*.test.ts\"","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.13","command-line-usage":"^6.1.1"},"readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```\nnpm install --save args-command-router\n```\n\n## Executing\n\n### JavaScript\n\n```bash\n$ node index.js\n```\n\n### Typescript\n\n```bash\n$ npx -p typescript tsc index.ts\n$ node index.js\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add ./files1 ./file2\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/...files')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .alias('b')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n> In **Typescript** and **JavaScript ES6**, import argsCommandRouter using code below instead of `require('args-command-router')`:\n>\n> ```js\n> import { argsCommandRouter } from 'args-command-router'\n> ```\n\n## Routes\n\nThe `route()` method maps patterns to callbacks. It receives a series of names separated by `/` and series of optional switch patterns at the end of the path each inside `[]`.\n\n```js\napp.route('/say/:greet/...names[age=21][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP say hi john --age 21 -s\n$ APP say hey john marry -s --age 21\n$ APP say hello 'everyone here' -s --age 21\n```\n\nThe `say`, `:greet`, `...names` and `[age=21][s]` are called **PathItem**.\n\n- `say` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:greet` is a **Dynamic PathItem**, and it matches to any value in its place.\n\n- `...names` is a **Spread PathItem**, and it matches to one to any number of values in its place.\n\n- `[age=21][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--age` with the exact value of _21_.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/say/:greet/...names[age=21][s]').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic and spread pathItem names and values passed for those.\n- **shortSwitches** is an object of short switch names with values passed to those switches.\n- **longSwitches** is an object of long switch names with values passed to those switches.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\nConsidering our example for `route('/say/:greet/...names[age=21][s]')` and execution `$APP say hey john marry -s --age 21` the `inputs` parameter will be:\n\n```js\n{\n  commands: [ 'say', 'hey', 'john', 'marry' ],\n  pathParams: { greet: 'hey', names: [ 'john', 'marry' ] },\n  shortSwitches: { s: [] },\n  longSwitches: { age: [ '21' ] },\n  switches: { s: [], age: [ '21' ] },\n  context: {}\n}\n```\n\nRemember if you mention switches in your route patterns, you need to define them as `requiredSwitch` on your routes otherwise they won't get matched.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `strictSwitchMatching`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\nThe `option` method can be used interchangably as an alias to `optionalSwitch` method.\n\n```js\napp\n  .route('/video/formats')\n  .option('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequiredSwitch('k', 'key', 'Api key', ['key'])\n  .commonOptionalSwitch('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\nThe `commonOption` method can be used interchangably as an alias to `commonOptionalSwitch` method.\n\n## Aliases\n\nStatic pathItems along with their name can also have aliases.\n\n```js\napp\n  .route('/say')\n  .alias('shout')\n  .alias('whisper')\n```\n\nNow calling the route `/say/:greet` can be done using any lines below:\n\n```bash\n$ App say 'my name'\n$ App shout 'my name'\n$ App whisper 'my name'\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Context\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties. Those will be available in the following hooks and callbacks in the context object.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\n## Hide Path\n\nIn order to prevent displying some paths in help and auto completion output, you can hide them.\n\n```js\napp.route('/_hideme').hide()\n```\n\nThis is can be useful to hide some functionality from users. You can still chain the hidden path with other route methods.\n\n## Plugin\n\nPlugins allow to add functionality from internal or external sources. Plugins are simply functions that receives the Application instance as their first argument.\n\n```js\nfunction myDebugPlugin(app) {\n  app.route('/_debug').callback(() => {\n    console.log('debug output.')\n  })\n}\n```\n\nIn order to use plugin in your application, you can pass the plugin function to `plugin` method.\n\n```js\napp.plugin(myDebugPlugin)\n```\n\nBe careful of plugins you import. If you don't know or trust a plugin, proceed with cautious.\n\n## Builtin Plugins\n\n### help plugin\n\nYou can use the builtin **help** plugin to add help outputs to your application.\n\n```js\nconst { argsCommandRouter, plugins } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'myApp',\n})\n\napp.plugin(plugins.help())\n```\n\nBy default **help** plugin uses `-h` and `--help` switches for displaying help, but this is configurable through **help** options.\n\nThese are the options and their default values that can be configured on the **help** plugin:\n\n```js\napp.plugin(\n  plugins.help({\n    helpType: 'switch', //set null to disable\n    helpShortSwitch: 'h', //short switch to show help\n    helpLongSwitch: 'help', //long switch to show help\n    helpOnNoTarget: true, //show help when no pathItem found\n    helpOnNoCallback: true, //show help when callback not exist\n    helpOnVerifySwitchFailure: true, //show help when switches not match\n    helpOnAskedForHelp: true, //show help when help switches are provided\n  })\n)\n```\n\n**help** sets a property `SKIP_matchRuntimeAndDefinedSwitches` on the context object to prevent mismatch failures on switches.\n\n### autoComplete plugin\n\nIn order to add shell autocompletion, you can use the builtin **autoComplete** plugin. Right now it supports only _bash_ shell autocompletion. In order to set it up:\n\n1. Include the autoComplete plugin.\n\n```js\nconst { argsCommandRouter, plugins } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'myApp',\n})\n\napp.plugin(plugins.autoComplete)\n```\n\n2. Create an executable with the exact name you instantiated your Application with and Add it to the `PATH` environment variable. For example here we are using `alias` bash builtin to create a temporary executable in the current bash session and assuming that **nodejs** is already installed on the machine and been added to the `PATH` environment variable.\n\n```bash\nalias myApp=\"node <ABSOLUTE PATH>/index.js\"\n```\n\n3. Get the bash autocomplete script in bash shell and append it to your _.bash_profile_ file.\n\n```bash\nmyApp __AUTOCOMPLETE__ generate bash >> ~/.bash_profile\n```\n\n### tree plugin\n\nAfter a while, number of routes can increase and gets complicated. Tree plugin adds a route to the application instance to print a application tree on console.\n\n```js\nconst { argsCommandRouter, plugins } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'myApp',\n})\n\napp.plugin(plugins.tree('/_tree'))\n```\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  checkForSwitchConflicts: true,\n  strictSwitchMatching: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `checkForSwitchConflicts`: Verify Switch names are not conflicting in your Application. You can disable this after you're done with your application development to improve performance.\n- `strictSwitchMatching`: Verify if the passed switches are matched with switches defined on the found pathItem. If it's set to false, the requiredSwitches won't be enforced, and switched that are not defined are accepted.\n","readmeFilename":"README.md","gitHead":"ef32aba5d9f227605296834f21f6651fc6be7a5c","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@4.0.1-beta","_nodeVersion":"14.4.0","_npmVersion":"7.11.2","dist":{"integrity":"sha512-dsdpvo6OpWx8xpeQABSVZyw3J//cECOFjPQtqN0eRiEDrsLASwigd+pnyDOoSIPN0zZv5IhFBnixE/iuGrE/5Q==","shasum":"ad7f5a40727701b9a7d4014a00b43cd933c21769","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-4.0.1-beta.tgz","fileCount":89,"unpackedSize":223390,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg3orjCRA9TVsSAnZWagAAfhAQAJ3FUZmzf3ds6qnauNB4\nofP7IikfhszzCoa09DEtSJBCR+rLGlaxDZ36oo4AdZglTOMJuTxfG/2jwvw8\n3dFxI5sqS5Eo+c81TU++EhJXvxbbD+wkPQtnEnt6teP5BbTjLrD/MXjG6FCT\n4wFyJASvLBPkgIgEO2y3hCvb7QvklcfjDo6di80i+LeCh6KmxVDNqcBDrzpZ\nrzh29qCi5e+TsrjJIQZpuEiKjmK+UHeeITg7F/f9Bh6m42lUczHd5PPWoxmd\ncWecua7iTaTBPXJ8VF1mntCgFbisHhoEb/1XmuegtBQHAbGmcXlpCccTEYzP\nGnTvdJ2nJn8SBluPcOItiMOFzuo+gzxaeIxrZ+4KzVJasdaYKWh9/PV/cimL\nere3h8n+T1pucybkZ8GPs+Nwu+E5R819GMEx2EqDxkOvaoFC9RLud12wosk1\nDkiyD2NxvgqPY4qp9AHMOyEbS4N8GcM8Rho/S/+EuceWCPgdCwl8H3WG4git\nwQCMXjYQPQToiUtgpaYkPFmNfIQggcX5+tjUFGfl9s5Dui4QFEVe+SzaAk4L\n3K215tD0uC1GRynYKFyjMsnTNQKqgbJLf0HRoPvzIooLPcx2NFnUgdLwRX5t\nzxVlyxr117EkgGA8gVOUW6Gbld9Q/gHbwL7PvnB5IcWc0qkEwMH5ujZW/prg\nEgbM\r\n=5j+G\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDErMfB/benk/SnK++vDTmrKkx2bk41ekxVab7Ut7lr/wIgPoYMHqajATHORHMSpKj3fp5inzitUImoDPeZTr576DU="}]},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_4.0.1-beta_1625197282533_0.2889286965838411"},"_hasShrinkwrap":false},"4.0.1":{"name":"args-command-router","version":"4.0.1","description":"Nodejs command-line argument router","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"start":"node ./dist/index.js","play":"npm run build; node ./play/index.js","build":"tsc","test":"cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --reporter spec --colors \"test/**/*.test.ts\"","coverage":"nyc npm run test","lint":"tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix","publish":"np"},"keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"license":"MIT","devDependencies":{"@types/chai":"^4.2.14","@types/mocha":"^5.2.7","@types/node":"^12.19.3","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","chai":"^4.2.0","coveralls":"^3.1.0","cross-env":"^6.0.3","eslint":"^6.8.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","mocha":"^6.2.3","nyc":"^14.1.1","prettier":"^1.19.1","ts-node":"^8.10.2","typescript":"^3.9.7"},"dependencies":{"args-command-parser":"^1.1.13","command-line-usage":"^6.1.1"},"gitHead":"b64b5efb6e1e24085708da056dc55ff7cef9309d","bugs":{"url":"https://github.com/SHND/args-command-router/issues"},"homepage":"https://github.com/SHND/args-command-router#readme","_id":"args-command-router@4.0.1","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-lMyECiTeSnKkFpT1XG8BII2+OyEWF9ovybEemM3i7mfJqzQ/bzzV3a3CcyAVB2ADjW9snh3XBqxdTOj8UnF45Q==","shasum":"f3de1e28620098edaf47d21225ccfeab4db10e79","tarball":"https://registry.npmjs.org/args-command-router/-/args-command-router-4.0.1.tgz","fileCount":89,"unpackedSize":223385,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDTBbwUiQ6+rYvNQivt131FuPraGJgJIu0yKP0roK/HywIhANRXFVHzFTFFZWElupPbzj2zHjCxgNUwYqlq8vSUNvjK"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiXFdbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpm5hAAjvVfMkPEeHN3KNJx7Epa8gNhDKc1XnGO50Xke1rcGfZ8e1Xk\r\njnQe4NuYC4RHKhXJkrlfMgC03VYj+AVYsw2pkLj4fFFkvxiFhMfPGiGm7psp\r\naoDL+VCEpuHBgVYCukK7jMvpqUG83NyXBVHEQDfsD9aIhLcj7+5ViITImO6f\r\nxHAGijKsLyVltTTJOfVqKRF1QOffXXpdADEiBhVwb6KwaUyJVBhNLbT/y+ec\r\nWIkYqt1tdmyPbpmCl5JiufzfbO7zF7dEonpgBzO+8SJloUk+g5JWRfE4f8K0\r\n4R4w9X4cqJmofUe4bgqvKJYB200FMlfdp8KArGw9uVOFwlRhTwgto9ZMaiju\r\nt5M/b350nYyJfxVeLo66l4vlta/jgkyzX+XkIE65T8glUNZvk/Hv5ukAe8AN\r\nksSBao2Wiyp1SiyKAXL7uWpONfxEbS4J+J159FMZTX84zaB0aYzqsSNsNB91\r\n2KP7LH0rm+iEWwZEUnnQh5XMcGVwVX3afB36I0kGlTNmEtP/c2NjkW4Ia4qC\r\nmLOQo9IpLN/JOTSOE3djVvxTnyMeg7X4jABVoL1LLNJeRqC8kSRV9e/LGkEb\r\ns+JBrJk0zGkOp/5AZ49xtJdy0K52EMblwDBaVVBNLf1yO2tk0vzzOjcgu4px\r\nqpFe1QWeAAxmS660djabOk6My2Zea7iZg+s=\r\n=/QWp\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"shnd","email":"sahand.javid@gmail.com"},"directories":{},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/args-command-router_4.0.1_1650218843708_0.9748122805988508"},"_hasShrinkwrap":false}},"time":{"created":"2019-10-09T07:14:04.018Z","1.0.0":"2019-10-09T07:14:04.152Z","modified":"2022-04-17T18:07:24.000Z","1.0.1":"2019-10-19T21:24:05.846Z","1.0.2":"2019-10-19T21:27:18.231Z","1.0.3":"2019-10-19T21:28:41.953Z","1.0.4-0":"2019-10-19T21:36:08.933Z","1.0.4-1":"2019-10-19T21:38:14.430Z","1.0.4-2":"2019-10-23T08:29:20.756Z","1.0.4":"2019-10-23T08:59:55.771Z","1.0.5":"2019-10-24T09:31:41.670Z","1.0.6":"2019-10-24T23:11:27.251Z","2.0.1":"2019-10-27T03:24:04.466Z","2.0.2":"2019-10-27T03:33:33.660Z","2.0.3":"2019-10-28T06:32:42.550Z","3.0.0-alpha.1":"2020-11-08T16:58:56.197Z","3.0.0-alpha.2":"2020-11-08T18:41:30.379Z","3.0.0-alpha.3":"2020-11-15T21:45:28.143Z","3.1.0-alpha.0":"2021-03-13T08:46:45.021Z","3.1.0-alpha.4":"2021-03-13T09:05:57.579Z","3.1.0-alpha.5":"2021-03-14T08:32:59.855Z","3.2.0-alpha.6":"2021-03-24T06:39:00.538Z","3.3.0-alpha.8":"2021-03-28T00:51:44.260Z","3.3.1-alpha.10":"2021-03-28T04:33:21.308Z","3.4.0":"2021-03-29T07:11:11.325Z","3.4.1":"2021-03-29T07:14:26.994Z","3.6.0":"2021-04-12T06:16:00.228Z","3.6.2":"2021-06-22T07:45:30.083Z","4.0.1-beta":"2021-07-02T03:41:22.681Z","4.0.1":"2022-04-17T18:07:23.889Z"},"maintainers":[{"name":"shnd","email":"sahand.javid@gmail.com"}],"description":"Nodejs command-line argument router","keywords":["args","argument","router","tty","command-line"],"author":{"name":"Sahand Javid","email":"sahand.javid@gmail.com"},"license":"MIT","readme":"# args-command-router\n\nNodejs opinionated command-line argument router.\n\nThe idea behind **Args Command Router** is from the **ExpressJS** package, in which you can define different routes for different routines and functions based on the request.\n\n![GitHub](https://img.shields.io/github/license/SHND/args-command-router)\n[![Build Status](https://travis-ci.org/SHND/args-command-router.svg?branch=master)](https://travis-ci.org/SHND/args-command-router)\n[![Coverage Status](https://coveralls.io/repos/github/SHND/args-command-router/badge.svg?branch=master)](https://coveralls.io/github/SHND/args-command-router?branch=master)\n\n## Installation\n\n```\nnpm install --save args-command-router\n```\n\n## Executing\n\n### JavaScript\n\n```bash\n$ node index.js\n```\n\n### Typescript\n\n```bash\n$ npx -p typescript tsc index.ts\n$ node index.js\n```\n\n## Usage\n\nLets say we want to create a simplified git command line interface:\n\n```bash\n$ git add ./files1 ./file2\n$ git commit -a -m \"My message\"\n$ git branch\n$ git push origin master --force\n```\n\nYou can implement the routing of commands above like this:\n\n```js\nconst { argsCommandRouter } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'git',\n})\n\napp\n  .route('/add/...files')\n  .description('Add file contents to the index')\n  .callback(() => {\n    /* Add command routine */\n  })\n\napp\n  .route('/commit')\n  .description('Record changes to the repository')\n  .optionalSwitch('a', 'all', 'commit all changed files')\n  .optionalSwitch('m', 'message', 'commit message', ['message'])\n  .callback(() => {\n    /* Commit command routine */\n  })\n\napp\n  .route('/branch')\n  .alias('b')\n  .description('List, create, or delete branches')\n  .callback(() => {\n    /* Branch command routine */\n  })\n\napp\n  .route('/push/:remote/:branch')\n  .description('Update remote refs along with associated objects')\n  .requiredSwitch('f', 'force', 'force updates')\n  .callback(() => {\n    /* Push command routine */\n  })\n\napp.run()\n```\n\n> In **Typescript** and **JavaScript ES6**, import argsCommandRouter using code below instead of `require('args-command-router')`:\n>\n> ```js\n> import { argsCommandRouter } from 'args-command-router'\n> ```\n\n## Routes\n\nThe `route()` method maps patterns to callbacks. It receives a series of names separated by `/` and series of optional switch patterns at the end of the path each inside `[]`.\n\n```js\napp.route('/say/:greet/...names[age=21][s]')\n```\n\nOn each run, Application goes through the routes in order they are defined and compares the passed arguments (commands and switches) with each route, and execute the first matched route callback.\n\nAll arguments below, would matched the route above:\n\n```bash\n$ APP say hi john --age 21 -s\n$ APP say hey john marry -s --age 21\n$ APP say hello 'everyone here' -s --age 21\n```\n\nThe `say`, `:greet`, `...names` and `[age=21][s]` are called **PathItem**.\n\n- `say` is a **Static PathItem**, since it always tries to match the exact name.\n\n- `:greet` is a **Dynamic PathItem**, and it matches to any value in its place.\n\n- `...names` is a **Spread PathItem**, and it matches to one to any number of values in its place.\n\n- `[age=21][s]` is a **Switch PathItem**, and it is matched to existence of switch `-s` (either with value or not) and existence of switch `--age` with the exact value of _21_.\n\n## Callbacks\n\nCallbacks specifies what routine (function) should be called when a matched route is found.\n\n```js\nroute('/say/:greet/...names[age=21][s]').callback(function(inputs) {\n  const {\n    commands,\n    pathParams,\n    shortSwitches,\n    longSwitches,\n    switches,\n    context,\n  } = inputs\n\n  const pathItem = this\n})\n```\n\nYour callbacks are called with data about the current execution of your application.\n\n- **commands** is an array of strings passed to your application as commands.\n- **pathParams** is an object of dynamic and spread pathItem names and values passed for those.\n- **shortSwitches** is an object of short switch names with values passed to those switches.\n- **longSwitches** is an object of long switch names with values passed to those switches.\n- **switches** is **shortSwitches** and **longSwitches** in one object.\n- **context** is an object that hooks can use to pass values to the next hooks and callbacks.\n- **this** points to the matched pathItem or it's _null_ if no pathItem is associated with the callback.\n\nYou can also add new properties to the input object in hooks and access them in the your callbacks.\n\nConsidering our example for `route('/say/:greet/...names[age=21][s]')` and execution `$APP say hey john marry -s --age 21` the `inputs` parameter will be:\n\n```js\n{\n  commands: [ 'say', 'hey', 'john', 'marry' ],\n  pathParams: { greet: 'hey', names: [ 'john', 'marry' ] },\n  shortSwitches: { s: [] },\n  longSwitches: { age: [ '21' ] },\n  switches: { s: [], age: [ '21' ] },\n  context: {}\n}\n```\n\nRemember if you mention switches in your route patterns, you need to define them as `requiredSwitch` on your routes otherwise they won't get matched.\n\n## Switches\n\nIn order to pass switches to your application, you need to define them on your routes.\n\nSwitches can be either **Required** or **Optional**.\n\n### Required Switches\n\nThese switches should be present when running your application for a specific route, otherwise your callback won't be called, even if you are mentioning them in your route string. (This behavior can be changed by the configuration option `strictSwitchMatching`)\n\n```js\napp\n  .route('/video/download')\n  .requiredSwitch('u', 'url', 'URL of the video', ['address'])\n  .callback(input => console.log(input.switches.url))\n```\n\nHere we are defining a Required Switch `u`, `url` for `/video/download` that gets one parameter with a name address. So an example of a shell execution could be:\n\n```bash\n$ App video download -u http://myvideo.com/v.avi\n$ App video download --url http://myvideo.com/v.avi\n```\n\n### Optional Switches\n\nThese switches can be absent when running your application.\n\n```js\napp.route('/video/formats').optionalSwitch('a', 'all', 'Show all formats')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video formats\n$ App video formats -a\n$ App video formats --all\n```\n\nIf your switch expects parameters, you can list them in the switch definition.\n\n```js\napp\n  .route('/video/formats')\n  .optionalSwitch('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\nThe `option` method can be used interchangably as an alias to `optionalSwitch` method.\n\n```js\napp\n  .route('/video/formats')\n  .option('f', 'filter', 'Filter format lists', ['pattern'])\n```\n\n### Common Required, Optional Switches\n\nThese type of switches can be defined on a route and will be inherited by all the subordinate routes.\n\n```js\napp\n  .route('/video')\n  .commonRequiredSwitch('k', 'key', 'Api key', ['key'])\n  .commonOptionalSwitch('v', 'verbose', 'Verbose output')\n```\n\nExamples of a shell execution could be:\n\n```bash\n$ App video -k abc123\n$ App video download --key abc123\n$ App video formats --key abc123 -v\n```\n\nThe `commonOption` method can be used interchangably as an alias to `commonOptionalSwitch` method.\n\n## Aliases\n\nStatic pathItems along with their name can also have aliases.\n\n```js\napp\n  .route('/say')\n  .alias('shout')\n  .alias('whisper')\n```\n\nNow calling the route `/say/:greet` can be done using any lines below:\n\n```bash\n$ App say 'my name'\n$ App shout 'my name'\n$ App whisper 'my name'\n```\n\n## Hooks\n\nHooks are functions that are getting executed at different stages of the execution of the application. You can view the order of execution of the callback and hooks from [this diagram](https://raw.githubusercontent.com/SHND/args-command-router/master/docs/hooks_order.png).\n\n- **beforeAll Hook:** is called before all executions.\n\n```js\napp.beforeAll(inputs => {\n  // do some stuff\n})\n```\n\n- **afterTargetFound Hook:** is called after a PathItem for the passed commands is found.\n\n```js\napp.afterTargetFound(inputs => {\n  // do some stuff\n})\n```\n\n- **afterCallbackFound Hook:** is called when PathItem is found and at least one callback is set on it.\n\n```js\napp.afterCallbackFound(inputs => {\n  // do some stuff\n}\n```\n\n- **beforeCallback Hook:** is called right before callback execution.\n\n```js\napp.beforeCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **afterCallback Hook:** is called right after callback execution.\n\n```js\napp.afterCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **noTarget Hook:** is called when no PathItems could be associated with passed commands.\n\n```js\napp.noTarget(inputs => {\n  // do some stuff\n}\n```\n\n- **noCallback Hook:** is called when PathItem is found but no callbacks are set on the PathItem.\n\n```js\napp.noCallback(inputs => {\n  // do some stuff\n}\n```\n\n- **onVerifySwitchFailure Hook:** is called when Callback is found but passed switches are not matched with defined switches for that PathItem.\n\n```js\napp.onVerifySwitchFailure(inputs => {\n  // do some stuff\n}\n```\n\nIf you want to stop the next hooks and callbacks to be called, return a string 'stop' from your callbacks.\n\n```js\napp.beforeAll(inputs => {\n  if (new Date().getHours() < 6) {\n    return 'stop'\n  }\n})\n```\n\n## Context\n\nYou can also add new properties and values to your inputs for the next hooks and callbacks. In order to do that just return an object with those properties. Those will be available in the following hooks and callbacks in the context object.\n\n```js\napp.beforeAll(inputs => {\n  return {\n    hello: 'hi',\n  }\n})\n\napp.route('/video/formats').callback(inputs => {\n  console.log(inputs.context.hello)\n})\n```\n\n## Hide Path\n\nIn order to prevent displying some paths in help and auto completion output, you can hide them.\n\n```js\napp.route('/_hideme').hide()\n```\n\nThis is can be useful to hide some functionality from users. You can still chain the hidden path with other route methods.\n\n## Plugin\n\nPlugins allow to add functionality from internal or external sources. Plugins are simply functions that receives the Application instance as their first argument.\n\n```js\nfunction myDebugPlugin(app) {\n  app.route('/_debug').callback(() => {\n    console.log('debug output.')\n  })\n}\n```\n\nIn order to use plugin in your application, you can pass the plugin function to `plugin` method.\n\n```js\napp.plugin(myDebugPlugin)\n```\n\nBe careful of plugins you import. If you don't know or trust a plugin, proceed with cautious.\n\n## Builtin Plugins\n\n### help plugin\n\nYou can use the builtin **help** plugin to add help outputs to your application.\n\n```js\nconst { argsCommandRouter, plugins } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'myApp',\n})\n\napp.plugin(plugins.help())\n```\n\nBy default **help** plugin uses `-h` and `--help` switches for displaying help, but this is configurable through **help** options.\n\nThese are the options and their default values that can be configured on the **help** plugin:\n\n```js\napp.plugin(\n  plugins.help({\n    helpType: 'switch', //set null to disable\n    helpShortSwitch: 'h', //short switch to show help\n    helpLongSwitch: 'help', //long switch to show help\n    helpOnNoTarget: true, //show help when no pathItem found\n    helpOnNoCallback: true, //show help when callback not exist\n    helpOnVerifySwitchFailure: true, //show help when switches not match\n    helpOnAskedForHelp: true, //show help when help switches are provided\n  })\n)\n```\n\n**help** sets a property `SKIP_matchRuntimeAndDefinedSwitches` on the context object to prevent mismatch failures on switches.\n\n### autoComplete plugin\n\nIn order to add shell autocompletion, you can use the builtin **autoComplete** plugin. Right now it supports only _bash_ shell autocompletion. In order to set it up:\n\n1. Include the autoComplete plugin.\n\n```js\nconst { argsCommandRouter, plugins } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'myApp',\n})\n\napp.plugin(plugins.autoComplete)\n```\n\n2. Create an executable with the exact name you instantiated your Application with and Add it to the `PATH` environment variable. For example here we are using `alias` bash builtin to create a temporary executable in the current bash session and assuming that **nodejs** is already installed on the machine and been added to the `PATH` environment variable.\n\n```bash\nalias myApp=\"node <ABSOLUTE PATH>/index.js\"\n```\n\n3. Get the bash autocomplete script in bash shell and append it to your _.bash_profile_ file.\n\n```bash\nmyApp __AUTOCOMPLETE__ generate bash >> ~/.bash_profile\n```\n\n### tree plugin\n\nAfter a while, number of routes can increase and gets complicated. Tree plugin adds a route to the application instance to print a application tree on console.\n\n```js\nconst { argsCommandRouter, plugins } = require('args-command-router')\n\nconst app = argsCommandRouter({\n  applicationName: 'myApp',\n})\n\napp.plugin(plugins.tree('/_tree'))\n```\n\n## Application Configuration\n\nYou can configure the args-command-router behavior when instantiating the Application.\n\nThese are the default values:\n\n```js\nconst app = new Application({\n  applicationName: '<App>',\n  checkForSwitchConflicts: true,\n  strictSwitchMatching: true,\n})\n```\n\n- `applicationName`: The name of the application used in generating the help (usage) output.\n- `checkForSwitchConflicts`: Verify Switch names are not conflicting in your Application. You can disable this after you're done with your application development to improve performance.\n- `strictSwitchMatching`: Verify if the passed switches are matched with switches defined on the found pathItem. If it's set to false, the requiredSwitches won't be enforced, and switched that are not defined are accepted.\n","readmeFilename":"README.md","homepage":"https://github.com/SHND/args-command-router#readme","repository":{"type":"git","url":"git+https://github.com/SHND/args-command-router.git"},"bugs":{"url":"https://github.com/SHND/args-command-router/issues"}}