[
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n#ide\n.vscode\n.idea\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (http://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Typescript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# build and Play\nplay\n\n# remove build or lib from repo\nlib\ndist"
  },
  {
    "path": ".npmignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n#ide\n.vscode\n.idea\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (http://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Typescript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# NPM  \nsrc\nexample\ngulpfile.js\n.prettierrc\n.travis.yml"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"semi\": true,\n  \"useTabs\": false,\n  \"singleQuote\": true,\n  \"printWidth\": 100,\n  \"trailingComma\": \"all\"\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n      - \"8\"\n      - \"9\"\n      - \"10\"\nbefore_script:\n     - export DISPLAY=:99.0\n     - sh -e /etc/init.d/xvfb start\ninstall:\n     - npm install\n     - npm run build\nscript:\n      - npm test\nafter_success:\n      - npm run test:coverage\n      - \"npm install coveralls && cat ./coverage/lcov.info | coveralls\""
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)\nand this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).\n\n## [Unreleased]\n\n## [1.0.9]\n## Bugs\n* Fix Bug [#41](https://github.com/shekohex/nest-router/issues/41)\n\n## [1.0.8]\n### Added\n* Resolve Full Controller Path from anywhere ([#32](https://github.com/shekohex/nest-router/pull/32))\n\n## Changed\n* Update Dev Dependencies\n\n## [1.0.7] - 2018-09-28\n### Changed\n* Project dependency refactor\n* add node v10 as a test target\n\n## [1.0.6] - 2018-06-20\n### Changed\n* Now Nest Router Module Using Nest V5+\n> See examples folder, there is `nest-v5x`.\n\n## [1.0.5] - 2018-02-27\n\n### Deprecated\n\n* `childrens`, use `children` instead.\n  see [why](https://github.com/shekohex/nest-router/issues/6)?\n\n## [1.0.4] - 2018-02-12\n\n### Added\n\n* You can now Omit the `module` keyword and just using an arry\n  of `children` and one `path` proparty.\n\n## [1.0.3] - 2018-02-10\n\n### Added\n\n* `children` array can be array with just modules.\n  this means you can omit the `path` keyword.\n* Unreleased section to gather unreleased changes and encourage note\n  keeping prior to releases.\n\n## [1.0.2] - 2018-02-08\n\n### Added\n\n* Routes now can be endless nested array.\n\n## [1.0.1] - 2018-02-05\n\n### Changed\n\n* `children` now an Array insted of `object`\n\n## [1.0.0] - 2018-02-05\n\n* Published to NPM :rocket:\n* add continuous integration \"Travis CI\"\n\n## [0.0.0] - 2018-01-31\n\n### Added\n\n* Greenkeeper badge\n* README\n* Good examples and basic guidelines, in example folder and README.\n* Build status badge\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Shady Khalifa\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Nest Router :vertical_traffic_light:\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/shekohex/nest-router.svg)](https://greenkeeper.io/) [![Build Status](https://travis-ci.org/shekohex/nest-router.svg?branch=master)](https://travis-ci.org/shekohex/nest-router) [![npm version](https://badge.fury.io/js/nest-router.svg)](Https://www.npmjs.com/package/nest-router) [![Coverage Status](https://coveralls.io/repos/github/shekohex/nest-router/badge.svg?branch=master)](https://coveralls.io/github/shekohex/nest-router?branch=master)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fshekohex%2Fnest-router.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fshekohex%2Fnest-router?ref=badge_shield)\n\nRouter Module For [Nestjs](https://github.com/nestjs/nest) Framework\n\n## Important Note\n\nAs of Nestjs `v8.0.0` This module got added into the `@nestjs/core`.\nsee the [docs](https://docs.nestjs.com/recipes/router-module)\nwith that being said, this package is still maintained (for now).\n\n## Quick Overview\n\n`RouterModule` helps you organize your routes and lets you create a routes tree.\n\n### How ?\n\nEvery module could have a path property. That path will be a prefix for all controllers in this module. If that module has a parent, it will be a child of it and again all controllers in this child module will be prefixed by `parent module prefix` + `this module prefix`\n\n> see issue [#255](https://github.com/nestjs/nest/issues/255) .\n\n## Install\n\nIMPORTANT: you need Nest > v4.5.10+\n\n```bash\nnpm install nest-router --save\n```\n\nOR\n\n```bash\nyarn add nest-router\n```\n\n## Setup\n\nSee how easy it is to set up.\n\n```ts\n... //imports\nconst routes: Routes = [\n    {\n      path: '/ninja',\n      module: NinjaModule,\n      children: [\n        {\n          path: '/cats',\n          module: CatsModule,\n        },\n        {\n          path: '/dogs',\n          module: DogsModule,\n        },\n      ],\n    },\n  ];\n\n@Module({\n  imports: [\n      RouterModule.forRoutes(routes), // setup the routes\n      CatsModule,\n      DogsModule,\n      NinjaModule\n  ], // as usual, nothing new\n})\nexport class ApplicationModule {}\n```\n\n> :+1: TIP: Keep all of your routes in a separate file like `routes.ts`\n\nIn this example, all the controllers in `NinjaModule` will be prefixed by `/ninja` and it\nhas two childs, `CatsModule` and `DogsModule`.\n\nWill the controllers of `CatsModule` be prefixed by `/cats`? NO!! :open_mouth:\nThe `CatsModule` is a child of `NinjaModule` so it will be prefixed by `/ninja/cats/` instead.\nAnd so will `DogsModule`.\n\n> See examples folder for more information.\n\n#### Example Folder Project Structure\n\n```bash\n.\n├── app.module.ts\n├── cats\n│   ├── cats.controller.ts\n│   ├── cats.module.ts\n│   └── ketty.controller.ts\n├── dogs\n│   ├── dogs.controller.ts\n│   ├── dogs.module.ts\n│   └── puppy.controller.ts\n├── main.ts\n└── ninja\n    ├── katana.controller.ts\n    ├── ninja.controller.ts\n    └── ninja.module.ts\n```\n\nAnd here is a simple, nice route tree of `example` folder:\n\n```bash\nninja\n    ├── /\n    ├── /katana\n    ├── cats\n    │   ├── /\n    │   └── /ketty\n    ├── dogs\n        ├── /\n        └── /puppy\n```\n\nNice!\n\n#### Params in nested routes\n\nIn a standard REST API, you probably would need to add some params to your nested routes. Here is an example of how you can achieve it:\n\n```ts\n... //imports\nconst routes: Routes = [\n    {\n      path: '/ninja',\n      module: NinjaModule,\n      children: [\n        {\n          path: '/:ninjaId/cats',\n          module: CatsModule,\n        },\n        {\n          path: '/:ninjaId/dogs',\n          module: DogsModule,\n        },\n      ],\n    },\n  ];\n```\n\nThe `ninjaId` param will be available inside `CatsModule` controllers and `DogsModule` controllers. Please, find the [instruction how to handle params in the official documentation](https://docs.nestjs.com/controllers#route-parameters). It might be a good practice to use a [pipe for transformation use case](https://docs.nestjs.com/pipes#transformation-use-case) to have an access to `ninja` object instead of just id.\n\n\n#### Resolve Full Controller Path:\nNestjs dosen't resolve or take into account `MODULE_PATH` metadata when it is coming to resolve Controller path in Middleware resolver for example, so that i introduced a new fancy method `RouterModule#resolvePath` that will resolve the full path of any controller so instead of doing so:\n\n```ts\nconsumer.apply(someMiddleware).forRoutes(SomeController);\n``` \nyou should do\n\n```ts\nconsumer.apply(someMiddleware).forRoutes(RouterModule.resolvePath(SomeController));\n``` \n\nsee [#32](https://github.com/shekohex/nest-router/pull/32) for more information about this.\n\n## CHANGELOG\n\nSee [CHANGELOG](CHANGELOG.md) for more information.\n\n## Contributing\n\nYou are welcome to contribute to this project, just open a PR.\n\n## Authors\n\n* **Shady Khalifa** - _Initial work_\n\nSee also the list of [contributors](https://github.com/shekohex/nest-router/contributors) who participated in this project.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fshekohex%2Fnest-router.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fshekohex%2Fnest-router?ref=badge_large)\n"
  },
  {
    "path": "examples/nest-v4x/index.js",
    "content": "require('ts-node/register');\nrequire('./src/main');\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "examples/nest-v4x/jest.json",
    "content": "{\n  \"moduleFileExtensions\": [\n        \"ts\",\n        \"tsx\",\n        \"js\",\n        \"json\"\n    ],\n    \"transform\": {\n        \"^.+\\\\.tsx?$\": \"<rootDir>/node_modules/ts-jest/preprocessor.js\"\n    },\n    \"testRegex\": \"/src/.*\\\\.(test|spec).(ts|tsx|js)$\",\n    \"collectCoverageFrom\" : [\"src/**/*.{js,jsx,tsx,ts}\", \"!**/node_modules/**\", \"!**/vendor/**\"],\n    \"coverageReporters\": [\"json\", \"lcov\"]\n}"
  },
  {
    "path": "examples/nest-v4x/package.json",
    "content": "{\n  \"name\": \"nest-router-example-v4x\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Nest TypeScript starter repository\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"start\": \"node index.js\",\n    \"prestart:prod\": \"tsc\",\n    \"start:prod\": \"node dist/main.js\",\n    \"test\": \"jest --config=jest.json\",\n    \"test:watch\": \"jest --watch --config=jest.json\",\n    \"test:coverage\": \"jest --config=jest.json --coverage --coverageDirectory=coverage\",\n    \"e2e\": \"jest --config=e2e/jest-e2e.json --forceExit\",\n    \"e2e:watch\": \"jest --watch --config=e2e/jest-e2e.json\"\n  },\n  \"dependencies\": {\n    \"@nestjs/common\": \"^4.6.4\",\n    \"@nestjs/core\": \"^4.6.4\",\n    \"@nestjs/testing\": \"^4.6.1\",\n    \"class-transformer\": \"^0.1.7\",\n    \"class-validator\": \"^0.7.2\",\n    \"nest-router\": \"^1.0.5\",\n    \"reflect-metadata\": \"^0.1.10\",\n    \"rxjs\": \"^5.4.3\",\n    \"typescript\": \"^2.4.2\"\n  },\n  \"devDependencies\": {\n    \"@types/jest\": \"^20.0.8\",\n    \"@types/node\": \"^7.0.41\",\n    \"jest\": \"^20.0.4\",\n    \"supertest\": \"^3.0.0\",\n    \"ts-jest\": \"^20.0.14\",\n    \"ts-node\": \"^3.3.0\"\n  }\n}\n"
  },
  {
    "path": "examples/nest-v4x/src/app.module.ts",
    "content": "import { Module, NestModule, MiddlewaresConsumer, RequestMethod } from '@nestjs/common';\nimport { RouterModule } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dogs/dogs.module';\nimport { NinjaModule } from './ninja/ninja.module';\nimport { routes } from './routes';\n@Module({\n  imports: [RouterModule.forRoutes(routes), CatsModule, DogsModule, NinjaModule],\n})\nexport class ApplicationModule {}\n"
  },
  {
    "path": "examples/nest-v4x/src/cats/cats.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class CatsController {\n  @Get('/')\n  sayHello() {\n    return `Hello From CatsController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v4x/src/cats/cats.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { CatsController } from './cats.controller';\nimport { KettyController } from './ketty.controller';\n\n@Module({\n  controllers: [CatsController, KettyController],\n})\nexport class CatsModule {}\n"
  },
  {
    "path": "examples/nest-v4x/src/cats/ketty.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/ketty')\nexport class KettyController {\n  @Get('/')\n  sayHello() {\n    return `Hello From KettyController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v4x/src/dogs/dogs.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class DogsController {\n  @Get('/')\n  sayHello() {\n    return `Hello From DogsController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v4x/src/dogs/dogs.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { DogsController } from './dogs.controller';\nimport { PuppyController } from './puppy.controller';\n\n@Module({\n  controllers: [DogsController, PuppyController],\n})\nexport class DogsModule {}\n"
  },
  {
    "path": "examples/nest-v4x/src/dogs/puppy.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/puppy')\nexport class PuppyController {\n  @Get('/')\n  sayHello() {\n    return `Hello From PuppyController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v4x/src/main.ts",
    "content": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\nasync function bootstrap() {\n  const app = await NestFactory.create(ApplicationModule);\n  await app.listen(3000);\n}\nbootstrap();\n"
  },
  {
    "path": "examples/nest-v4x/src/ninja/katana.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/katana')\nexport class KatanaController {\n  @Get('/')\n  sayHello() {\n    return `Hello From KatanaController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v4x/src/ninja/ninja.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class NinjaController {\n  @Get('/')\n  sayHello() {\n    return `Hello From NinjaController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v4x/src/ninja/ninja.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { NinjaController } from './ninja.controller';\nimport { KatanaController } from './katana.controller';\n\n@Module({\n  controllers: [NinjaController, KatanaController],\n})\nexport class NinjaModule {}\n"
  },
  {
    "path": "examples/nest-v4x/src/routes.ts",
    "content": "import { Routes } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dogs/dogs.module';\nimport { NinjaModule } from './ninja/ninja.module';\nexport const routes: Routes = [\n  {\n    path: '/ninja',\n    module: NinjaModule,\n    children: [{ path: '/cats', module: CatsModule }, { path: '/dogs', module: DogsModule }],\n  },\n];\n"
  },
  {
    "path": "examples/nest-v4x/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"declaration\": false,\n    \"noImplicitAny\": false,\n    \"removeComments\": true,\n    \"noLib\": false,\n    \"emitDecoratorMetadata\": true,\n    \"experimentalDecorators\": true,\n    \"target\": \"es6\",\n    \"sourceMap\": true,\n    \"allowJs\": true,\n    \"outDir\": \"./dist\"\n  },\n  \"include\": [\n    \"src/**/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"**/*.spec.ts\"\n  ]\n}"
  },
  {
    "path": "examples/nest-v4x/tslint.json",
    "content": "{\n    \"defaultSeverity\": \"error\",\n    \"extends\": [\n        \"tslint:recommended\"\n    ],\n    \"jsRules\": {\n        \"no-unused-expression\": true\n    },\n    \"rules\": {\n        \"eofline\": false,\n        \"quotemark\": [\n            true,\n            \"single\"\n        ],\n        \"ordered-imports\": [\n            false\n        ],\n        \"max-line-length\": [\n            150\n        ],\n        \"member-ordering\": [\n            false\n        ],\n        \"curly\": false,\n        \"interface-name\": [\n            false\n        ],\n        \"array-type\": [\n            false\n        ],\n        \"member-access\": [\n            false\n        ],\n        \"no-empty-interface\": false,\n        \"no-empty\": false,\n        \"arrow-parens\": false,\n        \"object-literal-sort-keys\": false,\n        \"no-unused-expression\": false,\n        \"max-classes-per-file\": [\n            false\n        ],\n        \"variable-name\": [\n            false\n        ],\n        \"one-line\": [\n            false\n        ],\n        \"one-variable-per-declaration\": [\n            false\n        ]\n    },\n    \"rulesDirectory\": []\n}"
  },
  {
    "path": "examples/nest-v5x/nodemon.json",
    "content": "{\n  \"watch\": [\"src\"],\n  \"ext\": \"ts\",\n  \"ignore\": [\"src/**/*.spec.ts\"],\n  \"exec\": \"ts-node -r tsconfig-paths/register src/main.ts\"\n}\n"
  },
  {
    "path": "examples/nest-v5x/package.json",
    "content": "{\n  \"name\": \"nest-router-example-v5x\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Nest TypeScript starter repository\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n    \"start\": \"ts-node -r tsconfig-paths/register src/main.ts\",\n    \"start:dev\": \"nodemon\",\n    \"prestart:prod\": \"rm -rf dist && tsc\",\n    \"start:prod\": \"node dist/main.js\",\n    \"start:hmr\": \"node dist/server\",\n    \"lint\": \"tslint -p tsconfig.json -c tslint.json\",\n    \"test\": \"jest\",\n    \"test:cov\": \"jest --coverage\",\n    \"test:e2e\": \"jest --config ./test/jest-e2e.json\",\n    \"webpack\": \"webpack --config webpack.config.js\"\n  },\n  \"dependencies\": {\n    \"@nestjs/common\": \"^5.5.0\",\n    \"@nestjs/core\": \"^5.5.0\",\n    \"@nestjs/microservices\": \"^5.5.0\",\n    \"@nestjs/testing\": \"^5.5.0\",\n    \"@nestjs/websockets\": \"^5.5.0\",\n    \"class-transformer\": \"^0.2.0\",\n    \"class-validator\": \"^0.9.1\",\n    \"nest-router\": \"^1.0.8\",\n    \"reflect-metadata\": \"^0.1.12\",\n    \"rxjs\": \"^6.3.0\",\n    \"typescript\": \"^2.9.2\"\n  },\n  \"devDependencies\": {\n    \"@types/express\": \"^4.0.39\",\n    \"@types/jest\": \"^21.1.8\",\n    \"@types/node\": \"^9.3.0\",\n    \"@types/supertest\": \"^2.0.4\",\n    \"jest\": \"^21.2.1\",\n    \"nodemon\": \"^1.14.1\",\n    \"prettier\": \"^1.11.1\",\n    \"supertest\": \"^3.0.0\",\n    \"ts-jest\": \"^21.2.4\",\n    \"ts-loader\": \"^4.1.0\",\n    \"ts-node\": \"^4.1.0\",\n    \"tsconfig-paths\": \"^3.1.1\",\n    \"tslint\": \"5.3.2\",\n    \"webpack\": \"^4.2.0\",\n    \"webpack-cli\": \"^5.0.1\",\n    \"webpack-node-externals\": \"^1.6.0\"\n  },\n  \"jest\": {\n    \"moduleFileExtensions\": [\n      \"js\",\n      \"json\",\n      \"ts\"\n    ],\n    \"rootDir\": \"src\",\n    \"testRegex\": \".spec.ts$\",\n    \"transform\": {\n      \"^.+\\\\.(t|j)s$\": \"ts-jest\"\n    },\n    \"coverageDirectory\": \"../coverage\"\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/app.module.ts",
    "content": "import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';\nimport { RouterModule, Route } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dogs/dogs.module';\nimport { NinjaModule } from './ninja/ninja.module';\nimport { routes } from './routes';\nimport { LoggerMiddleware } from './logger.middleware';\n@Module({\n  imports: [RouterModule.forRoutes(routes), CatsModule, DogsModule, NinjaModule],\n})\nexport class ApplicationModule implements NestModule {\n  configure(consumer: MiddlewareConsumer) {\n    consumer\n      .apply(LoggerMiddleware)\n      .with({ path: '/ninja' } as Route)\n      .forRoutes('/');\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/cats/cats.controller.ts",
    "content": "import { Controller, Get, Post, Body, ValidationPipe } from '@nestjs/common';\nimport { CreateCatDTO } from './dto/create-cat.dto';\n\n@Controller()\nexport class CatsController {\n  private cats: string[] = [];\n  @Get('/')\n  sayHello() {\n    return `Hello From CatsController`;\n  }\n\n  // For testing Pipes\n  @Post('/create')\n  public testing(@Body(new ValidationPipe()) data: CreateCatDTO): string[] {\n    this.cats.push(data.name);\n    return this.cats;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/cats/cats.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { CatsController } from './cats.controller';\nimport { KettyController } from './ketty.controller';\n\n@Module({\n  controllers: [CatsController, KettyController],\n})\nexport class CatsModule {}\n"
  },
  {
    "path": "examples/nest-v5x/src/cats/dto/create-cat.dto.ts",
    "content": "import { IsString } from 'class-validator';\nexport class CreateCatDTO {\n  @IsString()\n  public readonly name: string;\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/cats/ketty.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/ketty')\nexport class KettyController {\n  @Get('/')\n  sayHello() {\n    return `Hello From KettyController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/dogs/dogs.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class DogsController {\n  @Get('/')\n  sayHello() {\n    return `Hello From DogsController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/dogs/dogs.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { DogsController } from './dogs.controller';\nimport { PuppyController } from './puppy.controller';\n\n@Module({\n  controllers: [DogsController, PuppyController],\n})\nexport class DogsModule {}\n"
  },
  {
    "path": "examples/nest-v5x/src/dogs/puppy.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/puppy')\nexport class PuppyController {\n  @Get('/')\n  sayHello() {\n    return `Hello From PuppyController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/logger.middleware.ts",
    "content": "import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';\nimport { Routes } from 'nest-router';\n\n@Injectable()\nexport class LoggerMiddleware implements NestMiddleware {\n  resolve(...excluded: Routes): MiddlewareFunction {\n    return (req, _res, next) => {\n      const isExcluded =\n        excluded.filter(route => {\n          console.log(LoggerMiddleware.name, ':', '{ Request Path ->', req.path, ' }');\n          const excludePath = route.path === req.path;\n          return excludePath;\n        }).length > 0;\n      console.log(LoggerMiddleware.name, ':', '{ Is Excluded ->', isExcluded, ' }');\n      next();\n    };\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/main.hmr.ts",
    "content": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\ndeclare const module: any;\n\nasync function bootstrap() {\n  const app = await NestFactory.create(ApplicationModule);\n  await app.listen(3000);\n\n  if (module.hot) {\n    module.hot.accept();\n    module.hot.dispose(() => app.close());\n  }\n}\nbootstrap();\n"
  },
  {
    "path": "examples/nest-v5x/src/main.ts",
    "content": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\nasync function bootstrap() {\n  const app = await NestFactory.create(ApplicationModule);\n  await app.listen(3000);\n}\nbootstrap();\n"
  },
  {
    "path": "examples/nest-v5x/src/ninja/katana.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/katana')\nexport class KatanaController {\n  @Get('/')\n  sayHello() {\n    return `Hello From KatanaController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/ninja/ninja.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class NinjaController {\n  @Get('/')\n  sayHello() {\n    return `Hello From NinjaController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/src/ninja/ninja.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { NinjaController } from './ninja.controller';\nimport { KatanaController } from './katana.controller';\n\n@Module({\n  controllers: [NinjaController, KatanaController],\n})\nexport class NinjaModule {}\n"
  },
  {
    "path": "examples/nest-v5x/src/routes.ts",
    "content": "import { Routes } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dogs/dogs.module';\nimport { NinjaModule } from './ninja/ninja.module';\nexport const routes: Routes = [\n  {\n    path: '/ninja',\n    module: NinjaModule,\n    children: [{ path: '/cats', module: CatsModule }, { path: '/dogs', module: DogsModule }],\n  },\n];\n"
  },
  {
    "path": "examples/nest-v5x/test/app.e2e-spec.ts",
    "content": "import request from 'supertest';\nimport { Test } from '@nestjs/testing';\nimport { AppModule } from './../src/app.module';\nimport { INestApplication } from '@nestjs/common';\n\ndescribe('AppController (e2e)', () => {\n  let app: INestApplication;\n\n  beforeAll(async () => {\n    const moduleFixture = await Test.createTestingModule({\n      imports: [AppModule],\n    }).compile();\n\n    app = moduleFixture.createNestApplication();\n    await app.init();\n  });\n\n  it('/GET /', () => {\n    return request(app.getHttpServer())\n      .get('/')\n      .expect(200)\n      .expect('Hello World!');\n  });\n});\n"
  },
  {
    "path": "examples/nest-v5x/test/jest-e2e.json",
    "content": "{\n  \"moduleFileExtensions\": [\"js\", \"json\", \"ts\"],\n  \"rootDir\": \".\",\n  \"testRegex\": \".e2e-spec.ts$\",\n  \"transform\": {\n    \"^.+\\\\.(t|j)s$\": \"ts-jest\"\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"declaration\": true,\n    \"noImplicitAny\": false,\n    \"removeComments\": true,\n    \"noLib\": false,\n    \"allowSyntheticDefaultImports\": true,\n    \"emitDecoratorMetadata\": true,\n    \"experimentalDecorators\": true,\n    \"target\": \"es6\",\n    \"sourceMap\": true,\n    \"outDir\": \"./dist\",\n    \"baseUrl\": \"./src\"\n  },\n  \"include\": [\n    \"src/**/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"**/*.spec.ts\"\n  ]\n}\n"
  },
  {
    "path": "examples/nest-v5x/tsconfig.spec.json",
    "content": "{\n  \"extends\": \"tsconfig.json\",\n  \"compilerOptions\": {\n    \"types\": [\"jest\", \"node\"]\n  },\n  \"include\": [\"**/*.spec.ts\", \"**/*.d.ts\"]\n}\n"
  },
  {
    "path": "examples/nest-v5x/tslint.json",
    "content": "{\n  \"defaultSeverity\": \"error\",\n  \"extends\": [\"tslint:recommended\"],\n  \"jsRules\": {\n    \"no-unused-expression\": true\n  },\n  \"rules\": {\n    \"eofline\": false,\n    \"quotemark\": [true, \"single\"],\n    \"indent\": false,\n    \"member-access\": [false],\n    \"ordered-imports\": [false],\n    \"max-line-length\": [true, 150],\n    \"member-ordering\": [false],\n    \"curly\": false,\n    \"interface-name\": [false],\n    \"array-type\": [false],\n    \"no-empty-interface\": false,\n    \"no-empty\": false,\n    \"arrow-parens\": false,\n    \"object-literal-sort-keys\": false,\n    \"no-unused-expression\": false,\n    \"no-console\": false,\n    \"variable-name\": [false],\n    \"one-line\": [false],\n    \"one-variable-per-declaration\": [false]\n  },\n  \"rulesDirectory\": []\n}\n"
  },
  {
    "path": "examples/nest-v5x/webpack.config.js",
    "content": "const webpack = require('webpack');\nconst path = require('path');\nconst nodeExternals = require('webpack-node-externals');\n\nmodule.exports = {\n  entry: ['webpack/hot/poll?1000', './src/main.hmr.ts'],\n  watch: true,\n  target: 'node',\n  externals: [\n    nodeExternals({\n      whitelist: ['webpack/hot/poll?1000'],\n    }),\n  ],\n  module: {\n    rules: [\n      {\n        test: /\\.tsx?$/,\n        use: 'ts-loader',\n        exclude: /node_modules/,\n      },\n    ],\n  },\n  mode: \"development\",\n  resolve: {\n    extensions: ['.tsx', '.ts', '.js'],\n  },\n  plugins: [\n    new webpack.HotModuleReplacementPlugin(),\n  ],\n  output: {\n    path: path.join(__dirname, 'dist'),\n    filename: 'server.js',\n  },\n};\n"
  },
  {
    "path": "examples/nest-v5x-m2m/nodemon.json",
    "content": "{\n  \"watch\": [\"src\"],\n  \"ext\": \"ts\",\n  \"ignore\": [\"src/**/*.spec.ts\"],\n  \"exec\": \"ts-node -r tsconfig-paths/register src/main.ts\"\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/package.json",
    "content": "{\n  \"name\": \"nest-router-example-v5x-m2m\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Nest TypeScript starter repository\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n    \"start\": \"ts-node -r tsconfig-paths/register src/main.ts\",\n    \"start:dev\": \"nodemon\",\n    \"prestart:prod\": \"rm -rf dist && tsc\",\n    \"start:prod\": \"node dist/main.js\",\n    \"start:hmr\": \"node dist/server\",\n    \"lint\": \"tslint -p tsconfig.json -c tslint.json\",\n    \"test\": \"jest\",\n    \"test:cov\": \"jest --coverage\",\n    \"test:e2e\": \"jest --config ./test/jest-e2e.json\",\n    \"webpack\": \"webpack --config webpack.config.js\"\n  },\n  \"dependencies\": {\n    \"@nestjs/common\": \"^5.5.0\",\n    \"@nestjs/core\": \"^5.5.0\",\n    \"@nestjs/microservices\": \"^5.5.0\",\n    \"@nestjs/testing\": \"^5.5.0\",\n    \"@nestjs/websockets\": \"^5.5.0\",\n    \"class-transformer\": \"^0.2.0\",\n    \"class-validator\": \"^0.9.1\",\n    \"nest-router\": \"^1.0.9\",\n    \"reflect-metadata\": \"^0.1.12\",\n    \"rxjs\": \"^6.3.0\",\n    \"typescript\": \"^2.9.2\"\n  },\n  \"devDependencies\": {\n    \"@types/express\": \"^4.0.39\",\n    \"@types/jest\": \"^21.1.8\",\n    \"@types/node\": \"^9.3.0\",\n    \"@types/supertest\": \"^2.0.4\",\n    \"jest\": \"^21.2.1\",\n    \"nodemon\": \"^1.14.1\",\n    \"prettier\": \"^1.11.1\",\n    \"supertest\": \"^3.0.0\",\n    \"ts-jest\": \"^21.2.4\",\n    \"ts-loader\": \"^4.1.0\",\n    \"ts-node\": \"^4.1.0\",\n    \"tsconfig-paths\": \"^3.1.1\",\n    \"tslint\": \"5.3.2\",\n    \"webpack\": \"^4.28.0\",\n    \"webpack-cli\": \"^3.1.2\",\n    \"webpack-node-externals\": \"^1.7.2\"\n  },\n  \"jest\": {\n    \"moduleFileExtensions\": [\n      \"js\",\n      \"json\",\n      \"ts\"\n    ],\n    \"rootDir\": \"src\",\n    \"testRegex\": \".spec.ts$\",\n    \"transform\": {\n      \"^.+\\\\.(t|j)s$\": \"ts-jest\"\n    },\n    \"coverageDirectory\": \"../coverage\"\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/app.module.ts",
    "content": "import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';\nimport { RouterModule, Route } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dogs/dogs.module';\nimport { NinjaModule } from './ninja/ninja.module';\nimport { routes } from './routes';\nimport { LoggerMiddleware } from './logger.middleware';\n@Module({\n  imports: [RouterModule.forRoutes(routes), CatsModule, DogsModule, NinjaModule],\n})\nexport class ApplicationModule implements NestModule {\n  configure(consumer: MiddlewareConsumer) {\n    consumer\n      .apply(LoggerMiddleware)\n      .with({ path: '/ninja' } as Route)\n      .forRoutes('/');\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/cats/cats.controller.ts",
    "content": "import { Controller, Get, Post, Body, ValidationPipe, Param } from '@nestjs/common';\nimport { CreateCatDTO } from './dto/create-cat.dto';\n\n@Controller()\nexport class CatsController {\n  private cats: string[] = [];\n  @Get('/')\n  sayHello() {\n    return `Hello From CatsController`;\n  }\n\n  @Get('/parent')\n  whatIsTheNinjaId(@Param('ninjaId') ninjaId: string) {\n    return `Hello From CatsController the ninjeId: ${ninjaId}`;\n  }\n\n  @Get('/:catId')\n  getCat(@Param('catId') id: string) {\n    const idx = parseInt(id, 10) || 0;\n    return { cat: this.cats[idx - 1] || null };\n  }\n\n  // For testing Pipes\n  @Post('/create')\n  public testing(@Body(new ValidationPipe()) data: CreateCatDTO): string[] {\n    this.cats.push(data.name);\n    return this.cats;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/cats/cats.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { CatsController } from './cats.controller';\nimport { KettyController } from './ketty.controller';\n\n@Module({\n  controllers: [CatsController, KettyController],\n})\nexport class CatsModule {}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/cats/dto/create-cat.dto.ts",
    "content": "import { IsString } from 'class-validator';\nexport class CreateCatDTO {\n  @IsString()\n  public readonly name: string;\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/cats/ketty.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/ketty')\nexport class KettyController {\n  @Get('/')\n  sayHello() {\n    return `Hello From KettyController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/dogs/dogs.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class DogsController {\n  @Get('/')\n  sayHello() {\n    return `Hello From DogsController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/dogs/dogs.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { DogsController } from './dogs.controller';\nimport { PuppyController } from './puppy.controller';\n\n@Module({\n  controllers: [DogsController, PuppyController],\n})\nexport class DogsModule {}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/dogs/puppy.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/puppy')\nexport class PuppyController {\n  @Get('/')\n  sayHello() {\n    return `Hello From PuppyController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/logger.middleware.ts",
    "content": "import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';\nimport { Routes } from 'nest-router';\n\n@Injectable()\nexport class LoggerMiddleware implements NestMiddleware {\n  resolve(...excluded: Routes): MiddlewareFunction {\n    return (req, _res, next) => {\n      const isExcluded =\n        excluded.filter(route => {\n          console.log(LoggerMiddleware.name, ':', '{ Request Path ->', req.path, ' }');\n          const excludePath = route.path === req.path;\n          return excludePath;\n        }).length > 0;\n      console.log(LoggerMiddleware.name, ':', '{ Is Excluded ->', isExcluded, ' }');\n      next();\n    };\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/main.hmr.ts",
    "content": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\ndeclare const module: any;\n\nasync function bootstrap() {\n  const app = await NestFactory.create(ApplicationModule);\n  await app.listen(3000);\n\n  if (module.hot) {\n    module.hot.accept();\n    module.hot.dispose(() => app.close());\n  }\n}\nbootstrap();\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/main.ts",
    "content": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\nasync function bootstrap() {\n  const app = await NestFactory.create(ApplicationModule);\n  await app.listen(3000);\n}\nbootstrap();\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/ninja/katana.controller.ts",
    "content": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/katana')\nexport class KatanaController {\n  @Get('/')\n  sayHello() {\n    return `Hello From KatanaController`;\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/ninja/ninja.controller.ts",
    "content": "import { Controller, Get, Param, Post, Body } from '@nestjs/common';\n\n@Controller()\nexport class NinjaController {\n  private readonly ninjas: string[] = [];\n  @Get('/')\n  sayHello() {\n    return `Hello From NinjaController`;\n  }\n\n  @Get('/all')\n  getAllNinja() {\n    return this.ninjas;\n  }\n\n  @Get('/:ninjaId')\n  getNinja(@Param('ninjaId') id: string) {\n    const idx = parseInt(id, 10) || 0;\n    return { ninja: this.ninjas[idx - 1] || null };\n  }\n\n  @Post('/create')\n  createNinja(@Body('name') name: string) {\n    const id = this.ninjas.push(name);\n    return { ninja: this.ninjas[id - 1] || null };\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/ninja/ninja.module.ts",
    "content": "import { Module } from '@nestjs/common';\nimport { NinjaController } from './ninja.controller';\nimport { KatanaController } from './katana.controller';\n\n@Module({\n  controllers: [NinjaController, KatanaController],\n})\nexport class NinjaModule {}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/src/routes.ts",
    "content": "import { Routes } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dogs/dogs.module';\nimport { NinjaModule } from './ninja/ninja.module';\nexport const routes: Routes = [\n  {\n    path: '/ninja',\n    module: NinjaModule,\n    children: [\n      { path: 'nested/cats', module: CatsModule },\n      { path: ':ninjaId/cats', module: CatsModule },\n      { path: '/dogs', module: DogsModule },\n    ],\n  },\n];\n"
  },
  {
    "path": "examples/nest-v5x-m2m/test/app.e2e-spec.ts",
    "content": "import request from 'supertest';\nimport { Test } from '@nestjs/testing';\nimport { AppModule } from './../src/app.module';\nimport { INestApplication } from '@nestjs/common';\n\ndescribe('AppController (e2e)', () => {\n  let app: INestApplication;\n\n  beforeAll(async () => {\n    const moduleFixture = await Test.createTestingModule({\n      imports: [AppModule],\n    }).compile();\n\n    app = moduleFixture.createNestApplication();\n    await app.init();\n  });\n\n  it('/GET /', () => {\n    return request(app.getHttpServer())\n      .get('/')\n      .expect(200)\n      .expect('Hello World!');\n  });\n});\n"
  },
  {
    "path": "examples/nest-v5x-m2m/test/jest-e2e.json",
    "content": "{\n  \"moduleFileExtensions\": [\"js\", \"json\", \"ts\"],\n  \"rootDir\": \".\",\n  \"testRegex\": \".e2e-spec.ts$\",\n  \"transform\": {\n    \"^.+\\\\.(t|j)s$\": \"ts-jest\"\n  }\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"declaration\": true,\n    \"noImplicitAny\": false,\n    \"removeComments\": true,\n    \"noLib\": false,\n    \"allowSyntheticDefaultImports\": true,\n    \"emitDecoratorMetadata\": true,\n    \"experimentalDecorators\": true,\n    \"target\": \"es6\",\n    \"sourceMap\": true,\n    \"outDir\": \"./dist\",\n    \"baseUrl\": \"./src\"\n  },\n  \"include\": [\n    \"src/**/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"**/*.spec.ts\"\n  ]\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/tsconfig.spec.json",
    "content": "{\n  \"extends\": \"tsconfig.json\",\n  \"compilerOptions\": {\n    \"types\": [\"jest\", \"node\"]\n  },\n  \"include\": [\"**/*.spec.ts\", \"**/*.d.ts\"]\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/tslint.json",
    "content": "{\n  \"defaultSeverity\": \"error\",\n  \"extends\": [\"tslint:recommended\"],\n  \"jsRules\": {\n    \"no-unused-expression\": true\n  },\n  \"rules\": {\n    \"eofline\": false,\n    \"quotemark\": [true, \"single\"],\n    \"indent\": false,\n    \"member-access\": [false],\n    \"ordered-imports\": [false],\n    \"max-line-length\": [true, 150],\n    \"member-ordering\": [false],\n    \"curly\": false,\n    \"interface-name\": [false],\n    \"array-type\": [false],\n    \"no-empty-interface\": false,\n    \"no-empty\": false,\n    \"arrow-parens\": false,\n    \"object-literal-sort-keys\": false,\n    \"no-unused-expression\": false,\n    \"no-console\": false,\n    \"variable-name\": [false],\n    \"one-line\": [false],\n    \"one-variable-per-declaration\": [false]\n  },\n  \"rulesDirectory\": []\n}\n"
  },
  {
    "path": "examples/nest-v5x-m2m/webpack.config.js",
    "content": "const webpack = require('webpack');\nconst path = require('path');\nconst nodeExternals = require('webpack-node-externals');\n\nmodule.exports = {\n  entry: ['webpack/hot/poll?1000', './src/main.hmr.ts'],\n  watch: true,\n  target: 'node',\n  externals: [\n    nodeExternals({\n      whitelist: ['webpack/hot/poll?1000'],\n    }),\n  ],\n  module: {\n    rules: [\n      {\n        test: /\\.tsx?$/,\n        use: 'ts-loader',\n        exclude: /node_modules/,\n      },\n    ],\n  },\n  mode: \"development\",\n  resolve: {\n    extensions: ['.tsx', '.ts', '.js'],\n  },\n  plugins: [\n    new webpack.HotModuleReplacementPlugin(),\n  ],\n  output: {\n    path: path.join(__dirname, 'dist'),\n    filename: 'server.js',\n  },\n};\n"
  },
  {
    "path": "jest.json",
    "content": "{\n  \"moduleFileExtensions\": [\"ts\", \"tsx\", \"js\", \"json\"],\n  \"transform\": {\n    \"^.+\\\\.tsx?$\": \"<rootDir>/node_modules/ts-jest/preprocessor.js\"\n  },\n  \"testRegex\": \"/src/.*\\\\.(test|spec).(ts|tsx|js)$\",\n  \"testEnvironment\": \"node\",\n  \"collectCoverageFrom\": [\n    \"src/**/*.ts\",\n    \"!src/main.ts\",\n    \"!src/app/constants.ts\",\n    \"!src/**/index.ts\",\n    \"!src/**/*.module.ts\",\n    \"!src/**/*.interface.ts\",\n    \"!src/**/*.enum.ts\",\n    \"!**/node_modules/**\",\n    \"!**/vendor/**\"\n  ],\n  \"coverageReporters\": [\"json\", \"lcov\"]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"nest-router\",\n  \"version\": \"1.0.9\",\n  \"description\": \"Router Module For Nestjs Framework\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"jest --notify --config=jest.json\",\n    \"test:watch\": \"jest --watch --config=jest.json\",\n    \"test:coverage\": \"jest --config=jest.json --coverage --coverageDirectory=coverage\",\n    \"build\": \"./scripts/build.sh\",\n    \"build:andMove\": \"./scripts/build.sh andMove\",\n    \"npm:publish\": \"cd lib && npm publish\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/shekohex/nest-router.git\"\n  },\n  \"keywords\": [\n    \"nestjs\",\n    \"router\",\n    \"addons\"\n  ],\n  \"author\": \"Shady Khalifa <shekohex@gmail.com>\",\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"@nestjs/common\": \"^5.0.0\",\n    \"@nestjs/core\": \"^5.0.0\",\n    \"@nestjs/testing\": \"^5.3.11\",\n    \"@types/jest\": \"^24.0.0\",\n    \"@types/node\": \"^12.0.0\",\n    \"coveralls\": \"^3.0.2\",\n    \"jest\": \"^23.6.0\",\n    \"reflect-metadata\": \"^0.1.12\",\n    \"rxjs\": \"^6.3.0\",\n    \"ts-jest\": \"^24.0.0\",\n    \"typescript\": \"^3.0.0\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/shekohex/nest-router/issues\"\n  },\n  \"homepage\": \"https://github.com/shekohex/nest-router#readme\"\n}\n"
  },
  {
    "path": "scripts/build.sh",
    "content": "#!/bin/bash\n# A basic script to build and compile the typescript files using tsc\n\n# Set an error handler\ntrap onExit EXIT\n\n# printing the simple stack trace\nonExit() {\n    while caller $((n++));\n    do :;\n    done;\n}\n\nbuild() {\n    echo 'Start building..'\n    # Run tsc\n    tsc -p tsconfig.prod.json\n    echo 'tsc exist with status code:' $?\n    echo 'Copying Other files..'\n    cp -rf package.json lib\n    cp -rf README.md lib\n    echo 'Done.'\n    echo '--------'\n}\n\nmove() {\n    echo 'Copying files to examples/**/node_modules ..'\n    for d in examples/*; do\n        if [ -d \"$d\" ]; then\n            dist=\"$d\"/node_modules/nest-router\n            echo 'Start copying to' \"$dist\"\n            mkdir -p \"$dist\" && cp -rf lib/* \"$dist\"\n        fi\n    done\n    echo 'Done.'\n    echo '--------'\n}\n\nbuild\n\nif [ \"$1\" = \"andMove\" ]; then\n    move\nfi"
  },
  {
    "path": "src/index.ts",
    "content": "export * from './router.module';\nexport * from './routes.interface';\n"
  },
  {
    "path": "src/router.module.ts",
    "content": "import { Module, DynamicModule } from '@nestjs/common';\nimport { MODULE_PATH, PATH_METADATA } from '@nestjs/common/constants';\nimport { ModulesContainer } from '@nestjs/core/injector/modules-container';\nimport { Controller, Type } from '@nestjs/common/interfaces';\nimport { UnknownElementException } from '@nestjs/core/errors/exceptions/unknown-element.exception';\nimport { validatePath } from './utils/validate-path.util';\nimport { flatRoutes } from './utils/flat-routes.util';\nimport { Routes } from './routes.interface';\n\n/**\n * A utility Module to Organize your Routes,\n * it could be imported in the Root Module of you application.\n */\n@Module({})\nexport class RouterModule {\n  private static readonly routesContainer: Map<string, string> = new Map();\n  constructor(readonly modulesContainer: ModulesContainer) {\n    const modules = [...modulesContainer.values()];\n    for (const nestModule of modules) {\n      const modulePath: string = Reflect.getMetadata(MODULE_PATH, nestModule.metatype);\n      for (const route of nestModule.routes.values()) {\n        RouterModule.routesContainer.set(route.name, validatePath(modulePath));\n      }\n    }\n  }\n\n  /**\n   * takes an array of modules and organize them in hierarchy way\n   * @param {Routes} routes Array of Routes\n   */\n  public static forRoutes(routes: Routes): DynamicModule {\n    RouterModule.buildPathMap(routes);\n    return {\n      module: RouterModule,\n    };\n  }\n\n  /**\n   * get the controller full route path eg: (controller's module prefix + controller's path).\n   * @param {Type<Controller>} controller the controller you need to get it's full path\n   */\n  public static resolvePath(controller: Type<Controller>): string {\n    const controllerPath: string = Reflect.getMetadata(PATH_METADATA, controller);\n    const modulePath = RouterModule.routesContainer.get(controller.name);\n    if (modulePath && controllerPath) {\n      return validatePath(modulePath + validatePath(controllerPath));\n    } else {\n      throw new UnknownElementException();\n    }\n  }\n\n  private static buildPathMap(routes: Routes) {\n    const flattenRoutes = flatRoutes(routes);\n    flattenRoutes.forEach(route => {\n      Reflect.defineMetadata(MODULE_PATH, validatePath(route.path), route.module);\n    });\n  }\n}\n"
  },
  {
    "path": "src/routes.interface.ts",
    "content": "import { Type } from '@nestjs/common';\n\n/**\n * Defines the Routes Tree\n * - `path` - a string describe the Module path which will be applied\n * to all it's controllers and childs\n * - `module` - the parent Module.\n * - `children` - an array of child Modules.\n * - `childrens` @deprecated - @see children\n */\nexport interface Route {\n  path: string;\n  module?: Type<any> | string;\n  childrens?: Routes | Type<any>[] | string[];\n  children?: Routes | Type<any>[] | string[];\n}\n\n/**\n * Defines the Routes Tree\n * - `path` - a string describe the Module path which will be applied\n * to all it's controllers and childs\n * - `module` - the parent Module.\n * - `children` - an array of child Modules.\n * - `childrens` @deprecated - @see children\n */\nexport type Routes = Route[];\n"
  },
  {
    "path": "src/test/router.module.spec.ts",
    "content": "import { RouterModule } from '../router.module';\nimport { Routes } from '../routes.interface';\nimport { Module, Controller } from '@nestjs/common';\nimport { MODULE_PATH } from '@nestjs/common/constants';\nimport { Test } from '@nestjs/testing';\nimport { INestApplication } from '@nestjs/common';\n\ndescribe('RouterModule', () => {\n  let app: INestApplication;\n\n  @Controller('/parent-controller')\n  class ParentController {}\n  @Controller('/child-controller')\n  class ChildController {}\n  @Controller('no-slash-controller')\n  class NoSlashController {}\n\n  class UnknownController {}\n  @Module({ controllers: [ParentController] })\n  class ParentModule {}\n\n  @Module({ controllers: [ChildController] })\n  class ChildModule {}\n\n  @Module({})\n  class AuthModule {}\n  @Module({})\n  class PaymentsModule {}\n\n  @Module({ controllers: [NoSlashController] })\n  class NoSlashModule {}\n\n  const routes1: Routes = [\n    {\n      path: 'parent',\n      module: ParentModule,\n      children: [\n        {\n          path: 'child',\n          module: ChildModule,\n        },\n      ],\n    },\n  ];\n  const routes2: Routes = [{ path: 'v1', children: [AuthModule, PaymentsModule, NoSlashModule] }];\n\n  @Module({ imports: [ParentModule, ChildModule, RouterModule.forRoutes(routes1)] })\n  class MainModule {}\n\n  @Module({ imports: [AuthModule, PaymentsModule, NoSlashModule, RouterModule.forRoutes(routes2)] })\n  class AppModule {}\n\n  test('it should add Path Metadata to all Routes', () => {\n    const parentPath = Reflect.getMetadata(MODULE_PATH, ParentModule);\n    const childPath = Reflect.getMetadata(MODULE_PATH, ChildModule);\n    expect(parentPath).toEqual('/parent');\n    expect(childPath).toEqual('/parent/child');\n  });\n\n  test('it should add paths even we omitted the module keyword', () => {\n    const authPath = Reflect.getMetadata(MODULE_PATH, AuthModule);\n    const paymentPath = Reflect.getMetadata(MODULE_PATH, PaymentsModule);\n    expect(authPath).toEqual('/v1');\n    expect(paymentPath).toEqual('/v1');\n  });\n\n  describe('Full Running App', async () => {\n    beforeAll(async () => {\n      const module = await Test.createTestingModule({\n        imports: [MainModule, AppModule],\n      }).compile();\n      app = module.createNestApplication();\n      await app.init();\n    });\n\n    it('should Resolve Controllers path with its Module Path if any', async () => {\n      expect(RouterModule.resolvePath(ParentController)).toEqual('/parent/parent-controller');\n      expect(RouterModule.resolvePath(ChildController)).toEqual('/parent/child/child-controller');\n    });\n\n    it('should throw error when we cannot find the controller', async () => {\n      expect(() => RouterModule.resolvePath(UnknownController)).toThrowError(\n        'Nest cannot find given element (it does not exist in current context)',\n      );\n    });\n\n    it('should resolve controllers path concatinated with its module path correctly', async () => {\n      expect(RouterModule.resolvePath(NoSlashController)).toEqual('/v1/no-slash-controller');\n    });\n\n    afterAll(async () => {\n      await app.close();\n    });\n  });\n});\n"
  },
  {
    "path": "src/test/utils/flat-routes.spec.ts",
    "content": "import { flatRoutes } from '../../utils/flat-routes.util';\ndescribe('FlatRoutes', () => {\n  const f = flatRoutes;\n  test('it should flat all Routes to endless, and we could also ommit the path', () => {\n    const routes = [\n      {\n        path: '/parent',\n        module: 'ParentModule',\n        children: [\n          {\n            path: '/child',\n            module: 'ChildModule',\n            children: [\n              { path: '/child2', module: 'ChildModule2' },\n              {\n                path: '/parentchild',\n                module: 'ParentChildModule',\n                children: [\n                  {\n                    path: '/childchild',\n                    module: 'ChildChildModule',\n                    children: [{ path: '/child2child', module: 'ChildChildModule2' }],\n                  },\n                ],\n              },\n            ],\n          },\n        ],\n      },\n      { path: '/v1', children: ['AuthModule', 'CatsModule', 'DogsModule'] },\n      { path: '/v2', children: ['AuthModule2', 'CatsModule2'] },\n      { path: '/v3', childrens: ['AuthModule3', 'CatsModule3'] },\n    ];\n    const expectedRoutes = [\n      { path: '/parent', module: 'ParentModule' },\n      { path: '/parent/child', module: 'ChildModule' },\n      { path: '/parent/child/child2', module: 'ChildModule2' },\n      { path: '/parent/child/parentchild', module: 'ParentChildModule' },\n      { path: '/parent/child/parentchild/childchild', module: 'ChildChildModule' },\n      { path: '/parent/child/parentchild/childchild/child2child', module: 'ChildChildModule2' },\n      { path: '/v1', module: 'AuthModule' },\n      { path: '/v1', module: 'CatsModule' },\n      { path: '/v1', module: 'DogsModule' },\n      { path: '/v2', module: 'AuthModule2' },\n      { path: '/v2', module: 'CatsModule2' },\n      { path: '/v3', module: 'AuthModule3' },\n      { path: '/v3', module: 'CatsModule3' },\n    ];\n    expect(f(routes)).toEqual(expectedRoutes);\n  });\n});\n"
  },
  {
    "path": "src/test/utils/validate-path.spec.ts",
    "content": "import { validatePath } from '../../utils/validate-path.util';\n\ndescribe('ValidatePath', () => {\n  const v = validatePath;\n  test('it should add a / if it dose not exist', () => {\n    expect(v('')).toEqual('/');\n    expect(v('path')).toEqual('/path');\n  });\n\n  test('it should remove all trailing slashes at the end of the path', () => {\n    expect(v('path/')).toEqual('/path');\n    expect(v('path///')).toEqual('/path');\n    expect(v('/path/path///')).toEqual('/path/path');\n  });\n\n  test('it should replace all slashes with only one slash', () => {\n    expect(v('////path/')).toEqual('/path');\n    expect(v('///')).toEqual('/');\n    expect(v('/path////path///')).toEqual('/path/path');\n  });\n});\n"
  },
  {
    "path": "src/utils/flat-routes.util.ts",
    "content": "import { isString } from 'util';\nimport { Routes } from '../routes.interface';\nimport { validatePath } from './validate-path.util';\n\nconst result = [];\nexport function flatRoutes(routes: Routes) {\n  routes.forEach(element => {\n    if (element.module && element.path) {\n      result.push(element);\n    }\n    // this block will be removed soon\n    if (!element.children && element.childrens) {\n      element.children = element.childrens;\n      console.log(\n        `\\x1b[33m%s\\x1b[0m`,\n        `WARNING: 'childrens' is deprecated, use 'children' instead.`,\n      );\n    }\n    if (element.children) {\n      const childrenRef = element.children as Routes;\n      childrenRef.forEach(child => {\n        if (!isString(child) && child.path) {\n          child.path = validatePath(validatePath(element.path) + validatePath(child.path));\n        } else {\n          result.push({ path: element.path, module: child });\n        }\n      });\n      return flatRoutes(childrenRef);\n    }\n  });\n  result.forEach(route => {\n    delete route.children;\n  });\n  return result;\n}\n"
  },
  {
    "path": "src/utils/validate-path.util.ts",
    "content": "export const validatePath = (path: string): string =>\n  path\n    ? path.startsWith('/')\n      ? ('/' + path.replace(/\\/+$/, '')).replace(/\\/+/g, '/')\n      : '/' + path.replace(/\\/+$/, '')\n    : '/';\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"declaration\": true,\n    \"module\": \"commonjs\",\n    \"moduleResolution\": \"node\",\n    \"outDir\": \"./lib\",\n    \"preserveConstEnums\": true,\n    \"rootDir\": \"./src\",\n    \"baseUrl\": \".\",\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n    \"sourceMap\": true,\n    \"target\": \"es6\",\n    \"typeRoots\": [\n      \"node_modules/@types\"\n    ],\n    \"lib\": [\n      \"es7\"\n    ]\n  },\n  \"include\": [\n    \"src/**/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\"\n  ]\n}"
  },
  {
    "path": "tsconfig.prod.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\n    \"src/**/*.spec.ts\"\n  ]\n}\n"
  },
  {
    "path": "tslint.json",
    "content": "{\n  \"defaultSeverity\": \"warn\",\n  \"extends\": [\"tslint:recommended\"],\n  \"jsRules\": {\n    \"no-unused-expression\": true\n  },\n  \"rules\": {\n    \"eofline\": false,\n    \"quotemark\": [true, \"single\"],\n    \"indent\": false,\n    \"ordered-imports\": [false],\n    \"max-line-length\": [true, 100],\n    \"member-ordering\": [false],\n    \"curly\": false,\n    \"interface-name\": [false],\n    \"array-type\": [false],\n    \"no-empty-interface\": false,\n    \"no-empty\": false,\n    \"arrow-parens\": false,\n    \"object-literal-sort-keys\": false,\n    \"no-unused-expression\": false,\n    \"max-classes-per-file\": [false],\n    \"ban-types\": false,\n    \"variable-name\": [false],\n    \"one-line\": [false],\n    \"one-variable-per-declaration\": [false]\n  },\n  \"rulesDirectory\": []\n}\n"
  },
  {
    "path": "wallaby.js",
    "content": "module.exports = function() {\n  return {\n    files: ['src/**/*.ts', 'jest.json', '!src/**/*.spec.ts'], // <--\n    tests: ['src/**/*.spec.ts'],\n    env: { type: 'node', runner: 'node' },\n    testFramework: 'jest',\n    setup: function(wallaby) {\n      var jestConfig = require('./jest.json').jest;\n      wallaby.testFramework.configure(jestConfig);\n    },\n  };\n};\n"
  }
]