• This repository has been archived on 16/Aug/2024
  • Stars
    star
    382
  • Rank 111,918 (Top 3 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created about 8 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

node-decorators

Node Decorators

Installation

npm install express --save
npm install @decorators/di --save
npm install @decorators/server --save

Example

Fully working example can be found in example folder.

Application

In order to create an application, use Application class with app root module:

const app = await Application.create(AppModule);

Application instance provides an inject method to retrieve instances of any provided objects:

const app = await Application.create(AppModule);
const module = await app.inject<HttpModule>(HttpModule);

module.use(json());

await module.listen(3000);

Modules

  • HttpModule - main module to start an application:
import { Application, HttpModule, Module } from '@decorators/server';

@Module({
  modules: [
    HttpModule.create(ExpressAdapter),
  ],
})
export class AppModule { }

Adapters

  • ExpressAdapter - adapter for express

Payload vaidation

Package supports class-validator and class-transformer packages, basic types validation is supported as well:

@Get(':id', 200)
post(@Params('id') id: string) {
  return { id };
}

Pipes

Pipes allow to add additional "interceptors" before and after main route function. In order to implement a pipe import ProcessPipe interface and implement it:

import { HttpContext, PipeHandle, ProcessPipe } from '@decorators/server';

export class TransformPipe implements ProcessPipe {
  async run(context: HttpContext, handle: PipeHandle<string>) {
    const message = await handle();

    return message.toLocaleString();
  }
}

Add @Pipe decorator to the method or to entire controller:

@Pipe(TransformPipe)
process(@Body() body: object)

Pipes can be used both for controller and methods.

Injectables

Global server pipes can be applied by providing them via GLOBAL_PIPE injectable with multi (see di package for details) flag:

import { GLOBAL_PIPE, Module } from '@decorators/server';

@Module({
  providers: [
    {
      provide: GLOBAL_PIPE,
      useClass: ServerPipe,
      multi: true,
    },
  ],
})
export class AppModule { }

App prefix

To create global application prefix (aka version, namespace) use APP_VERSION injectable:

import { APP_VERSION, Module } from '@decorators/server';

@Module({
  providers: [
    {
      provide: APP_VERSION,
      useValue: 'v1',
    },
  ],
})
export class AppModule { }

Dependency injection

This module supports dependency injection provided by @decorators/di package. For convinience, @decorators/server reexports all decorators from @decorators/di package.

Decorators

Class

  • @Module(options: ModuleOptions) - Defines a module (namespace) for DI providers, controllers etc.
  • @Controller(url: string, options?: Record<string, unknown>) - Registers controller for base url with optional options
  • @Pipe(pipe: ClassConstructor<ProcessPipe>) - Registers a pipe for a controller

Method

  • @Pipe(pipe: ClassConstructor<ProcessPipe>) - Registers a pipe for a method

  • @Delete(url: string, status?: number) - Registers delete route

  • @Get(url: string, status?: number) - Registers get route

  • @Head(url: string, status?: number) - Registers head route

  • @Options(url: string, status?: number) - Registers options route

  • @Patch(url: string, status?: number) - Registers patch route

  • @Post(url: string, status?: number) - Registers post route

  • @Put(url: string, status?: number) - Registers put route

  • @Render(template: string) - Renders a template in the configured views folder

const app = await Application.create(AppModule);
const module = await app.inject<HttpModule>(HttpModule);

module.set('views', join(__dirname, '/views'));

Parameter

  • @Body(paramName?: string) - Request body object or single body param
  • @Cookies(paramName?: string) - Request cookies or single cookies param
  • @Headers(paramName?: string) - Request headers object or single headers param
  • @Params(paramName?: string) - Request params object or single param
  • @Query(paramName?: string) - Request query object or single query param
  • @Request(paramName?: string) - Returns request object or any other object available in req object itself
  • @Response(paramName?: string) - Returns response object or any other object available in response object itself

Custom Decorators

Package exports two main helpers to create custom decorators:

  • Decorate - allows to create custom class or method decorators
import { Decorate } from '@decorators/server';
// ...
@Decorate('hasAccess', 'granted')
create() {}

To read custom metadata use Reflector injectable and its getMeatada method:

@Injectable()
export class AccessPipe implements ProcessPipe {
  constructor(private reflector: Reflector) { }

  async run(context: HttpContext, handle: PipeHandle<string>) {
    const access = this.reflector.getMetadata('hasAccess', context.getHandler());
    const req = context.getRequest<Request>();

    if (access === req.query.access) {
      return handle();
    }

    throw new ApiError('unauthorized');
  }
}
  • createParamDecorator(factory: (context: Context) => any) - allows to create custom parameter decorators
import { createParamDecorator } from '@decorators/server';

function AccessParam() {
  return createParamDecorator((context: HttpContext) => {
    const req = context.getRequest<Request>();

    return req.query.access;
  });
}

// ...
create(@AccessParam() access: string) {}