@tsed/platform-response-filter 7.0.0-alpha.2 → 7.0.0-beta.11

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.
Files changed (48) hide show
  1. package/lib/cjs/decorators/responseFilter.js +23 -0
  2. package/lib/cjs/decorators/responseFilter.js.map +1 -0
  3. package/lib/cjs/domain/ResponseFiltersContainer.js +16 -0
  4. package/lib/cjs/domain/ResponseFiltersContainer.js.map +1 -0
  5. package/lib/cjs/errors/TemplateRenderError.js +23 -0
  6. package/lib/cjs/errors/TemplateRenderError.js.map +1 -0
  7. package/lib/cjs/index.js +14 -0
  8. package/lib/cjs/index.js.map +1 -0
  9. package/lib/cjs/interfaces/ResponseFilterMethods.js +3 -0
  10. package/lib/cjs/interfaces/ResponseFilterMethods.js.map +1 -0
  11. package/lib/cjs/package.json +3 -0
  12. package/lib/cjs/services/PlatformResponseFilter.js +94 -0
  13. package/lib/cjs/services/PlatformResponseFilter.js.map +1 -0
  14. package/lib/cjs/utils/getContentType.js +28 -0
  15. package/lib/cjs/utils/getContentType.js.map +1 -0
  16. package/lib/cjs/utils/renderView.js +17 -0
  17. package/lib/cjs/utils/renderView.js.map +1 -0
  18. package/lib/esm/decorators/responseFilter.js +19 -0
  19. package/lib/esm/decorators/responseFilter.js.map +1 -0
  20. package/lib/esm/domain/ResponseFiltersContainer.js +12 -0
  21. package/lib/esm/domain/ResponseFiltersContainer.js.map +1 -0
  22. package/lib/esm/errors/TemplateRenderError.js +19 -0
  23. package/lib/esm/errors/TemplateRenderError.js.map +1 -0
  24. package/lib/esm/index.js +11 -0
  25. package/lib/esm/index.js.map +1 -0
  26. package/lib/esm/interfaces/ResponseFilterMethods.js +2 -0
  27. package/lib/esm/interfaces/ResponseFilterMethods.js.map +1 -0
  28. package/lib/esm/package.json +3 -0
  29. package/lib/esm/services/PlatformResponseFilter.js +91 -0
  30. package/lib/esm/services/PlatformResponseFilter.js.map +1 -0
  31. package/lib/esm/utils/getContentType.js +24 -0
  32. package/lib/esm/utils/getContentType.js.map +1 -0
  33. package/lib/esm/utils/renderView.js +13 -0
  34. package/lib/esm/utils/renderView.js.map +1 -0
  35. package/lib/{decorators → types/decorators}/responseFilter.d.ts +0 -0
  36. package/lib/{domain → types/domain}/ResponseFiltersContainer.d.ts +0 -0
  37. package/lib/types/errors/TemplateRenderError.d.ts +14 -0
  38. package/lib/{index.d.ts → types/index.d.ts} +5 -0
  39. package/lib/{interfaces → types/interfaces}/ResponseFilterMethods.d.ts +0 -0
  40. package/lib/{services → types/services}/PlatformResponseFilter.d.ts +4 -4
  41. package/lib/{utils → types/utils}/getContentType.d.ts +0 -0
  42. package/lib/types/utils/renderView.d.ts +2 -0
  43. package/package.json +42 -22
  44. package/tsconfig.compile.esm.json +12 -0
  45. package/lib/index.js +0 -566
  46. package/lib/index.js.map +0 -1
  47. package/lib/index.modern.js +0 -562
  48. package/lib/index.modern.js.map +0 -1
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResponseFilter = void 0;
4
+ const di_1 = require("@tsed/di");
5
+ const ResponseFiltersContainer_1 = require("../domain/ResponseFiltersContainer");
6
+ /**
7
+ * Register a response filter service.
8
+ * @param contentTypes
9
+ * @decorator
10
+ */
11
+ function ResponseFilter(...contentTypes) {
12
+ return (target) => {
13
+ contentTypes.forEach((contentType) => {
14
+ (0, ResponseFiltersContainer_1.registerResponseFilter)(contentType, target);
15
+ });
16
+ (0, di_1.registerProvider)({
17
+ provide: target,
18
+ useClass: target
19
+ });
20
+ };
21
+ }
22
+ exports.ResponseFilter = ResponseFilter;
23
+ //# sourceMappingURL=responseFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseFilter.js","sourceRoot":"","sources":["../../../src/decorators/responseFilter.ts"],"names":[],"mappings":";;;AACA,iCAA0C;AAC1C,iFAA6F;AAE7F;;;;GAIG;AACH,SAAgB,cAAc,CAAC,GAAG,YAAiC;IACjE,OAAO,CAAU,MAAS,EAAY,EAAE;QACtC,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;YACnC,IAAA,iDAAsB,EAAC,WAAW,EAAE,MAAa,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QACH,IAAA,qBAAgB,EAAC;YACf,OAAO,EAAE,MAAM;YACf,QAAQ,EAAE,MAA8B;SACzC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAVD,wCAUC","sourcesContent":["import {Type} from \"@tsed/core\";\nimport {registerProvider} from \"@tsed/di\";\nimport {registerResponseFilter, ResponseFilterKey} from \"../domain/ResponseFiltersContainer\";\n\n/**\n * Register a response filter service.\n * @param contentTypes\n * @decorator\n */\nexport function ResponseFilter(...contentTypes: ResponseFilterKey[]): ClassDecorator {\n return <T = any>(target: T): void | T => {\n contentTypes.forEach((contentType) => {\n registerResponseFilter(contentType, target as any);\n });\n registerProvider({\n provide: target,\n useClass: target as unknown as Type<any>\n });\n };\n}\n"]}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerResponseFilter = exports.ResponseFiltersContainer = void 0;
4
+ /**
5
+ * @ignore
6
+ */
7
+ // tslint:disable-next-line:variable-name
8
+ exports.ResponseFiltersContainer = new Map();
9
+ /**
10
+ * @ignore
11
+ */
12
+ function registerResponseFilter(type, token) {
13
+ exports.ResponseFiltersContainer.set(type, token);
14
+ }
15
+ exports.registerResponseFilter = registerResponseFilter;
16
+ //# sourceMappingURL=ResponseFiltersContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponseFiltersContainer.js","sourceRoot":"","sources":["../../../src/domain/ResponseFiltersContainer.ts"],"names":[],"mappings":";;;AAMA;;GAEG;AACH,yCAAyC;AAC5B,QAAA,wBAAwB,GAAG,IAAI,GAAG,EAAkD,CAAC;AAClG;;GAEG;AACH,SAAgB,sBAAsB,CAAC,IAAuB,EAAE,KAAkC;IAChG,gCAAwB,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAFD,wDAEC","sourcesContent":["import {Type} from \"@tsed/core\";\nimport {ResponseFilterMethods} from \"../interfaces/ResponseFilterMethods\";\n/**\n * @ignore\n */\nexport type ResponseFilterKey = \"*/*\" | \"application/json\" | \"text/html\" | \"plain/text\" | string;\n/**\n * @ignore\n */\n// tslint:disable-next-line:variable-name\nexport const ResponseFiltersContainer = new Map<ResponseFilterKey, Type<ResponseFilterMethods>>();\n/**\n * @ignore\n */\nexport function registerResponseFilter(type: ResponseFilterKey, token: Type<ResponseFilterMethods>) {\n ResponseFiltersContainer.set(type, token);\n}\n"]}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TemplateRenderError = void 0;
4
+ const core_1 = require("@tsed/core");
5
+ const exceptions_1 = require("@tsed/exceptions");
6
+ /**
7
+ * @private
8
+ */
9
+ class TemplateRenderError extends exceptions_1.InternalServerError {
10
+ constructor(target, method, err) {
11
+ super(TemplateRenderError.buildMessage(target, method, err));
12
+ this.name = "TEMPLATE_RENDER_ERROR";
13
+ }
14
+ /**
15
+ *
16
+ * @returns {string}
17
+ */
18
+ static buildMessage(target, method, err) {
19
+ return `Template rendering error: ${(0, core_1.nameOf)(target)}.${String(method)}()\n` + err;
20
+ }
21
+ }
22
+ exports.TemplateRenderError = TemplateRenderError;
23
+ //# sourceMappingURL=TemplateRenderError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateRenderError.js","sourceRoot":"","sources":["../../../src/errors/TemplateRenderError.ts"],"names":[],"mappings":";;;AAAA,qCAAwC;AACxC,iDAAqD;AAErD;;GAEG;AACH,MAAa,mBAAoB,SAAQ,gCAAmB;IAG1D,YAAY,MAA0B,EAAE,MAAuB,EAAE,GAAU;QACzE,KAAK,CAAC,mBAAmB,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;QAH/D,SAAI,GAAG,uBAAuB,CAAC;IAI/B,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,MAA0B,EAAE,MAAuB,EAAE,GAAU;QACjF,OAAO,6BAA6B,IAAA,aAAM,EAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC;IACnF,CAAC;CACF;AAdD,kDAcC","sourcesContent":["import {nameOf, Type} from \"@tsed/core\";\nimport {InternalServerError} from \"@tsed/exceptions\";\n\n/**\n * @private\n */\nexport class TemplateRenderError extends InternalServerError {\n name = \"TEMPLATE_RENDER_ERROR\";\n\n constructor(target: Type<any> | string, method: string | symbol, err: Error) {\n super(TemplateRenderError.buildMessage(target, method, err));\n }\n\n /**\n *\n * @returns {string}\n */\n static buildMessage(target: Type<any> | string, method: string | symbol, err: Error) {\n return `Template rendering error: ${nameOf(target)}.${String(method)}()\\n` + err;\n }\n}\n"]}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * @file Automatically generated by barrelsby.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const tslib_1 = require("tslib");
7
+ tslib_1.__exportStar(require("./decorators/responseFilter"), exports);
8
+ tslib_1.__exportStar(require("./domain/ResponseFiltersContainer"), exports);
9
+ tslib_1.__exportStar(require("./errors/TemplateRenderError"), exports);
10
+ tslib_1.__exportStar(require("./interfaces/ResponseFilterMethods"), exports);
11
+ tslib_1.__exportStar(require("./services/PlatformResponseFilter"), exports);
12
+ tslib_1.__exportStar(require("./utils/getContentType"), exports);
13
+ tslib_1.__exportStar(require("./utils/renderView"), exports);
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,sEAA4C;AAC5C,4EAAkD;AAClD,uEAA6C;AAC7C,6EAAmD;AACnD,4EAAkD;AAClD,iEAAuC;AACvC,6DAAmC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./decorators/responseFilter\";\nexport * from \"./domain/ResponseFiltersContainer\";\nexport * from \"./errors/TemplateRenderError\";\nexport * from \"./interfaces/ResponseFilterMethods\";\nexport * from \"./services/PlatformResponseFilter\";\nexport * from \"./utils/getContentType\";\nexport * from \"./utils/renderView\";\n"]}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=ResponseFilterMethods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponseFilterMethods.js","sourceRoot":"","sources":["../../../src/interfaces/ResponseFilterMethods.ts"],"names":[],"mappings":"","sourcesContent":["import {Type} from \"@tsed/core\";\nimport type {BaseContext} from \"@tsed/di\";\n\ndeclare global {\n namespace TsED {\n interface Configuration {\n /**\n * A list of response filters must be called before returning a response to the consumer. See more on [Response filters](/docs/response-filter.md).\n */\n responseFilters: Type<ResponseFilterMethods>[];\n }\n }\n}\n\nexport interface ResponseFilterMethods<T = unknown> {\n transform(data: T, ctx: BaseContext): any;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PlatformResponseFilter = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const core_1 = require("@tsed/core");
6
+ const json_mapper_1 = require("@tsed/json-mapper");
7
+ const di_1 = require("@tsed/di");
8
+ const ResponseFiltersContainer_1 = require("../domain/ResponseFiltersContainer");
9
+ const getContentType_1 = require("../utils/getContentType");
10
+ const renderView_1 = require("../utils/renderView");
11
+ /**
12
+ * @platform
13
+ */
14
+ let PlatformResponseFilter = class PlatformResponseFilter {
15
+ constructor() {
16
+ this.types = new Map();
17
+ }
18
+ get contentTypes() {
19
+ return [...this.types.keys()];
20
+ }
21
+ $onInit() {
22
+ ResponseFiltersContainer_1.ResponseFiltersContainer.forEach((token, type) => {
23
+ if (this.responseFilters.includes(token)) {
24
+ this.types.set(type, this.injector.get(token));
25
+ }
26
+ });
27
+ }
28
+ getBestContentType(data, ctx) {
29
+ const contentType = (0, getContentType_1.getContentType)(data, ctx);
30
+ if (ctx.request.get("Accept")) {
31
+ const bestContentType = ctx.request.accepts([contentType].concat(this.contentTypes).filter(Boolean));
32
+ if (bestContentType) {
33
+ return [].concat(bestContentType).filter((type) => type !== "*/*")[0];
34
+ }
35
+ }
36
+ return contentType;
37
+ }
38
+ /**
39
+ * Call filters to transform data
40
+ * @param data
41
+ * @param ctx
42
+ */
43
+ async transform(data, ctx) {
44
+ const { response } = ctx;
45
+ const bestContentType = this.getBestContentType(data, ctx);
46
+ bestContentType && response.contentType(bestContentType);
47
+ if (this.types.has(bestContentType)) {
48
+ return this.types.get(bestContentType).transform(data, ctx);
49
+ }
50
+ if (this.types.has(getContentType_1.ANY_CONTENT_TYPE)) {
51
+ return this.types.get(getContentType_1.ANY_CONTENT_TYPE).transform(data, ctx);
52
+ }
53
+ return data;
54
+ }
55
+ /**
56
+ * Serialize data before calling filters
57
+ * @param data
58
+ * @param ctx
59
+ */
60
+ async serialize(data, ctx) {
61
+ const { response, endpoint } = ctx;
62
+ if (endpoint) {
63
+ if (endpoint.view) {
64
+ data = await (0, renderView_1.renderView)(data, ctx);
65
+ }
66
+ else if ((0, core_1.isSerializable)(data)) {
67
+ data = (0, json_mapper_1.serialize)(data, {
68
+ useAlias: true,
69
+ additionalProperties: this.additionalProperties,
70
+ ...endpoint.getResponseOptions(response.statusCode),
71
+ endpoint: true
72
+ });
73
+ }
74
+ }
75
+ return data;
76
+ }
77
+ };
78
+ tslib_1.__decorate([
79
+ (0, di_1.Inject)(),
80
+ tslib_1.__metadata("design:type", di_1.InjectorService)
81
+ ], PlatformResponseFilter.prototype, "injector", void 0);
82
+ tslib_1.__decorate([
83
+ (0, di_1.Constant)("responseFilters", []),
84
+ tslib_1.__metadata("design:type", Array)
85
+ ], PlatformResponseFilter.prototype, "responseFilters", void 0);
86
+ tslib_1.__decorate([
87
+ (0, di_1.Constant)("additionalProperties"),
88
+ tslib_1.__metadata("design:type", Boolean)
89
+ ], PlatformResponseFilter.prototype, "additionalProperties", void 0);
90
+ PlatformResponseFilter = tslib_1.__decorate([
91
+ (0, di_1.Injectable)()
92
+ ], PlatformResponseFilter);
93
+ exports.PlatformResponseFilter = PlatformResponseFilter;
94
+ //# sourceMappingURL=PlatformResponseFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformResponseFilter.js","sourceRoot":"","sources":["../../../src/services/PlatformResponseFilter.ts"],"names":[],"mappings":"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","sourcesContent":["import {isSerializable, Type} from \"@tsed/core\";\nimport {serialize} from \"@tsed/json-mapper\";\nimport {BaseContext, Constant, Inject, Injectable, InjectorService} from \"@tsed/di\";\nimport {ResponseFilterKey, ResponseFiltersContainer} from \"../domain/ResponseFiltersContainer\";\nimport {ResponseFilterMethods} from \"../interfaces/ResponseFilterMethods\";\nimport {ANY_CONTENT_TYPE, getContentType} from \"../utils/getContentType\";\nimport {renderView} from \"../utils/renderView\";\n\n/**\n * @platform\n */\n@Injectable()\nexport class PlatformResponseFilter {\n protected types: Map<ResponseFilterKey, ResponseFilterMethods> = new Map();\n\n @Inject()\n protected injector: InjectorService;\n\n @Constant(\"responseFilters\", [])\n protected responseFilters: Type<ResponseFilterMethods>[];\n\n @Constant(\"additionalProperties\")\n protected additionalProperties: boolean;\n\n get contentTypes(): ResponseFilterKey[] {\n return [...this.types.keys()];\n }\n\n $onInit() {\n ResponseFiltersContainer.forEach((token, type) => {\n if (this.responseFilters.includes(token)) {\n this.types.set(type, this.injector.get(token)!);\n }\n });\n }\n\n getBestContentType(data: any, ctx: BaseContext) {\n const contentType = getContentType(data, ctx);\n\n if (ctx.request.get(\"Accept\")) {\n const bestContentType = ctx.request.accepts([contentType].concat(this.contentTypes).filter(Boolean));\n\n if (bestContentType) {\n return [].concat(bestContentType as any).filter((type) => type !== \"*/*\")[0];\n }\n }\n\n return contentType;\n }\n\n /**\n * Call filters to transform data\n * @param data\n * @param ctx\n */\n async transform(data: unknown, ctx: BaseContext) {\n const {response} = ctx;\n const bestContentType = this.getBestContentType(data, ctx);\n\n bestContentType && response.contentType(bestContentType);\n\n if (this.types.has(bestContentType)) {\n return this.types.get(bestContentType)!.transform(data, ctx);\n }\n\n if (this.types.has(ANY_CONTENT_TYPE)) {\n return this.types.get(ANY_CONTENT_TYPE)!.transform(data, ctx);\n }\n\n return data;\n }\n\n /**\n * Serialize data before calling filters\n * @param data\n * @param ctx\n */\n async serialize(data: unknown, ctx: BaseContext) {\n const {response, endpoint} = ctx;\n\n if (endpoint) {\n if (endpoint.view) {\n data = await renderView(data, ctx);\n } else if (isSerializable(data)) {\n data = serialize(data, {\n useAlias: true,\n additionalProperties: this.additionalProperties,\n ...endpoint.getResponseOptions(response.statusCode),\n endpoint: true\n });\n }\n }\n\n return data;\n }\n}\n"]}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getContentType = exports.ANY_CONTENT_TYPE = void 0;
4
+ const core_1 = require("@tsed/core");
5
+ exports.ANY_CONTENT_TYPE = "*/*";
6
+ /**
7
+ * @ignore
8
+ */
9
+ function getContentType(data, ctx) {
10
+ const { endpoint, response } = ctx;
11
+ const { operation } = endpoint;
12
+ const contentType = response.getContentType() || operation.getContentTypeOf(response.statusCode) || "";
13
+ if (contentType && contentType !== exports.ANY_CONTENT_TYPE) {
14
+ if (contentType === "application/json") {
15
+ if ((0, core_1.isObject)(data)) {
16
+ return contentType;
17
+ }
18
+ }
19
+ else {
20
+ return contentType;
21
+ }
22
+ }
23
+ if (typeof data === "string" && endpoint.view) {
24
+ return "text/html";
25
+ }
26
+ }
27
+ exports.getContentType = getContentType;
28
+ //# sourceMappingURL=getContentType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getContentType.js","sourceRoot":"","sources":["../../../src/utils/getContentType.ts"],"names":[],"mappings":";;;AAAA,qCAAoC;AAEvB,QAAA,gBAAgB,GAAG,KAAK,CAAC;AACtC;;GAEG;AACH,SAAgB,cAAc,CAAC,IAAS,EAAE,GAAgB;IACxD,MAAM,EAAC,QAAQ,EAAE,QAAQ,EAAC,GAAG,GAAG,CAAC;IACjC,MAAM,EAAC,SAAS,EAAC,GAAG,QAAQ,CAAC;IAE7B,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,EAAE,IAAI,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAEvG,IAAI,WAAW,IAAI,WAAW,KAAK,wBAAgB,EAAE;QACnD,IAAI,WAAW,KAAK,kBAAkB,EAAE;YACtC,IAAI,IAAA,eAAQ,EAAC,IAAI,CAAC,EAAE;gBAClB,OAAO,WAAW,CAAC;aACpB;SACF;aAAM;YACL,OAAO,WAAW,CAAC;SACpB;KACF;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE;QAC7C,OAAO,WAAW,CAAC;KACpB;AACH,CAAC;AAnBD,wCAmBC","sourcesContent":["import {isObject} from \"@tsed/core\";\nimport type {BaseContext} from \"@tsed/di\";\nexport const ANY_CONTENT_TYPE = \"*/*\";\n/**\n * @ignore\n */\nexport function getContentType(data: any, ctx: BaseContext) {\n const {endpoint, response} = ctx;\n const {operation} = endpoint;\n\n const contentType = response.getContentType() || operation.getContentTypeOf(response.statusCode) || \"\";\n\n if (contentType && contentType !== ANY_CONTENT_TYPE) {\n if (contentType === \"application/json\") {\n if (isObject(data)) {\n return contentType;\n }\n } else {\n return contentType;\n }\n }\n\n if (typeof data === \"string\" && endpoint.view) {\n return \"text/html\";\n }\n}\n"]}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderView = void 0;
4
+ const TemplateRenderError_1 = require("../errors/TemplateRenderError");
5
+ async function renderView(data, $ctx) {
6
+ const { response, endpoint } = $ctx;
7
+ try {
8
+ const { data } = $ctx;
9
+ const { path, options } = endpoint.view;
10
+ return await response.render(path, { ...options, ...data, $ctx });
11
+ }
12
+ catch (err) {
13
+ throw new TemplateRenderError_1.TemplateRenderError(endpoint.targetName, endpoint.propertyKey, err);
14
+ }
15
+ }
16
+ exports.renderView = renderView;
17
+ //# sourceMappingURL=renderView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderView.js","sourceRoot":"","sources":["../../../src/utils/renderView.ts"],"names":[],"mappings":";;;AACA,uEAAkE;AAE3D,KAAK,UAAU,UAAU,CAAC,IAAS,EAAE,IAAiB;IAC3D,MAAM,EAAC,QAAQ,EAAE,QAAQ,EAAC,GAAG,IAAI,CAAC;IAClC,IAAI;QACF,MAAM,EAAC,IAAI,EAAC,GAAG,IAAI,CAAC;QACpB,MAAM,EAAC,IAAI,EAAE,OAAO,EAAC,GAAG,QAAQ,CAAC,IAAI,CAAC;QAEtC,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAC,GAAG,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;KACjE;IAAC,OAAO,GAAG,EAAE;QACZ,MAAM,IAAI,yCAAmB,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;KAC/E;AACH,CAAC;AAVD,gCAUC","sourcesContent":["import {BaseContext} from \"@tsed/di\";\nimport {TemplateRenderError} from \"../errors/TemplateRenderError\";\n\nexport async function renderView(data: any, $ctx: BaseContext) {\n const {response, endpoint} = $ctx;\n try {\n const {data} = $ctx;\n const {path, options} = endpoint.view;\n\n return await response.render(path, {...options, ...data, $ctx});\n } catch (err) {\n throw new TemplateRenderError(endpoint.targetName, endpoint.propertyKey, err);\n }\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import { registerProvider } from "@tsed/di";
2
+ import { registerResponseFilter } from "../domain/ResponseFiltersContainer.js";
3
+ /**
4
+ * Register a response filter service.
5
+ * @param contentTypes
6
+ * @decorator
7
+ */
8
+ export function ResponseFilter(...contentTypes) {
9
+ return (target) => {
10
+ contentTypes.forEach((contentType) => {
11
+ registerResponseFilter(contentType, target);
12
+ });
13
+ registerProvider({
14
+ provide: target,
15
+ useClass: target
16
+ });
17
+ };
18
+ }
19
+ //# sourceMappingURL=responseFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseFilter.js","sourceRoot":"","sources":["../../../src/decorators/responseFilter.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAC,sBAAsB,EAAoB,MAAM,oCAAoC,CAAC;AAE7F;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAG,YAAiC;IACjE,OAAO,CAAU,MAAS,EAAY,EAAE;QACtC,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;YACnC,sBAAsB,CAAC,WAAW,EAAE,MAAa,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QACH,gBAAgB,CAAC;YACf,OAAO,EAAE,MAAM;YACf,QAAQ,EAAE,MAA8B;SACzC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {Type} from \"@tsed/core\";\nimport {registerProvider} from \"@tsed/di\";\nimport {registerResponseFilter, ResponseFilterKey} from \"../domain/ResponseFiltersContainer\";\n\n/**\n * Register a response filter service.\n * @param contentTypes\n * @decorator\n */\nexport function ResponseFilter(...contentTypes: ResponseFilterKey[]): ClassDecorator {\n return <T = any>(target: T): void | T => {\n contentTypes.forEach((contentType) => {\n registerResponseFilter(contentType, target as any);\n });\n registerProvider({\n provide: target,\n useClass: target as unknown as Type<any>\n });\n };\n}\n"]}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @ignore
3
+ */
4
+ // tslint:disable-next-line:variable-name
5
+ export const ResponseFiltersContainer = new Map();
6
+ /**
7
+ * @ignore
8
+ */
9
+ export function registerResponseFilter(type, token) {
10
+ ResponseFiltersContainer.set(type, token);
11
+ }
12
+ //# sourceMappingURL=ResponseFiltersContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponseFiltersContainer.js","sourceRoot":"","sources":["../../../src/domain/ResponseFiltersContainer.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,yCAAyC;AACzC,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAkD,CAAC;AAClG;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAuB,EAAE,KAAkC;IAChG,wBAAwB,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC","sourcesContent":["import {Type} from \"@tsed/core\";\nimport {ResponseFilterMethods} from \"../interfaces/ResponseFilterMethods\";\n/**\n * @ignore\n */\nexport type ResponseFilterKey = \"*/*\" | \"application/json\" | \"text/html\" | \"plain/text\" | string;\n/**\n * @ignore\n */\n// tslint:disable-next-line:variable-name\nexport const ResponseFiltersContainer = new Map<ResponseFilterKey, Type<ResponseFilterMethods>>();\n/**\n * @ignore\n */\nexport function registerResponseFilter(type: ResponseFilterKey, token: Type<ResponseFilterMethods>) {\n ResponseFiltersContainer.set(type, token);\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import { nameOf } from "@tsed/core";
2
+ import { InternalServerError } from "@tsed/exceptions";
3
+ /**
4
+ * @private
5
+ */
6
+ export class TemplateRenderError extends InternalServerError {
7
+ constructor(target, method, err) {
8
+ super(TemplateRenderError.buildMessage(target, method, err));
9
+ this.name = "TEMPLATE_RENDER_ERROR";
10
+ }
11
+ /**
12
+ *
13
+ * @returns {string}
14
+ */
15
+ static buildMessage(target, method, err) {
16
+ return `Template rendering error: ${nameOf(target)}.${String(method)}()\n` + err;
17
+ }
18
+ }
19
+ //# sourceMappingURL=TemplateRenderError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateRenderError.js","sourceRoot":"","sources":["../../../src/errors/TemplateRenderError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAO,MAAM,YAAY,CAAC;AACxC,OAAO,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAErD;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,mBAAmB;IAG1D,YAAY,MAA0B,EAAE,MAAuB,EAAE,GAAU;QACzE,KAAK,CAAC,mBAAmB,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;QAH/D,SAAI,GAAG,uBAAuB,CAAC;IAI/B,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,MAA0B,EAAE,MAAuB,EAAE,GAAU;QACjF,OAAO,6BAA6B,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC;IACnF,CAAC;CACF","sourcesContent":["import {nameOf, Type} from \"@tsed/core\";\nimport {InternalServerError} from \"@tsed/exceptions\";\n\n/**\n * @private\n */\nexport class TemplateRenderError extends InternalServerError {\n name = \"TEMPLATE_RENDER_ERROR\";\n\n constructor(target: Type<any> | string, method: string | symbol, err: Error) {\n super(TemplateRenderError.buildMessage(target, method, err));\n }\n\n /**\n *\n * @returns {string}\n */\n static buildMessage(target: Type<any> | string, method: string | symbol, err: Error) {\n return `Template rendering error: ${nameOf(target)}.${String(method)}()\\n` + err;\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+ export * from "./decorators/responseFilter.js";
5
+ export * from "./domain/ResponseFiltersContainer.js";
6
+ export * from "./errors/TemplateRenderError.js";
7
+ export * from "./interfaces/ResponseFilterMethods.js";
8
+ export * from "./services/PlatformResponseFilter.js";
9
+ export * from "./utils/getContentType.js";
10
+ export * from "./utils/renderView.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./decorators/responseFilter\";\nexport * from \"./domain/ResponseFiltersContainer\";\nexport * from \"./errors/TemplateRenderError\";\nexport * from \"./interfaces/ResponseFilterMethods\";\nexport * from \"./services/PlatformResponseFilter\";\nexport * from \"./utils/getContentType\";\nexport * from \"./utils/renderView\";\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ResponseFilterMethods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponseFilterMethods.js","sourceRoot":"","sources":["../../../src/interfaces/ResponseFilterMethods.ts"],"names":[],"mappings":"","sourcesContent":["import {Type} from \"@tsed/core\";\nimport type {BaseContext} from \"@tsed/di\";\n\ndeclare global {\n namespace TsED {\n interface Configuration {\n /**\n * A list of response filters must be called before returning a response to the consumer. See more on [Response filters](/docs/response-filter.md).\n */\n responseFilters: Type<ResponseFilterMethods>[];\n }\n }\n}\n\nexport interface ResponseFilterMethods<T = unknown> {\n transform(data: T, ctx: BaseContext): any;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,91 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { isSerializable } from "@tsed/core";
3
+ import { serialize } from "@tsed/json-mapper";
4
+ import { Constant, Inject, Injectable, InjectorService } from "@tsed/di";
5
+ import { ResponseFiltersContainer } from "../domain/ResponseFiltersContainer.js";
6
+ import { ANY_CONTENT_TYPE, getContentType } from "../utils/getContentType.js";
7
+ import { renderView } from "../utils/renderView.js";
8
+ /**
9
+ * @platform
10
+ */
11
+ let PlatformResponseFilter = class PlatformResponseFilter {
12
+ constructor() {
13
+ this.types = new Map();
14
+ }
15
+ get contentTypes() {
16
+ return [...this.types.keys()];
17
+ }
18
+ $onInit() {
19
+ ResponseFiltersContainer.forEach((token, type) => {
20
+ if (this.responseFilters.includes(token)) {
21
+ this.types.set(type, this.injector.get(token));
22
+ }
23
+ });
24
+ }
25
+ getBestContentType(data, ctx) {
26
+ const contentType = getContentType(data, ctx);
27
+ if (ctx.request.get("Accept")) {
28
+ const bestContentType = ctx.request.accepts([contentType].concat(this.contentTypes).filter(Boolean));
29
+ if (bestContentType) {
30
+ return [].concat(bestContentType).filter((type) => type !== "*/*")[0];
31
+ }
32
+ }
33
+ return contentType;
34
+ }
35
+ /**
36
+ * Call filters to transform data
37
+ * @param data
38
+ * @param ctx
39
+ */
40
+ async transform(data, ctx) {
41
+ const { response } = ctx;
42
+ const bestContentType = this.getBestContentType(data, ctx);
43
+ bestContentType && response.contentType(bestContentType);
44
+ if (this.types.has(bestContentType)) {
45
+ return this.types.get(bestContentType).transform(data, ctx);
46
+ }
47
+ if (this.types.has(ANY_CONTENT_TYPE)) {
48
+ return this.types.get(ANY_CONTENT_TYPE).transform(data, ctx);
49
+ }
50
+ return data;
51
+ }
52
+ /**
53
+ * Serialize data before calling filters
54
+ * @param data
55
+ * @param ctx
56
+ */
57
+ async serialize(data, ctx) {
58
+ const { response, endpoint } = ctx;
59
+ if (endpoint) {
60
+ if (endpoint.view) {
61
+ data = await renderView(data, ctx);
62
+ }
63
+ else if (isSerializable(data)) {
64
+ data = serialize(data, {
65
+ useAlias: true,
66
+ additionalProperties: this.additionalProperties,
67
+ ...endpoint.getResponseOptions(response.statusCode),
68
+ endpoint: true
69
+ });
70
+ }
71
+ }
72
+ return data;
73
+ }
74
+ };
75
+ __decorate([
76
+ Inject(),
77
+ __metadata("design:type", InjectorService)
78
+ ], PlatformResponseFilter.prototype, "injector", void 0);
79
+ __decorate([
80
+ Constant("responseFilters", []),
81
+ __metadata("design:type", Array)
82
+ ], PlatformResponseFilter.prototype, "responseFilters", void 0);
83
+ __decorate([
84
+ Constant("additionalProperties"),
85
+ __metadata("design:type", Boolean)
86
+ ], PlatformResponseFilter.prototype, "additionalProperties", void 0);
87
+ PlatformResponseFilter = __decorate([
88
+ Injectable()
89
+ ], PlatformResponseFilter);
90
+ export { PlatformResponseFilter };
91
+ //# sourceMappingURL=PlatformResponseFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformResponseFilter.js","sourceRoot":"","sources":["../../../src/services/PlatformResponseFilter.ts"],"names":[],"mappings":"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","sourcesContent":["import {isSerializable, Type} from \"@tsed/core\";\nimport {serialize} from \"@tsed/json-mapper\";\nimport {BaseContext, Constant, Inject, Injectable, InjectorService} from \"@tsed/di\";\nimport {ResponseFilterKey, ResponseFiltersContainer} from \"../domain/ResponseFiltersContainer\";\nimport {ResponseFilterMethods} from \"../interfaces/ResponseFilterMethods\";\nimport {ANY_CONTENT_TYPE, getContentType} from \"../utils/getContentType\";\nimport {renderView} from \"../utils/renderView\";\n\n/**\n * @platform\n */\n@Injectable()\nexport class PlatformResponseFilter {\n protected types: Map<ResponseFilterKey, ResponseFilterMethods> = new Map();\n\n @Inject()\n protected injector: InjectorService;\n\n @Constant(\"responseFilters\", [])\n protected responseFilters: Type<ResponseFilterMethods>[];\n\n @Constant(\"additionalProperties\")\n protected additionalProperties: boolean;\n\n get contentTypes(): ResponseFilterKey[] {\n return [...this.types.keys()];\n }\n\n $onInit() {\n ResponseFiltersContainer.forEach((token, type) => {\n if (this.responseFilters.includes(token)) {\n this.types.set(type, this.injector.get(token)!);\n }\n });\n }\n\n getBestContentType(data: any, ctx: BaseContext) {\n const contentType = getContentType(data, ctx);\n\n if (ctx.request.get(\"Accept\")) {\n const bestContentType = ctx.request.accepts([contentType].concat(this.contentTypes).filter(Boolean));\n\n if (bestContentType) {\n return [].concat(bestContentType as any).filter((type) => type !== \"*/*\")[0];\n }\n }\n\n return contentType;\n }\n\n /**\n * Call filters to transform data\n * @param data\n * @param ctx\n */\n async transform(data: unknown, ctx: BaseContext) {\n const {response} = ctx;\n const bestContentType = this.getBestContentType(data, ctx);\n\n bestContentType && response.contentType(bestContentType);\n\n if (this.types.has(bestContentType)) {\n return this.types.get(bestContentType)!.transform(data, ctx);\n }\n\n if (this.types.has(ANY_CONTENT_TYPE)) {\n return this.types.get(ANY_CONTENT_TYPE)!.transform(data, ctx);\n }\n\n return data;\n }\n\n /**\n * Serialize data before calling filters\n * @param data\n * @param ctx\n */\n async serialize(data: unknown, ctx: BaseContext) {\n const {response, endpoint} = ctx;\n\n if (endpoint) {\n if (endpoint.view) {\n data = await renderView(data, ctx);\n } else if (isSerializable(data)) {\n data = serialize(data, {\n useAlias: true,\n additionalProperties: this.additionalProperties,\n ...endpoint.getResponseOptions(response.statusCode),\n endpoint: true\n });\n }\n }\n\n return data;\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { isObject } from "@tsed/core";
2
+ export const ANY_CONTENT_TYPE = "*/*";
3
+ /**
4
+ * @ignore
5
+ */
6
+ export function getContentType(data, ctx) {
7
+ const { endpoint, response } = ctx;
8
+ const { operation } = endpoint;
9
+ const contentType = response.getContentType() || operation.getContentTypeOf(response.statusCode) || "";
10
+ if (contentType && contentType !== ANY_CONTENT_TYPE) {
11
+ if (contentType === "application/json") {
12
+ if (isObject(data)) {
13
+ return contentType;
14
+ }
15
+ }
16
+ else {
17
+ return contentType;
18
+ }
19
+ }
20
+ if (typeof data === "string" && endpoint.view) {
21
+ return "text/html";
22
+ }
23
+ }
24
+ //# sourceMappingURL=getContentType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getContentType.js","sourceRoot":"","sources":["../../../src/utils/getContentType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AAEpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AACtC;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAS,EAAE,GAAgB;IACxD,MAAM,EAAC,QAAQ,EAAE,QAAQ,EAAC,GAAG,GAAG,CAAC;IACjC,MAAM,EAAC,SAAS,EAAC,GAAG,QAAQ,CAAC;IAE7B,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,EAAE,IAAI,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAEvG,IAAI,WAAW,IAAI,WAAW,KAAK,gBAAgB,EAAE;QACnD,IAAI,WAAW,KAAK,kBAAkB,EAAE;YACtC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE;gBAClB,OAAO,WAAW,CAAC;aACpB;SACF;aAAM;YACL,OAAO,WAAW,CAAC;SACpB;KACF;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE;QAC7C,OAAO,WAAW,CAAC;KACpB;AACH,CAAC","sourcesContent":["import {isObject} from \"@tsed/core\";\nimport type {BaseContext} from \"@tsed/di\";\nexport const ANY_CONTENT_TYPE = \"*/*\";\n/**\n * @ignore\n */\nexport function getContentType(data: any, ctx: BaseContext) {\n const {endpoint, response} = ctx;\n const {operation} = endpoint;\n\n const contentType = response.getContentType() || operation.getContentTypeOf(response.statusCode) || \"\";\n\n if (contentType && contentType !== ANY_CONTENT_TYPE) {\n if (contentType === \"application/json\") {\n if (isObject(data)) {\n return contentType;\n }\n } else {\n return contentType;\n }\n }\n\n if (typeof data === \"string\" && endpoint.view) {\n return \"text/html\";\n }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import { TemplateRenderError } from "../errors/TemplateRenderError.js";
2
+ export async function renderView(data, $ctx) {
3
+ const { response, endpoint } = $ctx;
4
+ try {
5
+ const { data } = $ctx;
6
+ const { path, options } = endpoint.view;
7
+ return await response.render(path, { ...options, ...data, $ctx });
8
+ }
9
+ catch (err) {
10
+ throw new TemplateRenderError(endpoint.targetName, endpoint.propertyKey, err);
11
+ }
12
+ }
13
+ //# sourceMappingURL=renderView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderView.js","sourceRoot":"","sources":["../../../src/utils/renderView.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,mBAAmB,EAAC,MAAM,+BAA+B,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAS,EAAE,IAAiB;IAC3D,MAAM,EAAC,QAAQ,EAAE,QAAQ,EAAC,GAAG,IAAI,CAAC;IAClC,IAAI;QACF,MAAM,EAAC,IAAI,EAAC,GAAG,IAAI,CAAC;QACpB,MAAM,EAAC,IAAI,EAAE,OAAO,EAAC,GAAG,QAAQ,CAAC,IAAI,CAAC;QAEtC,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAC,GAAG,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;KACjE;IAAC,OAAO,GAAG,EAAE;QACZ,MAAM,IAAI,mBAAmB,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;KAC/E;AACH,CAAC","sourcesContent":["import {BaseContext} from \"@tsed/di\";\nimport {TemplateRenderError} from \"../errors/TemplateRenderError\";\n\nexport async function renderView(data: any, $ctx: BaseContext) {\n const {response, endpoint} = $ctx;\n try {\n const {data} = $ctx;\n const {path, options} = endpoint.view;\n\n return await response.render(path, {...options, ...data, $ctx});\n } catch (err) {\n throw new TemplateRenderError(endpoint.targetName, endpoint.propertyKey, err);\n }\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { Type } from "@tsed/core";
2
+ import { InternalServerError } from "@tsed/exceptions";
3
+ /**
4
+ * @private
5
+ */
6
+ export declare class TemplateRenderError extends InternalServerError {
7
+ name: string;
8
+ constructor(target: Type<any> | string, method: string | symbol, err: Error);
9
+ /**
10
+ *
11
+ * @returns {string}
12
+ */
13
+ static buildMessage(target: Type<any> | string, method: string | symbol, err: Error): string;
14
+ }
@@ -1,5 +1,10 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
1
4
  export * from "./decorators/responseFilter";
2
5
  export * from "./domain/ResponseFiltersContainer";
6
+ export * from "./errors/TemplateRenderError";
3
7
  export * from "./interfaces/ResponseFilterMethods";
4
8
  export * from "./services/PlatformResponseFilter";
5
9
  export * from "./utils/getContentType";
10
+ export * from "./utils/renderView";
@@ -6,10 +6,10 @@ import { ResponseFilterMethods } from "../interfaces/ResponseFilterMethods";
6
6
  * @platform
7
7
  */
8
8
  export declare class PlatformResponseFilter {
9
- types: Map<ResponseFilterKey, ResponseFilterMethods>;
10
- injector: InjectorService;
9
+ protected types: Map<ResponseFilterKey, ResponseFilterMethods>;
10
+ protected injector: InjectorService;
11
11
  protected responseFilters: Type<ResponseFilterMethods>[];
12
- private additionalProperties;
12
+ protected additionalProperties: boolean;
13
13
  get contentTypes(): ResponseFilterKey[];
14
14
  $onInit(): void;
15
15
  getBestContentType(data: any, ctx: BaseContext): any;
@@ -20,7 +20,7 @@ export declare class PlatformResponseFilter {
20
20
  */
21
21
  transform(data: unknown, ctx: BaseContext): Promise<any>;
22
22
  /**
23
- * Serialize data from endpoint metadata
23
+ * Serialize data before calling filters
24
24
  * @param data
25
25
  * @param ctx
26
26
  */
File without changes
@@ -0,0 +1,2 @@
1
+ import { BaseContext } from "@tsed/di";
2
+ export declare function renderView(data: any, $ctx: BaseContext): Promise<any>;