@nestia/core 0.1.4 → 0.1.5
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/decorators/DynamicModule.d.ts +3 -0
- package/lib/decorators/DynamicModule.js +73 -0
- package/lib/decorators/DynamicModule.js.map +1 -0
- package/lib/decorators/EncryptedModule.js +16 -137
- package/lib/decorators/EncryptedModule.js.map +1 -1
- package/lib/decorators/internal/headers_to_object.d.ts +3 -1
- package/lib/decorators/internal/headers_to_object.js +0 -3
- package/lib/decorators/internal/headers_to_object.js.map +1 -1
- package/lib/decorators/internal/load_controller.d.ts +2 -0
- package/lib/decorators/internal/load_controller.js +153 -0
- package/lib/decorators/internal/load_controller.js.map +1 -0
- package/lib/decorators/internal/route_error.d.ts +3 -1
- package/lib/decorators/internal/route_error.js +0 -3
- package/lib/decorators/internal/route_error.js.map +1 -1
- package/lib/module.d.ts +2 -0
- package/lib/module.js +2 -0
- package/lib/module.js.map +1 -1
- package/package.json +1 -1
- package/src/decorators/DynamicModule.ts +16 -0
- package/src/decorators/EncryptedBody.ts +102 -102
- package/src/decorators/EncryptedController.ts +43 -43
- package/src/decorators/EncryptedModule.ts +77 -127
- package/src/decorators/EncryptedRoute.ts +203 -203
- package/src/decorators/PlainBody.ts +38 -38
- package/src/decorators/TypedBody.ts +49 -49
- package/src/decorators/TypedParam.ts +70 -70
- package/src/decorators/TypedRoute.ts +149 -149
- package/src/decorators/internal/EncryptedConstant.ts +4 -4
- package/src/decorators/internal/get_path_and_stringify.ts +77 -77
- package/src/decorators/internal/headers_to_object.ts +10 -13
- package/src/decorators/internal/load_controller.ts +35 -0
- package/src/decorators/internal/route_error.ts +38 -41
- package/src/decorators/internal/validate_request_body.ts +59 -59
- package/src/index.ts +5 -5
- package/src/module.ts +11 -9
- package/src/options/INestiaTransformOptions.ts +6 -6
- package/src/options/INestiaTransformProject.ts +7 -6
- package/src/options/IRequestBodyValidator.ts +20 -20
- package/src/options/IResponseBodyStringifier.ts +25 -25
- package/src/transform.ts +20 -20
- package/src/transformers/BodyTransformer.ts +106 -106
- package/src/transformers/FileTransformer.ts +49 -49
- package/src/transformers/MethodTransformer.ts +91 -91
- package/src/transformers/NodeTransformer.ts +18 -18
- package/src/transformers/ParameterTransformer.ts +45 -45
- package/src/transformers/RouteTransformer.ts +131 -131
- package/src/typings/Creator.ts +3 -3
- package/src/utils/ExceptionManager.ts +126 -126
- package/src/utils/Singleton.ts +20 -20
|
@@ -1,41 +1,38 @@
|
|
|
1
|
-
import { HttpException } from "@nestjs/common";
|
|
2
|
-
import express from "express";
|
|
3
|
-
import { Observable, throwError } from "rxjs";
|
|
4
|
-
|
|
5
|
-
import { ExceptionManager } from "../../utils/ExceptionManager";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}, 0);
|
|
40
|
-
return throwError(() => error);
|
|
41
|
-
}
|
|
1
|
+
import { HttpException } from "@nestjs/common";
|
|
2
|
+
import express from "express";
|
|
3
|
+
import { Observable, throwError } from "rxjs";
|
|
4
|
+
|
|
5
|
+
import { ExceptionManager } from "../../utils/ExceptionManager";
|
|
6
|
+
|
|
7
|
+
export function route_error(
|
|
8
|
+
request: express.Request,
|
|
9
|
+
error: any,
|
|
10
|
+
): Observable<never> {
|
|
11
|
+
error = (() => {
|
|
12
|
+
// HTTP-ERROR
|
|
13
|
+
if (error instanceof HttpException) return error;
|
|
14
|
+
|
|
15
|
+
// CUSTOM-REGISTERED ERROR
|
|
16
|
+
for (const [creator, closure] of ExceptionManager.tuples)
|
|
17
|
+
if (error instanceof creator) return closure(error);
|
|
18
|
+
|
|
19
|
+
// MAYBE INTERNAL ERROR
|
|
20
|
+
return error;
|
|
21
|
+
})();
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
error.method = request.method;
|
|
25
|
+
error.path = request.path;
|
|
26
|
+
} catch {}
|
|
27
|
+
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
for (const listener of ExceptionManager.listeners) {
|
|
30
|
+
try {
|
|
31
|
+
const res: any | Promise<any> = listener(error);
|
|
32
|
+
if (typeof res === "object" && typeof res.catch === "function")
|
|
33
|
+
res.catch(() => {});
|
|
34
|
+
} catch {}
|
|
35
|
+
}
|
|
36
|
+
}, 0);
|
|
37
|
+
return throwError(() => error);
|
|
38
|
+
}
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import { BadRequestException } from "@nestjs/common";
|
|
2
|
-
import { IValidation, TypeGuardError } from "typia";
|
|
3
|
-
|
|
4
|
-
import { IRequestBodyValidator } from "../../options/IRequestBodyValidator";
|
|
5
|
-
|
|
6
|
-
export const validate_request_body =
|
|
7
|
-
(method: string) =>
|
|
8
|
-
<T>(validator?: IRequestBodyValidator<T>) => {
|
|
9
|
-
if (!validator)
|
|
10
|
-
throw new Error(
|
|
11
|
-
`Error on nestia.core.${method}(): no transformer.`,
|
|
12
|
-
);
|
|
13
|
-
else if (validator.type === "assert") return assert(validator.assert);
|
|
14
|
-
else if (validator.type === "is") return is(validator.is);
|
|
15
|
-
else if (validator.type === "validate")
|
|
16
|
-
return validate(validator.validate);
|
|
17
|
-
throw new Error(
|
|
18
|
-
`Error on nestia.core.${method}(): invalid typed validator.`,
|
|
19
|
-
);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const assert =
|
|
23
|
-
<T>(closure: (data: T) => T) =>
|
|
24
|
-
(data: T) => {
|
|
25
|
-
try {
|
|
26
|
-
closure(data);
|
|
27
|
-
} catch (exp) {
|
|
28
|
-
if (exp instanceof TypeGuardError) {
|
|
29
|
-
throw new BadRequestException({
|
|
30
|
-
path: exp.path,
|
|
31
|
-
reason: exp.message,
|
|
32
|
-
expected: exp.expected,
|
|
33
|
-
value: exp.value,
|
|
34
|
-
message: MESSAGE,
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
throw exp;
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const is =
|
|
42
|
-
<T>(closure: (data: T) => boolean) =>
|
|
43
|
-
(data: T) => {
|
|
44
|
-
const success: boolean = closure(data);
|
|
45
|
-
if (success === false) throw new BadRequestException(MESSAGE);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const validate =
|
|
49
|
-
<T>(closure: (data: T) => IValidation<T>) =>
|
|
50
|
-
(data: T) => {
|
|
51
|
-
const result: IValidation<T> = closure(data);
|
|
52
|
-
if (result.success === false)
|
|
53
|
-
throw new BadRequestException({
|
|
54
|
-
errors: result.errors,
|
|
55
|
-
message: MESSAGE,
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const MESSAGE = "Request body data is not following the promised type.";
|
|
1
|
+
import { BadRequestException } from "@nestjs/common";
|
|
2
|
+
import { IValidation, TypeGuardError } from "typia";
|
|
3
|
+
|
|
4
|
+
import { IRequestBodyValidator } from "../../options/IRequestBodyValidator";
|
|
5
|
+
|
|
6
|
+
export const validate_request_body =
|
|
7
|
+
(method: string) =>
|
|
8
|
+
<T>(validator?: IRequestBodyValidator<T>) => {
|
|
9
|
+
if (!validator)
|
|
10
|
+
throw new Error(
|
|
11
|
+
`Error on nestia.core.${method}(): no transformer.`,
|
|
12
|
+
);
|
|
13
|
+
else if (validator.type === "assert") return assert(validator.assert);
|
|
14
|
+
else if (validator.type === "is") return is(validator.is);
|
|
15
|
+
else if (validator.type === "validate")
|
|
16
|
+
return validate(validator.validate);
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Error on nestia.core.${method}(): invalid typed validator.`,
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const assert =
|
|
23
|
+
<T>(closure: (data: T) => T) =>
|
|
24
|
+
(data: T) => {
|
|
25
|
+
try {
|
|
26
|
+
closure(data);
|
|
27
|
+
} catch (exp) {
|
|
28
|
+
if (exp instanceof TypeGuardError) {
|
|
29
|
+
throw new BadRequestException({
|
|
30
|
+
path: exp.path,
|
|
31
|
+
reason: exp.message,
|
|
32
|
+
expected: exp.expected,
|
|
33
|
+
value: exp.value,
|
|
34
|
+
message: MESSAGE,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
throw exp;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const is =
|
|
42
|
+
<T>(closure: (data: T) => boolean) =>
|
|
43
|
+
(data: T) => {
|
|
44
|
+
const success: boolean = closure(data);
|
|
45
|
+
if (success === false) throw new BadRequestException(MESSAGE);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const validate =
|
|
49
|
+
<T>(closure: (data: T) => IValidation<T>) =>
|
|
50
|
+
(data: T) => {
|
|
51
|
+
const result: IValidation<T> = closure(data);
|
|
52
|
+
if (result.success === false)
|
|
53
|
+
throw new BadRequestException({
|
|
54
|
+
errors: result.errors,
|
|
55
|
+
message: MESSAGE,
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const MESSAGE = "Request body data is not following the promised type.";
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as core from "./module";
|
|
2
|
-
|
|
3
|
-
export * from "./module";
|
|
4
|
-
|
|
5
|
-
export default core;
|
|
1
|
+
import * as core from "./module";
|
|
2
|
+
|
|
3
|
+
export * from "./module";
|
|
4
|
+
|
|
5
|
+
export default core;
|
package/src/module.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export * from "./decorators/
|
|
2
|
-
export * from "./decorators/
|
|
3
|
-
export * from "./decorators/
|
|
4
|
-
export * from "./decorators/
|
|
5
|
-
export * from "./
|
|
6
|
-
export * from "./
|
|
7
|
-
export * from "./decorators/
|
|
8
|
-
export * from "./decorators/
|
|
9
|
-
export * from "./decorators/
|
|
1
|
+
export * from "./decorators/DynamicModule";
|
|
2
|
+
export * from "./decorators/EncryptedBody";
|
|
3
|
+
export * from "./decorators/EncryptedController";
|
|
4
|
+
export * from "./decorators/EncryptedModule";
|
|
5
|
+
export * from "./decorators/EncryptedRoute";
|
|
6
|
+
export * from "./utils/ExceptionManager";
|
|
7
|
+
export * from "./decorators/PlainBody";
|
|
8
|
+
export * from "./decorators/TypedBody";
|
|
9
|
+
export * from "./decorators/TypedParam";
|
|
10
|
+
export * from "./decorators/TypedRoute";
|
|
11
|
+
export * from "./options/INestiaTransformOptions";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ITransformOptions } from "typia/lib/transformers/ITransformOptions";
|
|
2
|
-
|
|
3
|
-
export interface INestiaTransformOptions extends ITransformOptions {
|
|
4
|
-
validate?: "assert" | "is" | "validate";
|
|
5
|
-
stringify?: "stringify" | "assert" | "is" | "validate";
|
|
6
|
-
}
|
|
1
|
+
import { ITransformOptions } from "typia/lib/transformers/ITransformOptions";
|
|
2
|
+
|
|
3
|
+
export interface INestiaTransformOptions extends ITransformOptions {
|
|
4
|
+
validate?: "assert" | "is" | "validate";
|
|
5
|
+
stringify?: "stringify" | "assert" | "is" | "validate";
|
|
6
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { IProject } from "typia/lib/transformers/IProject";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { IProject } from "typia/lib/transformers/IProject";
|
|
2
|
+
|
|
3
|
+
import { INestiaTransformOptions } from "./INestiaTransformOptions";
|
|
4
|
+
|
|
5
|
+
export interface INestiaTransformProject extends Omit<IProject, "options"> {
|
|
6
|
+
options: INestiaTransformOptions;
|
|
7
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { IValidation } from "typia";
|
|
2
|
-
|
|
3
|
-
export type IRequestBodyValidator<T> =
|
|
4
|
-
| IRequestBodyValidator.IAssert<T>
|
|
5
|
-
| IRequestBodyValidator.IIs<T>
|
|
6
|
-
| IRequestBodyValidator.IValidate<T>;
|
|
7
|
-
export namespace IRequestBodyValidator {
|
|
8
|
-
export interface IAssert<T> {
|
|
9
|
-
type: "assert";
|
|
10
|
-
assert: (input: T) => T;
|
|
11
|
-
}
|
|
12
|
-
export interface IIs<T> {
|
|
13
|
-
type: "is";
|
|
14
|
-
is: (input: T) => boolean;
|
|
15
|
-
}
|
|
16
|
-
export interface IValidate<T> {
|
|
17
|
-
type: "validate";
|
|
18
|
-
validate: (input: T) => IValidation<T>;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
1
|
+
import { IValidation } from "typia";
|
|
2
|
+
|
|
3
|
+
export type IRequestBodyValidator<T> =
|
|
4
|
+
| IRequestBodyValidator.IAssert<T>
|
|
5
|
+
| IRequestBodyValidator.IIs<T>
|
|
6
|
+
| IRequestBodyValidator.IValidate<T>;
|
|
7
|
+
export namespace IRequestBodyValidator {
|
|
8
|
+
export interface IAssert<T> {
|
|
9
|
+
type: "assert";
|
|
10
|
+
assert: (input: T) => T;
|
|
11
|
+
}
|
|
12
|
+
export interface IIs<T> {
|
|
13
|
+
type: "is";
|
|
14
|
+
is: (input: T) => boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface IValidate<T> {
|
|
17
|
+
type: "validate";
|
|
18
|
+
validate: (input: T) => IValidation<T>;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { IValidation } from "typia";
|
|
2
|
-
|
|
3
|
-
export type IResponseBodyStringifier<T> =
|
|
4
|
-
| IResponseBodyStringifier.IStringify<T>
|
|
5
|
-
| IResponseBodyStringifier.IIs<T>
|
|
6
|
-
| IResponseBodyStringifier.IAssert<T>
|
|
7
|
-
| IResponseBodyStringifier.IValidate<T>;
|
|
8
|
-
export namespace IResponseBodyStringifier {
|
|
9
|
-
export interface IStringify<T> {
|
|
10
|
-
type: "stringify";
|
|
11
|
-
stringify: (input: T) => string;
|
|
12
|
-
}
|
|
13
|
-
export interface IIs<T> {
|
|
14
|
-
type: "is";
|
|
15
|
-
is: (input: T) => string | null;
|
|
16
|
-
}
|
|
17
|
-
export interface IAssert<T> {
|
|
18
|
-
type: "assert";
|
|
19
|
-
assert: (input: T) => string;
|
|
20
|
-
}
|
|
21
|
-
export interface IValidate<T> {
|
|
22
|
-
type: "validate";
|
|
23
|
-
validate: (input: T) => IValidation<string>;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
1
|
+
import { IValidation } from "typia";
|
|
2
|
+
|
|
3
|
+
export type IResponseBodyStringifier<T> =
|
|
4
|
+
| IResponseBodyStringifier.IStringify<T>
|
|
5
|
+
| IResponseBodyStringifier.IIs<T>
|
|
6
|
+
| IResponseBodyStringifier.IAssert<T>
|
|
7
|
+
| IResponseBodyStringifier.IValidate<T>;
|
|
8
|
+
export namespace IResponseBodyStringifier {
|
|
9
|
+
export interface IStringify<T> {
|
|
10
|
+
type: "stringify";
|
|
11
|
+
stringify: (input: T) => string;
|
|
12
|
+
}
|
|
13
|
+
export interface IIs<T> {
|
|
14
|
+
type: "is";
|
|
15
|
+
is: (input: T) => string | null;
|
|
16
|
+
}
|
|
17
|
+
export interface IAssert<T> {
|
|
18
|
+
type: "assert";
|
|
19
|
+
assert: (input: T) => string;
|
|
20
|
+
}
|
|
21
|
+
export interface IValidate<T> {
|
|
22
|
+
type: "validate";
|
|
23
|
+
validate: (input: T) => IValidation<string>;
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/transform.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
import { IProject } from "typia/lib/transformers/IProject";
|
|
3
|
-
|
|
4
|
-
import { INestiaTransformOptions } from "./options/INestiaTransformOptions";
|
|
5
|
-
import { FileTransformer } from "./transformers/FileTransformer";
|
|
6
|
-
|
|
7
|
-
export default function transform(
|
|
8
|
-
program: ts.Program,
|
|
9
|
-
options?: INestiaTransformOptions,
|
|
10
|
-
): ts.TransformerFactory<ts.SourceFile> {
|
|
11
|
-
const project: IProject = {
|
|
12
|
-
program,
|
|
13
|
-
compilerOptions: program.getCompilerOptions(),
|
|
14
|
-
checker: program.getTypeChecker(),
|
|
15
|
-
printer: ts.createPrinter(),
|
|
16
|
-
options: options || {},
|
|
17
|
-
};
|
|
18
|
-
return (context) => (file) =>
|
|
19
|
-
FileTransformer.transform(project, context, file);
|
|
20
|
-
}
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { IProject } from "typia/lib/transformers/IProject";
|
|
3
|
+
|
|
4
|
+
import { INestiaTransformOptions } from "./options/INestiaTransformOptions";
|
|
5
|
+
import { FileTransformer } from "./transformers/FileTransformer";
|
|
6
|
+
|
|
7
|
+
export default function transform(
|
|
8
|
+
program: ts.Program,
|
|
9
|
+
options?: INestiaTransformOptions,
|
|
10
|
+
): ts.TransformerFactory<ts.SourceFile> {
|
|
11
|
+
const project: IProject = {
|
|
12
|
+
program,
|
|
13
|
+
compilerOptions: program.getCompilerOptions(),
|
|
14
|
+
checker: program.getTypeChecker(),
|
|
15
|
+
printer: ts.createPrinter(),
|
|
16
|
+
options: options || {},
|
|
17
|
+
};
|
|
18
|
+
return (context) => (file) =>
|
|
19
|
+
FileTransformer.transform(project, context, file);
|
|
20
|
+
}
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import ts from "typescript";
|
|
3
|
-
import { AssertProgrammer } from "typia/lib/programmers/AssertProgrammer";
|
|
4
|
-
import { IsProgrammer } from "typia/lib/programmers/IsProgrammer";
|
|
5
|
-
import { ValidateProgrammer } from "typia/lib/programmers/ValidateProgrammer";
|
|
6
|
-
import { IProject } from "typia/lib/transformers/IProject";
|
|
7
|
-
|
|
8
|
-
import { INestiaTransformProject } from "../options/INestiaTransformProject";
|
|
9
|
-
|
|
10
|
-
export namespace BodyTransformer {
|
|
11
|
-
export function transform(
|
|
12
|
-
project: INestiaTransformProject,
|
|
13
|
-
type: ts.Type,
|
|
14
|
-
decorator: ts.Decorator,
|
|
15
|
-
): ts.Decorator {
|
|
16
|
-
if (!ts.isCallExpression(decorator.expression)) return decorator;
|
|
17
|
-
return ts.factory.createDecorator(
|
|
18
|
-
validate(project, type, decorator.expression),
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function validate(
|
|
23
|
-
project: INestiaTransformProject,
|
|
24
|
-
type: ts.Type,
|
|
25
|
-
expression: ts.CallExpression,
|
|
26
|
-
): ts.LeftHandSideExpression {
|
|
27
|
-
// CHECK SIGNATURE
|
|
28
|
-
const signature: ts.Signature | undefined =
|
|
29
|
-
project.checker.getResolvedSignature(expression);
|
|
30
|
-
if (!signature || !signature.declaration) return expression;
|
|
31
|
-
|
|
32
|
-
// CHECK TO BE TRANSFORMED
|
|
33
|
-
const validate: boolean = (() => {
|
|
34
|
-
// CHECK FILENAME
|
|
35
|
-
const location: string = path.resolve(
|
|
36
|
-
signature.declaration.getSourceFile().fileName,
|
|
37
|
-
);
|
|
38
|
-
if (
|
|
39
|
-
LIB_PATHS.every((str) => location.indexOf(str) === -1) &&
|
|
40
|
-
SRC_PATHS.every((str) => location !== str)
|
|
41
|
-
)
|
|
42
|
-
return false;
|
|
43
|
-
|
|
44
|
-
// CHECK DUPLICATED TRANSFORMATION
|
|
45
|
-
return expression.arguments.length === 0;
|
|
46
|
-
})();
|
|
47
|
-
if (validate === false) return expression;
|
|
48
|
-
|
|
49
|
-
// CHECK TYPE NODE
|
|
50
|
-
const typeNode: ts.TypeNode | undefined =
|
|
51
|
-
project.checker.typeToTypeNode(type, undefined, undefined);
|
|
52
|
-
if (typeNode === undefined) return expression;
|
|
53
|
-
|
|
54
|
-
//----
|
|
55
|
-
// TRANSFORMATION
|
|
56
|
-
//----
|
|
57
|
-
// GENERATE VALIDATION PLAN
|
|
58
|
-
const parameter = (
|
|
59
|
-
key: string,
|
|
60
|
-
programmer: (
|
|
61
|
-
project: IProject,
|
|
62
|
-
modulo: ts.LeftHandSideExpression,
|
|
63
|
-
) => (type: ts.Type) => ts.ArrowFunction,
|
|
64
|
-
) =>
|
|
65
|
-
ts.factory.createObjectLiteralExpression([
|
|
66
|
-
ts.factory.createPropertyAssignment(
|
|
67
|
-
ts.factory.createIdentifier("type"),
|
|
68
|
-
ts.factory.createStringLiteral(key),
|
|
69
|
-
),
|
|
70
|
-
ts.factory.createPropertyAssignment(
|
|
71
|
-
ts.factory.createIdentifier(key),
|
|
72
|
-
programmer(project, expression.expression)(type),
|
|
73
|
-
),
|
|
74
|
-
]);
|
|
75
|
-
const validator: ts.ObjectLiteralExpression = (() => {
|
|
76
|
-
if (project.options.validate === "is")
|
|
77
|
-
return parameter("is", IsProgrammer.generate);
|
|
78
|
-
else if (project.options.validate === "validate")
|
|
79
|
-
return parameter("validate", ValidateProgrammer.generate);
|
|
80
|
-
return parameter("assert", AssertProgrammer.generate);
|
|
81
|
-
})();
|
|
82
|
-
|
|
83
|
-
// UPDATE DECORATOR FUNCTION CALL
|
|
84
|
-
return ts.factory.updateCallExpression(
|
|
85
|
-
expression,
|
|
86
|
-
expression.expression,
|
|
87
|
-
expression.typeArguments,
|
|
88
|
-
[validator],
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const CLASSES = ["EncryptedBody", "TypedBody"];
|
|
93
|
-
const LIB_PATHS = CLASSES.map((cla) =>
|
|
94
|
-
path.join(
|
|
95
|
-
"node_modules",
|
|
96
|
-
"@nestia",
|
|
97
|
-
"core",
|
|
98
|
-
"lib",
|
|
99
|
-
"decorators",
|
|
100
|
-
`${cla}.d.ts`,
|
|
101
|
-
),
|
|
102
|
-
);
|
|
103
|
-
const SRC_PATHS = CLASSES.map((cla) =>
|
|
104
|
-
path.resolve(path.join(__dirname, "..", "decorators", `${cla}.ts`)),
|
|
105
|
-
);
|
|
106
|
-
}
|
|
1
|
+
import path from "path";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
import { AssertProgrammer } from "typia/lib/programmers/AssertProgrammer";
|
|
4
|
+
import { IsProgrammer } from "typia/lib/programmers/IsProgrammer";
|
|
5
|
+
import { ValidateProgrammer } from "typia/lib/programmers/ValidateProgrammer";
|
|
6
|
+
import { IProject } from "typia/lib/transformers/IProject";
|
|
7
|
+
|
|
8
|
+
import { INestiaTransformProject } from "../options/INestiaTransformProject";
|
|
9
|
+
|
|
10
|
+
export namespace BodyTransformer {
|
|
11
|
+
export function transform(
|
|
12
|
+
project: INestiaTransformProject,
|
|
13
|
+
type: ts.Type,
|
|
14
|
+
decorator: ts.Decorator,
|
|
15
|
+
): ts.Decorator {
|
|
16
|
+
if (!ts.isCallExpression(decorator.expression)) return decorator;
|
|
17
|
+
return ts.factory.createDecorator(
|
|
18
|
+
validate(project, type, decorator.expression),
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function validate(
|
|
23
|
+
project: INestiaTransformProject,
|
|
24
|
+
type: ts.Type,
|
|
25
|
+
expression: ts.CallExpression,
|
|
26
|
+
): ts.LeftHandSideExpression {
|
|
27
|
+
// CHECK SIGNATURE
|
|
28
|
+
const signature: ts.Signature | undefined =
|
|
29
|
+
project.checker.getResolvedSignature(expression);
|
|
30
|
+
if (!signature || !signature.declaration) return expression;
|
|
31
|
+
|
|
32
|
+
// CHECK TO BE TRANSFORMED
|
|
33
|
+
const validate: boolean = (() => {
|
|
34
|
+
// CHECK FILENAME
|
|
35
|
+
const location: string = path.resolve(
|
|
36
|
+
signature.declaration.getSourceFile().fileName,
|
|
37
|
+
);
|
|
38
|
+
if (
|
|
39
|
+
LIB_PATHS.every((str) => location.indexOf(str) === -1) &&
|
|
40
|
+
SRC_PATHS.every((str) => location !== str)
|
|
41
|
+
)
|
|
42
|
+
return false;
|
|
43
|
+
|
|
44
|
+
// CHECK DUPLICATED TRANSFORMATION
|
|
45
|
+
return expression.arguments.length === 0;
|
|
46
|
+
})();
|
|
47
|
+
if (validate === false) return expression;
|
|
48
|
+
|
|
49
|
+
// CHECK TYPE NODE
|
|
50
|
+
const typeNode: ts.TypeNode | undefined =
|
|
51
|
+
project.checker.typeToTypeNode(type, undefined, undefined);
|
|
52
|
+
if (typeNode === undefined) return expression;
|
|
53
|
+
|
|
54
|
+
//----
|
|
55
|
+
// TRANSFORMATION
|
|
56
|
+
//----
|
|
57
|
+
// GENERATE VALIDATION PLAN
|
|
58
|
+
const parameter = (
|
|
59
|
+
key: string,
|
|
60
|
+
programmer: (
|
|
61
|
+
project: IProject,
|
|
62
|
+
modulo: ts.LeftHandSideExpression,
|
|
63
|
+
) => (type: ts.Type) => ts.ArrowFunction,
|
|
64
|
+
) =>
|
|
65
|
+
ts.factory.createObjectLiteralExpression([
|
|
66
|
+
ts.factory.createPropertyAssignment(
|
|
67
|
+
ts.factory.createIdentifier("type"),
|
|
68
|
+
ts.factory.createStringLiteral(key),
|
|
69
|
+
),
|
|
70
|
+
ts.factory.createPropertyAssignment(
|
|
71
|
+
ts.factory.createIdentifier(key),
|
|
72
|
+
programmer(project, expression.expression)(type),
|
|
73
|
+
),
|
|
74
|
+
]);
|
|
75
|
+
const validator: ts.ObjectLiteralExpression = (() => {
|
|
76
|
+
if (project.options.validate === "is")
|
|
77
|
+
return parameter("is", IsProgrammer.generate);
|
|
78
|
+
else if (project.options.validate === "validate")
|
|
79
|
+
return parameter("validate", ValidateProgrammer.generate);
|
|
80
|
+
return parameter("assert", AssertProgrammer.generate);
|
|
81
|
+
})();
|
|
82
|
+
|
|
83
|
+
// UPDATE DECORATOR FUNCTION CALL
|
|
84
|
+
return ts.factory.updateCallExpression(
|
|
85
|
+
expression,
|
|
86
|
+
expression.expression,
|
|
87
|
+
expression.typeArguments,
|
|
88
|
+
[validator],
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const CLASSES = ["EncryptedBody", "TypedBody"];
|
|
93
|
+
const LIB_PATHS = CLASSES.map((cla) =>
|
|
94
|
+
path.join(
|
|
95
|
+
"node_modules",
|
|
96
|
+
"@nestia",
|
|
97
|
+
"core",
|
|
98
|
+
"lib",
|
|
99
|
+
"decorators",
|
|
100
|
+
`${cla}.d.ts`,
|
|
101
|
+
),
|
|
102
|
+
);
|
|
103
|
+
const SRC_PATHS = CLASSES.map((cla) =>
|
|
104
|
+
path.resolve(path.join(__dirname, "..", "decorators", `${cla}.ts`)),
|
|
105
|
+
);
|
|
106
|
+
}
|