@tsed/common 5.66.0 → 5.67.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,7 +41,7 @@ export interface PlatformLoggerSettings {
41
41
  */
42
42
  disableRoutesSummary?: boolean;
43
43
  /**
44
- * Specify log format. Example: `%[%d{[yyyy-MM-dd hh:mm:ss,SSS}] %p%] %m`. See [@tsed/logger configuration](https://typedproject.github.io/logger/).
44
+ * Specify log format. Example: `%[%d{[yyyy-MM-dd hh:mm:ss,SSS}] %p%] %m`. See [@tsed/logger configuration](https://tsedio.github.io/logger/).
45
45
  */
46
46
  format?: string;
47
47
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"PlatformLoggerSettings.js","sourceRoot":"","sources":["../../../src/config/interfaces/PlatformLoggerSettings.ts"],"names":[],"mappings":"","sourcesContent":["export interface PlatformLoggerSettings {\n /**\n * Enable debug mode. By default debug is false.\n */\n debug?: boolean;\n /**\n * Enable info mode. By default debug is false.\n */\n level?: \"debug\" | \"info\" | \"warn\" | \"error\" | \"off\";\n /**\n * Fields displayed when a request is logged. Possible values: `reqId`, `method`, `url`, `headers`, `body`, `query`,`params`, `duration`.\n */\n requestFields?: (\"reqId\" | \"method\" | \"url\" | \"headers\" | \"body\" | \"query\" | \"params\" | \"duration\" | string)[];\n /**\n * List of regexp to ignore log.\n */\n ignoreUrlPatterns?: string[];\n /**\n * Log all incoming request. By default is true and print the configured `logger.requestFields`.\n */\n logRequest?: boolean;\n /**\n * Log start of all incoming request. By default is true\n */\n logStart?: boolean;\n /**\n * Log end of all incoming request. By default is true\n */\n logEnd?: boolean;\n /**\n * The number of space characters to use as white space in JSON output. Default is 2 (0 in production).\n */\n jsonIndentation?: number;\n /**\n * A function called for each incoming request to create a request id.\n * @returns {number}\n */\n reqIdBuilder?: () => string;\n /**\n * Disable routes table displayed in the logger. By default debug is `false`.\n */\n disableRoutesSummary?: boolean;\n /**\n * Specify log format. Example: `%[%d{[yyyy-MM-dd hh:mm:ss,SSS}] %p%] %m`. See [@tsed/logger configuration](https://typedproject.github.io/logger/).\n */\n format?: string;\n /**\n * Specify the log stack size for the context.logger. When the stack.length is reach, the logger is flushed during the request.\n * Default size is set to 30.\n */\n maxStackSize?: number;\n}\n/**\n * @deprecated Use PlatformLoggerSettings interface instead\n */\nexport interface ILoggerSettings extends PlatformLoggerSettings {}\n"]}
1
+ {"version":3,"file":"PlatformLoggerSettings.js","sourceRoot":"","sources":["../../../src/config/interfaces/PlatformLoggerSettings.ts"],"names":[],"mappings":"","sourcesContent":["export interface PlatformLoggerSettings {\n /**\n * Enable debug mode. By default debug is false.\n */\n debug?: boolean;\n /**\n * Enable info mode. By default debug is false.\n */\n level?: \"debug\" | \"info\" | \"warn\" | \"error\" | \"off\";\n /**\n * Fields displayed when a request is logged. Possible values: `reqId`, `method`, `url`, `headers`, `body`, `query`,`params`, `duration`.\n */\n requestFields?: (\"reqId\" | \"method\" | \"url\" | \"headers\" | \"body\" | \"query\" | \"params\" | \"duration\" | string)[];\n /**\n * List of regexp to ignore log.\n */\n ignoreUrlPatterns?: string[];\n /**\n * Log all incoming request. By default is true and print the configured `logger.requestFields`.\n */\n logRequest?: boolean;\n /**\n * Log start of all incoming request. By default is true\n */\n logStart?: boolean;\n /**\n * Log end of all incoming request. By default is true\n */\n logEnd?: boolean;\n /**\n * The number of space characters to use as white space in JSON output. Default is 2 (0 in production).\n */\n jsonIndentation?: number;\n /**\n * A function called for each incoming request to create a request id.\n * @returns {number}\n */\n reqIdBuilder?: () => string;\n /**\n * Disable routes table displayed in the logger. By default debug is `false`.\n */\n disableRoutesSummary?: boolean;\n /**\n * Specify log format. Example: `%[%d{[yyyy-MM-dd hh:mm:ss,SSS}] %p%] %m`. See [@tsed/logger configuration](https://tsedio.github.io/logger/).\n */\n format?: string;\n /**\n * Specify the log stack size for the context.logger. When the stack.length is reach, the logger is flushed during the request.\n * Default size is set to 30.\n */\n maxStackSize?: number;\n}\n/**\n * @deprecated Use PlatformLoggerSettings interface instead\n */\nexport interface ILoggerSettings extends PlatformLoggerSettings {}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { InjectorService } from "@tsed/di";
2
2
  import { EndpointMetadata, HandlerMetadata, ParamMetadata } from "../../mvc";
3
3
  import { HandlerContext } from "../domain/HandlerContext";
4
+ import { PlatformContext } from "../domain/PlatformContext";
4
5
  /**
5
6
  * Platform Handler abstraction layer. Wrap original class method to a pure platform handler (Express, Koa, etc...).
6
7
  * @platform
@@ -30,6 +31,7 @@ export declare class PlatformHandler {
30
31
  mapHandlerContext(metadata: HandlerMetadata, { request, response, err, next }: any): HandlerContext;
31
32
  createRawHandler(metadata: HandlerMetadata): Function;
32
33
  protected onRequest(context: HandlerContext): Promise<void>;
34
+ run(ctx: PlatformContext, cb: Function): any;
33
35
  private sortPipes;
34
36
  /**
35
37
  *
@@ -150,13 +150,18 @@ let PlatformHandler = class PlatformHandler {
150
150
  }
151
151
  const { metadata: { parameters } } = context;
152
152
  try {
153
- context.args = await Promise.all(parameters.map((param) => this.mapParam(param, context)));
154
- await context.callHandler();
153
+ await this.run(context.ctx, async () => {
154
+ context.args = await Promise.all(parameters.map((param) => this.mapParam(param, context)));
155
+ await context.callHandler();
156
+ });
155
157
  }
156
158
  catch (error) {
157
159
  context.next(error);
158
160
  }
159
161
  }
162
+ run(ctx, cb) {
163
+ return cb();
164
+ }
160
165
  sortPipes(metadata) {
161
166
  const get = (pipe) => {
162
167
  return this.injector.getProvider(pipe).priority || 0;
@@ -1 +1 @@
1
- {"version":3,"file":"PlatformHandler.js","sourceRoot":"","sources":["../../../src/platform/services/PlatformHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import {Type} from \"@tsed/core\";\nimport {Injectable, InjectorService, ProviderScope} from \"@tsed/di\";\nimport {\n EndpointMetadata,\n HandlerMetadata,\n HandlerType,\n IFilter,\n IHandlerConstructorOptions,\n IPipe,\n ParamMetadata,\n ParamTypes\n} from \"../../mvc\";\nimport {ValidationError} from \"../../mvc/errors/ValidationError\";\nimport {HandlerContext} from \"../domain/HandlerContext\";\nimport {ParamValidationError} from \"../errors/ParamValidationError\";\nimport {UnknownFilterError} from \"../errors/UnknownFilterError\";\n\n/**\n * Platform Handler abstraction layer. Wrap original class method to a pure platform handler (Express, Koa, etc...).\n * @platform\n */\n@Injectable({\n scope: ProviderScope.SINGLETON\n})\nexport class PlatformHandler {\n constructor(protected injector: InjectorService) {}\n\n createHandlerMetadata(obj: any | EndpointMetadata) {\n const {injector} = this;\n let options: IHandlerConstructorOptions;\n\n if (obj instanceof EndpointMetadata) {\n const provider = injector.getProvider(obj.provide)!;\n\n options = {\n token: provider.provide,\n target: provider.useClass,\n type: HandlerType.CONTROLLER,\n propertyKey: obj.propertyKey\n };\n } else {\n const provider = injector.getProvider(obj);\n\n if (provider) {\n options = {\n token: provider.provide,\n target: provider.useClass,\n type: HandlerType.MIDDLEWARE,\n propertyKey: \"use\"\n };\n } else {\n options = {\n target: obj,\n type: HandlerType.FUNCTION\n };\n }\n }\n\n return new HandlerMetadata(options);\n }\n\n /**\n * Create a native middleware based on the given metadata and return an instance of HandlerContext\n * @param metadata\n */\n createHandler(metadata: HandlerMetadata | any) {\n if (!(metadata instanceof HandlerMetadata)) {\n metadata = this.createHandlerMetadata(metadata);\n }\n\n if (metadata.type === HandlerType.FUNCTION) {\n return metadata.handler;\n }\n\n this.sortPipes(metadata);\n\n return this.createRawHandler(metadata);\n }\n\n /**\n * Get param from the context\n * @param param\n * @param context\n */\n getParam(param: ParamMetadata, context: HandlerContext) {\n const {\n ctx,\n ctx: {request, response}\n } = context;\n\n switch (param.paramType) {\n case ParamTypes.FORM_DATA:\n return context.request;\n\n case ParamTypes.RESPONSE:\n return context.response;\n\n case ParamTypes.REQUEST:\n return context.request;\n\n case ParamTypes.NEXT_FN:\n return context.next;\n\n case ParamTypes.ERR:\n return context.err;\n\n case ParamTypes.CONTEXT:\n return ctx;\n\n case ParamTypes.ENDPOINT_INFO:\n return ctx.endpoint;\n\n case ParamTypes.RESPONSE_DATA:\n return ctx.data;\n\n case ParamTypes.BODY:\n return request.body;\n\n case ParamTypes.QUERY:\n return request.query;\n\n case ParamTypes.PATH:\n return request.params;\n\n case ParamTypes.HEADER:\n return request.headers;\n\n case ParamTypes.COOKIES:\n return request.cookies;\n\n case ParamTypes.SESSION:\n return request.session;\n\n case ParamTypes.LOCALS:\n return response.locals;\n\n default:\n if (param.filter) {\n return this.getFilter(param, context);\n }\n\n return context.request;\n }\n }\n\n /**\n * Return a custom filter\n * @param param\n * @param context\n * @deprecated\n */\n getFilter(param: ParamMetadata, context: HandlerContext) {\n const {expression} = param;\n const instance = this.injector.get<IFilter>(param.filter);\n\n if (!instance || !instance.transform) {\n throw new UnknownFilterError(param.filter!);\n }\n\n return instance.transform(expression, context.request, context.response);\n }\n\n mapHandlerContext(metadata: HandlerMetadata, {request, response, err, next}: any): HandlerContext {\n return new HandlerContext({\n injector: this.injector,\n request,\n response,\n next,\n err,\n metadata,\n args: []\n });\n }\n\n createRawHandler(metadata: HandlerMetadata): Function {\n if (metadata.hasErrorParam) {\n return (err: any, request: any, response: any, next: any) =>\n this.onRequest(\n this.mapHandlerContext(metadata, {\n request,\n response,\n next,\n err\n })\n );\n } else {\n return (request: any, response: any, next: any) => this.onRequest(this.mapHandlerContext(metadata, {request, response, next}));\n }\n }\n\n protected async onRequest(context: HandlerContext) {\n if (context.isDone) {\n return;\n }\n\n const {\n metadata: {parameters}\n } = context;\n\n try {\n context.args = await Promise.all(parameters.map((param) => this.mapParam(param, context)));\n\n await context.callHandler();\n } catch (error) {\n context.next(error);\n }\n }\n\n private sortPipes(metadata: HandlerMetadata) {\n const get = (pipe: Type<any>) => {\n return this.injector.getProvider(pipe)!.priority || 0;\n };\n\n metadata.parameters.forEach((param: ParamMetadata) => {\n return (param.pipes = param.pipes.sort((p1: Type<any>, p2: Type<any>) => {\n return get(p1) < get(p2) ? -1 : get(p1) > get(p2) ? 1 : 0;\n }));\n });\n }\n\n /**\n *\n * @param metadata\n * @param context\n */\n private async mapParam(metadata: ParamMetadata, context: HandlerContext) {\n const {injector} = context;\n const value = this.getParam(metadata, context);\n\n // istanbul ignore next\n const handleError = async (cb: Function) => {\n try {\n return await cb();\n } catch (er) {\n throw er instanceof ValidationError ? ParamValidationError.from(metadata, er) : er;\n }\n };\n\n return metadata.pipes.reduce(async (value, pipe) => {\n value = await value;\n\n return handleError(() => injector.get<IPipe>(pipe)!.transform(value, metadata));\n }, value);\n }\n}\n"]}
1
+ {"version":3,"file":"PlatformHandler.js","sourceRoot":"","sources":["../../../src/platform/services/PlatformHandler.ts"],"names":[],"mappings":";;;;AACA,iCAAoE;AACpE,mCASmB;AACnB,sEAAiE;AACjE,6DAAwD;AAExD,yEAAoE;AACpE,qEAAgE;AAEhE;;;GAGG;AAIH,IAAa,eAAe,GAA5B,MAAa,eAAe;IAC1B,YAAsB,QAAyB;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAEnD,qBAAqB,CAAC,GAA2B;QAC/C,MAAM,EAAC,QAAQ,EAAC,GAAG,IAAI,CAAC;QACxB,IAAI,OAAmC,CAAC;QAExC,IAAI,GAAG,YAAY,sBAAgB,EAAE;YACnC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC;YAEpD,OAAO,GAAG;gBACR,KAAK,EAAE,QAAQ,CAAC,OAAO;gBACvB,MAAM,EAAE,QAAQ,CAAC,QAAQ;gBACzB,IAAI,EAAE,iBAAW,CAAC,UAAU;gBAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;aAC7B,CAAC;SACH;aAAM;YACL,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAE3C,IAAI,QAAQ,EAAE;gBACZ,OAAO,GAAG;oBACR,KAAK,EAAE,QAAQ,CAAC,OAAO;oBACvB,MAAM,EAAE,QAAQ,CAAC,QAAQ;oBACzB,IAAI,EAAE,iBAAW,CAAC,UAAU;oBAC5B,WAAW,EAAE,KAAK;iBACnB,CAAC;aACH;iBAAM;gBACL,OAAO,GAAG;oBACR,MAAM,EAAE,GAAG;oBACX,IAAI,EAAE,iBAAW,CAAC,QAAQ;iBAC3B,CAAC;aACH;SACF;QAED,OAAO,IAAI,qBAAe,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,QAA+B;QAC3C,IAAI,CAAC,CAAC,QAAQ,YAAY,qBAAe,CAAC,EAAE;YAC1C,QAAQ,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;SACjD;QAED,IAAI,QAAQ,CAAC,IAAI,KAAK,iBAAW,CAAC,QAAQ,EAAE;YAC1C,OAAO,QAAQ,CAAC,OAAO,CAAC;SACzB;QAED,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,KAAoB,EAAE,OAAuB;QACpD,MAAM,EACJ,GAAG,EACH,GAAG,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAC,EACzB,GAAG,OAAO,CAAC;QAEZ,QAAQ,KAAK,CAAC,SAAS,EAAE;YACvB,KAAK,gBAAU,CAAC,SAAS;gBACvB,OAAO,OAAO,CAAC,OAAO,CAAC;YAEzB,KAAK,gBAAU,CAAC,QAAQ;gBACtB,OAAO,OAAO,CAAC,QAAQ,CAAC;YAE1B,KAAK,gBAAU,CAAC,OAAO;gBACrB,OAAO,OAAO,CAAC,OAAO,CAAC;YAEzB,KAAK,gBAAU,CAAC,OAAO;gBACrB,OAAO,OAAO,CAAC,IAAI,CAAC;YAEtB,KAAK,gBAAU,CAAC,GAAG;gBACjB,OAAO,OAAO,CAAC,GAAG,CAAC;YAErB,KAAK,gBAAU,CAAC,OAAO;gBACrB,OAAO,GAAG,CAAC;YAEb,KAAK,gBAAU,CAAC,aAAa;gBAC3B,OAAO,GAAG,CAAC,QAAQ,CAAC;YAEtB,KAAK,gBAAU,CAAC,aAAa;gBAC3B,OAAO,GAAG,CAAC,IAAI,CAAC;YAElB,KAAK,gBAAU,CAAC,IAAI;gBAClB,OAAO,OAAO,CAAC,IAAI,CAAC;YAEtB,KAAK,gBAAU,CAAC,KAAK;gBACnB,OAAO,OAAO,CAAC,KAAK,CAAC;YAEvB,KAAK,gBAAU,CAAC,IAAI;gBAClB,OAAO,OAAO,CAAC,MAAM,CAAC;YAExB,KAAK,gBAAU,CAAC,MAAM;gBACpB,OAAO,OAAO,CAAC,OAAO,CAAC;YAEzB,KAAK,gBAAU,CAAC,OAAO;gBACrB,OAAO,OAAO,CAAC,OAAO,CAAC;YAEzB,KAAK,gBAAU,CAAC,OAAO;gBACrB,OAAO,OAAO,CAAC,OAAO,CAAC;YAEzB,KAAK,gBAAU,CAAC,MAAM;gBACpB,OAAO,QAAQ,CAAC,MAAM,CAAC;YAEzB;gBACE,IAAI,KAAK,CAAC,MAAM,EAAE;oBAChB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;iBACvC;gBAED,OAAO,OAAO,CAAC,OAAO,CAAC;SAC1B;IACH,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,KAAoB,EAAE,OAAuB;QACrD,MAAM,EAAC,UAAU,EAAC,GAAG,KAAK,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAU,KAAK,CAAC,MAAM,CAAC,CAAC;QAE1D,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE;YACpC,MAAM,IAAI,uCAAkB,CAAC,KAAK,CAAC,MAAO,CAAC,CAAC;SAC7C;QAED,OAAO,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3E,CAAC;IAED,iBAAiB,CAAC,QAAyB,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAM;QAC9E,OAAO,IAAI,+BAAc,CAAC;YACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO;YACP,QAAQ;YACR,IAAI;YACJ,GAAG;YACH,QAAQ;YACR,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,QAAyB;QACxC,IAAI,QAAQ,CAAC,aAAa,EAAE;YAC1B,OAAO,CAAC,GAAQ,EAAE,OAAY,EAAE,QAAa,EAAE,IAAS,EAAE,EAAE,CAC1D,IAAI,CAAC,SAAS,CACZ,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE;gBAC/B,OAAO;gBACP,QAAQ;gBACR,IAAI;gBACJ,GAAG;aACJ,CAAC,CACH,CAAC;SACL;aAAM;YACL,OAAO,CAAC,OAAY,EAAE,QAAa,EAAE,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC;SAChI;IACH,CAAC;IAES,KAAK,CAAC,SAAS,CAAC,OAAuB;QAC/C,IAAI,OAAO,CAAC,MAAM,EAAE;YAClB,OAAO;SACR;QAED,MAAM,EACJ,QAAQ,EAAE,EAAC,UAAU,EAAC,EACvB,GAAG,OAAO,CAAC;QAEZ,IAAI;YACF,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;gBACrC,OAAO,CAAC,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;gBAE3F,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9B,CAAC,CAAC,CAAC;SACJ;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACrB;IACH,CAAC;IAED,GAAG,CAAC,GAAoB,EAAE,EAAY;QACpC,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;IAEO,SAAS,CAAC,QAAyB;QACzC,MAAM,GAAG,GAAG,CAAC,IAAe,EAAE,EAAE;YAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAE,CAAC,QAAQ,IAAI,CAAC,CAAC;QACxD,CAAC,CAAC;QAEF,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAoB,EAAE,EAAE;YACnD,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAa,EAAE,EAAa,EAAE,EAAE;gBACtE,OAAO,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5D,CAAC,CAAC,CAAC,CAAC;QACN,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,QAAQ,CAAC,QAAuB,EAAE,OAAuB;QACrE,MAAM,EAAC,QAAQ,EAAC,GAAG,OAAO,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE/C,uBAAuB;QACvB,MAAM,WAAW,GAAG,KAAK,EAAE,EAAY,EAAE,EAAE;YACzC,IAAI;gBACF,OAAO,MAAM,EAAE,EAAE,CAAC;aACnB;YAAC,OAAO,EAAE,EAAE;gBACX,MAAM,EAAE,YAAY,iCAAe,CAAC,CAAC,CAAC,2CAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aACpF;QACH,CAAC,CAAC;QAEF,OAAO,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACjD,KAAK,GAAG,MAAM,KAAK,CAAC;YAEpB,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAQ,IAAI,CAAE,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClF,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;CACF,CAAA;AAlOY,eAAe;IAH3B,eAAU,CAAC;QACV,KAAK,EAAE,kBAAa,CAAC,SAAS;KAC/B,CAAC;6CAEgC,oBAAe;GADpC,eAAe,CAkO3B;AAlOY,0CAAe","sourcesContent":["import {Type} from \"@tsed/core\";\nimport {Injectable, InjectorService, ProviderScope} from \"@tsed/di\";\nimport {\n EndpointMetadata,\n HandlerMetadata,\n HandlerType,\n IFilter,\n IHandlerConstructorOptions,\n IPipe,\n ParamMetadata,\n ParamTypes\n} from \"../../mvc\";\nimport {ValidationError} from \"../../mvc/errors/ValidationError\";\nimport {HandlerContext} from \"../domain/HandlerContext\";\nimport {PlatformContext} from \"../domain/PlatformContext\";\nimport {ParamValidationError} from \"../errors/ParamValidationError\";\nimport {UnknownFilterError} from \"../errors/UnknownFilterError\";\n\n/**\n * Platform Handler abstraction layer. Wrap original class method to a pure platform handler (Express, Koa, etc...).\n * @platform\n */\n@Injectable({\n scope: ProviderScope.SINGLETON\n})\nexport class PlatformHandler {\n constructor(protected injector: InjectorService) {}\n\n createHandlerMetadata(obj: any | EndpointMetadata) {\n const {injector} = this;\n let options: IHandlerConstructorOptions;\n\n if (obj instanceof EndpointMetadata) {\n const provider = injector.getProvider(obj.provide)!;\n\n options = {\n token: provider.provide,\n target: provider.useClass,\n type: HandlerType.CONTROLLER,\n propertyKey: obj.propertyKey\n };\n } else {\n const provider = injector.getProvider(obj);\n\n if (provider) {\n options = {\n token: provider.provide,\n target: provider.useClass,\n type: HandlerType.MIDDLEWARE,\n propertyKey: \"use\"\n };\n } else {\n options = {\n target: obj,\n type: HandlerType.FUNCTION\n };\n }\n }\n\n return new HandlerMetadata(options);\n }\n\n /**\n * Create a native middleware based on the given metadata and return an instance of HandlerContext\n * @param metadata\n */\n createHandler(metadata: HandlerMetadata | any) {\n if (!(metadata instanceof HandlerMetadata)) {\n metadata = this.createHandlerMetadata(metadata);\n }\n\n if (metadata.type === HandlerType.FUNCTION) {\n return metadata.handler;\n }\n\n this.sortPipes(metadata);\n\n return this.createRawHandler(metadata);\n }\n\n /**\n * Get param from the context\n * @param param\n * @param context\n */\n getParam(param: ParamMetadata, context: HandlerContext) {\n const {\n ctx,\n ctx: {request, response}\n } = context;\n\n switch (param.paramType) {\n case ParamTypes.FORM_DATA:\n return context.request;\n\n case ParamTypes.RESPONSE:\n return context.response;\n\n case ParamTypes.REQUEST:\n return context.request;\n\n case ParamTypes.NEXT_FN:\n return context.next;\n\n case ParamTypes.ERR:\n return context.err;\n\n case ParamTypes.CONTEXT:\n return ctx;\n\n case ParamTypes.ENDPOINT_INFO:\n return ctx.endpoint;\n\n case ParamTypes.RESPONSE_DATA:\n return ctx.data;\n\n case ParamTypes.BODY:\n return request.body;\n\n case ParamTypes.QUERY:\n return request.query;\n\n case ParamTypes.PATH:\n return request.params;\n\n case ParamTypes.HEADER:\n return request.headers;\n\n case ParamTypes.COOKIES:\n return request.cookies;\n\n case ParamTypes.SESSION:\n return request.session;\n\n case ParamTypes.LOCALS:\n return response.locals;\n\n default:\n if (param.filter) {\n return this.getFilter(param, context);\n }\n\n return context.request;\n }\n }\n\n /**\n * Return a custom filter\n * @param param\n * @param context\n * @deprecated\n */\n getFilter(param: ParamMetadata, context: HandlerContext) {\n const {expression} = param;\n const instance = this.injector.get<IFilter>(param.filter);\n\n if (!instance || !instance.transform) {\n throw new UnknownFilterError(param.filter!);\n }\n\n return instance.transform(expression, context.request, context.response);\n }\n\n mapHandlerContext(metadata: HandlerMetadata, {request, response, err, next}: any): HandlerContext {\n return new HandlerContext({\n injector: this.injector,\n request,\n response,\n next,\n err,\n metadata,\n args: []\n });\n }\n\n createRawHandler(metadata: HandlerMetadata): Function {\n if (metadata.hasErrorParam) {\n return (err: any, request: any, response: any, next: any) =>\n this.onRequest(\n this.mapHandlerContext(metadata, {\n request,\n response,\n next,\n err\n })\n );\n } else {\n return (request: any, response: any, next: any) => this.onRequest(this.mapHandlerContext(metadata, {request, response, next}));\n }\n }\n\n protected async onRequest(context: HandlerContext) {\n if (context.isDone) {\n return;\n }\n\n const {\n metadata: {parameters}\n } = context;\n\n try {\n await this.run(context.ctx, async () => {\n context.args = await Promise.all(parameters.map((param) => this.mapParam(param, context)));\n\n await context.callHandler();\n });\n } catch (error) {\n context.next(error);\n }\n }\n\n run(ctx: PlatformContext, cb: Function) {\n return cb();\n }\n\n private sortPipes(metadata: HandlerMetadata) {\n const get = (pipe: Type<any>) => {\n return this.injector.getProvider(pipe)!.priority || 0;\n };\n\n metadata.parameters.forEach((param: ParamMetadata) => {\n return (param.pipes = param.pipes.sort((p1: Type<any>, p2: Type<any>) => {\n return get(p1) < get(p2) ? -1 : get(p1) > get(p2) ? 1 : 0;\n }));\n });\n }\n\n /**\n *\n * @param metadata\n * @param context\n */\n private async mapParam(metadata: ParamMetadata, context: HandlerContext) {\n const {injector} = context;\n const value = this.getParam(metadata, context);\n\n // istanbul ignore next\n const handleError = async (cb: Function) => {\n try {\n return await cb();\n } catch (er) {\n throw er instanceof ValidationError ? ParamValidationError.from(metadata, er) : er;\n }\n };\n\n return metadata.pipes.reduce(async (value, pipe) => {\n value = await value;\n\n return handleError(() => injector.get<IPipe>(pipe)!.transform(value, metadata));\n }, value);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsed/common",
3
- "version": "5.66.0",
3
+ "version": "5.67.2",
4
4
  "description": "A TypeScript Framework on top of Express",
5
5
  "main": "./lib/index.js",
6
6
  "typings": "./lib/index.d.ts",
@@ -30,21 +30,21 @@
30
30
  "author": "Romain Lenzotti",
31
31
  "license": "MIT",
32
32
  "bugs": {
33
- "url": "https://github.com/TypedProject/tsed/issues"
33
+ "url": "https://github.com/tsedio/tsed/issues"
34
34
  },
35
- "homepage": "https://github.com/TypedProject/tsed/tree/5.x/packages/common",
36
- "repository": "https://github.com/TypedProject/tsed",
35
+ "homepage": "https://github.com/tsedio/tsed/tree/5.x/packages/common",
36
+ "repository": "https://github.com/tsedio/tsed",
37
37
  "scripts": {
38
38
  "build": "tsc --build tsconfig.compile.json"
39
39
  },
40
40
  "dependencies": {
41
- "@tsed/core": "5.66.0",
42
- "@tsed/di": "5.66.0",
43
- "@tsed/exceptions": "5.66.0",
41
+ "@tsed/core": "5.67.2",
42
+ "@tsed/di": "5.67.2",
43
+ "@tsed/exceptions": "5.67.2",
44
44
  "@tsed/logger": "5.5.3",
45
45
  "@types/json-schema": "7.0.6",
46
46
  "globby": "11.0.1",
47
- "json-schema": "^0.2.3",
47
+ "json-schema": "^0.4.0",
48
48
  "normalize-path": "3.0.0",
49
49
  "on-finished": "2.3.0",
50
50
  "rxjs": "^6.5.2",
package/readme.md CHANGED
@@ -2,14 +2,14 @@
2
2
  <a href="https://tsed.io" target="_blank"><img src="https://tsed.io/tsed-og.png" width="200" alt="Ts.ED logo"/></a>
3
3
  </p>
4
4
 
5
- [![Build Status](https://travis-ci.org/TypedProject/tsed.svg?branch=master)](https://travis-ci.org/TypedProject/tsed)
6
- [![Coverage Status](https://coveralls.io/repos/github/TypedProject/tsed/badge.svg?branch=production)](https://coveralls.io/github/TypedProject/tsed?branch=production)
5
+ [![Build Status](https://travis-ci.org/tsedio/tsed.svg?branch=master)](https://travis-ci.org/tsedio/tsed)
6
+ [![Coverage Status](https://coveralls.io/repos/github/tsedio/tsed/badge.svg?branch=production)](https://coveralls.io/github/tsedio/tsed?branch=production)
7
7
  ![npm](https://img.shields.io/npm/dm/@tsed/common.svg)
8
8
  [![npm version](https://badge.fury.io/js/%40tsed%2Fcommon.svg)](https://badge.fury.io/js/%40tsed%2Fcommon)
9
- [![Dependencies](https://david-dm.org/TypedProject/tsed.svg)](https://david-dm.org/TypedProject/tsed#info=dependencies)
10
- [![img](https://david-dm.org/TypedProject/tsed/dev-status.svg)](https://david-dm.org/TypedProject/tsed/#info=devDependencies)
11
- [![img](https://david-dm.org/TypedProject/tsed/peer-status.svg)](https://david-dm.org/TypedProject/tsed/#info=peerDependenciess)
12
- [![Known Vulnerabilities](https://snyk.io/test/github/TypedProject/tsed/badge.svg)](https://snyk.io/test/github/TypedProject/tsed)
9
+ [![Dependencies](https://david-dm.org/tsedio/tsed.svg)](https://david-dm.org/tsedio/tsed#info=dependencies)
10
+ [![img](https://david-dm.org/tsedio/tsed/dev-status.svg)](https://david-dm.org/tsedio/tsed/#info=devDependencies)
11
+ [![img](https://david-dm.org/tsedio/tsed/peer-status.svg)](https://david-dm.org/tsedio/tsed/#info=peerDependenciess)
12
+ [![Known Vulnerabilities](https://snyk.io/test/github/tsedio/tsed/badge.svg)](https://snyk.io/test/github/tsedio/tsed)
13
13
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
14
14
  [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
15
15
  [![backers](https://opencollective.com/tsed/tiers/badge.svg)](https://opencollective.com/tsed)
@@ -180,7 +180,7 @@ export class UsersCtrl {
180
180
  ## Contributors
181
181
  Please read [contributing guidelines here](./CONTRIBUTING.md).
182
182
 
183
- <a href="https://github.com/TypedProject/tsed/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
183
+ <a href="https://github.com/tsedio/tsed/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
184
184
 
185
185
 
186
186
  ## Backers