Repository: shekohex/nest-router
Branch: master
Commit: 78d907258e8e
Files: 85
Total size: 48.3 KB
Directory structure:
gitextract_4e6hp759/
├── .gitignore
├── .npmignore
├── .prettierrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── examples/
│ ├── nest-v4x/
│ │ ├── index.js
│ │ ├── jest.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── app.module.ts
│ │ │ ├── cats/
│ │ │ │ ├── cats.controller.ts
│ │ │ │ ├── cats.module.ts
│ │ │ │ └── ketty.controller.ts
│ │ │ ├── dogs/
│ │ │ │ ├── dogs.controller.ts
│ │ │ │ ├── dogs.module.ts
│ │ │ │ └── puppy.controller.ts
│ │ │ ├── main.ts
│ │ │ ├── ninja/
│ │ │ │ ├── katana.controller.ts
│ │ │ │ ├── ninja.controller.ts
│ │ │ │ └── ninja.module.ts
│ │ │ └── routes.ts
│ │ ├── tsconfig.json
│ │ └── tslint.json
│ ├── nest-v5x/
│ │ ├── nodemon.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── app.module.ts
│ │ │ ├── cats/
│ │ │ │ ├── cats.controller.ts
│ │ │ │ ├── cats.module.ts
│ │ │ │ ├── dto/
│ │ │ │ │ └── create-cat.dto.ts
│ │ │ │ └── ketty.controller.ts
│ │ │ ├── dogs/
│ │ │ │ ├── dogs.controller.ts
│ │ │ │ ├── dogs.module.ts
│ │ │ │ └── puppy.controller.ts
│ │ │ ├── logger.middleware.ts
│ │ │ ├── main.hmr.ts
│ │ │ ├── main.ts
│ │ │ ├── ninja/
│ │ │ │ ├── katana.controller.ts
│ │ │ │ ├── ninja.controller.ts
│ │ │ │ └── ninja.module.ts
│ │ │ └── routes.ts
│ │ ├── test/
│ │ │ ├── app.e2e-spec.ts
│ │ │ └── jest-e2e.json
│ │ ├── tsconfig.json
│ │ ├── tsconfig.spec.json
│ │ ├── tslint.json
│ │ └── webpack.config.js
│ └── nest-v5x-m2m/
│ ├── nodemon.json
│ ├── package.json
│ ├── src/
│ │ ├── app.module.ts
│ │ ├── cats/
│ │ │ ├── cats.controller.ts
│ │ │ ├── cats.module.ts
│ │ │ ├── dto/
│ │ │ │ └── create-cat.dto.ts
│ │ │ └── ketty.controller.ts
│ │ ├── dogs/
│ │ │ ├── dogs.controller.ts
│ │ │ ├── dogs.module.ts
│ │ │ └── puppy.controller.ts
│ │ ├── logger.middleware.ts
│ │ ├── main.hmr.ts
│ │ ├── main.ts
│ │ ├── ninja/
│ │ │ ├── katana.controller.ts
│ │ │ ├── ninja.controller.ts
│ │ │ └── ninja.module.ts
│ │ └── routes.ts
│ ├── test/
│ │ ├── app.e2e-spec.ts
│ │ └── jest-e2e.json
│ ├── tsconfig.json
│ ├── tsconfig.spec.json
│ ├── tslint.json
│ └── webpack.config.js
├── jest.json
├── package.json
├── scripts/
│ └── build.sh
├── src/
│ ├── index.ts
│ ├── router.module.ts
│ ├── routes.interface.ts
│ ├── test/
│ │ ├── router.module.spec.ts
│ │ └── utils/
│ │ ├── flat-routes.spec.ts
│ │ └── validate-path.spec.ts
│ └── utils/
│ ├── flat-routes.util.ts
│ └── validate-path.util.ts
├── tsconfig.json
├── tsconfig.prod.json
├── tslint.json
└── wallaby.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
#ide
.vscode
.idea
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# build and Play
play
# remove build or lib from repo
lib
dist
================================================
FILE: .npmignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
#ide
.vscode
.idea
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# NPM
src
example
gulpfile.js
.prettierrc
.travis.yml
================================================
FILE: .prettierrc
================================================
{
"semi": true,
"useTabs": false,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "all"
}
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- "8"
- "9"
- "10"
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
install:
- npm install
- npm run build
script:
- npm test
after_success:
- npm run test:coverage
- "npm install coveralls && cat ./coverage/lcov.info | coveralls"
================================================
FILE: CHANGELOG.md
================================================
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.0.9]
## Bugs
* Fix Bug [#41](https://github.com/shekohex/nest-router/issues/41)
## [1.0.8]
### Added
* Resolve Full Controller Path from anywhere ([#32](https://github.com/shekohex/nest-router/pull/32))
## Changed
* Update Dev Dependencies
## [1.0.7] - 2018-09-28
### Changed
* Project dependency refactor
* add node v10 as a test target
## [1.0.6] - 2018-06-20
### Changed
* Now Nest Router Module Using Nest V5+
> See examples folder, there is `nest-v5x`.
## [1.0.5] - 2018-02-27
### Deprecated
* `childrens`, use `children` instead.
see [why](https://github.com/shekohex/nest-router/issues/6)?
## [1.0.4] - 2018-02-12
### Added
* You can now Omit the `module` keyword and just using an arry
of `children` and one `path` proparty.
## [1.0.3] - 2018-02-10
### Added
* `children` array can be array with just modules.
this means you can omit the `path` keyword.
* Unreleased section to gather unreleased changes and encourage note
keeping prior to releases.
## [1.0.2] - 2018-02-08
### Added
* Routes now can be endless nested array.
## [1.0.1] - 2018-02-05
### Changed
* `children` now an Array insted of `object`
## [1.0.0] - 2018-02-05
* Published to NPM :rocket:
* add continuous integration "Travis CI"
## [0.0.0] - 2018-01-31
### Added
* Greenkeeper badge
* README
* Good examples and basic guidelines, in example folder and README.
* Build status badge
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Shady Khalifa
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Nest Router :vertical_traffic_light:
[](https://greenkeeper.io/) [](https://travis-ci.org/shekohex/nest-router) [](Https://www.npmjs.com/package/nest-router) [](https://coveralls.io/github/shekohex/nest-router?branch=master)
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fshekohex%2Fnest-router?ref=badge_shield)
Router Module For [Nestjs](https://github.com/nestjs/nest) Framework
## Important Note
As of Nestjs `v8.0.0` This module got added into the `@nestjs/core`.
see the [docs](https://docs.nestjs.com/recipes/router-module)
with that being said, this package is still maintained (for now).
## Quick Overview
`RouterModule` helps you organize your routes and lets you create a routes tree.
### How ?
Every 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`
> see issue [#255](https://github.com/nestjs/nest/issues/255) .
## Install
IMPORTANT: you need Nest > v4.5.10+
```bash
npm install nest-router --save
```
OR
```bash
yarn add nest-router
```
## Setup
See how easy it is to set up.
```ts
... //imports
const routes: Routes = [
{
path: '/ninja',
module: NinjaModule,
children: [
{
path: '/cats',
module: CatsModule,
},
{
path: '/dogs',
module: DogsModule,
},
],
},
];
@Module({
imports: [
RouterModule.forRoutes(routes), // setup the routes
CatsModule,
DogsModule,
NinjaModule
], // as usual, nothing new
})
export class ApplicationModule {}
```
> :+1: TIP: Keep all of your routes in a separate file like `routes.ts`
In this example, all the controllers in `NinjaModule` will be prefixed by `/ninja` and it
has two childs, `CatsModule` and `DogsModule`.
Will the controllers of `CatsModule` be prefixed by `/cats`? NO!! :open_mouth:
The `CatsModule` is a child of `NinjaModule` so it will be prefixed by `/ninja/cats/` instead.
And so will `DogsModule`.
> See examples folder for more information.
#### Example Folder Project Structure
```bash
.
├── app.module.ts
├── cats
│ ├── cats.controller.ts
│ ├── cats.module.ts
│ └── ketty.controller.ts
├── dogs
│ ├── dogs.controller.ts
│ ├── dogs.module.ts
│ └── puppy.controller.ts
├── main.ts
└── ninja
├── katana.controller.ts
├── ninja.controller.ts
└── ninja.module.ts
```
And here is a simple, nice route tree of `example` folder:
```bash
ninja
├── /
├── /katana
├── cats
│ ├── /
│ └── /ketty
├── dogs
├── /
└── /puppy
```
Nice!
#### Params in nested routes
In 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:
```ts
... //imports
const routes: Routes = [
{
path: '/ninja',
module: NinjaModule,
children: [
{
path: '/:ninjaId/cats',
module: CatsModule,
},
{
path: '/:ninjaId/dogs',
module: DogsModule,
},
],
},
];
```
The `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.
#### Resolve Full Controller Path:
Nestjs 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:
```ts
consumer.apply(someMiddleware).forRoutes(SomeController);
```
you should do
```ts
consumer.apply(someMiddleware).forRoutes(RouterModule.resolvePath(SomeController));
```
see [#32](https://github.com/shekohex/nest-router/pull/32) for more information about this.
## CHANGELOG
See [CHANGELOG](CHANGELOG.md) for more information.
## Contributing
You are welcome to contribute to this project, just open a PR.
## Authors
* **Shady Khalifa** - _Initial work_
See also the list of [contributors](https://github.com/shekohex/nest-router/contributors) who participated in this project.
## License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fshekohex%2Fnest-router?ref=badge_large)
================================================
FILE: examples/nest-v4x/index.js
================================================
require('ts-node/register');
require('./src/main');
================================================
FILE: examples/nest-v4x/jest.json
================================================
{
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"transform": {
"^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "/src/.*\\.(test|spec).(ts|tsx|js)$",
"collectCoverageFrom" : ["src/**/*.{js,jsx,tsx,ts}", "!**/node_modules/**", "!**/vendor/**"],
"coverageReporters": ["json", "lcov"]
}
================================================
FILE: examples/nest-v4x/package.json
================================================
{
"name": "nest-router-example-v4x",
"version": "1.0.0",
"description": "Nest TypeScript starter repository",
"license": "MIT",
"scripts": {
"start": "node index.js",
"prestart:prod": "tsc",
"start:prod": "node dist/main.js",
"test": "jest --config=jest.json",
"test:watch": "jest --watch --config=jest.json",
"test:coverage": "jest --config=jest.json --coverage --coverageDirectory=coverage",
"e2e": "jest --config=e2e/jest-e2e.json --forceExit",
"e2e:watch": "jest --watch --config=e2e/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^4.6.4",
"@nestjs/core": "^4.6.4",
"@nestjs/testing": "^4.6.1",
"class-transformer": "^0.1.7",
"class-validator": "^0.7.2",
"nest-router": "^1.0.5",
"reflect-metadata": "^0.1.10",
"rxjs": "^5.4.3",
"typescript": "^2.4.2"
},
"devDependencies": {
"@types/jest": "^20.0.8",
"@types/node": "^7.0.41",
"jest": "^20.0.4",
"supertest": "^3.0.0",
"ts-jest": "^20.0.14",
"ts-node": "^3.3.0"
}
}
================================================
FILE: examples/nest-v4x/src/app.module.ts
================================================
import { Module, NestModule, MiddlewaresConsumer, RequestMethod } from '@nestjs/common';
import { RouterModule } from 'nest-router';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';
import { NinjaModule } from './ninja/ninja.module';
import { routes } from './routes';
@Module({
imports: [RouterModule.forRoutes(routes), CatsModule, DogsModule, NinjaModule],
})
export class ApplicationModule {}
================================================
FILE: examples/nest-v4x/src/cats/cats.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller()
export class CatsController {
@Get('/')
sayHello() {
return `Hello From CatsController`;
}
}
================================================
FILE: examples/nest-v4x/src/cats/cats.module.ts
================================================
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { KettyController } from './ketty.controller';
@Module({
controllers: [CatsController, KettyController],
})
export class CatsModule {}
================================================
FILE: examples/nest-v4x/src/cats/ketty.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/ketty')
export class KettyController {
@Get('/')
sayHello() {
return `Hello From KettyController`;
}
}
================================================
FILE: examples/nest-v4x/src/dogs/dogs.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller()
export class DogsController {
@Get('/')
sayHello() {
return `Hello From DogsController`;
}
}
================================================
FILE: examples/nest-v4x/src/dogs/dogs.module.ts
================================================
import { Module } from '@nestjs/common';
import { DogsController } from './dogs.controller';
import { PuppyController } from './puppy.controller';
@Module({
controllers: [DogsController, PuppyController],
})
export class DogsModule {}
================================================
FILE: examples/nest-v4x/src/dogs/puppy.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/puppy')
export class PuppyController {
@Get('/')
sayHello() {
return `Hello From PuppyController`;
}
}
================================================
FILE: examples/nest-v4x/src/main.ts
================================================
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(ApplicationModule);
await app.listen(3000);
}
bootstrap();
================================================
FILE: examples/nest-v4x/src/ninja/katana.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/katana')
export class KatanaController {
@Get('/')
sayHello() {
return `Hello From KatanaController`;
}
}
================================================
FILE: examples/nest-v4x/src/ninja/ninja.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller()
export class NinjaController {
@Get('/')
sayHello() {
return `Hello From NinjaController`;
}
}
================================================
FILE: examples/nest-v4x/src/ninja/ninja.module.ts
================================================
import { Module } from '@nestjs/common';
import { NinjaController } from './ninja.controller';
import { KatanaController } from './katana.controller';
@Module({
controllers: [NinjaController, KatanaController],
})
export class NinjaModule {}
================================================
FILE: examples/nest-v4x/src/routes.ts
================================================
import { Routes } from 'nest-router';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';
import { NinjaModule } from './ninja/ninja.module';
export const routes: Routes = [
{
path: '/ninja',
module: NinjaModule,
children: [{ path: '/cats', module: CatsModule }, { path: '/dogs', module: DogsModule }],
},
];
================================================
FILE: examples/nest-v4x/tsconfig.json
================================================
{
"compilerOptions": {
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"allowJs": true,
"outDir": "./dist"
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
================================================
FILE: examples/nest-v4x/tslint.json
================================================
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {
"no-unused-expression": true
},
"rules": {
"eofline": false,
"quotemark": [
true,
"single"
],
"ordered-imports": [
false
],
"max-line-length": [
150
],
"member-ordering": [
false
],
"curly": false,
"interface-name": [
false
],
"array-type": [
false
],
"member-access": [
false
],
"no-empty-interface": false,
"no-empty": false,
"arrow-parens": false,
"object-literal-sort-keys": false,
"no-unused-expression": false,
"max-classes-per-file": [
false
],
"variable-name": [
false
],
"one-line": [
false
],
"one-variable-per-declaration": [
false
]
},
"rulesDirectory": []
}
================================================
FILE: examples/nest-v5x/nodemon.json
================================================
{
"watch": ["src"],
"ext": "ts",
"ignore": ["src/**/*.spec.ts"],
"exec": "ts-node -r tsconfig-paths/register src/main.ts"
}
================================================
FILE: examples/nest-v5x/package.json
================================================
{
"name": "nest-router-example-v5x",
"version": "1.0.0",
"description": "Nest TypeScript starter repository",
"license": "MIT",
"scripts": {
"format": "prettier --write \"src/**/*.ts\"",
"start": "ts-node -r tsconfig-paths/register src/main.ts",
"start:dev": "nodemon",
"prestart:prod": "rm -rf dist && tsc",
"start:prod": "node dist/main.js",
"start:hmr": "node dist/server",
"lint": "tslint -p tsconfig.json -c tslint.json",
"test": "jest",
"test:cov": "jest --coverage",
"test:e2e": "jest --config ./test/jest-e2e.json",
"webpack": "webpack --config webpack.config.js"
},
"dependencies": {
"@nestjs/common": "^5.5.0",
"@nestjs/core": "^5.5.0",
"@nestjs/microservices": "^5.5.0",
"@nestjs/testing": "^5.5.0",
"@nestjs/websockets": "^5.5.0",
"class-transformer": "^0.2.0",
"class-validator": "^0.9.1",
"nest-router": "^1.0.8",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.3.0",
"typescript": "^2.9.2"
},
"devDependencies": {
"@types/express": "^4.0.39",
"@types/jest": "^21.1.8",
"@types/node": "^9.3.0",
"@types/supertest": "^2.0.4",
"jest": "^21.2.1",
"nodemon": "^1.14.1",
"prettier": "^1.11.1",
"supertest": "^3.0.0",
"ts-jest": "^21.2.4",
"ts-loader": "^4.1.0",
"ts-node": "^4.1.0",
"tsconfig-paths": "^3.1.1",
"tslint": "5.3.2",
"webpack": "^4.2.0",
"webpack-cli": "^5.0.1",
"webpack-node-externals": "^1.6.0"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage"
}
}
================================================
FILE: examples/nest-v5x/src/app.module.ts
================================================
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { RouterModule, Route } from 'nest-router';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';
import { NinjaModule } from './ninja/ninja.module';
import { routes } from './routes';
import { LoggerMiddleware } from './logger.middleware';
@Module({
imports: [RouterModule.forRoutes(routes), CatsModule, DogsModule, NinjaModule],
})
export class ApplicationModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.with({ path: '/ninja' } as Route)
.forRoutes('/');
}
}
================================================
FILE: examples/nest-v5x/src/cats/cats.controller.ts
================================================
import { Controller, Get, Post, Body, ValidationPipe } from '@nestjs/common';
import { CreateCatDTO } from './dto/create-cat.dto';
@Controller()
export class CatsController {
private cats: string[] = [];
@Get('/')
sayHello() {
return `Hello From CatsController`;
}
// For testing Pipes
@Post('/create')
public testing(@Body(new ValidationPipe()) data: CreateCatDTO): string[] {
this.cats.push(data.name);
return this.cats;
}
}
================================================
FILE: examples/nest-v5x/src/cats/cats.module.ts
================================================
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { KettyController } from './ketty.controller';
@Module({
controllers: [CatsController, KettyController],
})
export class CatsModule {}
================================================
FILE: examples/nest-v5x/src/cats/dto/create-cat.dto.ts
================================================
import { IsString } from 'class-validator';
export class CreateCatDTO {
@IsString()
public readonly name: string;
}
================================================
FILE: examples/nest-v5x/src/cats/ketty.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/ketty')
export class KettyController {
@Get('/')
sayHello() {
return `Hello From KettyController`;
}
}
================================================
FILE: examples/nest-v5x/src/dogs/dogs.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller()
export class DogsController {
@Get('/')
sayHello() {
return `Hello From DogsController`;
}
}
================================================
FILE: examples/nest-v5x/src/dogs/dogs.module.ts
================================================
import { Module } from '@nestjs/common';
import { DogsController } from './dogs.controller';
import { PuppyController } from './puppy.controller';
@Module({
controllers: [DogsController, PuppyController],
})
export class DogsModule {}
================================================
FILE: examples/nest-v5x/src/dogs/puppy.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/puppy')
export class PuppyController {
@Get('/')
sayHello() {
return `Hello From PuppyController`;
}
}
================================================
FILE: examples/nest-v5x/src/logger.middleware.ts
================================================
import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';
import { Routes } from 'nest-router';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
resolve(...excluded: Routes): MiddlewareFunction {
return (req, _res, next) => {
const isExcluded =
excluded.filter(route => {
console.log(LoggerMiddleware.name, ':', '{ Request Path ->', req.path, ' }');
const excludePath = route.path === req.path;
return excludePath;
}).length > 0;
console.log(LoggerMiddleware.name, ':', '{ Is Excluded ->', isExcluded, ' }');
next();
};
}
}
================================================
FILE: examples/nest-v5x/src/main.hmr.ts
================================================
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';
declare const module: any;
async function bootstrap() {
const app = await NestFactory.create(ApplicationModule);
await app.listen(3000);
if (module.hot) {
module.hot.accept();
module.hot.dispose(() => app.close());
}
}
bootstrap();
================================================
FILE: examples/nest-v5x/src/main.ts
================================================
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(ApplicationModule);
await app.listen(3000);
}
bootstrap();
================================================
FILE: examples/nest-v5x/src/ninja/katana.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/katana')
export class KatanaController {
@Get('/')
sayHello() {
return `Hello From KatanaController`;
}
}
================================================
FILE: examples/nest-v5x/src/ninja/ninja.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller()
export class NinjaController {
@Get('/')
sayHello() {
return `Hello From NinjaController`;
}
}
================================================
FILE: examples/nest-v5x/src/ninja/ninja.module.ts
================================================
import { Module } from '@nestjs/common';
import { NinjaController } from './ninja.controller';
import { KatanaController } from './katana.controller';
@Module({
controllers: [NinjaController, KatanaController],
})
export class NinjaModule {}
================================================
FILE: examples/nest-v5x/src/routes.ts
================================================
import { Routes } from 'nest-router';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';
import { NinjaModule } from './ninja/ninja.module';
export const routes: Routes = [
{
path: '/ninja',
module: NinjaModule,
children: [{ path: '/cats', module: CatsModule }, { path: '/dogs', module: DogsModule }],
},
];
================================================
FILE: examples/nest-v5x/test/app.e2e-spec.ts
================================================
import request from 'supertest';
import { Test } from '@nestjs/testing';
import { AppModule } from './../src/app.module';
import { INestApplication } from '@nestjs/common';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/GET /', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});
================================================
FILE: examples/nest-v5x/test/jest-e2e.json
================================================
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}
================================================
FILE: examples/nest-v5x/tsconfig.json
================================================
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"allowSyntheticDefaultImports": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
================================================
FILE: examples/nest-v5x/tsconfig.spec.json
================================================
{
"extends": "tsconfig.json",
"compilerOptions": {
"types": ["jest", "node"]
},
"include": ["**/*.spec.ts", "**/*.d.ts"]
}
================================================
FILE: examples/nest-v5x/tslint.json
================================================
{
"defaultSeverity": "error",
"extends": ["tslint:recommended"],
"jsRules": {
"no-unused-expression": true
},
"rules": {
"eofline": false,
"quotemark": [true, "single"],
"indent": false,
"member-access": [false],
"ordered-imports": [false],
"max-line-length": [true, 150],
"member-ordering": [false],
"curly": false,
"interface-name": [false],
"array-type": [false],
"no-empty-interface": false,
"no-empty": false,
"arrow-parens": false,
"object-literal-sort-keys": false,
"no-unused-expression": false,
"no-console": false,
"variable-name": [false],
"one-line": [false],
"one-variable-per-declaration": [false]
},
"rulesDirectory": []
}
================================================
FILE: examples/nest-v5x/webpack.config.js
================================================
const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
entry: ['webpack/hot/poll?1000', './src/main.hmr.ts'],
watch: true,
target: 'node',
externals: [
nodeExternals({
whitelist: ['webpack/hot/poll?1000'],
}),
],
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
mode: "development",
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'server.js',
},
};
================================================
FILE: examples/nest-v5x-m2m/nodemon.json
================================================
{
"watch": ["src"],
"ext": "ts",
"ignore": ["src/**/*.spec.ts"],
"exec": "ts-node -r tsconfig-paths/register src/main.ts"
}
================================================
FILE: examples/nest-v5x-m2m/package.json
================================================
{
"name": "nest-router-example-v5x-m2m",
"version": "1.0.0",
"description": "Nest TypeScript starter repository",
"license": "MIT",
"scripts": {
"format": "prettier --write \"src/**/*.ts\"",
"start": "ts-node -r tsconfig-paths/register src/main.ts",
"start:dev": "nodemon",
"prestart:prod": "rm -rf dist && tsc",
"start:prod": "node dist/main.js",
"start:hmr": "node dist/server",
"lint": "tslint -p tsconfig.json -c tslint.json",
"test": "jest",
"test:cov": "jest --coverage",
"test:e2e": "jest --config ./test/jest-e2e.json",
"webpack": "webpack --config webpack.config.js"
},
"dependencies": {
"@nestjs/common": "^5.5.0",
"@nestjs/core": "^5.5.0",
"@nestjs/microservices": "^5.5.0",
"@nestjs/testing": "^5.5.0",
"@nestjs/websockets": "^5.5.0",
"class-transformer": "^0.2.0",
"class-validator": "^0.9.1",
"nest-router": "^1.0.9",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.3.0",
"typescript": "^2.9.2"
},
"devDependencies": {
"@types/express": "^4.0.39",
"@types/jest": "^21.1.8",
"@types/node": "^9.3.0",
"@types/supertest": "^2.0.4",
"jest": "^21.2.1",
"nodemon": "^1.14.1",
"prettier": "^1.11.1",
"supertest": "^3.0.0",
"ts-jest": "^21.2.4",
"ts-loader": "^4.1.0",
"ts-node": "^4.1.0",
"tsconfig-paths": "^3.1.1",
"tslint": "5.3.2",
"webpack": "^4.28.0",
"webpack-cli": "^3.1.2",
"webpack-node-externals": "^1.7.2"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage"
}
}
================================================
FILE: examples/nest-v5x-m2m/src/app.module.ts
================================================
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { RouterModule, Route } from 'nest-router';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';
import { NinjaModule } from './ninja/ninja.module';
import { routes } from './routes';
import { LoggerMiddleware } from './logger.middleware';
@Module({
imports: [RouterModule.forRoutes(routes), CatsModule, DogsModule, NinjaModule],
})
export class ApplicationModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.with({ path: '/ninja' } as Route)
.forRoutes('/');
}
}
================================================
FILE: examples/nest-v5x-m2m/src/cats/cats.controller.ts
================================================
import { Controller, Get, Post, Body, ValidationPipe, Param } from '@nestjs/common';
import { CreateCatDTO } from './dto/create-cat.dto';
@Controller()
export class CatsController {
private cats: string[] = [];
@Get('/')
sayHello() {
return `Hello From CatsController`;
}
@Get('/parent')
whatIsTheNinjaId(@Param('ninjaId') ninjaId: string) {
return `Hello From CatsController the ninjeId: ${ninjaId}`;
}
@Get('/:catId')
getCat(@Param('catId') id: string) {
const idx = parseInt(id, 10) || 0;
return { cat: this.cats[idx - 1] || null };
}
// For testing Pipes
@Post('/create')
public testing(@Body(new ValidationPipe()) data: CreateCatDTO): string[] {
this.cats.push(data.name);
return this.cats;
}
}
================================================
FILE: examples/nest-v5x-m2m/src/cats/cats.module.ts
================================================
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { KettyController } from './ketty.controller';
@Module({
controllers: [CatsController, KettyController],
})
export class CatsModule {}
================================================
FILE: examples/nest-v5x-m2m/src/cats/dto/create-cat.dto.ts
================================================
import { IsString } from 'class-validator';
export class CreateCatDTO {
@IsString()
public readonly name: string;
}
================================================
FILE: examples/nest-v5x-m2m/src/cats/ketty.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/ketty')
export class KettyController {
@Get('/')
sayHello() {
return `Hello From KettyController`;
}
}
================================================
FILE: examples/nest-v5x-m2m/src/dogs/dogs.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller()
export class DogsController {
@Get('/')
sayHello() {
return `Hello From DogsController`;
}
}
================================================
FILE: examples/nest-v5x-m2m/src/dogs/dogs.module.ts
================================================
import { Module } from '@nestjs/common';
import { DogsController } from './dogs.controller';
import { PuppyController } from './puppy.controller';
@Module({
controllers: [DogsController, PuppyController],
})
export class DogsModule {}
================================================
FILE: examples/nest-v5x-m2m/src/dogs/puppy.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/puppy')
export class PuppyController {
@Get('/')
sayHello() {
return `Hello From PuppyController`;
}
}
================================================
FILE: examples/nest-v5x-m2m/src/logger.middleware.ts
================================================
import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';
import { Routes } from 'nest-router';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
resolve(...excluded: Routes): MiddlewareFunction {
return (req, _res, next) => {
const isExcluded =
excluded.filter(route => {
console.log(LoggerMiddleware.name, ':', '{ Request Path ->', req.path, ' }');
const excludePath = route.path === req.path;
return excludePath;
}).length > 0;
console.log(LoggerMiddleware.name, ':', '{ Is Excluded ->', isExcluded, ' }');
next();
};
}
}
================================================
FILE: examples/nest-v5x-m2m/src/main.hmr.ts
================================================
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';
declare const module: any;
async function bootstrap() {
const app = await NestFactory.create(ApplicationModule);
await app.listen(3000);
if (module.hot) {
module.hot.accept();
module.hot.dispose(() => app.close());
}
}
bootstrap();
================================================
FILE: examples/nest-v5x-m2m/src/main.ts
================================================
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(ApplicationModule);
await app.listen(3000);
}
bootstrap();
================================================
FILE: examples/nest-v5x-m2m/src/ninja/katana.controller.ts
================================================
import { Controller, Get } from '@nestjs/common';
@Controller('/katana')
export class KatanaController {
@Get('/')
sayHello() {
return `Hello From KatanaController`;
}
}
================================================
FILE: examples/nest-v5x-m2m/src/ninja/ninja.controller.ts
================================================
import { Controller, Get, Param, Post, Body } from '@nestjs/common';
@Controller()
export class NinjaController {
private readonly ninjas: string[] = [];
@Get('/')
sayHello() {
return `Hello From NinjaController`;
}
@Get('/all')
getAllNinja() {
return this.ninjas;
}
@Get('/:ninjaId')
getNinja(@Param('ninjaId') id: string) {
const idx = parseInt(id, 10) || 0;
return { ninja: this.ninjas[idx - 1] || null };
}
@Post('/create')
createNinja(@Body('name') name: string) {
const id = this.ninjas.push(name);
return { ninja: this.ninjas[id - 1] || null };
}
}
================================================
FILE: examples/nest-v5x-m2m/src/ninja/ninja.module.ts
================================================
import { Module } from '@nestjs/common';
import { NinjaController } from './ninja.controller';
import { KatanaController } from './katana.controller';
@Module({
controllers: [NinjaController, KatanaController],
})
export class NinjaModule {}
================================================
FILE: examples/nest-v5x-m2m/src/routes.ts
================================================
import { Routes } from 'nest-router';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';
import { NinjaModule } from './ninja/ninja.module';
export const routes: Routes = [
{
path: '/ninja',
module: NinjaModule,
children: [
{ path: 'nested/cats', module: CatsModule },
{ path: ':ninjaId/cats', module: CatsModule },
{ path: '/dogs', module: DogsModule },
],
},
];
================================================
FILE: examples/nest-v5x-m2m/test/app.e2e-spec.ts
================================================
import request from 'supertest';
import { Test } from '@nestjs/testing';
import { AppModule } from './../src/app.module';
import { INestApplication } from '@nestjs/common';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/GET /', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});
================================================
FILE: examples/nest-v5x-m2m/test/jest-e2e.json
================================================
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}
================================================
FILE: examples/nest-v5x-m2m/tsconfig.json
================================================
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"allowSyntheticDefaultImports": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
================================================
FILE: examples/nest-v5x-m2m/tsconfig.spec.json
================================================
{
"extends": "tsconfig.json",
"compilerOptions": {
"types": ["jest", "node"]
},
"include": ["**/*.spec.ts", "**/*.d.ts"]
}
================================================
FILE: examples/nest-v5x-m2m/tslint.json
================================================
{
"defaultSeverity": "error",
"extends": ["tslint:recommended"],
"jsRules": {
"no-unused-expression": true
},
"rules": {
"eofline": false,
"quotemark": [true, "single"],
"indent": false,
"member-access": [false],
"ordered-imports": [false],
"max-line-length": [true, 150],
"member-ordering": [false],
"curly": false,
"interface-name": [false],
"array-type": [false],
"no-empty-interface": false,
"no-empty": false,
"arrow-parens": false,
"object-literal-sort-keys": false,
"no-unused-expression": false,
"no-console": false,
"variable-name": [false],
"one-line": [false],
"one-variable-per-declaration": [false]
},
"rulesDirectory": []
}
================================================
FILE: examples/nest-v5x-m2m/webpack.config.js
================================================
const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
entry: ['webpack/hot/poll?1000', './src/main.hmr.ts'],
watch: true,
target: 'node',
externals: [
nodeExternals({
whitelist: ['webpack/hot/poll?1000'],
}),
],
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
mode: "development",
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'server.js',
},
};
================================================
FILE: jest.json
================================================
{
"moduleFileExtensions": ["ts", "tsx", "js", "json"],
"transform": {
"^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "/src/.*\\.(test|spec).(ts|tsx|js)$",
"testEnvironment": "node",
"collectCoverageFrom": [
"src/**/*.ts",
"!src/main.ts",
"!src/app/constants.ts",
"!src/**/index.ts",
"!src/**/*.module.ts",
"!src/**/*.interface.ts",
"!src/**/*.enum.ts",
"!**/node_modules/**",
"!**/vendor/**"
],
"coverageReporters": ["json", "lcov"]
}
================================================
FILE: package.json
================================================
{
"name": "nest-router",
"version": "1.0.9",
"description": "Router Module For Nestjs Framework",
"main": "index.js",
"scripts": {
"test": "jest --notify --config=jest.json",
"test:watch": "jest --watch --config=jest.json",
"test:coverage": "jest --config=jest.json --coverage --coverageDirectory=coverage",
"build": "./scripts/build.sh",
"build:andMove": "./scripts/build.sh andMove",
"npm:publish": "cd lib && npm publish"
},
"repository": {
"type": "git",
"url": "git+https://github.com/shekohex/nest-router.git"
},
"keywords": [
"nestjs",
"router",
"addons"
],
"author": "Shady Khalifa <shekohex@gmail.com>",
"license": "MIT",
"devDependencies": {
"@nestjs/common": "^5.0.0",
"@nestjs/core": "^5.0.0",
"@nestjs/testing": "^5.3.11",
"@types/jest": "^24.0.0",
"@types/node": "^12.0.0",
"coveralls": "^3.0.2",
"jest": "^23.6.0",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.3.0",
"ts-jest": "^24.0.0",
"typescript": "^3.0.0"
},
"bugs": {
"url": "https://github.com/shekohex/nest-router/issues"
},
"homepage": "https://github.com/shekohex/nest-router#readme"
}
================================================
FILE: scripts/build.sh
================================================
#!/bin/bash
# A basic script to build and compile the typescript files using tsc
# Set an error handler
trap onExit EXIT
# printing the simple stack trace
onExit() {
while caller $((n++));
do :;
done;
}
build() {
echo 'Start building..'
# Run tsc
tsc -p tsconfig.prod.json
echo 'tsc exist with status code:' $?
echo 'Copying Other files..'
cp -rf package.json lib
cp -rf README.md lib
echo 'Done.'
echo '--------'
}
move() {
echo 'Copying files to examples/**/node_modules ..'
for d in examples/*; do
if [ -d "$d" ]; then
dist="$d"/node_modules/nest-router
echo 'Start copying to' "$dist"
mkdir -p "$dist" && cp -rf lib/* "$dist"
fi
done
echo 'Done.'
echo '--------'
}
build
if [ "$1" = "andMove" ]; then
move
fi
================================================
FILE: src/index.ts
================================================
export * from './router.module';
export * from './routes.interface';
================================================
FILE: src/router.module.ts
================================================
import { Module, DynamicModule } from '@nestjs/common';
import { MODULE_PATH, PATH_METADATA } from '@nestjs/common/constants';
import { ModulesContainer } from '@nestjs/core/injector/modules-container';
import { Controller, Type } from '@nestjs/common/interfaces';
import { UnknownElementException } from '@nestjs/core/errors/exceptions/unknown-element.exception';
import { validatePath } from './utils/validate-path.util';
import { flatRoutes } from './utils/flat-routes.util';
import { Routes } from './routes.interface';
/**
* A utility Module to Organize your Routes,
* it could be imported in the Root Module of you application.
*/
@Module({})
export class RouterModule {
private static readonly routesContainer: Map<string, string> = new Map();
constructor(readonly modulesContainer: ModulesContainer) {
const modules = [...modulesContainer.values()];
for (const nestModule of modules) {
const modulePath: string = Reflect.getMetadata(MODULE_PATH, nestModule.metatype);
for (const route of nestModule.routes.values()) {
RouterModule.routesContainer.set(route.name, validatePath(modulePath));
}
}
}
/**
* takes an array of modules and organize them in hierarchy way
* @param {Routes} routes Array of Routes
*/
public static forRoutes(routes: Routes): DynamicModule {
RouterModule.buildPathMap(routes);
return {
module: RouterModule,
};
}
/**
* get the controller full route path eg: (controller's module prefix + controller's path).
* @param {Type<Controller>} controller the controller you need to get it's full path
*/
public static resolvePath(controller: Type<Controller>): string {
const controllerPath: string = Reflect.getMetadata(PATH_METADATA, controller);
const modulePath = RouterModule.routesContainer.get(controller.name);
if (modulePath && controllerPath) {
return validatePath(modulePath + validatePath(controllerPath));
} else {
throw new UnknownElementException();
}
}
private static buildPathMap(routes: Routes) {
const flattenRoutes = flatRoutes(routes);
flattenRoutes.forEach(route => {
Reflect.defineMetadata(MODULE_PATH, validatePath(route.path), route.module);
});
}
}
================================================
FILE: src/routes.interface.ts
================================================
import { Type } from '@nestjs/common';
/**
* Defines the Routes Tree
* - `path` - a string describe the Module path which will be applied
* to all it's controllers and childs
* - `module` - the parent Module.
* - `children` - an array of child Modules.
* - `childrens` @deprecated - @see children
*/
export interface Route {
path: string;
module?: Type<any> | string;
childrens?: Routes | Type<any>[] | string[];
children?: Routes | Type<any>[] | string[];
}
/**
* Defines the Routes Tree
* - `path` - a string describe the Module path which will be applied
* to all it's controllers and childs
* - `module` - the parent Module.
* - `children` - an array of child Modules.
* - `childrens` @deprecated - @see children
*/
export type Routes = Route[];
================================================
FILE: src/test/router.module.spec.ts
================================================
import { RouterModule } from '../router.module';
import { Routes } from '../routes.interface';
import { Module, Controller } from '@nestjs/common';
import { MODULE_PATH } from '@nestjs/common/constants';
import { Test } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
describe('RouterModule', () => {
let app: INestApplication;
@Controller('/parent-controller')
class ParentController {}
@Controller('/child-controller')
class ChildController {}
@Controller('no-slash-controller')
class NoSlashController {}
class UnknownController {}
@Module({ controllers: [ParentController] })
class ParentModule {}
@Module({ controllers: [ChildController] })
class ChildModule {}
@Module({})
class AuthModule {}
@Module({})
class PaymentsModule {}
@Module({ controllers: [NoSlashController] })
class NoSlashModule {}
const routes1: Routes = [
{
path: 'parent',
module: ParentModule,
children: [
{
path: 'child',
module: ChildModule,
},
],
},
];
const routes2: Routes = [{ path: 'v1', children: [AuthModule, PaymentsModule, NoSlashModule] }];
@Module({ imports: [ParentModule, ChildModule, RouterModule.forRoutes(routes1)] })
class MainModule {}
@Module({ imports: [AuthModule, PaymentsModule, NoSlashModule, RouterModule.forRoutes(routes2)] })
class AppModule {}
test('it should add Path Metadata to all Routes', () => {
const parentPath = Reflect.getMetadata(MODULE_PATH, ParentModule);
const childPath = Reflect.getMetadata(MODULE_PATH, ChildModule);
expect(parentPath).toEqual('/parent');
expect(childPath).toEqual('/parent/child');
});
test('it should add paths even we omitted the module keyword', () => {
const authPath = Reflect.getMetadata(MODULE_PATH, AuthModule);
const paymentPath = Reflect.getMetadata(MODULE_PATH, PaymentsModule);
expect(authPath).toEqual('/v1');
expect(paymentPath).toEqual('/v1');
});
describe('Full Running App', async () => {
beforeAll(async () => {
const module = await Test.createTestingModule({
imports: [MainModule, AppModule],
}).compile();
app = module.createNestApplication();
await app.init();
});
it('should Resolve Controllers path with its Module Path if any', async () => {
expect(RouterModule.resolvePath(ParentController)).toEqual('/parent/parent-controller');
expect(RouterModule.resolvePath(ChildController)).toEqual('/parent/child/child-controller');
});
it('should throw error when we cannot find the controller', async () => {
expect(() => RouterModule.resolvePath(UnknownController)).toThrowError(
'Nest cannot find given element (it does not exist in current context)',
);
});
it('should resolve controllers path concatinated with its module path correctly', async () => {
expect(RouterModule.resolvePath(NoSlashController)).toEqual('/v1/no-slash-controller');
});
afterAll(async () => {
await app.close();
});
});
});
================================================
FILE: src/test/utils/flat-routes.spec.ts
================================================
import { flatRoutes } from '../../utils/flat-routes.util';
describe('FlatRoutes', () => {
const f = flatRoutes;
test('it should flat all Routes to endless, and we could also ommit the path', () => {
const routes = [
{
path: '/parent',
module: 'ParentModule',
children: [
{
path: '/child',
module: 'ChildModule',
children: [
{ path: '/child2', module: 'ChildModule2' },
{
path: '/parentchild',
module: 'ParentChildModule',
children: [
{
path: '/childchild',
module: 'ChildChildModule',
children: [{ path: '/child2child', module: 'ChildChildModule2' }],
},
],
},
],
},
],
},
{ path: '/v1', children: ['AuthModule', 'CatsModule', 'DogsModule'] },
{ path: '/v2', children: ['AuthModule2', 'CatsModule2'] },
{ path: '/v3', childrens: ['AuthModule3', 'CatsModule3'] },
];
const expectedRoutes = [
{ path: '/parent', module: 'ParentModule' },
{ path: '/parent/child', module: 'ChildModule' },
{ path: '/parent/child/child2', module: 'ChildModule2' },
{ path: '/parent/child/parentchild', module: 'ParentChildModule' },
{ path: '/parent/child/parentchild/childchild', module: 'ChildChildModule' },
{ path: '/parent/child/parentchild/childchild/child2child', module: 'ChildChildModule2' },
{ path: '/v1', module: 'AuthModule' },
{ path: '/v1', module: 'CatsModule' },
{ path: '/v1', module: 'DogsModule' },
{ path: '/v2', module: 'AuthModule2' },
{ path: '/v2', module: 'CatsModule2' },
{ path: '/v3', module: 'AuthModule3' },
{ path: '/v3', module: 'CatsModule3' },
];
expect(f(routes)).toEqual(expectedRoutes);
});
});
================================================
FILE: src/test/utils/validate-path.spec.ts
================================================
import { validatePath } from '../../utils/validate-path.util';
describe('ValidatePath', () => {
const v = validatePath;
test('it should add a / if it dose not exist', () => {
expect(v('')).toEqual('/');
expect(v('path')).toEqual('/path');
});
test('it should remove all trailing slashes at the end of the path', () => {
expect(v('path/')).toEqual('/path');
expect(v('path///')).toEqual('/path');
expect(v('/path/path///')).toEqual('/path/path');
});
test('it should replace all slashes with only one slash', () => {
expect(v('////path/')).toEqual('/path');
expect(v('///')).toEqual('/');
expect(v('/path////path///')).toEqual('/path/path');
});
});
================================================
FILE: src/utils/flat-routes.util.ts
================================================
import { isString } from 'util';
import { Routes } from '../routes.interface';
import { validatePath } from './validate-path.util';
const result = [];
export function flatRoutes(routes: Routes) {
routes.forEach(element => {
if (element.module && element.path) {
result.push(element);
}
// this block will be removed soon
if (!element.children && element.childrens) {
element.children = element.childrens;
console.log(
`\x1b[33m%s\x1b[0m`,
`WARNING: 'childrens' is deprecated, use 'children' instead.`,
);
}
if (element.children) {
const childrenRef = element.children as Routes;
childrenRef.forEach(child => {
if (!isString(child) && child.path) {
child.path = validatePath(validatePath(element.path) + validatePath(child.path));
} else {
result.push({ path: element.path, module: child });
}
});
return flatRoutes(childrenRef);
}
});
result.forEach(route => {
delete route.children;
});
return result;
}
================================================
FILE: src/utils/validate-path.util.ts
================================================
export const validatePath = (path: string): string =>
path
? path.startsWith('/')
? ('/' + path.replace(/\/+$/, '')).replace(/\/+/g, '/')
: '/' + path.replace(/\/+$/, '')
: '/';
================================================
FILE: tsconfig.json
================================================
{
"compilerOptions": {
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "./lib",
"preserveConstEnums": true,
"rootDir": "./src",
"baseUrl": ".",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"sourceMap": true,
"target": "es6",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es7"
]
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
]
}
================================================
FILE: tsconfig.prod.json
================================================
{
"extends": "./tsconfig.json",
"exclude": [
"src/**/*.spec.ts"
]
}
================================================
FILE: tslint.json
================================================
{
"defaultSeverity": "warn",
"extends": ["tslint:recommended"],
"jsRules": {
"no-unused-expression": true
},
"rules": {
"eofline": false,
"quotemark": [true, "single"],
"indent": false,
"ordered-imports": [false],
"max-line-length": [true, 100],
"member-ordering": [false],
"curly": false,
"interface-name": [false],
"array-type": [false],
"no-empty-interface": false,
"no-empty": false,
"arrow-parens": false,
"object-literal-sort-keys": false,
"no-unused-expression": false,
"max-classes-per-file": [false],
"ban-types": false,
"variable-name": [false],
"one-line": [false],
"one-variable-per-declaration": [false]
},
"rulesDirectory": []
}
================================================
FILE: wallaby.js
================================================
module.exports = function() {
return {
files: ['src/**/*.ts', 'jest.json', '!src/**/*.spec.ts'], // <--
tests: ['src/**/*.spec.ts'],
env: { type: 'node', runner: 'node' },
testFramework: 'jest',
setup: function(wallaby) {
var jestConfig = require('./jest.json').jest;
wallaby.testFramework.configure(jestConfig);
},
};
};
gitextract_4e6hp759/ ├── .gitignore ├── .npmignore ├── .prettierrc ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples/ │ ├── nest-v4x/ │ │ ├── index.js │ │ ├── jest.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.module.ts │ │ │ ├── cats/ │ │ │ │ ├── cats.controller.ts │ │ │ │ ├── cats.module.ts │ │ │ │ └── ketty.controller.ts │ │ │ ├── dogs/ │ │ │ │ ├── dogs.controller.ts │ │ │ │ ├── dogs.module.ts │ │ │ │ └── puppy.controller.ts │ │ │ ├── main.ts │ │ │ ├── ninja/ │ │ │ │ ├── katana.controller.ts │ │ │ │ ├── ninja.controller.ts │ │ │ │ └── ninja.module.ts │ │ │ └── routes.ts │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── nest-v5x/ │ │ ├── nodemon.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.module.ts │ │ │ ├── cats/ │ │ │ │ ├── cats.controller.ts │ │ │ │ ├── cats.module.ts │ │ │ │ ├── dto/ │ │ │ │ │ └── create-cat.dto.ts │ │ │ │ └── ketty.controller.ts │ │ │ ├── dogs/ │ │ │ │ ├── dogs.controller.ts │ │ │ │ ├── dogs.module.ts │ │ │ │ └── puppy.controller.ts │ │ │ ├── logger.middleware.ts │ │ │ ├── main.hmr.ts │ │ │ ├── main.ts │ │ │ ├── ninja/ │ │ │ │ ├── katana.controller.ts │ │ │ │ ├── ninja.controller.ts │ │ │ │ └── ninja.module.ts │ │ │ └── routes.ts │ │ ├── test/ │ │ │ ├── app.e2e-spec.ts │ │ │ └── jest-e2e.json │ │ ├── tsconfig.json │ │ ├── tsconfig.spec.json │ │ ├── tslint.json │ │ └── webpack.config.js │ └── nest-v5x-m2m/ │ ├── nodemon.json │ ├── package.json │ ├── src/ │ │ ├── app.module.ts │ │ ├── cats/ │ │ │ ├── cats.controller.ts │ │ │ ├── cats.module.ts │ │ │ ├── dto/ │ │ │ │ └── create-cat.dto.ts │ │ │ └── ketty.controller.ts │ │ ├── dogs/ │ │ │ ├── dogs.controller.ts │ │ │ ├── dogs.module.ts │ │ │ └── puppy.controller.ts │ │ ├── logger.middleware.ts │ │ ├── main.hmr.ts │ │ ├── main.ts │ │ ├── ninja/ │ │ │ ├── katana.controller.ts │ │ │ ├── ninja.controller.ts │ │ │ └── ninja.module.ts │ │ └── routes.ts │ ├── test/ │ │ ├── app.e2e-spec.ts │ │ └── jest-e2e.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ ├── tslint.json │ └── webpack.config.js ├── jest.json ├── package.json ├── scripts/ │ └── build.sh ├── src/ │ ├── index.ts │ ├── router.module.ts │ ├── routes.interface.ts │ ├── test/ │ │ ├── router.module.spec.ts │ │ └── utils/ │ │ ├── flat-routes.spec.ts │ │ └── validate-path.spec.ts │ └── utils/ │ ├── flat-routes.util.ts │ └── validate-path.util.ts ├── tsconfig.json ├── tsconfig.prod.json ├── tslint.json └── wallaby.js
SYMBOL INDEX (87 symbols across 43 files)
FILE: examples/nest-v4x/src/app.module.ts
class ApplicationModule (line 10) | class ApplicationModule {}
FILE: examples/nest-v4x/src/cats/cats.controller.ts
class CatsController (line 4) | class CatsController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v4x/src/cats/cats.module.ts
class CatsModule (line 8) | class CatsModule {}
FILE: examples/nest-v4x/src/cats/ketty.controller.ts
class KettyController (line 4) | class KettyController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v4x/src/dogs/dogs.controller.ts
class DogsController (line 4) | class DogsController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v4x/src/dogs/dogs.module.ts
class DogsModule (line 8) | class DogsModule {}
FILE: examples/nest-v4x/src/dogs/puppy.controller.ts
class PuppyController (line 4) | class PuppyController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v4x/src/main.ts
function bootstrap (line 4) | async function bootstrap() {
FILE: examples/nest-v4x/src/ninja/katana.controller.ts
class KatanaController (line 4) | class KatanaController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v4x/src/ninja/ninja.controller.ts
class NinjaController (line 4) | class NinjaController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v4x/src/ninja/ninja.module.ts
class NinjaModule (line 8) | class NinjaModule {}
FILE: examples/nest-v5x-m2m/src/app.module.ts
class ApplicationModule (line 11) | class ApplicationModule implements NestModule {
method configure (line 12) | configure(consumer: MiddlewareConsumer) {
FILE: examples/nest-v5x-m2m/src/cats/cats.controller.ts
class CatsController (line 5) | class CatsController {
method sayHello (line 8) | sayHello() {
method whatIsTheNinjaId (line 13) | whatIsTheNinjaId(@Param('ninjaId') ninjaId: string) {
method getCat (line 18) | getCat(@Param('catId') id: string) {
method testing (line 25) | public testing(@Body(new ValidationPipe()) data: CreateCatDTO): string...
FILE: examples/nest-v5x-m2m/src/cats/cats.module.ts
class CatsModule (line 8) | class CatsModule {}
FILE: examples/nest-v5x-m2m/src/cats/dto/create-cat.dto.ts
class CreateCatDTO (line 2) | class CreateCatDTO {
FILE: examples/nest-v5x-m2m/src/cats/ketty.controller.ts
class KettyController (line 4) | class KettyController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x-m2m/src/dogs/dogs.controller.ts
class DogsController (line 4) | class DogsController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x-m2m/src/dogs/dogs.module.ts
class DogsModule (line 8) | class DogsModule {}
FILE: examples/nest-v5x-m2m/src/dogs/puppy.controller.ts
class PuppyController (line 4) | class PuppyController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x-m2m/src/logger.middleware.ts
class LoggerMiddleware (line 5) | class LoggerMiddleware implements NestMiddleware {
method resolve (line 6) | resolve(...excluded: Routes): MiddlewareFunction {
FILE: examples/nest-v5x-m2m/src/main.hmr.ts
function bootstrap (line 6) | async function bootstrap() {
FILE: examples/nest-v5x-m2m/src/main.ts
function bootstrap (line 4) | async function bootstrap() {
FILE: examples/nest-v5x-m2m/src/ninja/katana.controller.ts
class KatanaController (line 4) | class KatanaController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x-m2m/src/ninja/ninja.controller.ts
class NinjaController (line 4) | class NinjaController {
method sayHello (line 7) | sayHello() {
method getAllNinja (line 12) | getAllNinja() {
method getNinja (line 17) | getNinja(@Param('ninjaId') id: string) {
method createNinja (line 23) | createNinja(@Body('name') name: string) {
FILE: examples/nest-v5x-m2m/src/ninja/ninja.module.ts
class NinjaModule (line 8) | class NinjaModule {}
FILE: examples/nest-v5x/src/app.module.ts
class ApplicationModule (line 11) | class ApplicationModule implements NestModule {
method configure (line 12) | configure(consumer: MiddlewareConsumer) {
FILE: examples/nest-v5x/src/cats/cats.controller.ts
class CatsController (line 5) | class CatsController {
method sayHello (line 8) | sayHello() {
method testing (line 14) | public testing(@Body(new ValidationPipe()) data: CreateCatDTO): string...
FILE: examples/nest-v5x/src/cats/cats.module.ts
class CatsModule (line 8) | class CatsModule {}
FILE: examples/nest-v5x/src/cats/dto/create-cat.dto.ts
class CreateCatDTO (line 2) | class CreateCatDTO {
FILE: examples/nest-v5x/src/cats/ketty.controller.ts
class KettyController (line 4) | class KettyController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x/src/dogs/dogs.controller.ts
class DogsController (line 4) | class DogsController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x/src/dogs/dogs.module.ts
class DogsModule (line 8) | class DogsModule {}
FILE: examples/nest-v5x/src/dogs/puppy.controller.ts
class PuppyController (line 4) | class PuppyController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x/src/logger.middleware.ts
class LoggerMiddleware (line 5) | class LoggerMiddleware implements NestMiddleware {
method resolve (line 6) | resolve(...excluded: Routes): MiddlewareFunction {
FILE: examples/nest-v5x/src/main.hmr.ts
function bootstrap (line 6) | async function bootstrap() {
FILE: examples/nest-v5x/src/main.ts
function bootstrap (line 4) | async function bootstrap() {
FILE: examples/nest-v5x/src/ninja/katana.controller.ts
class KatanaController (line 4) | class KatanaController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x/src/ninja/ninja.controller.ts
class NinjaController (line 4) | class NinjaController {
method sayHello (line 6) | sayHello() {
FILE: examples/nest-v5x/src/ninja/ninja.module.ts
class NinjaModule (line 8) | class NinjaModule {}
FILE: src/router.module.ts
class RouterModule (line 15) | class RouterModule {
method constructor (line 17) | constructor(readonly modulesContainer: ModulesContainer) {
method forRoutes (line 31) | public static forRoutes(routes: Routes): DynamicModule {
method resolvePath (line 42) | public static resolvePath(controller: Type<Controller>): string {
method buildPathMap (line 52) | private static buildPathMap(routes: Routes) {
FILE: src/routes.interface.ts
type Route (line 11) | interface Route {
type Routes (line 26) | type Routes = Route[];
FILE: src/test/router.module.spec.ts
class ParentController (line 11) | @Controller('/parent-controller')
class ChildController (line 13) | @Controller('/child-controller')
class NoSlashController (line 15) | @Controller('no-slash-controller')
class UnknownController (line 18) | class UnknownController {}
class ParentModule (line 19) | @Module({ controllers: [ParentController] })
class ChildModule (line 22) | @Module({ controllers: [ChildController] })
class AuthModule (line 25) | @Module({})
class PaymentsModule (line 27) | @Module({})
class NoSlashModule (line 30) | @Module({ controllers: [NoSlashController] })
class MainModule (line 47) | @Module({ imports: [ParentModule, ChildModule, RouterModule.forRoutes(ro...
class AppModule (line 50) | @Module({ imports: [AuthModule, PaymentsModule, NoSlashModule, RouterMod...
FILE: src/utils/flat-routes.util.ts
function flatRoutes (line 6) | function flatRoutes(routes: Routes) {
Condensed preview — 85 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (58K chars).
[
{
"path": ".gitignore",
"chars": 967,
"preview": "# 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# Directo"
},
{
"path": ".npmignore",
"chars": 959,
"preview": "# 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# Directo"
},
{
"path": ".prettierrc",
"chars": 109,
"preview": "{\n \"semi\": true,\n \"useTabs\": false,\n \"singleQuote\": true,\n \"printWidth\": 100,\n \"trailingComma\": \"all\"\n}\n"
},
{
"path": ".travis.yml",
"chars": 333,
"preview": "language: node_js\nnode_js:\n - \"8\"\n - \"9\"\n - \"10\"\nbefore_script:\n - export DISPLAY=:99.0\n - sh -e "
},
{
"path": "CHANGELOG.md",
"chars": 1665,
"preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
},
{
"path": "LICENSE",
"chars": 1070,
"preview": "MIT License\n\nCopyright (c) 2017 Shady Khalifa\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
},
{
"path": "README.md",
"chars": 5290,
"preview": "# Nest Router :vertical_traffic_light:\n\n[](h"
},
{
"path": "examples/nest-v4x/index.js",
"chars": 64,
"preview": "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",
"chars": 389,
"preview": "{\n \"moduleFileExtensions\": [\n \"ts\",\n \"tsx\",\n \"js\",\n \"json\"\n ],\n \"transform\": {\n "
},
{
"path": "examples/nest-v4x/package.json",
"chars": 1041,
"preview": "{\n \"name\": \"nest-router-example-v4x\",\n \"version\": \"1.0.0\",\n \"description\": \"Nest TypeScript starter repository\",\n \"l"
},
{
"path": "examples/nest-v4x/src/app.module.ts",
"chars": 447,
"preview": "import { Module, NestModule, MiddlewaresConsumer, RequestMethod } from '@nestjs/common';\nimport { RouterModule } from 'n"
},
{
"path": "examples/nest-v4x/src/cats/cats.controller.ts",
"chars": 168,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class CatsController {\n @Get('/')\n sayHello() "
},
{
"path": "examples/nest-v4x/src/cats/cats.module.ts",
"chars": 238,
"preview": "import { Module } from '@nestjs/common';\nimport { CatsController } from './cats.controller';\nimport { KettyController } "
},
{
"path": "examples/nest-v4x/src/cats/ketty.controller.ts",
"chars": 178,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/ketty')\nexport class KettyController {\n @Get('/')\n sa"
},
{
"path": "examples/nest-v4x/src/dogs/dogs.controller.ts",
"chars": 168,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class DogsController {\n @Get('/')\n sayHello() "
},
{
"path": "examples/nest-v4x/src/dogs/dogs.module.ts",
"chars": 238,
"preview": "import { Module } from '@nestjs/common';\nimport { DogsController } from './dogs.controller';\nimport { PuppyController } "
},
{
"path": "examples/nest-v4x/src/dogs/puppy.controller.ts",
"chars": 178,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/puppy')\nexport class PuppyController {\n @Get('/')\n sa"
},
{
"path": "examples/nest-v4x/src/main.ts",
"chars": 224,
"preview": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\nasync function bootstrap("
},
{
"path": "examples/nest-v4x/src/ninja/katana.controller.ts",
"chars": 181,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/katana')\nexport class KatanaController {\n @Get('/')\n "
},
{
"path": "examples/nest-v4x/src/ninja/ninja.controller.ts",
"chars": 170,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class NinjaController {\n @Get('/')\n sayHello()"
},
{
"path": "examples/nest-v4x/src/ninja/ninja.module.ts",
"chars": 245,
"preview": "import { Module } from '@nestjs/common';\nimport { NinjaController } from './ninja.controller';\nimport { KatanaController"
},
{
"path": "examples/nest-v4x/src/routes.ts",
"chars": 371,
"preview": "import { Routes } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dog"
},
{
"path": "examples/nest-v4x/tsconfig.json",
"chars": 411,
"preview": "{\n \"compilerOptions\": {\n \"module\": \"commonjs\",\n \"declaration\": false,\n \"noImplicitAny\": false,\n \"removeComm"
},
{
"path": "examples/nest-v4x/tslint.json",
"chars": 1074,
"preview": "{\n \"defaultSeverity\": \"error\",\n \"extends\": [\n \"tslint:recommended\"\n ],\n \"jsRules\": {\n \"no-unus"
},
{
"path": "examples/nest-v5x/nodemon.json",
"chars": 132,
"preview": "{\n \"watch\": [\"src\"],\n \"ext\": \"ts\",\n \"ignore\": [\"src/**/*.spec.ts\"],\n \"exec\": \"ts-node -r tsconfig-paths/register src"
},
{
"path": "examples/nest-v5x/package.json",
"chars": 1732,
"preview": "{\n \"name\": \"nest-router-example-v5x\",\n \"version\": \"1.0.0\",\n \"description\": \"Nest TypeScript starter repository\",\n \"l"
},
{
"path": "examples/nest-v5x/src/app.module.ts",
"chars": 673,
"preview": "import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';\nimport { RouterModule, Route } from 'nest-route"
},
{
"path": "examples/nest-v5x/src/cats/cats.controller.ts",
"chars": 457,
"preview": "import { Controller, Get, Post, Body, ValidationPipe } from '@nestjs/common';\nimport { CreateCatDTO } from './dto/create"
},
{
"path": "examples/nest-v5x/src/cats/cats.module.ts",
"chars": 238,
"preview": "import { Module } from '@nestjs/common';\nimport { CatsController } from './cats.controller';\nimport { KettyController } "
},
{
"path": "examples/nest-v5x/src/cats/dto/create-cat.dto.ts",
"chars": 120,
"preview": "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",
"chars": 178,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/ketty')\nexport class KettyController {\n @Get('/')\n sa"
},
{
"path": "examples/nest-v5x/src/dogs/dogs.controller.ts",
"chars": 168,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class DogsController {\n @Get('/')\n sayHello() "
},
{
"path": "examples/nest-v5x/src/dogs/dogs.module.ts",
"chars": 238,
"preview": "import { Module } from '@nestjs/common';\nimport { DogsController } from './dogs.controller';\nimport { PuppyController } "
},
{
"path": "examples/nest-v5x/src/dogs/puppy.controller.ts",
"chars": 178,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/puppy')\nexport class PuppyController {\n @Get('/')\n sa"
},
{
"path": "examples/nest-v5x/src/logger.middleware.ts",
"chars": 647,
"preview": "import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';\nimport { Routes } from 'nest-router';\n\n"
},
{
"path": "examples/nest-v5x/src/main.hmr.ts",
"chars": 345,
"preview": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\ndeclare const module: any"
},
{
"path": "examples/nest-v5x/src/main.ts",
"chars": 224,
"preview": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\nasync function bootstrap("
},
{
"path": "examples/nest-v5x/src/ninja/katana.controller.ts",
"chars": 181,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/katana')\nexport class KatanaController {\n @Get('/')\n "
},
{
"path": "examples/nest-v5x/src/ninja/ninja.controller.ts",
"chars": 170,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class NinjaController {\n @Get('/')\n sayHello()"
},
{
"path": "examples/nest-v5x/src/ninja/ninja.module.ts",
"chars": 245,
"preview": "import { Module } from '@nestjs/common';\nimport { NinjaController } from './ninja.controller';\nimport { KatanaController"
},
{
"path": "examples/nest-v5x/src/routes.ts",
"chars": 371,
"preview": "import { Routes } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dog"
},
{
"path": "examples/nest-v5x/test/app.e2e-spec.ts",
"chars": 593,
"preview": "import request from 'supertest';\nimport { Test } from '@nestjs/testing';\nimport { AppModule } from './../src/app.module'"
},
{
"path": "examples/nest-v5x/test/jest-e2e.json",
"chars": 154,
"preview": "{\n \"moduleFileExtensions\": [\"js\", \"json\", \"ts\"],\n \"rootDir\": \".\",\n \"testRegex\": \".e2e-spec.ts$\",\n \"transform\": {\n "
},
{
"path": "examples/nest-v5x/tsconfig.json",
"chars": 456,
"preview": "{\n \"compilerOptions\": {\n \"module\": \"commonjs\",\n \"declaration\": true,\n \"noImplicitAny\": false,\n \"removeComme"
},
{
"path": "examples/nest-v5x/tsconfig.spec.json",
"chars": 135,
"preview": "{\n \"extends\": \"tsconfig.json\",\n \"compilerOptions\": {\n \"types\": [\"jest\", \"node\"]\n },\n \"include\": [\"**/*.spec.ts\", "
},
{
"path": "examples/nest-v5x/tslint.json",
"chars": 732,
"preview": "{\n \"defaultSeverity\": \"error\",\n \"extends\": [\"tslint:recommended\"],\n \"jsRules\": {\n \"no-unused-expression\": true\n }"
},
{
"path": "examples/nest-v5x/webpack.config.js",
"chars": 695,
"preview": "const webpack = require('webpack');\nconst path = require('path');\nconst nodeExternals = require('webpack-node-externals'"
},
{
"path": "examples/nest-v5x-m2m/nodemon.json",
"chars": 132,
"preview": "{\n \"watch\": [\"src\"],\n \"ext\": \"ts\",\n \"ignore\": [\"src/**/*.spec.ts\"],\n \"exec\": \"ts-node -r tsconfig-paths/register src"
},
{
"path": "examples/nest-v5x-m2m/package.json",
"chars": 1737,
"preview": "{\n \"name\": \"nest-router-example-v5x-m2m\",\n \"version\": \"1.0.0\",\n \"description\": \"Nest TypeScript starter repository\",\n"
},
{
"path": "examples/nest-v5x-m2m/src/app.module.ts",
"chars": 673,
"preview": "import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';\nimport { RouterModule, Route } from 'nest-route"
},
{
"path": "examples/nest-v5x-m2m/src/cats/cats.controller.ts",
"chars": 756,
"preview": "import { Controller, Get, Post, Body, ValidationPipe, Param } from '@nestjs/common';\nimport { CreateCatDTO } from './dto"
},
{
"path": "examples/nest-v5x-m2m/src/cats/cats.module.ts",
"chars": 238,
"preview": "import { Module } from '@nestjs/common';\nimport { CatsController } from './cats.controller';\nimport { KettyController } "
},
{
"path": "examples/nest-v5x-m2m/src/cats/dto/create-cat.dto.ts",
"chars": 120,
"preview": "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",
"chars": 178,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/ketty')\nexport class KettyController {\n @Get('/')\n sa"
},
{
"path": "examples/nest-v5x-m2m/src/dogs/dogs.controller.ts",
"chars": 168,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller()\nexport class DogsController {\n @Get('/')\n sayHello() "
},
{
"path": "examples/nest-v5x-m2m/src/dogs/dogs.module.ts",
"chars": 238,
"preview": "import { Module } from '@nestjs/common';\nimport { DogsController } from './dogs.controller';\nimport { PuppyController } "
},
{
"path": "examples/nest-v5x-m2m/src/dogs/puppy.controller.ts",
"chars": 178,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/puppy')\nexport class PuppyController {\n @Get('/')\n sa"
},
{
"path": "examples/nest-v5x-m2m/src/logger.middleware.ts",
"chars": 647,
"preview": "import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';\nimport { Routes } from 'nest-router';\n\n"
},
{
"path": "examples/nest-v5x-m2m/src/main.hmr.ts",
"chars": 345,
"preview": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\ndeclare const module: any"
},
{
"path": "examples/nest-v5x-m2m/src/main.ts",
"chars": 224,
"preview": "import { NestFactory } from '@nestjs/core';\nimport { ApplicationModule } from './app.module';\n\nasync function bootstrap("
},
{
"path": "examples/nest-v5x-m2m/src/ninja/katana.controller.ts",
"chars": 181,
"preview": "import { Controller, Get } from '@nestjs/common';\n\n@Controller('/katana')\nexport class KatanaController {\n @Get('/')\n "
},
{
"path": "examples/nest-v5x-m2m/src/ninja/ninja.controller.ts",
"chars": 610,
"preview": "import { Controller, Get, Param, Post, Body } from '@nestjs/common';\n\n@Controller()\nexport class NinjaController {\n pri"
},
{
"path": "examples/nest-v5x-m2m/src/ninja/ninja.module.ts",
"chars": 245,
"preview": "import { Module } from '@nestjs/common';\nimport { NinjaController } from './ninja.controller';\nimport { KatanaController"
},
{
"path": "examples/nest-v5x-m2m/src/routes.ts",
"chars": 449,
"preview": "import { Routes } from 'nest-router';\nimport { CatsModule } from './cats/cats.module';\nimport { DogsModule } from './dog"
},
{
"path": "examples/nest-v5x-m2m/test/app.e2e-spec.ts",
"chars": 593,
"preview": "import request from 'supertest';\nimport { Test } from '@nestjs/testing';\nimport { AppModule } from './../src/app.module'"
},
{
"path": "examples/nest-v5x-m2m/test/jest-e2e.json",
"chars": 154,
"preview": "{\n \"moduleFileExtensions\": [\"js\", \"json\", \"ts\"],\n \"rootDir\": \".\",\n \"testRegex\": \".e2e-spec.ts$\",\n \"transform\": {\n "
},
{
"path": "examples/nest-v5x-m2m/tsconfig.json",
"chars": 456,
"preview": "{\n \"compilerOptions\": {\n \"module\": \"commonjs\",\n \"declaration\": true,\n \"noImplicitAny\": false,\n \"removeComme"
},
{
"path": "examples/nest-v5x-m2m/tsconfig.spec.json",
"chars": 135,
"preview": "{\n \"extends\": \"tsconfig.json\",\n \"compilerOptions\": {\n \"types\": [\"jest\", \"node\"]\n },\n \"include\": [\"**/*.spec.ts\", "
},
{
"path": "examples/nest-v5x-m2m/tslint.json",
"chars": 732,
"preview": "{\n \"defaultSeverity\": \"error\",\n \"extends\": [\"tslint:recommended\"],\n \"jsRules\": {\n \"no-unused-expression\": true\n }"
},
{
"path": "examples/nest-v5x-m2m/webpack.config.js",
"chars": 695,
"preview": "const webpack = require('webpack');\nconst path = require('path');\nconst nodeExternals = require('webpack-node-externals'"
},
{
"path": "jest.json",
"chars": 524,
"preview": "{\n \"moduleFileExtensions\": [\"ts\", \"tsx\", \"js\", \"json\"],\n \"transform\": {\n \"^.+\\\\.tsx?$\": \"<rootDir>/node_modules/ts-"
},
{
"path": "package.json",
"chars": 1185,
"preview": "{\n \"name\": \"nest-router\",\n \"version\": \"1.0.9\",\n \"description\": \"Router Module For Nestjs Framework\",\n \"main\": \"index"
},
{
"path": "scripts/build.sh",
"chars": 842,
"preview": "#!/bin/bash\n# A basic script to build and compile the typescript files using tsc\n\n# Set an error handler\ntrap onExit EXI"
},
{
"path": "src/index.ts",
"chars": 69,
"preview": "export * from './router.module';\nexport * from './routes.interface';\n"
},
{
"path": "src/router.module.ts",
"chars": 2250,
"preview": "import { Module, DynamicModule } from '@nestjs/common';\nimport { MODULE_PATH, PATH_METADATA } from '@nestjs/common/const"
},
{
"path": "src/routes.interface.ts",
"chars": 774,
"preview": "import { Type } from '@nestjs/common';\n\n/**\n * Defines the Routes Tree\n * - `path` - a string describe the Module path w"
},
{
"path": "src/test/router.module.spec.ts",
"chars": 3082,
"preview": "import { RouterModule } from '../router.module';\nimport { Routes } from '../routes.interface';\nimport { Module, Controll"
},
{
"path": "src/test/utils/flat-routes.spec.ts",
"chars": 1948,
"preview": "import { flatRoutes } from '../../utils/flat-routes.util';\ndescribe('FlatRoutes', () => {\n const f = flatRoutes;\n test"
},
{
"path": "src/test/utils/validate-path.spec.ts",
"chars": 698,
"preview": "import { validatePath } from '../../utils/validate-path.util';\n\ndescribe('ValidatePath', () => {\n const v = validatePat"
},
{
"path": "src/utils/flat-routes.util.ts",
"chars": 1056,
"preview": "import { isString } from 'util';\nimport { Routes } from '../routes.interface';\nimport { validatePath } from './validate-"
},
{
"path": "src/utils/validate-path.util.ts",
"chars": 200,
"preview": "export const validatePath = (path: string): string =>\n path\n ? path.startsWith('/')\n ? ('/' + path.replace(/\\/+"
},
{
"path": "tsconfig.json",
"chars": 486,
"preview": "{\n \"compilerOptions\": {\n \"declaration\": true,\n \"module\": \"commonjs\",\n \"moduleResolution\": \"node\",\n \"outDir\""
},
{
"path": "tsconfig.prod.json",
"chars": 78,
"preview": "{\n \"extends\": \"./tsconfig.json\",\n \"exclude\": [\n \"src/**/*.spec.ts\"\n ]\n}\n"
},
{
"path": "tslint.json",
"chars": 737,
"preview": "{\n \"defaultSeverity\": \"warn\",\n \"extends\": [\"tslint:recommended\"],\n \"jsRules\": {\n \"no-unused-expression\": true\n },"
},
{
"path": "wallaby.js",
"chars": 362,
"preview": "module.exports = function() {\n return {\n files: ['src/**/*.ts', 'jest.json', '!src/**/*.spec.ts'], // <--\n tests:"
}
]
About this extraction
This page contains the full source code of the shekohex/nest-router GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 85 files (48.3 KB), approximately 15.9k tokens, and a symbol index with 87 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.