@nestia/core 14.0.0 → 14.0.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/MIGRATION.md +20 -0
- package/README.md +1 -1
- package/lib/adaptors/McpAdaptor.d.ts +5 -0
- package/lib/adaptors/McpAdaptor.js +114 -26
- package/lib/adaptors/McpAdaptor.js.map +1 -1
- package/lib/adaptors/WebSocketAdaptor.js +124 -32
- package/lib/adaptors/WebSocketAdaptor.js.map +1 -1
- package/lib/adaptors/internal/RoutePathMatcher.d.ts +1 -0
- package/lib/adaptors/internal/RoutePathMatcher.js +88 -0
- package/lib/adaptors/internal/RoutePathMatcher.js.map +1 -0
- package/lib/adaptors/internal/external_context.d.ts +1 -0
- package/lib/adaptors/internal/external_context.js +43 -0
- package/lib/adaptors/internal/external_context.js.map +1 -0
- package/lib/decorators/EncryptedBody.js +2 -2
- package/lib/decorators/EncryptedBody.js.map +1 -1
- package/lib/decorators/EncryptedController.js +1 -1
- package/lib/decorators/EncryptedController.js.map +1 -1
- package/lib/decorators/EncryptedModule.d.ts +7 -3
- package/lib/decorators/EncryptedModule.js +69 -15
- package/lib/decorators/EncryptedModule.js.map +1 -1
- package/lib/decorators/EncryptedRoute.js +7 -2
- package/lib/decorators/EncryptedRoute.js.map +1 -1
- package/lib/decorators/TypedBody.d.ts +1 -1
- package/lib/decorators/TypedBody.js +1 -1
- package/lib/decorators/TypedFormData.d.ts +22 -8
- package/lib/decorators/TypedFormData.js +116 -31
- package/lib/decorators/TypedFormData.js.map +1 -1
- package/lib/decorators/TypedParam.d.ts +3 -3
- package/lib/decorators/TypedParam.js +3 -3
- package/lib/decorators/TypedQuery.d.ts +1 -1
- package/lib/decorators/TypedQuery.js +9 -4
- package/lib/decorators/TypedQuery.js.map +1 -1
- package/lib/decorators/internal/EncryptedConstant.js +13 -2
- package/lib/decorators/internal/EncryptedConstant.js.map +1 -1
- package/lib/decorators/internal/get_encryption_password.d.ts +1 -0
- package/lib/decorators/internal/get_encryption_password.js +14 -0
- package/lib/decorators/internal/get_encryption_password.js.map +1 -0
- package/lib/decorators/internal/get_path_and_querify.js +21 -3
- package/lib/decorators/internal/get_path_and_querify.js.map +1 -1
- package/lib/decorators/internal/get_text_body.js +9 -3
- package/lib/decorators/internal/get_text_body.js.map +1 -1
- package/lib/decorators/internal/group_entries.d.ts +1 -0
- package/lib/decorators/internal/group_entries.js +19 -0
- package/lib/decorators/internal/group_entries.js.map +1 -0
- package/lib/decorators/internal/validate_request_form_data.js +3 -1
- package/lib/decorators/internal/validate_request_form_data.js.map +1 -1
- package/lib/decorators/internal/validate_request_headers.js +2 -1
- package/lib/decorators/internal/validate_request_headers.js.map +1 -1
- package/lib/decorators/internal/validate_request_query.js +3 -1
- package/lib/decorators/internal/validate_request_query.js.map +1 -1
- package/lib/options/IResponseBodyQuerifier.d.ts +5 -1
- package/lib/utils/ExceptionManager.d.ts +3 -4
- package/lib/utils/ExceptionManager.js +10 -6
- package/lib/utils/ExceptionManager.js.map +1 -1
- package/lib/utils/SourceFinder.js +26 -3
- package/lib/utils/SourceFinder.js.map +1 -1
- package/lib/utils/VersioningStrategy.d.ts +9 -1
- package/lib/utils/VersioningStrategy.js +18 -6
- package/lib/utils/VersioningStrategy.js.map +1 -1
- package/native/go.mod +1 -1
- package/native/go.sum +2 -2
- package/native/transform/ast.go +4 -2
- package/native/transform/core_querify.go +26 -6
- package/native/transform/core_transform.go +76 -1
- package/native/transform/core_websocket.go +94 -13
- package/native/transform/node_transform.go +6 -0
- package/native/transform/transform.go +8 -18
- package/native/transform/typia_fast.go +6 -0
- package/native/transform.cjs +49 -0
- package/package.json +12 -15
- package/src/adaptors/McpAdaptor.ts +150 -28
- package/src/adaptors/WebSocketAdaptor.ts +136 -38
- package/src/adaptors/internal/RoutePathMatcher.ts +91 -0
- package/src/adaptors/internal/external_context.ts +50 -0
- package/src/decorators/EncryptedBody.ts +2 -2
- package/src/decorators/EncryptedController.ts +6 -2
- package/src/decorators/EncryptedModule.ts +71 -15
- package/src/decorators/EncryptedRoute.ts +7 -5
- package/src/decorators/TypedBody.ts +1 -1
- package/src/decorators/TypedFormData.ts +148 -44
- package/src/decorators/TypedParam.ts +3 -3
- package/src/decorators/TypedQuery.ts +19 -7
- package/src/decorators/internal/EncryptedConstant.ts +14 -1
- package/src/decorators/internal/get_encryption_password.ts +19 -0
- package/src/decorators/internal/get_path_and_querify.ts +29 -2
- package/src/decorators/internal/get_text_body.ts +8 -4
- package/src/decorators/internal/group_entries.ts +17 -0
- package/src/decorators/internal/validate_request_form_data.ts +3 -1
- package/src/decorators/internal/validate_request_headers.ts +2 -2
- package/src/decorators/internal/validate_request_query.ts +3 -2
- package/src/options/IResponseBodyQuerifier.ts +6 -1
- package/src/utils/ExceptionManager.ts +10 -6
- package/src/utils/SourceFinder.ts +24 -3
- package/src/utils/VersioningStrategy.ts +21 -7
- package/lib/transform.d.ts +0 -10
- package/lib/transform.js +0 -25
- package/lib/transform.js.map +0 -1
- package/src/transform.ts +0 -26
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RoutePathMatcher = void 0;
|
|
4
|
+
const path_to_regexp_1 = require("path-to-regexp");
|
|
5
|
+
/**
|
|
6
|
+
* A WebSocket route's path, matched as NestJS 11's Express router matches an
|
|
7
|
+
* HTTP route: path-to-regexp 8's syntax, where `\:` is a literal colon, `*name`
|
|
8
|
+
* a wildcard, and `{...}` an optional group; find-my-way's (Fastify) literal
|
|
9
|
+
* colon `::` is read too, as `@nestia/sdk` reads it when it builds the SDK's
|
|
10
|
+
* URL.
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
class RoutePathMatcher {
|
|
15
|
+
constructor(path) {
|
|
16
|
+
this.path = path;
|
|
17
|
+
const route = fromFastifyColons(path);
|
|
18
|
+
this.params = names((0, path_to_regexp_1.parse)(route).tokens);
|
|
19
|
+
this.match_ = (0, path_to_regexp_1.match)(route, {
|
|
20
|
+
decode: (value) => {
|
|
21
|
+
try {
|
|
22
|
+
return decodeURIComponent(value);
|
|
23
|
+
}
|
|
24
|
+
catch (_a) {
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The parameters of a matching request path, or `null`. A wildcard's segments
|
|
32
|
+
* are joined by `/`, and an optional parameter absent is left out.
|
|
33
|
+
*/
|
|
34
|
+
test(path) {
|
|
35
|
+
const matched = this.match_(path);
|
|
36
|
+
if (matched === false)
|
|
37
|
+
return null;
|
|
38
|
+
const output = {};
|
|
39
|
+
for (const [key, value] of Object.entries(matched.params))
|
|
40
|
+
if (value !== undefined)
|
|
41
|
+
output[key] = Array.isArray(value) ? value.join("/") : value;
|
|
42
|
+
return output;
|
|
43
|
+
}
|
|
44
|
+
toString() {
|
|
45
|
+
return this.path;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.RoutePathMatcher = RoutePathMatcher;
|
|
49
|
+
const names = (tokens) => tokens.flatMap((token) => token.type === "param" || token.type === "wildcard"
|
|
50
|
+
? [token.name]
|
|
51
|
+
: token.type === "group"
|
|
52
|
+
? names(token.tokens)
|
|
53
|
+
: []);
|
|
54
|
+
/**
|
|
55
|
+
* A route with find-my-way's (Fastify) literal colon `::` spelled as
|
|
56
|
+
* path-to-regexp's `\:`. find-my-way reads `::` as a colon in static text
|
|
57
|
+
* alone: after a parameter it is part of the parameter's name, so it is left as
|
|
58
|
+
* is there, and path-to-regexp then rejects the route, as no parameter of that
|
|
59
|
+
* name is what the handler reads.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
const fromFastifyColons = (route) => {
|
|
64
|
+
let output = "";
|
|
65
|
+
for (let i = 0; i < route.length;) {
|
|
66
|
+
if (route[i] === "\\") {
|
|
67
|
+
output += route.slice(i, i + 2);
|
|
68
|
+
i += 2;
|
|
69
|
+
}
|
|
70
|
+
else if (route.startsWith("::", i)) {
|
|
71
|
+
output += "\\:";
|
|
72
|
+
i += 2;
|
|
73
|
+
}
|
|
74
|
+
else if (route[i] === ":") {
|
|
75
|
+
const name = /^:[A-Za-z0-9_$]*/.exec(route.slice(i))[0];
|
|
76
|
+
output += name;
|
|
77
|
+
i += name.length;
|
|
78
|
+
if (route.startsWith("::", i)) {
|
|
79
|
+
output += "::";
|
|
80
|
+
i += 2;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else
|
|
84
|
+
output += route[i++];
|
|
85
|
+
}
|
|
86
|
+
return output;
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=RoutePathMatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoutePathMatcher.js","sourceRoot":"","sources":["../../../src/adaptors/internal/RoutePathMatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_request_context_id = exports.create_external_context_creator = void 0;
|
|
4
|
+
const core_1 = require("@nestjs/core");
|
|
5
|
+
const external_context_creator_1 = require("@nestjs/core/helpers/external-context-creator");
|
|
6
|
+
const request_constants_1 = require("@nestjs/core/router/request/request-constants");
|
|
7
|
+
/**
|
|
8
|
+
* The creator of NestJS's enhancer pipeline (guards, interceptors, pipes, and
|
|
9
|
+
* exception filters) for the controllers of one module.
|
|
10
|
+
*
|
|
11
|
+
* `ExternalContextCreator` looks the module up among those providing the class,
|
|
12
|
+
* and a controller is provided by none, so its enhancers would not resolve: the
|
|
13
|
+
* module is named here instead.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
const create_external_context_creator = (container, moduleKey) => {
|
|
18
|
+
const creator = external_context_creator_1.ExternalContextCreator.fromContainer(container);
|
|
19
|
+
creator.getContextModuleKey = () => moduleKey;
|
|
20
|
+
return creator;
|
|
21
|
+
};
|
|
22
|
+
exports.create_external_context_creator = create_external_context_creator;
|
|
23
|
+
/**
|
|
24
|
+
* The context a request-scoped provider is built in for this request, the one
|
|
25
|
+
* NestJS's router attaches to it, registering the request as `REQUEST`.
|
|
26
|
+
*
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
const get_request_context_id = (container, request, durable) => {
|
|
30
|
+
const contextId = core_1.ContextIdFactory.getByRequest(request);
|
|
31
|
+
if (!request[request_constants_1.REQUEST_CONTEXT_ID]) {
|
|
32
|
+
Object.defineProperty(request, request_constants_1.REQUEST_CONTEXT_ID, {
|
|
33
|
+
value: contextId,
|
|
34
|
+
enumerable: false,
|
|
35
|
+
writable: false,
|
|
36
|
+
configurable: false,
|
|
37
|
+
});
|
|
38
|
+
container.registerRequestProvider(durable ? contextId.payload : Object.assign(request, contextId.payload), contextId);
|
|
39
|
+
}
|
|
40
|
+
return contextId;
|
|
41
|
+
};
|
|
42
|
+
exports.get_request_context_id = get_request_context_id;
|
|
43
|
+
//# sourceMappingURL=external_context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external_context.js","sourceRoot":"","sources":["../../../src/adaptors/internal/external_context.ts"],"names":[],"mappings":";;;AAAA,uCAA0E;AAC1E,4FAAuF;AACvF,qFAAmF;AAEnF;;;;;;;;;GASG;AACI,MAAM,+BAA+B,GAAG,CAC7C,SAAwB,EACxB,SAAiB,EACO,EAAE;IAC1B,MAAM,OAAO,GACX,iDAAsB,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAClD,OAAO,CAAC,mBAAmB,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AARW,QAAA,+BAA+B,GAA/B,+BAA+B,CAQ1C;AAEF;;;;;GAKG;AACI,MAAM,sBAAsB,GAAG,CACpC,SAAwB,EACxB,OAAY,EACZ,OAAgB,EACL,EAAE;IACb,MAAM,SAAS,GAAc,uBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,CAAC,sCAAkB,CAAC,EAAE,CAAC;QACjC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,sCAAkB,EAAE;YACjD,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;QACH,SAAS,CAAC,uBAAuB,CAC/B,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,EACvE,SAAS,CACV,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAnBW,QAAA,sBAAsB,GAAtB,sBAAsB,CAmBjC"}
|
|
@@ -13,7 +13,7 @@ exports.EncryptedBody = EncryptedBody;
|
|
|
13
13
|
const AesPkcs5_1 = require("@nestia/fetcher/lib/AesPkcs5");
|
|
14
14
|
const common_1 = require("@nestjs/common");
|
|
15
15
|
const Singleton_1 = require("../utils/Singleton");
|
|
16
|
-
const
|
|
16
|
+
const get_encryption_password_1 = require("./internal/get_encryption_password");
|
|
17
17
|
const get_text_body_1 = require("./internal/get_text_body");
|
|
18
18
|
const headers_to_object_1 = require("./internal/headers_to_object");
|
|
19
19
|
const is_media_type_1 = require("./internal/is_media_type");
|
|
@@ -48,7 +48,7 @@ function EncryptedBody(validator) {
|
|
|
48
48
|
.getRequest();
|
|
49
49
|
if ((0, is_media_type_1.is_media_type)(request.headers["content-type"], "text/plain") === false)
|
|
50
50
|
throw new common_1.BadRequestException(`Request body type is not "text/plain".`);
|
|
51
|
-
const param =
|
|
51
|
+
const param = (0, get_encryption_password_1.get_encryption_password)(context.getClass());
|
|
52
52
|
if (!param)
|
|
53
53
|
throw new Error("Error on nestia.core.EncryptedBody(): no encryption password is given.");
|
|
54
54
|
// GET BODY DATA
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EncryptedBody.js","sourceRoot":"","sources":["../../src/decorators/EncryptedBody.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,2DAAwD;AACxD,2CAIwB;AAKxB,kDAA+C;AAC/C,
|
|
1
|
+
{"version":3,"file":"EncryptedBody.js","sourceRoot":"","sources":["../../src/decorators/EncryptedBody.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,2DAAwD;AACxD,2CAIwB;AAKxB,kDAA+C;AAC/C,gFAA6E;AAC7E,4DAAyD;AACzD,oEAAiE;AACjE,4DAAyD;AACzD,4EAAyE;AAEzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,uBACE,SAAoC;IAEpC,MAAM,OAAO,GAAG,IAAA,6CAAqB,EAAC,eAAe,CAAC,CAAC,SAAS,CAAC,CAAC;IAClE,OAAO,IAAA,6BAAoB,EAAC,SAAe,aAAa,CACtD,QAAa,EACb,OAAyB;;YAEzB,MAAM,OAAO,GAAqC,OAAO;iBACtD,YAAY,EAAE;iBACd,UAAU,EAAE,CAAC;YAChB,IAAI,IAAA,6BAAa,EAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,YAAY,CAAC,KAAK,KAAK;gBACxE,MAAM,IAAI,4BAAmB,CAAC,wCAAwC,CAAC,CAAC;YAE1E,MAAM,KAAK,GACT,IAAA,iDAAuB,EAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC9C,IAAI,CAAC,KAAK;gBACR,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;YAEJ,gBAAgB;YAChB,MAAM,OAAO,GAAsC,IAAI,qBAAS,CAAC,GAAG,EAAE,CACpE,IAAA,qCAAiB,EAAC,OAAO,CAAC,OAAO,CAAC,CACnC,CAAC;YACF,MAAM,IAAI,GAAW,MAAM,IAAA,6BAAa,EAAC,OAAO,CAAC,CAAC;YAClD,MAAM,QAAQ,GACZ,OAAO,KAAK,KAAK,UAAU;gBACzB,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;gBAC9D,CAAC,CAAC,KAAK,CAAC;YAEZ,0BAA0B;YAC1B,MAAM,IAAI,GAAQ,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC1D,MAAM,KAAK,GAAiB,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,KAAK,KAAK,IAAI;gBAAE,MAAM,KAAK,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;KAAA,CAAC,EAAE,CAAC;AACP,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,GAAW,EAAE,EAAU,EAAW,EAAE;IAChE,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,mBAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK;YACtB,MAAM,IAAI,4BAAmB,CAC3B,qFAAqF,CACtF,CAAC;;YACC,MAAM,GAAG,CAAC;IACjB,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -31,7 +31,7 @@ const EncryptedConstant_1 = require("./internal/EncryptedConstant");
|
|
|
31
31
|
*/
|
|
32
32
|
function EncryptedController(path, password) {
|
|
33
33
|
return function (target) {
|
|
34
|
-
Reflect.defineMetadata(EncryptedConstant_1.
|
|
34
|
+
Reflect.defineMetadata(EncryptedConstant_1.ENCRYPTION_CONTROLLER_METADATA_KEY, password, target);
|
|
35
35
|
(0, common_1.Controller)(path)(target);
|
|
36
36
|
};
|
|
37
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EncryptedController.js","sourceRoot":"","sources":["../../src/decorators/EncryptedController.ts"],"names":[],"mappings":";;;AACA,2CAA4C;AAE5C,
|
|
1
|
+
{"version":3,"file":"EncryptedController.js","sourceRoot":"","sources":["../../src/decorators/EncryptedController.ts"],"names":[],"mappings":";;;AACA,2CAA4C;AAE5C,oEAAkF;AAElF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,6BACE,IAAY,EACZ,QAA2D;IAE3D,OAAO,UAAU,MAAW;QAC1B,OAAO,CAAC,cAAc,CACpB,sDAAkC,EAClC,QAAQ,EACR,MAAM,CACP,CAAC;QACF,IAAA,mBAAU,EAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -11,9 +11,13 @@ import { Module } from "@nestjs/common";
|
|
|
11
11
|
*
|
|
12
12
|
* By using this `EncryptedModule` decorator function, all of the
|
|
13
13
|
* {@link Controller controllers} configured in the _metadata_ would be
|
|
14
|
-
* automatically changed to the {@link EncryptedController} with the _password_
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* automatically changed to the {@link EncryptedController} with the _password_,
|
|
15
|
+
* and so would the controllers of every module it imports: module classes,
|
|
16
|
+
* dynamic modules (`{ module, imports, controllers }`), `forwardRef()`s, and
|
|
17
|
+
* promises of them, however deep and even when cyclic. If there're some
|
|
18
|
+
* original {@link EncryptedController} decorated classes in the _metadata_,
|
|
19
|
+
* their encryption password would be kept, as would a subclass's that inherits
|
|
20
|
+
* one.
|
|
17
21
|
*
|
|
18
22
|
* Therefore, if you're planning to place original {@link EncryptedController}
|
|
19
23
|
* decorated classes in the _metadata_, I hope them to have different encryption
|
|
@@ -62,9 +62,13 @@ const load_controller_1 = require("./internal/load_controller");
|
|
|
62
62
|
*
|
|
63
63
|
* By using this `EncryptedModule` decorator function, all of the
|
|
64
64
|
* {@link Controller controllers} configured in the _metadata_ would be
|
|
65
|
-
* automatically changed to the {@link EncryptedController} with the _password_
|
|
66
|
-
*
|
|
67
|
-
*
|
|
65
|
+
* automatically changed to the {@link EncryptedController} with the _password_,
|
|
66
|
+
* and so would the controllers of every module it imports: module classes,
|
|
67
|
+
* dynamic modules (`{ module, imports, controllers }`), `forwardRef()`s, and
|
|
68
|
+
* promises of them, however deep and even when cyclic. If there're some
|
|
69
|
+
* original {@link EncryptedController} decorated classes in the _metadata_,
|
|
70
|
+
* their encryption password would be kept, as would a subclass's that inherits
|
|
71
|
+
* one.
|
|
68
72
|
*
|
|
69
73
|
* Therefore, if you're planning to place original {@link EncryptedController}
|
|
70
74
|
* decorated classes in the _metadata_, I hope them to have different encryption
|
|
@@ -128,17 +132,67 @@ function EncryptedModule(metadata, password) {
|
|
|
128
132
|
}
|
|
129
133
|
EncryptedModule.dynamic = dynamic;
|
|
130
134
|
})(EncryptedModule || (exports.EncryptedModule = EncryptedModule = {}));
|
|
131
|
-
/**
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Gives every controller the module reaches the module's password: those of the
|
|
137
|
+
* module itself and of each import, whether a module class, a dynamic module
|
|
138
|
+
* (its `module`, and its own `imports` and `controllers`), a `forwardRef()`, or
|
|
139
|
+
* a promise of one. Each module is visited once, so a cyclic import graph
|
|
140
|
+
* terminates.
|
|
141
|
+
*
|
|
142
|
+
* @internal
|
|
143
|
+
*/
|
|
144
|
+
const iterate = (password) => {
|
|
145
|
+
const visited = new Set();
|
|
146
|
+
const controllers = (list) => {
|
|
147
|
+
if (Array.isArray(list))
|
|
148
|
+
for (const c of list)
|
|
149
|
+
if (typeof c === "function")
|
|
150
|
+
Reflect.defineMetadata(EncryptedConstant_1.ENCRYPTION_METADATA_KEY, password, c);
|
|
151
|
+
};
|
|
152
|
+
const imports = (list) => {
|
|
153
|
+
if (Array.isArray(list))
|
|
154
|
+
for (const imp of list)
|
|
155
|
+
visit(imp);
|
|
156
|
+
};
|
|
157
|
+
const visit = (input) => {
|
|
158
|
+
if (typeof input !== "function" &&
|
|
159
|
+
(typeof input !== "object" || input === null))
|
|
160
|
+
return;
|
|
161
|
+
if (visited.has(input))
|
|
162
|
+
return;
|
|
163
|
+
visited.add(input);
|
|
164
|
+
if (typeof input === "function") {
|
|
165
|
+
imports(Reflect.getMetadata("imports", input));
|
|
166
|
+
controllers(Reflect.getMetadata("controllers", input));
|
|
167
|
+
}
|
|
168
|
+
else if (typeof input.then === "function")
|
|
169
|
+
// an asynchronous dynamic module; NestJS awaits the same promise while
|
|
170
|
+
// scanning, after this callback, registered first, has run
|
|
171
|
+
input.then(visit, () => { });
|
|
172
|
+
else if (typeof input.forwardRef === "function") {
|
|
173
|
+
// the class a forward reference names may not be defined yet while the
|
|
174
|
+
// decorators run; it is once the synchronous module graph has loaded
|
|
175
|
+
const resolve = () => {
|
|
176
|
+
try {
|
|
177
|
+
return input.forwardRef();
|
|
178
|
+
}
|
|
179
|
+
catch (_a) {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const target = resolve();
|
|
184
|
+
if (target !== undefined)
|
|
185
|
+
visit(target);
|
|
186
|
+
else
|
|
187
|
+
void Promise.resolve().then(() => visit(resolve()));
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const dynamic = input;
|
|
191
|
+
visit(dynamic.module);
|
|
192
|
+
imports(dynamic.imports);
|
|
193
|
+
controllers(dynamic.controllers);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
return visit;
|
|
143
197
|
};
|
|
144
198
|
//# sourceMappingURL=EncryptedModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EncryptedModule.js","sourceRoot":"","sources":["../../src/decorators/EncryptedModule.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,2CAAwC;AAGxC,oEAAuE;AACvE,gEAA8D;AAE9D
|
|
1
|
+
{"version":3,"file":"EncryptedModule.js","sourceRoot":"","sources":["../../src/decorators/EncryptedModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
10
10
|
const typia_1 = __importDefault(require("typia"));
|
|
11
11
|
const Singleton_1 = require("../utils/Singleton");
|
|
12
12
|
const TypedRoute_1 = require("./TypedRoute");
|
|
13
|
-
const
|
|
13
|
+
const get_encryption_password_1 = require("./internal/get_encryption_password");
|
|
14
14
|
const get_path_and_stringify_1 = require("./internal/get_path_and_stringify");
|
|
15
15
|
const headers_to_object_1 = require("./internal/headers_to_object");
|
|
16
16
|
const route_error_1 = require("./internal/route_error");
|
|
@@ -124,7 +124,7 @@ class EncryptedRouteInterceptor {
|
|
|
124
124
|
intercept(context, next) {
|
|
125
125
|
const http = context.switchToHttp();
|
|
126
126
|
return next.handle().pipe((0, operators_1.map)((value) => {
|
|
127
|
-
const param =
|
|
127
|
+
const param = (0, get_encryption_password_1.get_encryption_password)(context.getClass());
|
|
128
128
|
if (!param)
|
|
129
129
|
throw new Error(`Error on EncryptedRoute.${this.method}(): no password found.`);
|
|
130
130
|
const request = http.getRequest();
|
|
@@ -139,6 +139,11 @@ class EncryptedRouteInterceptor {
|
|
|
139
139
|
: param;
|
|
140
140
|
if (body === undefined)
|
|
141
141
|
return body;
|
|
142
|
+
// the ciphertext is text/plain, as the document declares; set on the
|
|
143
|
+
// success path alone, so an error keeps its JSON body's type (Express
|
|
144
|
+
// would otherwise send a string as text/html)
|
|
145
|
+
const response = http.getResponse();
|
|
146
|
+
response.header("Content-Type", "text/plain");
|
|
142
147
|
return AesPkcs5_1.AesPkcs5.encrypt(body, password.key, password.iv);
|
|
143
148
|
}), (0, operators_1.catchError)((err) => (0, route_error_1.route_error)(http.getRequest(), err)));
|
|
144
149
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EncryptedRoute.js","sourceRoot":"","sources":["../../src/decorators/EncryptedRoute.ts"],"names":[],"mappings":";;;;;;AACA,2DAAwD;AACxD,2CAWwB;AAGxB,8CAAiD;AACjD,kDAA0B;AAG1B,kDAA+C;AAC/C,6CAA0C;AAC1C,
|
|
1
|
+
{"version":3,"file":"EncryptedRoute.js","sourceRoot":"","sources":["../../src/decorators/EncryptedRoute.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,6 @@ import { IRequestBodyValidator } from "../options/IRequestBodyValidator";
|
|
|
11
11
|
* `T`, `BadRequestException` error (status code: 400) would be thrown.
|
|
12
12
|
*
|
|
13
13
|
* @author Jeongho Nam - https://github.com/samchon
|
|
14
|
-
* @param validator Custom validator if required. Default is `typia.
|
|
14
|
+
* @param validator Custom validator if required. Default is `typia.validate()`
|
|
15
15
|
*/
|
|
16
16
|
export declare function TypedBody<T>(validator?: IRequestBodyValidator<T>): ParameterDecorator;
|
|
@@ -17,7 +17,7 @@ const validate_request_body_1 = require("./internal/validate_request_body");
|
|
|
17
17
|
* `T`, `BadRequestException` error (status code: 400) would be thrown.
|
|
18
18
|
*
|
|
19
19
|
* @author Jeongho Nam - https://github.com/samchon
|
|
20
|
-
* @param validator Custom validator if required. Default is `typia.
|
|
20
|
+
* @param validator Custom validator if required. Default is `typia.validate()`
|
|
21
21
|
*/
|
|
22
22
|
function TypedBody(validator) {
|
|
23
23
|
const checker = (0, validate_request_body_1.validate_request_body)("TypedBody")(validator);
|
|
@@ -21,10 +21,13 @@
|
|
|
21
21
|
* types are allowed
|
|
22
22
|
* 4. By the way, union type never be not allowed
|
|
23
23
|
*
|
|
24
|
-
* By the way, if you're using `fastify`,
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
24
|
+
* By the way, if you're using `fastify`, pass a `fastify-multer` instance as
|
|
25
|
+
* the factory, and register a `multipart/form-data` content type parser that
|
|
26
|
+
* leaves the request stream to it when composing the NestJS application.
|
|
27
|
+
* Without the parser, Fastify rejects every multipart request with 415.
|
|
28
|
+
* `fastify-multer`'s own `contentParser` plugin declares the content type
|
|
29
|
+
* `multipart` without a subtype, which Fastify 5 (NestJS 11) refuses to
|
|
30
|
+
* register.
|
|
28
31
|
*
|
|
29
32
|
* ```typescript
|
|
30
33
|
* import { NestFactory } from "@nestjs/core";
|
|
@@ -32,16 +35,25 @@
|
|
|
32
35
|
* FastifyAdapter,
|
|
33
36
|
* NestFastifyApplication,
|
|
34
37
|
* } from "@nestjs/platform-fastify";
|
|
35
|
-
* import fastifyMulter from "fastify-multer";
|
|
36
38
|
*
|
|
37
39
|
* export async function main() {
|
|
38
40
|
* const app = await NestFactory.create<NestFastifyApplication>(
|
|
39
41
|
* AppModule,
|
|
40
42
|
* new FastifyAdapter(),
|
|
41
43
|
* );
|
|
42
|
-
* app
|
|
44
|
+
* app
|
|
45
|
+
* .getHttpAdapter()
|
|
46
|
+
* .getInstance()
|
|
47
|
+
* .addContentTypeParser("multipart/form-data", (_req, _payload, done) =>
|
|
48
|
+
* done(null),
|
|
49
|
+
* );
|
|
43
50
|
* await app.listen(3000);
|
|
44
51
|
* }
|
|
52
|
+
*
|
|
53
|
+
* // in the controller, with `import FastifyMulter from "fastify-multer"`
|
|
54
|
+
* public async upload(
|
|
55
|
+
* @TypedFormData.Body(() => FastifyMulter()) body: IMultipart,
|
|
56
|
+
* ): Promise<void> {}
|
|
45
57
|
* ```
|
|
46
58
|
*
|
|
47
59
|
* @author Jeongho Nam - https://github.com/samchon
|
|
@@ -55,9 +67,11 @@ export declare namespace TypedFormData {
|
|
|
55
67
|
*
|
|
56
68
|
* Much easier and type safer than `@nest.UploadFile()` decorator.
|
|
57
69
|
*
|
|
58
|
-
* @param factory Factory function
|
|
70
|
+
* @param factory Factory function creating the `multer` or `fastify-multer`
|
|
59
71
|
* instance. In the factory function, you also can specify the multer
|
|
60
|
-
* composition options like `storage` engine
|
|
72
|
+
* composition options like `storage` engine: memory and disk storage
|
|
73
|
+
* deliver the uploaded bytes, and an engine keeping neither the buffer nor
|
|
74
|
+
* a file path is rejected.
|
|
61
75
|
*/
|
|
62
76
|
function Body<Multer extends IMulterBase>(factory: () => Multer | Promise<Multer>): ParameterDecorator;
|
|
63
77
|
/** Base type of the `multer` or `fastify-multer`. */
|