mirror of
https://github.com/nestjs/nest.git
synced 2026-02-21 23:11:44 +00:00
Merge branch 'master' into 5.2.0
This commit is contained in:
10
Readme.md
10
Readme.md
@@ -46,15 +46,19 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors
|
||||
|
||||
#### Principal Sponsor
|
||||
|
||||
<a href="https://valor-software.com/"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="300" /></a>
|
||||
<a href="https://valor-software.com/"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="320" /></a>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<a href="http://xtremis.com/"><img src="https://nestjs.com/img/logo-xtremis.svg" width="220" /></a>
|
||||
|
||||
#### Silver Sponsors
|
||||
|
||||
<a href="https://neoteric.eu/"><img src="https://nestjs.com/img/neoteric-cut.png" width="130" /></a> <a href="https://www.swingdev.io"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="160" /></a>
|
||||
<a href="https://neoteric.eu/"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" /></a> <a href="https://www.swingdev.io"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="150" /></a>
|
||||
|
||||
#### Sponsors
|
||||
|
||||
<a href="https://scal.io"><img src="https://nestjs.com/img/scalio-logo.svg" width="120" /></a> <a href="http://angularity.io"><img src="http://angularity.io/media/logo.svg" height="32" /></a> <a href="http://gojob.com"><img src="https://gojob.com/w/wp-content/uploads/2017/02/cropped-Logo-web-home.png" height="44" /> <a href="https://keycdn.com"><img src="https://nestjs.com/img/keycdn.svg" height="37" /></a> <a href="https://hostpresto.com"><img src="https://nestjs.com/img/hostpresto.png" height="32" /></a>
|
||||
<a href="https://scal.io"><img src="https://nestjs.com/img/scalio-logo.svg" width="110" /></a> <a href="http://angularity.io"><img src="http://angularity.io/media/logo.svg" height="30" /></a> <a href="http://gojob.com"><img src="https://gojob.com/w/wp-content/uploads/2017/02/cropped-Logo-web-home.png" height="40" /> <a href="https://keycdn.com"><img src="https://nestjs.com/img/keycdn.svg" height="30" /></a> <a href="https://hostpresto.com"><img src="https://nestjs.com/img/hostpresto.png" height="30" /></a>
|
||||
|
||||
## Backers
|
||||
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
"packages/microservices/exceptions/",
|
||||
"packages/microservices/microservices-module.ts",
|
||||
"packages/core/middleware/middleware-module.ts",
|
||||
"packages/core/injector/module-ref.ts",
|
||||
"packages/common/services/logger.service.ts"
|
||||
],
|
||||
"extension": [
|
||||
|
||||
1
packages/common/http/http.constants.ts
Normal file
1
packages/common/http/http.constants.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const AXIOS_INSTANCE_TOKEN = 'AXIOS_INSTANCE_TOKEN';
|
||||
@@ -1,8 +1,24 @@
|
||||
import axios, { AxiosRequestConfig } from 'axios';
|
||||
import { Module } from '../decorators/modules/module.decorator';
|
||||
import { DynamicModule } from '../interfaces';
|
||||
import { AXIOS_INSTANCE_TOKEN } from './http.constants';
|
||||
import { HttpService } from './http.service';
|
||||
|
||||
@Module({
|
||||
providers: [HttpService],
|
||||
providers: [HttpService, {
|
||||
provide: AXIOS_INSTANCE_TOKEN,
|
||||
useValue: axios,
|
||||
}],
|
||||
exports: [HttpService],
|
||||
})
|
||||
export class HttpModule {}
|
||||
export class HttpModule {
|
||||
static register(config: AxiosRequestConfig): DynamicModule {
|
||||
return {
|
||||
module: HttpModule,
|
||||
providers: [{
|
||||
provide: AXIOS_INSTANCE_TOKEN,
|
||||
useValue: axios.create(config),
|
||||
}],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,37 @@
|
||||
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
import { from as fromPromise, Observable } from 'rxjs';
|
||||
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
import { defer, Observable } from 'rxjs';
|
||||
import { Inject } from '../decorators';
|
||||
import { AXIOS_INSTANCE_TOKEN } from './http.constants';
|
||||
|
||||
export class HttpService {
|
||||
constructor(
|
||||
@Inject(AXIOS_INSTANCE_TOKEN)
|
||||
private readonly instance: AxiosInstance = axios,
|
||||
) {}
|
||||
|
||||
request<T = any>(config: AxiosRequestConfig): Observable<AxiosResponse<T>> {
|
||||
return fromPromise(axios.request<T>(config));
|
||||
return defer(() => this.instance.request<T>(config));
|
||||
}
|
||||
|
||||
get<T = any>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig,
|
||||
): Observable<AxiosResponse<T>> {
|
||||
return fromPromise(axios.get<T>(url, config));
|
||||
return defer(() => this.instance.get<T>(url, config));
|
||||
}
|
||||
|
||||
delete<T = any>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig,
|
||||
): Observable<AxiosResponse<T>> {
|
||||
return fromPromise(axios.delete(url, config));
|
||||
return defer(() => this.instance.delete(url, config));
|
||||
}
|
||||
|
||||
head<T = any>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig,
|
||||
): Observable<AxiosResponse<T>> {
|
||||
return fromPromise(axios.head(url, config));
|
||||
return defer(() => this.instance.head(url, config));
|
||||
}
|
||||
|
||||
post<T = any>(
|
||||
@@ -32,7 +39,7 @@ export class HttpService {
|
||||
data?,
|
||||
config?: AxiosRequestConfig,
|
||||
): Observable<AxiosResponse<T>> {
|
||||
return fromPromise(axios.post(url, data, config));
|
||||
return defer(() => this.instance.post(url, data, config));
|
||||
}
|
||||
|
||||
put<T = any>(
|
||||
@@ -40,7 +47,7 @@ export class HttpService {
|
||||
data?,
|
||||
config?: AxiosRequestConfig,
|
||||
): Observable<AxiosResponse<T>> {
|
||||
return fromPromise(axios.put(url, data, config));
|
||||
return defer(() => this.instance.put(url, data, config));
|
||||
}
|
||||
|
||||
patch<T = any>(
|
||||
@@ -48,10 +55,10 @@ export class HttpService {
|
||||
data?,
|
||||
config?: AxiosRequestConfig,
|
||||
): Observable<AxiosResponse<T>> {
|
||||
return fromPromise(axios.patch(url, data, config));
|
||||
return defer(() => this.instance.patch(url, data, config));
|
||||
}
|
||||
|
||||
get axiosRef() {
|
||||
return axios as any;
|
||||
get axiosRef(): AxiosInstance {
|
||||
return this.instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Type } from './type.interface';
|
||||
import { LoggerService } from '../services/logger.service';
|
||||
|
||||
export interface INestApplicationContext {
|
||||
/**
|
||||
@@ -10,10 +9,17 @@ export interface INestApplicationContext {
|
||||
|
||||
/**
|
||||
* Retrieves an instance of either injectable or controller available anywhere, otherwise, throws exception.
|
||||
* @returns {T}
|
||||
* @returns {TResult}
|
||||
*/
|
||||
get<T>(
|
||||
typeOrToken: Type<T> | string | symbol,
|
||||
get<TInput = any, TResult = TInput>(
|
||||
typeOrToken: Type<TInput> | string | symbol,
|
||||
options?: { strict: boolean },
|
||||
): T;
|
||||
): TResult;
|
||||
|
||||
/**
|
||||
* Terminates the application
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
close(): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { FILTER_CATCH_EXCEPTIONS } from '@nestjs/common/constants';
|
||||
import { Type } from '@nestjs/common/interfaces';
|
||||
import { ExceptionFilter } from '@nestjs/common/interfaces/exceptions/exception-filter.interface';
|
||||
import { Type } from '@nestjs/common/interfaces/index';
|
||||
import { isEmpty, isFunction, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import iterate from 'iterare';
|
||||
import 'reflect-metadata';
|
||||
import { ContextCreator } from '../helpers/context-creator';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { ContextCreator } from './../helpers/context-creator';
|
||||
|
||||
export class BaseExceptionFilterContext extends ContextCreator {
|
||||
protected moduleContext: string;
|
||||
|
||||
43
packages/core/exceptions/base-exception-filter.ts
Normal file
43
packages/core/exceptions/base-exception-filter.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { ArgumentsHost, ExceptionFilter, HttpException, HttpServer, HttpStatus, Logger } from '@nestjs/common';
|
||||
import { isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { messages } from '../constants';
|
||||
|
||||
export class BaseExceptionFilter<T = any> implements ExceptionFilter<T> {
|
||||
private static readonly logger = new Logger('ExceptionsHandler');
|
||||
|
||||
constructor(protected readonly applicationRef: HttpServer) {}
|
||||
|
||||
catch(exception: T, host: ArgumentsHost) {
|
||||
if (!(exception instanceof HttpException)) {
|
||||
const body = {
|
||||
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
message: messages.UNKNOWN_EXCEPTION_MESSAGE,
|
||||
};
|
||||
this.applicationRef.reply(host.getArgByIndex(1), body, body.statusCode);
|
||||
if (this.isExceptionObject(exception)) {
|
||||
return BaseExceptionFilter.logger.error(
|
||||
exception.message,
|
||||
exception.stack,
|
||||
);
|
||||
}
|
||||
return BaseExceptionFilter.logger.error(exception as any);
|
||||
}
|
||||
const res = exception.getResponse();
|
||||
const message = isObject(res)
|
||||
? res
|
||||
: {
|
||||
statusCode: exception.getStatus(),
|
||||
message: res,
|
||||
};
|
||||
|
||||
this.applicationRef.reply(
|
||||
host.getArgByIndex(1),
|
||||
message,
|
||||
exception.getStatus(),
|
||||
);
|
||||
}
|
||||
|
||||
public isExceptionObject(err): err is Error {
|
||||
return isObject(err) && !!(err as Error).message;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +1,22 @@
|
||||
import { HttpException, HttpServer, Logger } from '@nestjs/common';
|
||||
import { HttpException, HttpServer } from '@nestjs/common';
|
||||
import { ExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions/exception-filter-metadata.interface';
|
||||
import { ArgumentsHost } from '@nestjs/common/interfaces/features/arguments-host.interface';
|
||||
import { isEmpty, isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { messages } from '../constants';
|
||||
import { isEmpty } from '@nestjs/common/utils/shared.utils';
|
||||
import { InvalidExceptionFilterException } from '../errors/exceptions/invalid-exception-filter.exception';
|
||||
import { BaseExceptionFilter } from './base-exception-filter';
|
||||
|
||||
export class ExceptionsHandler {
|
||||
private static readonly logger = new Logger(ExceptionsHandler.name);
|
||||
export class ExceptionsHandler extends BaseExceptionFilter {
|
||||
private filters: ExceptionFilterMetadata[] = [];
|
||||
|
||||
constructor(private readonly applicationRef: HttpServer) {}
|
||||
constructor(applicationRef: HttpServer) {
|
||||
super(applicationRef);
|
||||
}
|
||||
|
||||
public next(exception: Error | HttpException | any, ctx: ArgumentsHost) {
|
||||
if (this.invokeCustomFilters(exception, ctx)) return;
|
||||
|
||||
if (!(exception instanceof HttpException)) {
|
||||
const body = {
|
||||
statusCode: 500,
|
||||
message: messages.UNKNOWN_EXCEPTION_MESSAGE,
|
||||
};
|
||||
this.applicationRef.reply(ctx.getArgByIndex(1), body, body.statusCode);
|
||||
if (this.isExceptionObject(exception)) {
|
||||
return ExceptionsHandler.logger.error(
|
||||
exception.message,
|
||||
exception.stack,
|
||||
);
|
||||
}
|
||||
return ExceptionsHandler.logger.error(exception);
|
||||
if (this.invokeCustomFilters(exception, ctx)) {
|
||||
return void 0;
|
||||
}
|
||||
const res = exception.getResponse();
|
||||
const message = isObject(res)
|
||||
? res
|
||||
: {
|
||||
statusCode: exception.getStatus(),
|
||||
message: res,
|
||||
};
|
||||
|
||||
this.applicationRef.reply(
|
||||
ctx.getArgByIndex(1),
|
||||
message,
|
||||
exception.getStatus(),
|
||||
);
|
||||
super.catch(exception, ctx);
|
||||
}
|
||||
|
||||
public setCustomFilters(filters: ExceptionFilterMetadata[]) {
|
||||
@@ -64,8 +40,4 @@ export class ExceptionsHandler {
|
||||
filter && filter.func(exception, response);
|
||||
return !!filter;
|
||||
}
|
||||
|
||||
public isExceptionObject(err): err is Error {
|
||||
return isObject(err) && !!(err as Error).message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import 'reflect-metadata';
|
||||
import iterate from 'iterare';
|
||||
import { Controller } from '@nestjs/common/interfaces';
|
||||
import { GUARDS_METADATA } from '@nestjs/common/constants';
|
||||
import {
|
||||
isUndefined,
|
||||
isFunction,
|
||||
isNil,
|
||||
isEmpty,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
import { ContextCreator } from './../helpers/context-creator';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { CanActivate } from '@nestjs/common';
|
||||
import { GUARDS_METADATA } from '@nestjs/common/constants';
|
||||
import { Controller } from '@nestjs/common/interfaces';
|
||||
import { ConfigurationProvider } from '@nestjs/common/interfaces/configuration-provider.interface';
|
||||
import { isEmpty, isFunction, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import iterate from 'iterare';
|
||||
import 'reflect-metadata';
|
||||
import { ContextCreator } from '../helpers/context-creator';
|
||||
import { NestContainer } from '../injector/container';
|
||||
|
||||
export class GuardsContextCreator extends ContextCreator {
|
||||
private moduleContext: string;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import 'reflect-metadata';
|
||||
import iterate from 'iterare';
|
||||
import { Controller } from '@nestjs/common/interfaces';
|
||||
import { isUndefined, isFunction } from '@nestjs/common/utils/shared.utils';
|
||||
import { ApplicationConfig } from './../application-config';
|
||||
import 'reflect-metadata';
|
||||
|
||||
export abstract class ContextCreator {
|
||||
public abstract createConcreteContext<T extends any[], R extends any[]>(
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import 'reflect-metadata';
|
||||
import { GuardsContextCreator } from './../guards/guards-context-creator';
|
||||
import { GuardsConsumer } from './../guards/guards-consumer';
|
||||
import { InterceptorsContextCreator } from './../interceptors/interceptors-context-creator';
|
||||
import { InterceptorsConsumer } from './../interceptors/interceptors-consumer';
|
||||
import { Controller } from '@nestjs/common/interfaces';
|
||||
import { FORBIDDEN_MESSAGE } from '../guards/constants';
|
||||
import { ForbiddenException } from '@nestjs/common';
|
||||
import { Module } from './../injector/module';
|
||||
import { ModulesContainer } from './../injector/modules-container';
|
||||
import { Controller } from '@nestjs/common/interfaces';
|
||||
import 'reflect-metadata';
|
||||
import { FORBIDDEN_MESSAGE } from '../guards/constants';
|
||||
import { GuardsConsumer } from '../guards/guards-consumer';
|
||||
import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { Module } from '../injector/module';
|
||||
import { ModulesContainer } from '../injector/modules-container';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
|
||||
export class ExternalContextCreator {
|
||||
constructor(
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
export { MiddlewareBuilder } from './middleware/builder';
|
||||
export { ModuleRef } from './injector/module-ref';
|
||||
export { NestFactory } from './nest-factory';
|
||||
export { HTTP_SERVER_REF } from './injector/tokens';
|
||||
export { APP_INTERCEPTOR, APP_FILTER, APP_GUARD, APP_PIPE } from './constants';
|
||||
export * from './adapters';
|
||||
export * from './services';
|
||||
export { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from './constants';
|
||||
export { BaseExceptionFilter } from './exceptions/base-exception-filter';
|
||||
export { ModuleRef } from './injector/module-ref';
|
||||
export { HTTP_SERVER_REF } from './injector/tokens';
|
||||
export { MiddlewareBuilder } from './middleware/builder';
|
||||
export * from './nest-application';
|
||||
export * from './nest-application-context';
|
||||
export { NestFactory } from './nest-factory';
|
||||
export * from './services';
|
||||
|
||||
@@ -2,9 +2,9 @@ import { DynamicModule } from '@nestjs/common';
|
||||
import { GLOBAL_MODULE_METADATA } from '@nestjs/common/constants';
|
||||
import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import 'reflect-metadata';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
import { InvalidModuleException } from '../errors/exceptions/invalid-module.exception';
|
||||
import { UnknownModuleException } from '../errors/exceptions/unknown-module.exception';
|
||||
import { ApplicationConfig } from './../application-config';
|
||||
import { InvalidModuleException } from './../errors/exceptions/invalid-module.exception';
|
||||
import { ModuleCompiler } from './compiler';
|
||||
import { Module } from './module';
|
||||
import { ModulesContainer } from './modules-container';
|
||||
|
||||
@@ -5,9 +5,9 @@ import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import { isFunction, isNil, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import 'reflect-metadata';
|
||||
import { RuntimeException } from '../errors/exceptions/runtime.exception';
|
||||
import { UndefinedDependencyException } from '../errors/exceptions/undefined-dependency.exception';
|
||||
import { UnknownDependenciesException } from '../errors/exceptions/unknown-dependencies.exception';
|
||||
import { MiddlewareWrapper } from '../middleware/container';
|
||||
import { UndefinedDependencyException } from './../errors/exceptions/undefined-dependency.exception';
|
||||
import { InstanceWrapper } from './container';
|
||||
import { Module } from './module';
|
||||
|
||||
|
||||
@@ -1,5 +1,65 @@
|
||||
import { OpaqueToken } from './module';
|
||||
import { Type } from '@nestjs/common';
|
||||
import { isFunction } from '@nestjs/common/utils/shared.utils';
|
||||
import { UnknownElementException } from '../errors/exceptions/unknown-element.exception';
|
||||
import { InstanceWrapper, NestContainer } from './container';
|
||||
import { Module } from './module';
|
||||
|
||||
export abstract class ModuleRef {
|
||||
public abstract get<T>(type: OpaqueToken): T;
|
||||
private flattenModuleFixture: Partial<Module>;
|
||||
|
||||
constructor(protected readonly container: NestContainer) {}
|
||||
|
||||
public abstract get<TInput = any, TResult = TInput>(
|
||||
typeOrToken: Type<TInput> | string | symbol,
|
||||
options?: { strict: boolean },
|
||||
): TResult;
|
||||
|
||||
protected find<TInput = any, TResult = TInput>(
|
||||
typeOrToken: Type<TInput> | string | symbol,
|
||||
): TResult {
|
||||
this.initFlattenModule();
|
||||
return this.findInstanceByPrototypeOrToken<TInput, TResult>(
|
||||
typeOrToken,
|
||||
this.flattenModuleFixture,
|
||||
);
|
||||
}
|
||||
|
||||
protected findInstanceByPrototypeOrToken<TInput = any, TResult = TInput>(
|
||||
metatypeOrToken: Type<TInput> | string | symbol,
|
||||
contextModule: Partial<Module>,
|
||||
): TResult {
|
||||
const dependencies = new Map([
|
||||
...contextModule.components,
|
||||
...contextModule.routes,
|
||||
...contextModule.injectables,
|
||||
]);
|
||||
const name = isFunction(metatypeOrToken)
|
||||
? (metatypeOrToken as any).name
|
||||
: metatypeOrToken;
|
||||
const instanceWrapper = dependencies.get(name);
|
||||
if (!instanceWrapper) {
|
||||
throw new UnknownElementException();
|
||||
}
|
||||
return (instanceWrapper as InstanceWrapper<any>).instance;
|
||||
}
|
||||
|
||||
private initFlattenModule() {
|
||||
if (this.flattenModuleFixture) {
|
||||
return void 0;
|
||||
}
|
||||
const modules = this.container.getModules();
|
||||
const initialValue = {
|
||||
components: [],
|
||||
routes: [],
|
||||
injectables: [],
|
||||
};
|
||||
this.flattenModuleFixture = [...modules.values()].reduce(
|
||||
(flatten, curr) => ({
|
||||
components: [...flatten.components, ...curr.components],
|
||||
routes: [...flatten.routes, ...curr.routes],
|
||||
injectables: [...flatten.injectables, ...curr.injectables],
|
||||
}),
|
||||
initialValue,
|
||||
) as any;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import { isFunction, isNil, isString, isSymbol, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import { RuntimeException } from '../errors/exceptions/runtime.exception';
|
||||
import { UnknownExportException } from '../errors/exceptions/unknown-export.exception';
|
||||
import { GuardsConsumer } from '../guards/guards-consumer';
|
||||
import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { ExternalContextCreator } from '../helpers/external-context-creator';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
import { Reflector } from '../services/reflector.service';
|
||||
import { GuardsConsumer } from './../guards/guards-consumer';
|
||||
import { GuardsContextCreator } from './../guards/guards-context-creator';
|
||||
import { ExternalContextCreator } from './../helpers/external-context-creator';
|
||||
import { InterceptorsConsumer } from './../interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from './../interceptors/interceptors-context-creator';
|
||||
import { InstanceWrapper, NestContainer } from './container';
|
||||
import { ModuleRef } from './module-ref';
|
||||
import { ModulesContainer } from './modules-container';
|
||||
@@ -41,7 +41,7 @@ export class Module {
|
||||
constructor(
|
||||
private readonly _metatype: Type<any>,
|
||||
private readonly _scope: Type<any>[],
|
||||
container: NestContainer,
|
||||
private readonly container: NestContainer,
|
||||
) {
|
||||
this.addCoreInjectables(container);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ export class Module {
|
||||
}
|
||||
|
||||
public addModuleRef() {
|
||||
const moduleRef = this.createModuleRefMetatype(this._components);
|
||||
const moduleRef = this.createModuleRefMetatype();
|
||||
this._components.set(ModuleRef.name, {
|
||||
name: ModuleRef.name,
|
||||
metatype: ModuleRef as any,
|
||||
@@ -324,15 +324,24 @@ export class Module {
|
||||
});
|
||||
}
|
||||
|
||||
public createModuleRefMetatype(components) {
|
||||
return class {
|
||||
public readonly components = components;
|
||||
public createModuleRefMetatype(): any {
|
||||
const self = this;
|
||||
return class extends ModuleRef {
|
||||
constructor() {
|
||||
super(self.container);
|
||||
}
|
||||
|
||||
public get<T>(type: OpaqueToken): T {
|
||||
const name = isFunction(type) ? (type as Type<any>).name : type;
|
||||
const exists = this.components.has(name);
|
||||
|
||||
return exists ? (this.components.get(name).instance as T) : null;
|
||||
public get<TInput = any, TResult = TInput>(
|
||||
typeOrToken: Type<TInput> | string | symbol,
|
||||
options: { strict: boolean } = { strict: true },
|
||||
): TResult {
|
||||
if (!(options && options.strict)) {
|
||||
return this.find<TInput, TResult>(typeOrToken);
|
||||
}
|
||||
return this.findInstanceByPrototypeOrToken<TInput, TResult>(
|
||||
typeOrToken,
|
||||
self,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import 'reflect-metadata';
|
||||
import iterate from 'iterare';
|
||||
import { Controller, NestInterceptor } from '@nestjs/common/interfaces';
|
||||
import { INTERCEPTORS_METADATA } from '@nestjs/common/constants';
|
||||
import {
|
||||
isUndefined,
|
||||
isFunction,
|
||||
isNil,
|
||||
isEmpty,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
import { ContextCreator } from './../helpers/context-creator';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { Controller, NestInterceptor } from '@nestjs/common/interfaces';
|
||||
import { ConfigurationProvider } from '@nestjs/common/interfaces/configuration-provider.interface';
|
||||
import { isEmpty, isFunction, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import iterate from 'iterare';
|
||||
import 'reflect-metadata';
|
||||
import { ContextCreator } from '../helpers/context-creator';
|
||||
import { NestContainer } from '../injector/container';
|
||||
|
||||
export class InterceptorsContextCreator extends ContextCreator {
|
||||
private moduleContext: string;
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
import { INestApplicationContext, OnModuleInit } from '@nestjs/common';
|
||||
import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import {
|
||||
isFunction,
|
||||
isNil,
|
||||
isUndefined,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
INestApplicationContext,
|
||||
OnModuleDestroy,
|
||||
OnModuleInit,
|
||||
} from '@nestjs/common';
|
||||
import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import { isNil, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import iterate from 'iterare';
|
||||
import { UnknownElementException } from './errors/exceptions/unknown-element.exception';
|
||||
import { UnknownModuleException } from './errors/exceptions/unknown-module.exception';
|
||||
import { InstanceWrapper, NestContainer } from './injector/container';
|
||||
import { NestContainer } from './injector/container';
|
||||
import { Module } from './injector/module';
|
||||
import { ModuleRef } from './injector/module-ref';
|
||||
import { ModuleTokenFactory } from './injector/module-token-factory';
|
||||
|
||||
export class NestApplicationContext implements INestApplicationContext {
|
||||
export class NestApplicationContext extends ModuleRef
|
||||
implements INestApplicationContext {
|
||||
private readonly moduleTokenFactory = new ModuleTokenFactory();
|
||||
private contextModuleFixture: Partial<Module>;
|
||||
|
||||
constructor(
|
||||
protected readonly container: NestContainer,
|
||||
container: NestContainer,
|
||||
private readonly scope: Type<any>[],
|
||||
protected contextModule: Module,
|
||||
) {}
|
||||
) {
|
||||
super(container);
|
||||
}
|
||||
|
||||
public selectContextModule() {
|
||||
const modules = this.container.getModules().values();
|
||||
@@ -53,21 +55,15 @@ export class NestApplicationContext implements INestApplicationContext {
|
||||
);
|
||||
}
|
||||
|
||||
public find<TInput = any, TResult = TInput>(
|
||||
typeOrToken: Type<TInput> | string | symbol,
|
||||
): TResult {
|
||||
this.initFlattenModule();
|
||||
return this.findInstanceByPrototypeOrToken<TInput, TResult>(
|
||||
typeOrToken,
|
||||
this.contextModuleFixture,
|
||||
);
|
||||
}
|
||||
|
||||
public async init(): Promise<this> {
|
||||
await this.callInitHook();
|
||||
return this;
|
||||
}
|
||||
|
||||
public async close(): Promise<void> {
|
||||
await this.callDestroyHook();
|
||||
}
|
||||
|
||||
protected async callInitHook(): Promise<any> {
|
||||
const modules = this.container.getModules();
|
||||
await Promise.all(
|
||||
@@ -92,42 +88,30 @@ export class NestApplicationContext implements INestApplicationContext {
|
||||
return !isUndefined((instance as OnModuleInit).onModuleInit);
|
||||
}
|
||||
|
||||
private findInstanceByPrototypeOrToken<TInput = any, TResult = TInput>(
|
||||
metatypeOrToken: Type<TInput> | string | symbol,
|
||||
contextModule,
|
||||
): TResult {
|
||||
const dependencies = new Map([
|
||||
...contextModule.components,
|
||||
...contextModule.routes,
|
||||
...contextModule.injectables,
|
||||
]);
|
||||
const name = isFunction(metatypeOrToken)
|
||||
? (metatypeOrToken as any).name
|
||||
: metatypeOrToken;
|
||||
const instanceWrapper = dependencies.get(name);
|
||||
if (!instanceWrapper) {
|
||||
throw new UnknownElementException();
|
||||
}
|
||||
return (instanceWrapper as InstanceWrapper<any>).instance;
|
||||
protected async callDestroyHook(): Promise<any> {
|
||||
const modules = this.container.getModules();
|
||||
await Promise.all(
|
||||
iterate(modules.values()).map(
|
||||
async module => await this.callModuleDestroyHook(module),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private initFlattenModule() {
|
||||
if (this.contextModuleFixture) {
|
||||
return undefined;
|
||||
}
|
||||
const modules = this.container.getModules();
|
||||
const initialValue = {
|
||||
components: [],
|
||||
routes: [],
|
||||
injectables: [],
|
||||
};
|
||||
this.contextModuleFixture = [...modules.values()].reduce(
|
||||
(flatten, curr) => ({
|
||||
components: [...flatten.components, ...curr.components],
|
||||
routes: [...flatten.routes, ...curr.routes],
|
||||
injectables: [...flatten.injectables, ...curr.injectables],
|
||||
}),
|
||||
initialValue,
|
||||
) as any;
|
||||
protected async callModuleDestroyHook(module: Module): Promise<any> {
|
||||
const components = [...module.routes, ...module.components];
|
||||
await Promise.all(
|
||||
iterate(components)
|
||||
.map(([key, { instance }]) => instance)
|
||||
.filter(instance => !isNil(instance))
|
||||
.filter(this.hasOnModuleDestroyHook)
|
||||
.map(
|
||||
async instance =>
|
||||
await (instance as OnModuleDestroy).onModuleDestroy(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected hasOnModuleDestroyHook(instance): instance is OnModuleDestroy {
|
||||
return !isUndefined((instance as OnModuleDestroy).onModuleDestroy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
INestApplication,
|
||||
INestMicroservice,
|
||||
NestInterceptor,
|
||||
OnModuleDestroy,
|
||||
PipeTransform,
|
||||
WebSocketAdapter,
|
||||
} from '@nestjs/common';
|
||||
@@ -19,9 +18,7 @@ import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import {
|
||||
isFunction,
|
||||
isNil,
|
||||
isObject,
|
||||
isUndefined,
|
||||
validatePath,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
import * as bodyParser from 'body-parser';
|
||||
@@ -35,7 +32,6 @@ import { FastifyAdapter } from './adapters/fastify-adapter';
|
||||
import { ApplicationConfig } from './application-config';
|
||||
import { messages } from './constants';
|
||||
import { NestContainer } from './injector/container';
|
||||
import { Module } from './injector/module';
|
||||
import { MiddlewareContainer } from './middleware/container';
|
||||
import { MiddlewareModule } from './middleware/middleware-module';
|
||||
import { NestApplicationContext } from './nest-application-context';
|
||||
@@ -308,7 +304,7 @@ export class NestApplication extends NestApplicationContext
|
||||
await microservice.close();
|
||||
}),
|
||||
);
|
||||
await this.callDestroyHook();
|
||||
await super.close();
|
||||
}
|
||||
|
||||
public setGlobalPrefix(prefix: string): this {
|
||||
@@ -387,31 +383,4 @@ export class NestApplication extends NestApplicationContext
|
||||
await microservice.listen(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
private async callDestroyHook(): Promise<any> {
|
||||
const modules = this.container.getModules();
|
||||
await Promise.all(
|
||||
iterate(modules.values()).map(
|
||||
async module => await this.callModuleDestroyHook(module),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private async callModuleDestroyHook(module: Module): Promise<any> {
|
||||
const components = [...module.routes, ...module.components];
|
||||
await Promise.all(
|
||||
iterate(components)
|
||||
.map(([key, { instance }]) => instance)
|
||||
.filter(instance => !isNil(instance))
|
||||
.filter(this.hasOnModuleDestroyHook)
|
||||
.map(
|
||||
async instance =>
|
||||
await (instance as OnModuleDestroy).onModuleDestroy(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private hasOnModuleDestroyHook(instance): instance is OnModuleDestroy {
|
||||
return !isUndefined((instance as OnModuleDestroy).onModuleDestroy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Transform, Paramtype } from '@nestjs/common/interfaces';
|
||||
import { RouteParamtypes } from '@nestjs/common/enums/route-paramtypes.enum';
|
||||
import { ParamsTokenFactory } from './../pipes/params-token-factory';
|
||||
import { Transform } from '@nestjs/common/interfaces';
|
||||
import { ParamsTokenFactory } from './params-token-factory';
|
||||
|
||||
export class PipesConsumer {
|
||||
private readonly paramsTokenFactory = new ParamsTokenFactory();
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
import 'reflect-metadata';
|
||||
import iterate from 'iterare';
|
||||
import {
|
||||
Controller,
|
||||
PipeTransform,
|
||||
Transform,
|
||||
} from '@nestjs/common/interfaces';
|
||||
import { PIPES_METADATA } from '@nestjs/common/constants';
|
||||
import {
|
||||
isUndefined,
|
||||
isFunction,
|
||||
isEmpty,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
import { ApplicationConfig } from './../application-config';
|
||||
import { ContextCreator } from './../helpers/context-creator';
|
||||
import { Controller, PipeTransform, Transform } from '@nestjs/common/interfaces';
|
||||
import { isEmpty, isFunction, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import iterate from 'iterare';
|
||||
import 'reflect-metadata';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
import { ContextCreator } from '../helpers/context-creator';
|
||||
import { NestContainer } from '../injector/container';
|
||||
|
||||
export class PipesContextCreator extends ContextCreator {
|
||||
|
||||
@@ -3,11 +3,11 @@ import { EXCEPTION_FILTERS_METADATA } from '@nestjs/common/constants';
|
||||
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
|
||||
import { isEmpty } from '@nestjs/common/utils/shared.utils';
|
||||
import 'reflect-metadata';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
import { BaseExceptionFilterContext } from '../exceptions/base-exception-filter-context';
|
||||
import { ExceptionsHandler } from '../exceptions/exceptions-handler';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { ApplicationConfig } from './../application-config';
|
||||
import { RouterProxyCallback } from './../router/router-proxy';
|
||||
import { RouterProxyCallback } from './router-proxy';
|
||||
|
||||
export class RouterExceptionFilters extends BaseExceptionFilterContext {
|
||||
constructor(
|
||||
|
||||
@@ -1,39 +1,19 @@
|
||||
import 'reflect-metadata';
|
||||
import {
|
||||
ROUTE_ARGS_METADATA,
|
||||
PARAMTYPES_METADATA,
|
||||
HTTP_CODE_METADATA,
|
||||
CUSTOM_ROUTE_AGRS_METADATA,
|
||||
RENDER_METADATA,
|
||||
HEADERS_METADATA,
|
||||
} from '@nestjs/common/constants';
|
||||
import {
|
||||
isUndefined,
|
||||
isFunction,
|
||||
isString,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
import { ForbiddenException, HttpServer, ParamData, PipeTransform, RequestMethod } from '@nestjs/common';
|
||||
import { CUSTOM_ROUTE_AGRS_METADATA, HEADERS_METADATA, HTTP_CODE_METADATA, PARAMTYPES_METADATA, RENDER_METADATA, ROUTE_ARGS_METADATA } from '@nestjs/common/constants';
|
||||
import { RouteParamsMetadata } from '@nestjs/common/decorators';
|
||||
import { RouteParamtypes } from '@nestjs/common/enums/route-paramtypes.enum';
|
||||
import { Controller, Transform } from '@nestjs/common/interfaces';
|
||||
import { RouteParamsMetadata } from '@nestjs/common/decorators';
|
||||
import { IRouteParamsFactory } from './interfaces/route-params-factory.interface';
|
||||
import { PipesContextCreator } from './../pipes/pipes-context-creator';
|
||||
import { PipesConsumer } from './../pipes/pipes-consumer';
|
||||
import {
|
||||
ParamData,
|
||||
PipeTransform,
|
||||
RequestMethod,
|
||||
ForbiddenException,
|
||||
HttpServer,
|
||||
} from '@nestjs/common';
|
||||
import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { GuardsConsumer } from '../guards/guards-consumer';
|
||||
import {
|
||||
RouterResponseController,
|
||||
CustomHeader,
|
||||
} from './router-response-controller';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { isFunction, isString, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import 'reflect-metadata';
|
||||
import { FORBIDDEN_MESSAGE } from '../guards/constants';
|
||||
import { GuardsConsumer } from '../guards/guards-consumer';
|
||||
import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
import { PipesConsumer } from '../pipes/pipes-consumer';
|
||||
import { PipesContextCreator } from '../pipes/pipes-context-creator';
|
||||
import { IRouteParamsFactory } from './interfaces/route-params-factory.interface';
|
||||
import { CustomHeader, RouterResponseController } from './router-response-controller';
|
||||
|
||||
export interface ParamProperties {
|
||||
index: number;
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import 'reflect-metadata';
|
||||
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
|
||||
import { METHOD_METADATA, PATH_METADATA } from '@nestjs/common/constants';
|
||||
import { RequestMethod } from '@nestjs/common/enums/request-method.enum';
|
||||
import { RouterProxy, RouterProxyCallback } from './router-proxy';
|
||||
import { UnknownRequestMappingException } from '../errors/exceptions/unknown-request-mapping.exception';
|
||||
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
|
||||
import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import { isUndefined, validatePath } from '@nestjs/common/utils/shared.utils';
|
||||
import { RouterMethodFactory } from '../helpers/router-method-factory';
|
||||
import { PATH_METADATA, METHOD_METADATA } from '@nestjs/common/constants';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { isUndefined, validatePath } from '@nestjs/common/utils/shared.utils';
|
||||
import 'reflect-metadata';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
import { UnknownRequestMappingException } from '../errors/exceptions/unknown-request-mapping.exception';
|
||||
import { GuardsConsumer } from '../guards/guards-consumer';
|
||||
import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { routeMappedMessage } from '../helpers/messages';
|
||||
import { RouterExecutionContext } from './router-execution-context';
|
||||
import { RouterMethodFactory } from '../helpers/router-method-factory';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
import { MetadataScanner } from '../metadata-scanner';
|
||||
import { PipesConsumer } from '../pipes/pipes-consumer';
|
||||
import { PipesContextCreator } from '../pipes/pipes-context-creator';
|
||||
import { ExceptionsFilter } from './interfaces/exceptions-filter.interface';
|
||||
import { RouteParamsFactory } from './route-params-factory';
|
||||
import { MetadataScanner } from '../metadata-scanner';
|
||||
import { ApplicationConfig } from './../application-config';
|
||||
import { PipesContextCreator } from './../pipes/pipes-context-creator';
|
||||
import { PipesConsumer } from './../pipes/pipes-consumer';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { GuardsConsumer } from '../guards/guards-consumer';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { RouterExecutionContext } from './router-execution-context';
|
||||
import { RouterProxy, RouterProxyCallback } from './router-proxy';
|
||||
|
||||
export class RouterExplorer {
|
||||
private readonly executionContextCreator: RouterExecutionContext;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { NestContainer, InstanceWrapper } from '../injector/container';
|
||||
import { RouterProxy } from './router-proxy';
|
||||
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { controllerMappingMessage } from '../helpers/messages';
|
||||
import { Resolver } from './interfaces/resolver.interface';
|
||||
import { RouterExceptionFilters } from './router-exception-filters';
|
||||
import { MetadataScanner } from '../metadata-scanner';
|
||||
import { RouterExplorer } from './router-explorer';
|
||||
import { ApplicationConfig } from './../application-config';
|
||||
import { NotFoundException, BadRequestException } from '@nestjs/common';
|
||||
import { BadRequestException, NotFoundException } from '@nestjs/common';
|
||||
import { MODULE_PATH } from '@nestjs/common/constants';
|
||||
import { HttpServer } from '@nestjs/common/interfaces';
|
||||
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
import { controllerMappingMessage } from '../helpers/messages';
|
||||
import { InstanceWrapper, NestContainer } from '../injector/container';
|
||||
import { MetadataScanner } from '../metadata-scanner';
|
||||
import { Resolver } from './interfaces/resolver.interface';
|
||||
import { RouterExceptionFilters } from './router-exception-filters';
|
||||
import { RouterExplorer } from './router-explorer';
|
||||
import { RouterProxy } from './router-proxy';
|
||||
|
||||
export class RoutesResolver implements Resolver {
|
||||
private readonly logger = new Logger(RoutesResolver.name, true);
|
||||
|
||||
@@ -18,11 +18,11 @@ import {
|
||||
isUndefined,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
import 'reflect-metadata';
|
||||
import { MetadataScanner } from '../core/metadata-scanner';
|
||||
import { ApplicationConfig } from './application-config';
|
||||
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from './constants';
|
||||
import { CircularDependencyException } from './errors/exceptions/circular-dependency.exception';
|
||||
import { NestContainer } from './injector/container';
|
||||
import { MetadataScanner } from './metadata-scanner';
|
||||
|
||||
interface ApplicationProviderWrapper {
|
||||
moduleKey: string;
|
||||
@@ -217,11 +217,20 @@ export class DependenciesScanner {
|
||||
key: string,
|
||||
method: string,
|
||||
) {
|
||||
const descriptor = Reflect.getOwnPropertyDescriptor(
|
||||
component.prototype,
|
||||
method,
|
||||
let prototype = component.prototype;
|
||||
do {
|
||||
const descriptor = Reflect.getOwnPropertyDescriptor(prototype, method);
|
||||
if (!descriptor) {
|
||||
continue;
|
||||
}
|
||||
return Reflect.getMetadata(key, descriptor.value);
|
||||
} while (
|
||||
// tslint:disable-next-line:no-conditional-assignment
|
||||
(prototype = Reflect.getPrototypeOf(prototype)) &&
|
||||
prototype !== Object.prototype &&
|
||||
prototype
|
||||
);
|
||||
return descriptor ? Reflect.getMetadata(key, descriptor.value) : undefined;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public async storeRelatedModule(
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { expect } from 'chai';
|
||||
import * as sinon from 'sinon';
|
||||
import { Module as ModuleDecorator } from '../../../common/decorators/modules/module.decorator';
|
||||
import { UnknownExportException } from '../../errors/exceptions/unknown-export.exception';
|
||||
import { Module } from '../../injector/module';
|
||||
import { Component } from '../../../common/decorators/core/component.decorator';
|
||||
import { Module as ModuleDecorator } from '../../../common/decorators/modules/module.decorator';
|
||||
import { RuntimeException } from '../../errors/exceptions/runtime.exception';
|
||||
import { UnknownElementException } from '../../errors/exceptions/unknown-element.exception';
|
||||
import { UnknownExportException } from '../../errors/exceptions/unknown-export.exception';
|
||||
import { NestContainer } from '../../injector/container';
|
||||
import { Module } from '../../injector/module';
|
||||
|
||||
describe('Module', () => {
|
||||
let module: Module;
|
||||
let container: NestContainer;
|
||||
|
||||
@ModuleDecorator({})
|
||||
class TestModule {}
|
||||
@@ -16,7 +18,8 @@ describe('Module', () => {
|
||||
class TestComponent {}
|
||||
|
||||
beforeEach(() => {
|
||||
module = new Module(TestModule as any, [], new NestContainer());
|
||||
container = new NestContainer();
|
||||
module = new Module(TestModule as any, [], container);
|
||||
});
|
||||
|
||||
it('should add route', () => {
|
||||
@@ -287,13 +290,12 @@ describe('Module', () => {
|
||||
});
|
||||
|
||||
describe('createModuleRefMetatype', () => {
|
||||
let components: Map<string, any>;
|
||||
let moduleRef;
|
||||
|
||||
beforeEach(() => {
|
||||
components = new Map();
|
||||
class SimpleClass {}
|
||||
|
||||
const Class = module.createModuleRefMetatype(components);
|
||||
beforeEach(() => {
|
||||
const Class = module.createModuleRefMetatype();
|
||||
moduleRef = new Class();
|
||||
});
|
||||
|
||||
@@ -301,13 +303,8 @@ describe('Module', () => {
|
||||
expect(!!moduleRef.get).to.be.true;
|
||||
});
|
||||
describe('get', () => {
|
||||
it('should return component if exists', () => {
|
||||
const comp = { instance: [] };
|
||||
components.set('comp', comp);
|
||||
expect(moduleRef.get('comp')).to.be.eql(comp.instance);
|
||||
});
|
||||
it('should return null if not exists', () => {
|
||||
expect(moduleRef.get('fail')).to.be.null;
|
||||
it('should throw exception if not exists', () => {
|
||||
expect(() => moduleRef.get('fail')).to.throws(UnknownElementException);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { Observable } from 'rxjs';
|
||||
import { InvalidGrpcPackageException } from '../exceptions/invalid-grpc-package.exception';
|
||||
import { InvalidGrpcServiceException } from '../exceptions/invalid-grpc-service.exception';
|
||||
import { InvalidProtoDefinitionException } from '../exceptions/invalid-proto-definition.exception';
|
||||
import { GRPC_DEFAULT_URL } from '../constants';
|
||||
import { InvalidGrpcPackageException } from '../exceptions/errors/invalid-grpc-package.exception';
|
||||
import { InvalidGrpcServiceException } from '../exceptions/errors/invalid-grpc-service.exception';
|
||||
import { InvalidProtoDefinitionException } from '../exceptions/errors/invalid-proto-definition.exception';
|
||||
import { ClientGrpc, GrpcOptions } from '../interfaces';
|
||||
import { ClientOptions } from '../interfaces/client-metadata.interface';
|
||||
import { GRPC_DEFAULT_URL } from './../constants';
|
||||
import { ClientGrpc, GrpcOptions } from './../interfaces';
|
||||
import { ClientProxy } from './client-proxy';
|
||||
import { GRPC_CANCELLED } from './constants';
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { ERROR_EVENT, MESSAGE_EVENT, MQTT_DEFAULT_URL } from '../constants';
|
||||
import { MqttClient } from '../external/mqtt-client.interface';
|
||||
import { MqttOptions, PacketId, ReadPacket, WritePacket } from '../interfaces';
|
||||
import { ClientOptions } from '../interfaces/client-metadata.interface';
|
||||
import { ERROR_EVENT, MESSAGE_EVENT, MQTT_DEFAULT_URL } from './../constants';
|
||||
import { MqttOptions, PacketId, ReadPacket, WritePacket } from './../interfaces';
|
||||
import { ClientProxy } from './client-proxy';
|
||||
import { ECONNREFUSED } from './constants';
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { ERROR_EVENT, NATS_DEFAULT_URL } from '../constants';
|
||||
import { Client } from '../external/nats-client.interface';
|
||||
import { NatsOptions, PacketId, ReadPacket, WritePacket } from '../interfaces';
|
||||
import { ClientOptions } from '../interfaces/client-metadata.interface';
|
||||
import { ERROR_EVENT, NATS_DEFAULT_URL } from './../constants';
|
||||
import { NatsOptions, PacketId, ReadPacket, WritePacket } from './../interfaces';
|
||||
import { ClientProxy } from './client-proxy';
|
||||
import { CONN_ERR } from './constants';
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import { isNil } from '@nestjs/common/utils/shared.utils';
|
||||
import { defer, fromEvent, merge, Observable, Observer, throwError as _throw } from 'rxjs';
|
||||
import { map, mergeMap, take } from 'rxjs/operators';
|
||||
import { CONNECT_EVENT, ERROR_EVENT } from '../constants';
|
||||
import { InvalidMessageException } from '../exceptions/invalid-message.exception';
|
||||
import { ClientOptions, PacketId, ReadPacket, WritePacket } from './../interfaces';
|
||||
import { InvalidMessageException } from '../exceptions/errors/invalid-message.exception';
|
||||
import { ClientOptions, PacketId, ReadPacket, WritePacket } from '../interfaces';
|
||||
|
||||
export abstract class ClientProxy {
|
||||
public abstract connect(): Promise<any>;
|
||||
|
||||
@@ -2,10 +2,10 @@ import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { fromEvent, merge, Subject, zip } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { CONNECT_EVENT, ERROR_EVENT, MESSAGE_EVENT, REDIS_DEFAULT_URL, SUBSCRIBE } from '../constants';
|
||||
import { ClientOpts, RedisClient, RetryStrategyOptions } from '../external/redis.interface';
|
||||
import { PacketId, ReadPacket, RedisOptions, WritePacket } from '../interfaces';
|
||||
import { ClientOptions } from '../interfaces/client-metadata.interface';
|
||||
import { CONNECT_EVENT, ERROR_EVENT, MESSAGE_EVENT, REDIS_DEFAULT_URL, SUBSCRIBE } from './../constants';
|
||||
import { PacketId, ReadPacket, RedisOptions, WritePacket } from './../interfaces';
|
||||
import { ClientProxy } from './client-proxy';
|
||||
import { ECONNREFUSED } from './constants';
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ import { Logger } from '@nestjs/common';
|
||||
import * as JsonSocket from 'json-socket';
|
||||
import * as net from 'net';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { CLOSE_EVENT, ERROR_EVENT, MESSAGE_EVENT, TCP_DEFAULT_HOST, TCP_DEFAULT_PORT } from '../constants';
|
||||
import { PacketId, ReadPacket, WritePacket } from '../interfaces';
|
||||
import { ClientOptions, TcpClientOptions } from '../interfaces/client-metadata.interface';
|
||||
import { CLOSE_EVENT, ERROR_EVENT, MESSAGE_EVENT, TCP_DEFAULT_HOST, TCP_DEFAULT_PORT } from './../constants';
|
||||
import { PacketId, ReadPacket, WritePacket } from './../interfaces';
|
||||
import { ClientProxy } from './client-proxy';
|
||||
import { ECONNREFUSED } from './constants';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ClientProxy } from './index';
|
||||
import { ClientProxy } from '.';
|
||||
import { Closeable } from './interfaces/closeable.interface';
|
||||
|
||||
export type CloseableClient = Closeable & ClientProxy;
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { RpcProxy } from './rpc-proxy';
|
||||
import { RpcExceptionsHandler } from '../exceptions/rpc-exceptions-handler';
|
||||
import { ExceptionFiltersContext } from './exception-filters-context';
|
||||
import { Controller } from '@nestjs/common/interfaces';
|
||||
import { PipesContextCreator } from '@nestjs/core/pipes/pipes-context-creator';
|
||||
import { PipesConsumer } from '@nestjs/core/pipes/pipes-consumer';
|
||||
import { PARAMTYPES_METADATA } from '@nestjs/common/constants';
|
||||
import { GuardsContextCreator } from '@nestjs/core/guards/guards-context-creator';
|
||||
import { GuardsConsumer } from '@nestjs/core/guards/guards-consumer';
|
||||
import { Controller } from '@nestjs/common/interfaces';
|
||||
import { FORBIDDEN_MESSAGE } from '@nestjs/core/guards/constants';
|
||||
import { RpcException } from '../index';
|
||||
import { InterceptorsContextCreator } from '@nestjs/core/interceptors/interceptors-context-creator';
|
||||
import { GuardsConsumer } from '@nestjs/core/guards/guards-consumer';
|
||||
import { GuardsContextCreator } from '@nestjs/core/guards/guards-context-creator';
|
||||
import { InterceptorsConsumer } from '@nestjs/core/interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '@nestjs/core/interceptors/interceptors-context-creator';
|
||||
import { PipesConsumer } from '@nestjs/core/pipes/pipes-consumer';
|
||||
import { PipesContextCreator } from '@nestjs/core/pipes/pipes-context-creator';
|
||||
import { Observable } from 'rxjs';
|
||||
import { RpcException } from '..';
|
||||
import { ExceptionFiltersContext } from './exception-filters-context';
|
||||
import { RpcProxy } from './rpc-proxy';
|
||||
|
||||
export class RpcContextCreator {
|
||||
constructor(
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { ArgumentsHost, Logger, RpcExceptionFilter } from '@nestjs/common';
|
||||
import { isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { messages } from '@nestjs/core/constants';
|
||||
import { Observable, throwError as _throw } from 'rxjs';
|
||||
import { RpcException } from './rpc-exception';
|
||||
|
||||
export class BaseRpcExceptionFilter<T = any, R = any>
|
||||
implements RpcExceptionFilter<T> {
|
||||
private static readonly logger = new Logger('RpcExceptionsHandler');
|
||||
|
||||
catch(exception: T, host: ArgumentsHost): Observable<R> {
|
||||
const status = 'error';
|
||||
if (!(exception instanceof RpcException)) {
|
||||
const errorMessage = messages.UNKNOWN_EXCEPTION_MESSAGE;
|
||||
|
||||
const isError = isObject(exception) && (exception as Error).message;
|
||||
const loggerArgs = isError
|
||||
? [
|
||||
((exception as any) as Error).message,
|
||||
((exception as any) as Error).stack,
|
||||
]
|
||||
: [exception];
|
||||
const logger = BaseRpcExceptionFilter.logger;
|
||||
logger.error.apply(logger, loggerArgs);
|
||||
|
||||
return _throw({ status, message: errorMessage });
|
||||
}
|
||||
const res = exception.getError();
|
||||
const message = isObject(res) ? res : { status, message: res };
|
||||
return _throw(message);
|
||||
}
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export * from './base-rpc-exception-filter';
|
||||
export * from './rpc-exception';
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { RpcExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions';
|
||||
import { ArgumentsHost } from '@nestjs/common/interfaces/features/arguments-host.interface';
|
||||
import { isEmpty, isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { messages } from '@nestjs/core/constants';
|
||||
import { isEmpty } from '@nestjs/common/utils/shared.utils';
|
||||
import { InvalidExceptionFilterException } from '@nestjs/core/errors/exceptions/invalid-exception-filter.exception';
|
||||
import { Observable, throwError as _throw } from 'rxjs';
|
||||
import { Observable } from 'rxjs';
|
||||
import { BaseRpcExceptionFilter } from './base-rpc-exception-filter';
|
||||
import { RpcException } from './rpc-exception';
|
||||
|
||||
export class RpcExceptionsHandler {
|
||||
private static readonly logger = new Logger(RpcExceptionsHandler.name);
|
||||
export class RpcExceptionsHandler extends BaseRpcExceptionFilter {
|
||||
private filters: RpcExceptionFilterMetadata[] = [];
|
||||
|
||||
public handle(
|
||||
@@ -19,22 +17,7 @@ export class RpcExceptionsHandler {
|
||||
if (filterResult$) {
|
||||
return filterResult$;
|
||||
}
|
||||
const status = 'error';
|
||||
if (!(exception instanceof RpcException)) {
|
||||
const errorMessage = messages.UNKNOWN_EXCEPTION_MESSAGE;
|
||||
|
||||
const isError = isObject(exception) && (exception as Error).message;
|
||||
const loggerArgs = isError
|
||||
? [(exception as Error).message, (exception as Error).stack]
|
||||
: [exception];
|
||||
const logger = RpcExceptionsHandler.logger;
|
||||
logger.error.apply(logger, loggerArgs);
|
||||
|
||||
return _throw({ status, message: errorMessage });
|
||||
}
|
||||
const res = exception.getError();
|
||||
const message = isObject(res) ? res : { status, message: res };
|
||||
return _throw(message);
|
||||
return super.catch(exception, host);
|
||||
}
|
||||
|
||||
public setCustomFilters(filters: RpcExceptionFilterMetadata[]) {
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { Transport } from './../enums/transport.enum';
|
||||
import {
|
||||
TcpOptions,
|
||||
RedisOptions,
|
||||
NatsOptions,
|
||||
MqttOptions,
|
||||
GrpcOptions,
|
||||
} from './microservice-configuration.interface';
|
||||
import { Transport } from '../enums/transport.enum';
|
||||
import { GrpcOptions, MqttOptions, NatsOptions, RedisOptions } from './microservice-configuration.interface';
|
||||
|
||||
export type ClientOptions =
|
||||
| RedisOptions
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MqttClientOptions } from '@nestjs/common/interfaces/external/mqtt-options.interface';
|
||||
import { Transport } from '../enums/transport.enum';
|
||||
import { Server } from './../server/server';
|
||||
import { Server } from '../server/server';
|
||||
import { CustomTransportStrategy } from './custom-transport-strategy.interface';
|
||||
|
||||
export type MicroserviceOptions =
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
import * as optional from 'optional';
|
||||
import iterate from 'iterare';
|
||||
import { NestContainer } from '@nestjs/core/injector/container';
|
||||
import { MicroservicesModule } from './microservices-module';
|
||||
import { messages } from '@nestjs/core/constants';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { Server } from './server/server';
|
||||
import { MicroserviceOptions } from './interfaces/microservice-configuration.interface';
|
||||
import { ServerFactory } from './server/server-factory';
|
||||
import { Transport } from './enums/transport.enum';
|
||||
import {
|
||||
INestMicroservice,
|
||||
WebSocketAdapter,
|
||||
CanActivate,
|
||||
PipeTransform,
|
||||
NestInterceptor,
|
||||
ExceptionFilter,
|
||||
OnModuleInit,
|
||||
INestMicroservice,
|
||||
NestInterceptor,
|
||||
PipeTransform,
|
||||
WebSocketAdapter,
|
||||
} from '@nestjs/common';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { ApplicationConfig } from '@nestjs/core/application-config';
|
||||
import { CustomTransportStrategy } from '@nestjs/microservices';
|
||||
import { Module } from '@nestjs/core/injector/module';
|
||||
import { isNil, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import { OnModuleDestroy } from '@nestjs/common/interfaces';
|
||||
import { messages } from '@nestjs/core/constants';
|
||||
import { NestContainer } from '@nestjs/core/injector/container';
|
||||
import { NestApplicationContext } from '@nestjs/core/nest-application-context';
|
||||
import { CustomTransportStrategy } from '@nestjs/microservices';
|
||||
import * as optional from 'optional';
|
||||
import { Transport } from './enums/transport.enum';
|
||||
import { MicroserviceOptions } from './interfaces/microservice-configuration.interface';
|
||||
import { MicroservicesModule } from './microservices-module';
|
||||
import { Server } from './server/server';
|
||||
import { ServerFactory } from './server/server-factory';
|
||||
|
||||
const { SocketModule } =
|
||||
optional('@nestjs/websockets/socket-module') || ({} as any);
|
||||
@@ -144,59 +139,7 @@ export class NestMicroservice extends NestApplicationContext
|
||||
|
||||
protected async closeApplication(): Promise<any> {
|
||||
this.socketModule && (await this.socketModule.close());
|
||||
await this.callDestroyHook();
|
||||
await super.close();
|
||||
this.setIsTerminated(true);
|
||||
}
|
||||
|
||||
protected async callInitHook(): Promise<any> {
|
||||
const modules = this.container.getModules();
|
||||
await Promise.all(
|
||||
iterate(modules.values()).map(
|
||||
async module => await this.callModuleInitHook(module),
|
||||
),
|
||||
);
|
||||
this.setIsInitHookCalled(true);
|
||||
}
|
||||
|
||||
protected async callModuleInitHook(module: Module): Promise<any> {
|
||||
const components = [...module.routes, ...module.components];
|
||||
await Promise.all(
|
||||
iterate(components)
|
||||
.map(([key, { instance }]) => instance)
|
||||
.filter(instance => !isNil(instance))
|
||||
.filter(this.hasOnModuleInitHook)
|
||||
.map(async instance => await (instance as OnModuleInit).onModuleInit()),
|
||||
);
|
||||
}
|
||||
|
||||
protected hasOnModuleInitHook(instance: any): instance is OnModuleInit {
|
||||
return !isUndefined((instance as OnModuleInit).onModuleInit);
|
||||
}
|
||||
|
||||
private async callDestroyHook(): Promise<any> {
|
||||
const modules = this.container.getModules();
|
||||
await Promise.all(
|
||||
iterate(modules.values()).map(
|
||||
async module => await this.callModuleDestroyHook(module),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private async callModuleDestroyHook(module: Module): Promise<any> {
|
||||
const components = [...module.routes, ...module.components];
|
||||
await Promise.all(
|
||||
iterate(components)
|
||||
.map(([key, { instance }]) => instance)
|
||||
.filter(instance => !isNil(instance))
|
||||
.filter(this.hasOnModuleDestroyHook)
|
||||
.map(
|
||||
async instance =>
|
||||
await (instance as OnModuleDestroy).onModuleDestroy(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private hasOnModuleDestroyHook(instance): instance is OnModuleDestroy {
|
||||
return !isUndefined((instance as OnModuleDestroy).onModuleDestroy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { fromEvent } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { InvalidGrpcPackageException } from '../exceptions/invalid-grpc-package.exception';
|
||||
import { InvalidProtoDefinitionException } from '../exceptions/invalid-proto-definition.exception';
|
||||
import { CANCEL_EVENT, GRPC_DEFAULT_URL } from '../constants';
|
||||
import { InvalidGrpcPackageException } from '../exceptions/errors/invalid-grpc-package.exception';
|
||||
import { InvalidProtoDefinitionException } from '../exceptions/errors/invalid-proto-definition.exception';
|
||||
import { CustomTransportStrategy } from '../interfaces';
|
||||
import { GrpcOptions, MicroserviceOptions } from '../interfaces/microservice-configuration.interface';
|
||||
import { CANCEL_EVENT, GRPC_DEFAULT_URL } from './../constants';
|
||||
import { CustomTransportStrategy } from './../interfaces';
|
||||
import { Server } from './server';
|
||||
|
||||
let grpcPackage: any = {};
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
import { Server } from './server';
|
||||
import { NO_PATTERN_MESSAGE } from '../constants';
|
||||
import {
|
||||
MicroserviceOptions,
|
||||
MqttOptions,
|
||||
} from '../interfaces/microservice-configuration.interface';
|
||||
import { CustomTransportStrategy, PacketId } from './../interfaces';
|
||||
import { Observable, EMPTY as empty } from 'rxjs';
|
||||
import { catchError, finalize } from 'rxjs/operators';
|
||||
import {
|
||||
MQTT_DEFAULT_URL,
|
||||
CONNECT_EVENT,
|
||||
MESSAGE_EVENT,
|
||||
ERROR_EVENT,
|
||||
} from './../constants';
|
||||
import { ReadPacket } from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CONNECT_EVENT, ERROR_EVENT, MESSAGE_EVENT, MQTT_DEFAULT_URL, NO_PATTERN_MESSAGE } from '../constants';
|
||||
import { MqttClient } from '../external/mqtt-client.interface';
|
||||
import { CustomTransportStrategy, PacketId } from '../interfaces';
|
||||
import { MicroserviceOptions, MqttOptions } from '../interfaces/microservice-configuration.interface';
|
||||
import { Server } from './server';
|
||||
|
||||
let mqttPackage: any = {};
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { NO_PATTERN_MESSAGE } from '../constants';
|
||||
import { CONNECT_EVENT, ERROR_EVENT, NATS_DEFAULT_URL, NO_PATTERN_MESSAGE } from '../constants';
|
||||
import { Client } from '../external/nats-client.interface';
|
||||
import { CustomTransportStrategy, PacketId } from '../interfaces';
|
||||
import { MicroserviceOptions, NatsOptions } from '../interfaces/microservice-configuration.interface';
|
||||
import { CONNECT_EVENT, ERROR_EVENT, NATS_DEFAULT_URL } from './../constants';
|
||||
import { CustomTransportStrategy, PacketId } from './../interfaces';
|
||||
import { ReadPacket } from './../interfaces/packet.interface';
|
||||
import { ReadPacket } from '../interfaces/packet.interface';
|
||||
import { Server } from './server';
|
||||
|
||||
let natsPackage: any = {};
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { ReadPacket } from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs';
|
||||
import { NO_PATTERN_MESSAGE } from '../constants';
|
||||
import { CONNECT_EVENT, ERROR_EVENT, MESSAGE_EVENT, NO_PATTERN_MESSAGE, REDIS_DEFAULT_URL } from '../constants';
|
||||
import { ClientOpts, RedisClient, RetryStrategyOptions } from '../external/redis.interface';
|
||||
import { CustomTransportStrategy, PacketId } from '../interfaces';
|
||||
import { MicroserviceOptions, RedisOptions } from '../interfaces/microservice-configuration.interface';
|
||||
import { CONNECT_EVENT, ERROR_EVENT, MESSAGE_EVENT, REDIS_DEFAULT_URL } from './../constants';
|
||||
import { CustomTransportStrategy, PacketId } from './../interfaces';
|
||||
import { Server } from './server';
|
||||
|
||||
let redisPackage: any = {};
|
||||
|
||||
@@ -2,10 +2,9 @@ import * as JsonSocket from 'json-socket';
|
||||
import * as net from 'net';
|
||||
import { Server as NetSocket } from 'net';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CLOSE_EVENT, NO_PATTERN_MESSAGE } from '../constants';
|
||||
import { CLOSE_EVENT, ERROR_EVENT, MESSAGE_EVENT, NO_PATTERN_MESSAGE, TCP_DEFAULT_PORT } from '../constants';
|
||||
import { CustomTransportStrategy, PacketId, ReadPacket } from '../interfaces';
|
||||
import { MicroserviceOptions, TcpOptions } from '../interfaces/microservice-configuration.interface';
|
||||
import { ERROR_EVENT, MESSAGE_EVENT, TCP_DEFAULT_PORT } from './../constants';
|
||||
import { CustomTransportStrategy, PacketId, ReadPacket } from './../interfaces';
|
||||
import { Server } from './server';
|
||||
|
||||
export class ServerTCP extends Server implements CustomTransportStrategy {
|
||||
|
||||
@@ -3,8 +3,8 @@ import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { isFunction, isString } from '@nestjs/common/utils/shared.utils';
|
||||
import { EMPTY as empty, from as fromPromise, Observable, of, Subscription } from 'rxjs';
|
||||
import { catchError, finalize } from 'rxjs/operators';
|
||||
import { MicroserviceOptions, WritePacket } from '../interfaces';
|
||||
import { MessageHandlers } from '../interfaces/message-handlers.interface';
|
||||
import { MicroserviceOptions, WritePacket } from './../interfaces';
|
||||
|
||||
export abstract class Server {
|
||||
protected readonly messageHandlers: MessageHandlers = {};
|
||||
|
||||
@@ -3,9 +3,9 @@ import { join } from 'path';
|
||||
import { Observable } from 'rxjs';
|
||||
import * as sinon from 'sinon';
|
||||
import { ClientGrpcProxy } from '../../client/client-grpc';
|
||||
import { InvalidGrpcPackageException } from '../../exceptions/invalid-grpc-package.exception';
|
||||
import { InvalidGrpcServiceException } from '../../exceptions/invalid-grpc-service.exception';
|
||||
import { InvalidProtoDefinitionException } from '../../exceptions/invalid-proto-definition.exception';
|
||||
import { InvalidGrpcPackageException } from '../../exceptions/errors/invalid-grpc-package.exception';
|
||||
import { InvalidGrpcServiceException } from '../../exceptions/errors/invalid-grpc-service.exception';
|
||||
import { InvalidProtoDefinitionException } from '../../exceptions/errors/invalid-proto-definition.exception';
|
||||
// tslint:disable:no-string-literal
|
||||
|
||||
class GrpcService {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ServerGrpc } from '../../server/server-grpc';
|
||||
import { expect } from 'chai';
|
||||
import * as sinon from 'sinon';
|
||||
import { of } from 'rxjs';
|
||||
import { join } from 'path';
|
||||
import { InvalidGrpcPackageException } from '../../exceptions/invalid-grpc-package.exception';
|
||||
import { of } from 'rxjs';
|
||||
import * as sinon from 'sinon';
|
||||
import { InvalidGrpcPackageException } from '../../exceptions/errors/invalid-grpc-package.exception';
|
||||
import { ServerGrpc } from '../../server/server-grpc';
|
||||
|
||||
describe('ServerGrpc', () => {
|
||||
let server: ServerGrpc;
|
||||
|
||||
24
packages/websockets/exceptions/base-ws-exception-filter.ts
Normal file
24
packages/websockets/exceptions/base-ws-exception-filter.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { ArgumentsHost, WsExceptionFilter } from '@nestjs/common';
|
||||
import { isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { messages } from '@nestjs/core/constants';
|
||||
import { WsException } from './ws-exception';
|
||||
|
||||
export class BaseWsExceptionFilter<T = any> implements WsExceptionFilter<T> {
|
||||
catch(exception: T, host: ArgumentsHost) {
|
||||
const client = host.switchToWs().getClient();
|
||||
const status = 'error';
|
||||
|
||||
if (!(exception instanceof WsException)) {
|
||||
const errorMessage = messages.UNKNOWN_EXCEPTION_MESSAGE;
|
||||
return client.emit('exception', { status, message: errorMessage });
|
||||
}
|
||||
const result = exception.getError();
|
||||
const message = isObject(result)
|
||||
? result
|
||||
: {
|
||||
status,
|
||||
message: result,
|
||||
};
|
||||
client.emit('exception', message);
|
||||
}
|
||||
}
|
||||
2
packages/websockets/exceptions/index.ts
Normal file
2
packages/websockets/exceptions/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './base-ws-exception-filter';
|
||||
export * from './ws-exception';
|
||||
@@ -1,31 +1,19 @@
|
||||
import { messages } from '@nestjs/core/constants';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { ArgumentsHost } from '@nestjs/common';
|
||||
import { ExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions/exception-filter-metadata.interface';
|
||||
import { isEmpty, isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { isEmpty } from '@nestjs/common/utils/shared.utils';
|
||||
import { InvalidExceptionFilterException } from '@nestjs/core/errors/exceptions/invalid-exception-filter.exception';
|
||||
import { WsException } from '../exceptions/ws-exception';
|
||||
import { ArgumentsHost } from '@nestjs/common';
|
||||
import { BaseWsExceptionFilter } from './base-ws-exception-filter';
|
||||
|
||||
export class WsExceptionsHandler {
|
||||
export class WsExceptionsHandler extends BaseWsExceptionFilter {
|
||||
private filters: ExceptionFilterMetadata[] = [];
|
||||
|
||||
public handle(exception: Error | WsException | any, args: ArgumentsHost) {
|
||||
const client = args.switchToWs().getClient();
|
||||
if (this.invokeCustomFilters(exception, args) || !client.emit) return;
|
||||
|
||||
const status = 'error';
|
||||
if (!(exception instanceof WsException)) {
|
||||
const errorMessage = messages.UNKNOWN_EXCEPTION_MESSAGE;
|
||||
return client.emit('exception', { status, message: errorMessage });
|
||||
public handle(exception: Error | WsException | any, host: ArgumentsHost) {
|
||||
const client = host.switchToWs().getClient();
|
||||
if (this.invokeCustomFilters(exception, host) || !client.emit) {
|
||||
return void 0;
|
||||
}
|
||||
const result = exception.getError();
|
||||
const message = isObject(result)
|
||||
? result
|
||||
: {
|
||||
status,
|
||||
message: result,
|
||||
};
|
||||
client.emit('exception', message);
|
||||
super.catch(exception, host);
|
||||
}
|
||||
|
||||
public setCustomFilters(filters: ExceptionFilterMetadata[]) {
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
export * from './adapters/ws-adapter';
|
||||
export * from './adapters/io-adapter';
|
||||
export * from './interfaces';
|
||||
export * from './exceptions/ws-exception';
|
||||
export * from './utils';
|
||||
export * from './adapters/ws-adapter';
|
||||
export * from './exceptions';
|
||||
export { MessageMappingProperties } from './gateway-metadata-explorer';
|
||||
export * from './interfaces';
|
||||
export * from './utils';
|
||||
|
||||
Reference in New Issue
Block a user