@tsed/platform-response-filter 8.2.0 → 8.3.1
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.
- package/lib/esm/constants/ANY_CONTENT_TYPE.js +2 -0
- package/lib/esm/constants/ANY_CONTENT_TYPE.js.map +1 -0
- package/lib/esm/index.js +3 -1
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/services/PlatformContentTypeResolver.js +39 -0
- package/lib/esm/services/PlatformContentTypeResolver.js.map +1 -0
- package/lib/esm/services/PlatformContentTypesContainer.js +23 -0
- package/lib/esm/services/PlatformContentTypesContainer.js.map +1 -0
- package/lib/esm/services/PlatformResponseFilter.js +6 -30
- package/lib/esm/services/PlatformResponseFilter.js.map +1 -1
- package/lib/types/constants/ANY_CONTENT_TYPE.d.ts +1 -0
- package/lib/types/index.d.ts +3 -1
- package/lib/types/services/PlatformContentTypeResolver.d.ts +15 -0
- package/lib/types/services/PlatformContentTypesContainer.d.ts +8 -0
- package/lib/types/services/PlatformResponseFilter.d.ts +6 -10
- package/package.json +13 -13
- package/readme.md +4 -6
- package/src/constants/ANY_CONTENT_TYPE.ts +1 -0
- package/src/index.ts +3 -1
- package/src/{utils/getContentType.spec.ts → services/PlatformContentTypeResolver.spec.ts} +46 -42
- package/src/services/PlatformContentTypeResolver.ts +54 -0
- package/src/services/PlatformContentTypesContainer.ts +31 -0
- package/src/services/PlatformResponseFilter.ts +8 -43
- package/lib/esm/utils/getContentType.js +0 -20
- package/lib/esm/utils/getContentType.js.map +0 -1
- package/lib/types/utils/getContentType.d.ts +0 -6
- package/src/utils/getContentType.ts +0 -26
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ANY_CONTENT_TYPE.js","sourceRoot":"","sources":["../../../src/constants/ANY_CONTENT_TYPE.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC"}
|
package/lib/esm/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file Automatically generated by @tsed/barrels.
|
|
3
3
|
*/
|
|
4
|
+
export * from "./constants/ANY_CONTENT_TYPE.js";
|
|
4
5
|
export * from "./decorators/responseFilter.js";
|
|
5
6
|
export * from "./domain/ResponseFiltersContainer.js";
|
|
6
7
|
export * from "./errors/TemplateRenderError.js";
|
|
7
8
|
export * from "./interfaces/ResponseFilterMethods.js";
|
|
9
|
+
export * from "./services/PlatformContentTypeResolver.js";
|
|
10
|
+
export * from "./services/PlatformContentTypesContainer.js";
|
|
8
11
|
export * from "./services/PlatformResponseFilter.js";
|
|
9
|
-
export * from "./utils/getContentType.js";
|
|
10
12
|
export * from "./utils/renderView.js";
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
package/lib/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;AACtD,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,sCAAsC,CAAC;AACrD,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { isObject } from "@tsed/core";
|
|
2
|
+
import { inject, injectable } from "@tsed/di";
|
|
3
|
+
import { ANY_CONTENT_TYPE } from "../constants/ANY_CONTENT_TYPE.js";
|
|
4
|
+
import { PLATFORM_CONTENT_TYPES_CONTAINER } from "./PlatformContentTypesContainer.js";
|
|
5
|
+
/**
|
|
6
|
+
* @ignore
|
|
7
|
+
*/
|
|
8
|
+
export function getContentType(data, ctx) {
|
|
9
|
+
const { endpoint, response } = ctx;
|
|
10
|
+
const { operation } = endpoint;
|
|
11
|
+
const contentType = response.getContentType() || operation.getContentTypeOf(response.statusCode) || "";
|
|
12
|
+
if (contentType && contentType !== ANY_CONTENT_TYPE) {
|
|
13
|
+
if (contentType === "application/json" && isObject(data)) {
|
|
14
|
+
return "application/json";
|
|
15
|
+
}
|
|
16
|
+
return contentType;
|
|
17
|
+
}
|
|
18
|
+
if (endpoint.view) {
|
|
19
|
+
return "text/html";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @ignore
|
|
24
|
+
*/
|
|
25
|
+
function resolver(data, ctx) {
|
|
26
|
+
const contentType = getContentType(data, ctx);
|
|
27
|
+
if (ctx.request.get("Accept")) {
|
|
28
|
+
const { contentTypes } = inject(PLATFORM_CONTENT_TYPES_CONTAINER);
|
|
29
|
+
const bestContentType = ctx.request.accepts([contentType].concat(contentTypes).filter(Boolean));
|
|
30
|
+
if (bestContentType) {
|
|
31
|
+
return [].concat(bestContentType).filter((type) => type !== "*/*")[0];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return contentType;
|
|
35
|
+
}
|
|
36
|
+
export const PLATFORM_CONTENT_TYPE_RESOLVER = injectable(Symbol.for("PLATFORM_CONTENT_TYPE_RESOLVER"))
|
|
37
|
+
.factory(() => resolver)
|
|
38
|
+
.token();
|
|
39
|
+
//# sourceMappingURL=PlatformContentTypeResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlatformContentTypeResolver.js","sourceRoot":"","sources":["../../../src/services/PlatformContentTypeResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAmB,MAAM,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AAE9D,OAAO,EAAC,gBAAgB,EAAC,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAC,gCAAgC,EAAC,MAAM,oCAAoC,CAAC;AAEpF;;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,CAAC;QACpD,IAAI,WAAW,KAAK,kBAAkB,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,IAAS,EAAE,GAAgB;IAC3C,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAE9C,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,MAAM,EAAC,YAAY,EAAC,GAAG,MAAM,CAAmC,gCAAgC,CAAC,CAAC;QAElG,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAEhG,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC,MAAM,CAAC,eAAsB,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAMD,MAAM,CAAC,MAAM,8BAA8B,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;KACnG,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC;KACvB,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { constant, inject, injectable } from "@tsed/di";
|
|
2
|
+
import { ANY_CONTENT_TYPE } from "../constants/ANY_CONTENT_TYPE.js";
|
|
3
|
+
import { ResponseFiltersContainer } from "../domain/ResponseFiltersContainer.js";
|
|
4
|
+
function factory() {
|
|
5
|
+
const responseFilters = constant("responseFilters", []);
|
|
6
|
+
const containers = new Map();
|
|
7
|
+
ResponseFiltersContainer.forEach((token, type) => {
|
|
8
|
+
if (responseFilters.includes(token)) {
|
|
9
|
+
containers.set(type, token);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return {
|
|
13
|
+
contentTypes: [...containers.keys()],
|
|
14
|
+
resolve(bestContentType) {
|
|
15
|
+
const token = containers.get(bestContentType) || containers.get(ANY_CONTENT_TYPE);
|
|
16
|
+
if (token) {
|
|
17
|
+
return inject(token);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export const PLATFORM_CONTENT_TYPES_CONTAINER = injectable(Symbol.for("PLATFORM_CONTENT_TYPES_CONTAINER")).factory(factory).token();
|
|
23
|
+
//# sourceMappingURL=PlatformContentTypesContainer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlatformContentTypesContainer.js","sourceRoot":"","sources":["../../../src/services/PlatformContentTypesContainer.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAqB,MAAM,UAAU,CAAC;AAE1E,OAAO,EAAC,gBAAgB,EAAC,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAoB,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAGlG,SAAS,OAAO;IACd,MAAM,eAAe,GAAG,QAAQ,CAAgC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACvF,MAAM,UAAU,GAA0C,IAAI,GAAG,EAAE,CAAC;IAEpE,wBAAwB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC/C,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,YAAY,EAAE,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QACpC,OAAO,CAAC,eAAuB;YAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAElF,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,MAAM,CAAwB,KAAK,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAGD,MAAM,CAAC,MAAM,gCAAgC,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -1,35 +1,17 @@
|
|
|
1
1
|
import { isSerializable } from "@tsed/core";
|
|
2
2
|
import { constant, inject, injectable } from "@tsed/di";
|
|
3
3
|
import { serialize } from "@tsed/json-mapper";
|
|
4
|
-
import { ResponseFiltersContainer } from "../domain/ResponseFiltersContainer.js";
|
|
5
|
-
import { ANY_CONTENT_TYPE, getContentType } from "../utils/getContentType.js";
|
|
6
4
|
import { renderView } from "../utils/renderView.js";
|
|
5
|
+
import { PLATFORM_CONTENT_TYPE_RESOLVER } from "./PlatformContentTypeResolver.js";
|
|
6
|
+
import { PLATFORM_CONTENT_TYPES_CONTAINER } from "./PlatformContentTypesContainer.js";
|
|
7
7
|
/**
|
|
8
8
|
* @platform
|
|
9
9
|
*/
|
|
10
10
|
export class PlatformResponseFilter {
|
|
11
11
|
constructor() {
|
|
12
|
-
this.types = new Map();
|
|
13
|
-
this.responseFilters = constant("responseFilters", []);
|
|
14
12
|
this.additionalProperties = constant("additionalProperties");
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this.types.set(type, token);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
get contentTypes() {
|
|
22
|
-
return [...this.types.keys()];
|
|
23
|
-
}
|
|
24
|
-
getBestContentType(data, ctx) {
|
|
25
|
-
const contentType = getContentType(data, ctx);
|
|
26
|
-
if (ctx.request.get("Accept")) {
|
|
27
|
-
const bestContentType = ctx.request.accepts([contentType].concat(this.contentTypes).filter(Boolean));
|
|
28
|
-
if (bestContentType) {
|
|
29
|
-
return [].concat(bestContentType).filter((type) => type !== "*/*")[0];
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return contentType;
|
|
13
|
+
this.container = inject(PLATFORM_CONTENT_TYPES_CONTAINER);
|
|
14
|
+
this.contentTypeResolver = inject(PLATFORM_CONTENT_TYPE_RESOLVER);
|
|
33
15
|
}
|
|
34
16
|
/**
|
|
35
17
|
* Call filters to transform data
|
|
@@ -39,9 +21,9 @@ export class PlatformResponseFilter {
|
|
|
39
21
|
transform(data, ctx) {
|
|
40
22
|
const { response } = ctx;
|
|
41
23
|
if (ctx.endpoint?.operation) {
|
|
42
|
-
const bestContentType = this.
|
|
24
|
+
const bestContentType = this.contentTypeResolver(data, ctx);
|
|
43
25
|
bestContentType && response.contentType(bestContentType);
|
|
44
|
-
const resolved = this.resolve(bestContentType);
|
|
26
|
+
const resolved = this.container.resolve(bestContentType);
|
|
45
27
|
if (resolved) {
|
|
46
28
|
return resolved.transform(data, ctx);
|
|
47
29
|
}
|
|
@@ -73,12 +55,6 @@ export class PlatformResponseFilter {
|
|
|
73
55
|
}
|
|
74
56
|
return data;
|
|
75
57
|
}
|
|
76
|
-
resolve(bestContentType) {
|
|
77
|
-
const token = this.types.get(bestContentType) || this.types.get(ANY_CONTENT_TYPE);
|
|
78
|
-
if (token) {
|
|
79
|
-
return inject(token);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
58
|
getIncludes(ctx) {
|
|
83
59
|
if (ctx.request.query.includes) {
|
|
84
60
|
return [].concat(ctx.request.query.includes).flatMap((include) => include.split(","));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlatformResponseFilter.js","sourceRoot":"","sources":["../../../src/services/PlatformResponseFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"PlatformResponseFilter.js","sourceRoot":"","sources":["../../../src/services/PlatformResponseFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAc,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AACnE,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAC,UAAU,EAAC,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAC,8BAA8B,EAAC,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAC,gCAAgC,EAAC,MAAM,oCAAoC,CAAC;AAEpF;;GAEG;AACH,MAAM,OAAO,sBAAsB;IAAnC;QACY,yBAAoB,GAAG,QAAQ,CAAU,sBAAsB,CAAC,CAAC;QACjE,cAAS,GAAG,MAAM,CAAmC,gCAAgC,CAAC,CAAC;QACvF,wBAAmB,GAAG,MAAM,CAAiC,8BAA8B,CAAC,CAAC;IA4DzG,CAAC;IA1DC;;;;OAIG;IACH,SAAS,CAAC,IAAa,EAAE,GAAgB;QACvC,MAAM,EAAC,QAAQ,EAAC,GAAG,GAAG,CAAC;QAEvB,IAAI,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC;YAC5B,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAE5D,eAAe,IAAI,QAAQ,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;YAEzD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAEzD,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,IAAa,EAAE,GAAgB;QAC7C,MAAM,EAAC,QAAQ,EAAE,QAAQ,EAAC,GAAG,GAAG,CAAC;QAEjC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClB,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACrC,CAAC;iBAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChC,MAAM,YAAY,GAAG,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,CAAC,UAAU,EAAE;oBACpE,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;iBAChC,CAAC,CAAC;gBAEH,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE;oBACrB,QAAQ,EAAE,IAAI;oBACd,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;oBAC/C,GAAG,YAAY;oBACf,QAAQ,EAAE,IAAI;iBACf,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,WAAW,CAAC,GAAgB;QAClC,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC/B,OAAO,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAChG,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAED,UAAU,CAAC,sBAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ANY_CONTENT_TYPE = "*/*";
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file Automatically generated by @tsed/barrels.
|
|
3
3
|
*/
|
|
4
|
+
export * from "./constants/ANY_CONTENT_TYPE.js";
|
|
4
5
|
export * from "./decorators/responseFilter.js";
|
|
5
6
|
export * from "./domain/ResponseFiltersContainer.js";
|
|
6
7
|
export * from "./errors/TemplateRenderError.js";
|
|
7
8
|
export * from "./interfaces/ResponseFilterMethods.js";
|
|
9
|
+
export * from "./services/PlatformContentTypeResolver.js";
|
|
10
|
+
export * from "./services/PlatformContentTypesContainer.js";
|
|
8
11
|
export * from "./services/PlatformResponseFilter.js";
|
|
9
|
-
export * from "./utils/getContentType.js";
|
|
10
12
|
export * from "./utils/renderView.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type BaseContext } from "@tsed/di";
|
|
2
|
+
/**
|
|
3
|
+
* @ignore
|
|
4
|
+
*/
|
|
5
|
+
export declare function getContentType(data: any, ctx: BaseContext): any;
|
|
6
|
+
/**
|
|
7
|
+
* @ignore
|
|
8
|
+
*/
|
|
9
|
+
declare function resolver(data: any, ctx: BaseContext): any;
|
|
10
|
+
/**
|
|
11
|
+
* @ignore
|
|
12
|
+
*/
|
|
13
|
+
export type PLATFORM_CONTENT_TYPE_RESOLVER = typeof resolver;
|
|
14
|
+
export declare const PLATFORM_CONTENT_TYPE_RESOLVER: any;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResponseFilterMethods } from "../interfaces/ResponseFilterMethods.js";
|
|
2
|
+
declare function factory(): {
|
|
3
|
+
contentTypes: string[];
|
|
4
|
+
resolve(bestContentType: string): ResponseFilterMethods<unknown> | undefined;
|
|
5
|
+
};
|
|
6
|
+
export type PLATFORM_CONTENT_TYPES_CONTAINER = ReturnType<typeof factory>;
|
|
7
|
+
export declare const PLATFORM_CONTENT_TYPES_CONTAINER: any;
|
|
8
|
+
export {};
|
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { BaseContext, TokenProvider } from "@tsed/di";
|
|
3
|
-
import { ResponseFilterKey } from "../domain/ResponseFiltersContainer.js";
|
|
4
|
-
import { ResponseFilterMethods } from "../interfaces/ResponseFilterMethods.js";
|
|
1
|
+
import { BaseContext } from "@tsed/di";
|
|
5
2
|
/**
|
|
6
3
|
* @platform
|
|
7
4
|
*/
|
|
8
5
|
export declare class PlatformResponseFilter {
|
|
9
|
-
protected types: Map<ResponseFilterKey, TokenProvider>;
|
|
10
|
-
protected responseFilters: Type<ResponseFilterMethods<unknown>>[];
|
|
11
6
|
protected additionalProperties: boolean | undefined;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
protected container: {
|
|
8
|
+
contentTypes: string[];
|
|
9
|
+
resolve(bestContentType: string): import("../index.js").ResponseFilterMethods<unknown> | undefined;
|
|
10
|
+
};
|
|
11
|
+
protected contentTypeResolver: (data: any, ctx: BaseContext) => any;
|
|
15
12
|
/**
|
|
16
13
|
* Call filters to transform data
|
|
17
14
|
* @param data
|
|
@@ -24,6 +21,5 @@ export declare class PlatformResponseFilter {
|
|
|
24
21
|
* @param ctx
|
|
25
22
|
*/
|
|
26
23
|
serialize(data: unknown, ctx: BaseContext): Promise<unknown>;
|
|
27
|
-
private resolve;
|
|
28
24
|
private getIncludes;
|
|
29
25
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@tsed/platform-response-filter",
|
|
3
3
|
"description": "Platform response filter module for Ts.ED Framework",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "8.
|
|
5
|
+
"version": "8.3.1",
|
|
6
6
|
"source": "./src/index.ts",
|
|
7
7
|
"main": "./lib/esm/index.js",
|
|
8
8
|
"module": "./lib/esm/index.js",
|
|
@@ -26,23 +26,23 @@
|
|
|
26
26
|
"tslib": "2.7.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@tsed/barrels": "8.
|
|
30
|
-
"@tsed/core": "8.
|
|
31
|
-
"@tsed/di": "8.
|
|
32
|
-
"@tsed/exceptions": "8.
|
|
33
|
-
"@tsed/json-mapper": "8.
|
|
34
|
-
"@tsed/schema": "8.
|
|
35
|
-
"@tsed/typescript": "8.
|
|
29
|
+
"@tsed/barrels": "8.3.1",
|
|
30
|
+
"@tsed/core": "8.3.1",
|
|
31
|
+
"@tsed/di": "8.3.1",
|
|
32
|
+
"@tsed/exceptions": "8.3.1",
|
|
33
|
+
"@tsed/json-mapper": "8.3.1",
|
|
34
|
+
"@tsed/schema": "8.3.1",
|
|
35
|
+
"@tsed/typescript": "8.3.1",
|
|
36
36
|
"eslint": "9.12.0",
|
|
37
37
|
"typescript": "5.4.5",
|
|
38
38
|
"vitest": "2.1.2"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@tsed/core": "8.
|
|
42
|
-
"@tsed/di": "8.
|
|
43
|
-
"@tsed/exceptions": "8.
|
|
44
|
-
"@tsed/json-mapper": "8.
|
|
45
|
-
"@tsed/schema": "8.
|
|
41
|
+
"@tsed/core": "8.3.1",
|
|
42
|
+
"@tsed/di": "8.3.1",
|
|
43
|
+
"@tsed/exceptions": "8.3.1",
|
|
44
|
+
"@tsed/json-mapper": "8.3.1",
|
|
45
|
+
"@tsed/schema": "8.3.1"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"@tsed/core": {
|
package/readme.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p style="text-align: center" align="center">
|
|
2
|
-
<a href="https://tsed.
|
|
2
|
+
<a href="https://tsed.dev" target="_blank"><img src="https://tsed.devtsed-og.png" width="200" alt="Ts.ED logo"/></a>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div align="center">
|
|
19
|
-
<a href="https://tsed.
|
|
19
|
+
<a href="https://tsed.dev/">Website</a>
|
|
20
20
|
<span> • </span>
|
|
21
|
-
<a href="https://tsed.
|
|
21
|
+
<a href="https://tsed.dev/getting-started/">Getting started</a>
|
|
22
22
|
<span> • </span>
|
|
23
23
|
<a href="https://slack.tsed.io">Slack</a>
|
|
24
24
|
<span> • </span>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
<hr />
|
|
29
29
|
|
|
30
|
-
A package of Ts.ED framework. See website: https://tsed.
|
|
30
|
+
A package of Ts.ED framework. See website: https://tsed.dev/
|
|
31
31
|
|
|
32
32
|
# Features
|
|
33
33
|
|
|
@@ -148,8 +148,6 @@ to produce the following response:
|
|
|
148
148
|
|
|
149
149
|
## Contributors
|
|
150
150
|
|
|
151
|
-
Please read [contributing guidelines here](https://tsed.io/contributing.html).
|
|
152
|
-
|
|
153
151
|
<a href="https://github.com/tsedio/tsed/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
|
|
154
152
|
|
|
155
153
|
## Backers
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const ANY_CONTENT_TYPE = "*/*";
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file Automatically generated by @tsed/barrels.
|
|
3
3
|
*/
|
|
4
|
+
export * from "./constants/ANY_CONTENT_TYPE.js";
|
|
4
5
|
export * from "./decorators/responseFilter.js";
|
|
5
6
|
export * from "./domain/ResponseFiltersContainer.js";
|
|
6
7
|
export * from "./errors/TemplateRenderError.js";
|
|
7
8
|
export * from "./interfaces/ResponseFilterMethods.js";
|
|
9
|
+
export * from "./services/PlatformContentTypeResolver.js";
|
|
10
|
+
export * from "./services/PlatformContentTypesContainer.js";
|
|
8
11
|
export * from "./services/PlatformResponseFilter.js";
|
|
9
|
-
export * from "./utils/getContentType.js";
|
|
10
12
|
export * from "./utils/renderView.js";
|
|
@@ -1,94 +1,102 @@
|
|
|
1
1
|
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
2
2
|
import {EndpointMetadata, Get, Returns, View} from "@tsed/schema";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {PLATFORM_CONTENT_TYPE_RESOLVER} from "./PlatformContentTypeResolver.js";
|
|
5
|
+
import {PLATFORM_CONTENT_TYPES_CONTAINER} from "./PlatformContentTypesContainer.js";
|
|
6
|
+
|
|
7
|
+
async function getTestFixture(contentTypes = ["application/json", "text/html"]) {
|
|
8
|
+
const contentTypeResolver = await PlatformTest.invoke<PLATFORM_CONTENT_TYPE_RESOLVER>(PLATFORM_CONTENT_TYPE_RESOLVER, [
|
|
9
|
+
{
|
|
10
|
+
token: PLATFORM_CONTENT_TYPES_CONTAINER,
|
|
11
|
+
use: {
|
|
12
|
+
contentTypes
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
const data = {
|
|
18
|
+
test: "test"
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const ctx = PlatformTest.createRequestContext();
|
|
22
|
+
return {
|
|
23
|
+
data,
|
|
24
|
+
ctx,
|
|
25
|
+
contentTypeResolver
|
|
26
|
+
};
|
|
27
|
+
}
|
|
5
28
|
|
|
6
|
-
describe("
|
|
29
|
+
describe("PlatformContentTypeResolver", () => {
|
|
7
30
|
beforeEach(() => PlatformTest.create());
|
|
8
31
|
afterEach(() => PlatformTest.reset());
|
|
9
32
|
|
|
10
|
-
it("should return the content type (undefined)", () => {
|
|
33
|
+
it("should return the content type (undefined)", async () => {
|
|
11
34
|
class TestController {
|
|
12
35
|
@Get("/")
|
|
13
36
|
get() {}
|
|
14
37
|
}
|
|
15
38
|
|
|
16
|
-
const ctx =
|
|
39
|
+
const {contentTypeResolver, ctx, data} = await getTestFixture();
|
|
40
|
+
|
|
17
41
|
ctx.endpoint = EndpointMetadata.get(TestController, "get");
|
|
18
42
|
|
|
19
|
-
const result =
|
|
20
|
-
{
|
|
21
|
-
test: "test"
|
|
22
|
-
},
|
|
23
|
-
ctx
|
|
24
|
-
);
|
|
43
|
+
const result = await contentTypeResolver(data, ctx);
|
|
25
44
|
|
|
26
45
|
expect(result).toEqual(undefined);
|
|
27
46
|
});
|
|
28
|
-
it("should return the content type (object - application/json)", () => {
|
|
47
|
+
it("should return the content type (object - application/json)", async () => {
|
|
29
48
|
class TestController {
|
|
30
49
|
@Get("/")
|
|
31
50
|
@(Returns(200).ContentType("application/json"))
|
|
32
51
|
get() {}
|
|
33
52
|
}
|
|
34
53
|
|
|
35
|
-
const ctx =
|
|
54
|
+
const {contentTypeResolver, ctx, data} = await getTestFixture();
|
|
55
|
+
|
|
36
56
|
ctx.endpoint = EndpointMetadata.get(TestController, "get");
|
|
37
57
|
ctx.response.getRes().statusCode = 200;
|
|
58
|
+
|
|
38
59
|
vi.spyOn(ctx.response, "getContentType").mockReturnValue("application/json");
|
|
39
60
|
|
|
40
|
-
const result =
|
|
41
|
-
{
|
|
42
|
-
test: "test"
|
|
43
|
-
},
|
|
44
|
-
ctx
|
|
45
|
-
);
|
|
61
|
+
const result = contentTypeResolver(data, ctx);
|
|
46
62
|
|
|
47
63
|
expect(result).toEqual("application/json");
|
|
48
64
|
});
|
|
49
|
-
it("should return the content type (string - application/json)", () => {
|
|
65
|
+
it("should return the content type (string - application/json)", async () => {
|
|
50
66
|
class TestController {
|
|
51
67
|
@Get("/")
|
|
52
68
|
@(Returns(200).ContentType("application/json"))
|
|
53
69
|
get() {}
|
|
54
70
|
}
|
|
55
71
|
|
|
56
|
-
const ctx =
|
|
72
|
+
const {contentTypeResolver, ctx, data} = await getTestFixture();
|
|
73
|
+
|
|
57
74
|
ctx.endpoint = EndpointMetadata.get(TestController, "get");
|
|
58
75
|
ctx.response.getRes().statusCode = 200;
|
|
59
76
|
vi.spyOn(ctx.response, "getContentType").mockReturnValue("application/json");
|
|
60
77
|
|
|
61
|
-
const result =
|
|
62
|
-
{
|
|
63
|
-
test: "test"
|
|
64
|
-
},
|
|
65
|
-
ctx
|
|
66
|
-
);
|
|
78
|
+
const result = contentTypeResolver(data, ctx);
|
|
67
79
|
|
|
68
80
|
expect(result).toEqual("application/json");
|
|
69
81
|
});
|
|
70
|
-
it("should return the content type (string - text/html)", () => {
|
|
82
|
+
it("should return the content type (string - text/html)", async () => {
|
|
71
83
|
class TestController {
|
|
72
84
|
@Get("/")
|
|
73
85
|
@(Returns(200).ContentType("text/html"))
|
|
74
86
|
get() {}
|
|
75
87
|
}
|
|
76
88
|
|
|
77
|
-
const ctx =
|
|
89
|
+
const {contentTypeResolver, ctx, data} = await getTestFixture();
|
|
90
|
+
|
|
78
91
|
ctx.endpoint = EndpointMetadata.get(TestController, "get");
|
|
79
92
|
ctx.response.getRes().statusCode = 200;
|
|
80
93
|
vi.spyOn(ctx.response, "getContentType").mockReturnValue("text/html");
|
|
81
94
|
|
|
82
|
-
const result =
|
|
83
|
-
{
|
|
84
|
-
test: "test"
|
|
85
|
-
},
|
|
86
|
-
ctx
|
|
87
|
-
);
|
|
95
|
+
const result = contentTypeResolver(data, ctx);
|
|
88
96
|
|
|
89
97
|
expect(result).toEqual("text/html");
|
|
90
98
|
});
|
|
91
|
-
it("should return the content type (string - view)", () => {
|
|
99
|
+
it("should return the content type (string - view)", async () => {
|
|
92
100
|
class TestController {
|
|
93
101
|
@Get("/")
|
|
94
102
|
@Returns(200)
|
|
@@ -96,17 +104,13 @@ describe("getContentType", () => {
|
|
|
96
104
|
get() {}
|
|
97
105
|
}
|
|
98
106
|
|
|
99
|
-
const ctx =
|
|
107
|
+
const {contentTypeResolver, ctx, data} = await getTestFixture();
|
|
108
|
+
|
|
100
109
|
ctx.endpoint = EndpointMetadata.get(TestController, "get");
|
|
101
110
|
ctx.response.getRes().statusCode = 200;
|
|
102
111
|
ctx.view = "true";
|
|
103
112
|
|
|
104
|
-
const result =
|
|
105
|
-
{
|
|
106
|
-
test: "test"
|
|
107
|
-
},
|
|
108
|
-
ctx
|
|
109
|
-
);
|
|
113
|
+
const result = contentTypeResolver(data, ctx);
|
|
110
114
|
|
|
111
115
|
expect(result).toEqual("text/html");
|
|
112
116
|
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {isObject} from "@tsed/core";
|
|
2
|
+
import {type BaseContext, inject, injectable} from "@tsed/di";
|
|
3
|
+
|
|
4
|
+
import {ANY_CONTENT_TYPE} from "../constants/ANY_CONTENT_TYPE.js";
|
|
5
|
+
import {PLATFORM_CONTENT_TYPES_CONTAINER} from "./PlatformContentTypesContainer.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @ignore
|
|
9
|
+
*/
|
|
10
|
+
export function getContentType(data: any, ctx: BaseContext) {
|
|
11
|
+
const {endpoint, response} = ctx;
|
|
12
|
+
const {operation} = endpoint;
|
|
13
|
+
|
|
14
|
+
const contentType = response.getContentType() || operation.getContentTypeOf(response.statusCode) || "";
|
|
15
|
+
|
|
16
|
+
if (contentType && contentType !== ANY_CONTENT_TYPE) {
|
|
17
|
+
if (contentType === "application/json" && isObject(data)) {
|
|
18
|
+
return "application/json";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return contentType;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (endpoint.view) {
|
|
25
|
+
return "text/html";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @ignore
|
|
31
|
+
*/
|
|
32
|
+
function resolver(data: any, ctx: BaseContext) {
|
|
33
|
+
const contentType = getContentType(data, ctx);
|
|
34
|
+
|
|
35
|
+
if (ctx.request.get("Accept")) {
|
|
36
|
+
const {contentTypes} = inject<PLATFORM_CONTENT_TYPES_CONTAINER>(PLATFORM_CONTENT_TYPES_CONTAINER);
|
|
37
|
+
|
|
38
|
+
const bestContentType = ctx.request.accepts([contentType].concat(contentTypes).filter(Boolean));
|
|
39
|
+
|
|
40
|
+
if (bestContentType) {
|
|
41
|
+
return [].concat(bestContentType as any).filter((type) => type !== "*/*")[0];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return contentType;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @ignore
|
|
50
|
+
*/
|
|
51
|
+
export type PLATFORM_CONTENT_TYPE_RESOLVER = typeof resolver;
|
|
52
|
+
export const PLATFORM_CONTENT_TYPE_RESOLVER = injectable(Symbol.for("PLATFORM_CONTENT_TYPE_RESOLVER"))
|
|
53
|
+
.factory(() => resolver)
|
|
54
|
+
.token();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type {Type} from "@tsed/core";
|
|
2
|
+
import {constant, inject, injectable, type TokenProvider} from "@tsed/di";
|
|
3
|
+
|
|
4
|
+
import {ANY_CONTENT_TYPE} from "../constants/ANY_CONTENT_TYPE.js";
|
|
5
|
+
import {ResponseFilterKey, ResponseFiltersContainer} from "../domain/ResponseFiltersContainer.js";
|
|
6
|
+
import type {ResponseFilterMethods} from "../interfaces/ResponseFilterMethods.js";
|
|
7
|
+
|
|
8
|
+
function factory() {
|
|
9
|
+
const responseFilters = constant<Type<ResponseFilterMethods>[]>("responseFilters", []);
|
|
10
|
+
const containers: Map<ResponseFilterKey, TokenProvider> = new Map();
|
|
11
|
+
|
|
12
|
+
ResponseFiltersContainer.forEach((token, type) => {
|
|
13
|
+
if (responseFilters.includes(token)) {
|
|
14
|
+
containers.set(type, token);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
contentTypes: [...containers.keys()],
|
|
20
|
+
resolve(bestContentType: string) {
|
|
21
|
+
const token = containers.get(bestContentType) || containers.get(ANY_CONTENT_TYPE);
|
|
22
|
+
|
|
23
|
+
if (token) {
|
|
24
|
+
return inject<ResponseFilterMethods>(token);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type PLATFORM_CONTENT_TYPES_CONTAINER = ReturnType<typeof factory>;
|
|
31
|
+
export const PLATFORM_CONTENT_TYPES_CONTAINER = injectable(Symbol.for("PLATFORM_CONTENT_TYPES_CONTAINER")).factory(factory).token();
|
|
@@ -1,45 +1,18 @@
|
|
|
1
|
-
import {isSerializable
|
|
2
|
-
import {BaseContext, constant, inject, injectable
|
|
1
|
+
import {isSerializable} from "@tsed/core";
|
|
2
|
+
import {BaseContext, constant, inject, injectable} from "@tsed/di";
|
|
3
3
|
import {serialize} from "@tsed/json-mapper";
|
|
4
4
|
|
|
5
|
-
import {ResponseFilterKey, ResponseFiltersContainer} from "../domain/ResponseFiltersContainer.js";
|
|
6
|
-
import {ResponseFilterMethods} from "../interfaces/ResponseFilterMethods.js";
|
|
7
|
-
import {ANY_CONTENT_TYPE, getContentType} from "../utils/getContentType.js";
|
|
8
5
|
import {renderView} from "../utils/renderView.js";
|
|
6
|
+
import {PLATFORM_CONTENT_TYPE_RESOLVER} from "./PlatformContentTypeResolver.js";
|
|
7
|
+
import {PLATFORM_CONTENT_TYPES_CONTAINER} from "./PlatformContentTypesContainer.js";
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* @platform
|
|
12
11
|
*/
|
|
13
12
|
export class PlatformResponseFilter {
|
|
14
|
-
protected types: Map<ResponseFilterKey, TokenProvider> = new Map();
|
|
15
|
-
protected responseFilters = constant<Type<ResponseFilterMethods>[]>("responseFilters", []);
|
|
16
13
|
protected additionalProperties = constant<boolean>("additionalProperties");
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
ResponseFiltersContainer.forEach((token, type) => {
|
|
20
|
-
if (this.responseFilters.includes(token)) {
|
|
21
|
-
this.types.set(type, token);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
get contentTypes(): ResponseFilterKey[] {
|
|
27
|
-
return [...this.types.keys()];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
getBestContentType(data: any, ctx: BaseContext) {
|
|
31
|
-
const contentType = getContentType(data, ctx);
|
|
32
|
-
|
|
33
|
-
if (ctx.request.get("Accept")) {
|
|
34
|
-
const bestContentType = ctx.request.accepts([contentType].concat(this.contentTypes).filter(Boolean));
|
|
35
|
-
|
|
36
|
-
if (bestContentType) {
|
|
37
|
-
return [].concat(bestContentType as any).filter((type) => type !== "*/*")[0];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return contentType;
|
|
42
|
-
}
|
|
14
|
+
protected container = inject<PLATFORM_CONTENT_TYPES_CONTAINER>(PLATFORM_CONTENT_TYPES_CONTAINER);
|
|
15
|
+
protected contentTypeResolver = inject<PLATFORM_CONTENT_TYPE_RESOLVER>(PLATFORM_CONTENT_TYPE_RESOLVER);
|
|
43
16
|
|
|
44
17
|
/**
|
|
45
18
|
* Call filters to transform data
|
|
@@ -50,11 +23,11 @@ export class PlatformResponseFilter {
|
|
|
50
23
|
const {response} = ctx;
|
|
51
24
|
|
|
52
25
|
if (ctx.endpoint?.operation) {
|
|
53
|
-
const bestContentType = this.
|
|
26
|
+
const bestContentType = this.contentTypeResolver(data, ctx);
|
|
54
27
|
|
|
55
28
|
bestContentType && response.contentType(bestContentType);
|
|
56
29
|
|
|
57
|
-
const resolved = this.resolve(bestContentType);
|
|
30
|
+
const resolved = this.container.resolve(bestContentType);
|
|
58
31
|
|
|
59
32
|
if (resolved) {
|
|
60
33
|
return resolved.transform(data, ctx);
|
|
@@ -92,14 +65,6 @@ export class PlatformResponseFilter {
|
|
|
92
65
|
return data;
|
|
93
66
|
}
|
|
94
67
|
|
|
95
|
-
private resolve(bestContentType: string) {
|
|
96
|
-
const token = this.types.get(bestContentType) || this.types.get(ANY_CONTENT_TYPE);
|
|
97
|
-
|
|
98
|
-
if (token) {
|
|
99
|
-
return inject<ResponseFilterMethods>(token);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
68
|
private getIncludes(ctx: BaseContext) {
|
|
104
69
|
if (ctx.request.query.includes) {
|
|
105
70
|
return [].concat(ctx.request.query.includes).flatMap((include: string) => include.split(","));
|
|
@@ -1,20 +0,0 @@
|
|
|
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" && isObject(data)) {
|
|
12
|
-
return "application/json";
|
|
13
|
-
}
|
|
14
|
-
return contentType;
|
|
15
|
-
}
|
|
16
|
-
if (endpoint.view) {
|
|
17
|
-
return "text/html";
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=getContentType.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getContentType.js","sourceRoot":"","sources":["../../../src/utils/getContentType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AAGpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAEtC;;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,CAAC;QACpD,IAAI,WAAW,KAAK,kBAAkB,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import {isObject} from "@tsed/core";
|
|
2
|
-
import type {BaseContext} from "@tsed/di";
|
|
3
|
-
|
|
4
|
-
export const ANY_CONTENT_TYPE = "*/*";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @ignore
|
|
8
|
-
*/
|
|
9
|
-
export function getContentType(data: any, ctx: BaseContext) {
|
|
10
|
-
const {endpoint, response} = ctx;
|
|
11
|
-
const {operation} = endpoint;
|
|
12
|
-
|
|
13
|
-
const contentType = response.getContentType() || operation.getContentTypeOf(response.statusCode) || "";
|
|
14
|
-
|
|
15
|
-
if (contentType && contentType !== ANY_CONTENT_TYPE) {
|
|
16
|
-
if (contentType === "application/json" && isObject(data)) {
|
|
17
|
-
return "application/json";
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return contentType;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (endpoint.view) {
|
|
24
|
-
return "text/html";
|
|
25
|
-
}
|
|
26
|
-
}
|