@nestia/core 2.0.0-dev.20230831-5 → 2.0.0-dev.20230831-6

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 (62) hide show
  1. package/lib/decorators/EncryptedRoute.js +10 -7
  2. package/lib/decorators/EncryptedRoute.js.map +1 -1
  3. package/lib/decorators/TypedHeaders.js +2 -2
  4. package/lib/decorators/TypedHeaders.js.map +1 -1
  5. package/lib/decorators/TypedParam.d.ts +14 -13
  6. package/lib/decorators/TypedParam.js +16 -48
  7. package/lib/decorators/TypedParam.js.map +1 -1
  8. package/lib/decorators/TypedQuery.d.ts +2 -3
  9. package/lib/decorators/TypedQuery.js +4 -5
  10. package/lib/decorators/TypedQuery.js.map +1 -1
  11. package/lib/decorators/TypedRoute.js +8 -5
  12. package/lib/decorators/TypedRoute.js.map +1 -1
  13. package/lib/decorators/internal/{TransformError.js → NoTransformConfigureError.js} +4 -4
  14. package/lib/decorators/internal/NoTransformConfigureError.js.map +1 -0
  15. package/lib/decorators/internal/get_path_and_stringify.js +2 -2
  16. package/lib/decorators/internal/get_path_and_stringify.js.map +1 -1
  17. package/lib/decorators/internal/validate_request_body.js +2 -2
  18. package/lib/decorators/internal/validate_request_body.js.map +1 -1
  19. package/lib/programmers/PlainBodyProgrammer.js +17 -13
  20. package/lib/programmers/PlainBodyProgrammer.js.map +1 -1
  21. package/lib/programmers/TypedHeadersProgrammer.d.ts +3 -0
  22. package/lib/programmers/TypedHeadersProgrammer.js +86 -136
  23. package/lib/programmers/TypedHeadersProgrammer.js.map +1 -1
  24. package/lib/programmers/TypedParamProgrammer.d.ts +3 -1
  25. package/lib/programmers/TypedParamProgrammer.js +74 -67
  26. package/lib/programmers/TypedParamProgrammer.js.map +1 -1
  27. package/lib/programmers/TypedQueryProgrammer.d.ts +3 -0
  28. package/lib/programmers/TypedQueryProgrammer.js +88 -149
  29. package/lib/programmers/TypedQueryProgrammer.js.map +1 -1
  30. package/lib/programmers/TypedRouteProgrammer.js +8 -8
  31. package/lib/programmers/TypedRouteProgrammer.js.map +1 -1
  32. package/lib/programmers/internal/CoreMetadataUtil.d.ts +5 -0
  33. package/lib/programmers/internal/CoreMetadataUtil.js +44 -0
  34. package/lib/programmers/internal/CoreMetadataUtil.js.map +1 -0
  35. package/lib/transform.d.ts +2 -1
  36. package/lib/transform.js +11 -3
  37. package/lib/transform.js.map +1 -1
  38. package/lib/transformers/FileTransformer.d.ts +1 -1
  39. package/lib/transformers/FileTransformer.js +16 -1
  40. package/lib/transformers/FileTransformer.js.map +1 -1
  41. package/lib/transformers/ParameterDecoratorTransformer.js +3 -1
  42. package/lib/transformers/ParameterDecoratorTransformer.js.map +1 -1
  43. package/package.json +5 -5
  44. package/src/decorators/EncryptedRoute.ts +9 -12
  45. package/src/decorators/TypedHeaders.ts +2 -2
  46. package/src/decorators/TypedParam.ts +30 -51
  47. package/src/decorators/TypedQuery.ts +4 -5
  48. package/src/decorators/TypedRoute.ts +5 -10
  49. package/src/decorators/internal/{TransformError.ts → NoTransformConfigureError.ts} +1 -1
  50. package/src/decorators/internal/get_path_and_stringify.ts +2 -2
  51. package/src/decorators/internal/validate_request_body.ts +2 -2
  52. package/src/programmers/PlainBodyProgrammer.ts +24 -19
  53. package/src/programmers/TypedHeadersProgrammer.ts +100 -106
  54. package/src/programmers/TypedParamProgrammer.ts +113 -79
  55. package/src/programmers/TypedQueryProgrammer.ts +115 -114
  56. package/src/programmers/TypedRouteProgrammer.ts +11 -8
  57. package/src/programmers/internal/CoreMetadataUtil.ts +21 -0
  58. package/src/transform.ts +14 -5
  59. package/src/transformers/FileTransformer.ts +7 -2
  60. package/src/transformers/ParameterDecoratorTransformer.ts +2 -1
  61. package/lib/decorators/internal/TransformError.js.map +0 -1
  62. /package/lib/decorators/internal/{TransformError.d.ts → NoTransformConfigureError.d.ts} +0 -0
@@ -1,101 +1,135 @@
1
1
  import ts from "typescript";
2
2
 
3
+ import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
3
4
  import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
4
5
  import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
5
- import { Metadata } from "typia/lib/metadata/Metadata";
6
+ import { IsProgrammer } from "typia/lib/programmers/IsProgrammer";
7
+ import { Metadata } from "typia/lib/schemas/metadata/Metadata";
8
+ import { TransformerError } from "typia/lib/transformers/TransformerError";
6
9
 
7
10
  import { INestiaTransformProject } from "../options/INestiaTransformProject";
11
+ import { CoreMetadataUtil } from "./internal/CoreMetadataUtil";
8
12
 
9
13
  export namespace TypedParamProgrammer {
10
14
  export const generate =
11
- ({ checker }: INestiaTransformProject) =>
15
+ (project: INestiaTransformProject) =>
16
+ (modulo: ts.LeftHandSideExpression) =>
12
17
  (parameters: readonly ts.Expression[]) =>
13
18
  (type: ts.Type): readonly ts.Expression[] => {
14
- const metadata: Metadata = MetadataFactory.analyze(checker)({
15
- resolve: false,
16
- constant: true,
17
- absorb: true,
18
- })(new MetadataCollection())(type);
19
- validate(metadata);
20
- const [atomic] = get_atomic_types(metadata);
21
-
22
- // AUTO TYPE SPECIFICATION
23
- if (parameters.length === 1)
24
- return [
25
- parameters[0],
26
- ts.factory.createStringLiteral(atomic),
27
- metadata.nullable
28
- ? ts.factory.createTrue()
29
- : ts.factory.createFalse(),
30
- ];
19
+ // ALREADY BEING TRANSFORMED
20
+ if (parameters.length !== 1) return parameters;
31
21
 
32
- // TYPE HAS BEEN SPECIFIED IN DECORATOR
33
- const specified: Metadata = MetadataFactory.analyze(checker)({
34
- resolve: false,
22
+ const result = MetadataFactory.analyze(project.checker)({
23
+ escape: false,
35
24
  constant: true,
36
25
  absorb: true,
37
- })(new MetadataCollection())(
38
- checker.getTypeAtLocation(parameters[1]),
39
- );
40
- if (equals(atomic, specified) === false)
41
- throw error("different type between parameter and variable");
42
-
43
- if (parameters.length === 2)
44
- return [
45
- parameters[0],
46
- parameters[1],
47
- metadata.nullable
48
- ? ts.factory.createTrue()
49
- : ts.factory.createFalse(),
50
- ];
51
-
52
- // NULLABLE HAS BEEN SPECIFIED
53
- const nullable: Metadata = MetadataFactory.analyze(checker)({
54
- resolve: false,
55
- constant: true,
56
- absorb: true,
57
- })(new MetadataCollection())(
58
- checker.getTypeAtLocation(parameters[2]),
59
- );
60
- if (nullable.getName() !== "true" && nullable.getName() !== "false")
61
- throw error("nullable value must be literal type");
62
- else if (metadata.nullable !== (nullable.getName() === "true"))
63
- throw error(
64
- "different type (nullable) between parameter and variable",
26
+ validate,
27
+ })(new MetadataCollection())(type);
28
+ if (result.success === false)
29
+ throw TransformerError.from("@core.nestia.TypedParam")(
30
+ result.errors,
65
31
  );
66
- return parameters;
32
+ const [atomic] = [...CoreMetadataUtil.atomics(result.data)];
33
+ const name: string = result.data.getName();
34
+ const is: ts.ArrowFunction = IsProgrammer.write({
35
+ ...project,
36
+ options: {
37
+ numeric: true,
38
+ },
39
+ })(modulo)(false)(type);
40
+ const cast: ts.ArrowFunction = CASTERS[atomic]();
41
+
42
+ return [
43
+ parameters[0],
44
+ ts.factory.createObjectLiteralExpression(
45
+ [
46
+ ts.factory.createPropertyAssignment(
47
+ "name",
48
+ ts.factory.createIdentifier(name),
49
+ ),
50
+ ts.factory.createPropertyAssignment("is", is),
51
+ ts.factory.createPropertyAssignment("cast", cast),
52
+ ],
53
+ true,
54
+ ),
55
+ ];
67
56
  };
68
- }
69
57
 
70
- const validate = (meta: Metadata) => {
71
- if (meta.any) throw error("do not allow any type");
72
- else if (meta.isRequired() === false)
73
- throw error("do not allow undefindable type");
58
+ export const validate = (meta: Metadata): string[] => {
59
+ const errors: string[] = [];
60
+ const insert = (msg: string) => errors.push(msg);
74
61
 
75
- const atomics: string[] = get_atomic_types(meta);
76
- const expected: number =
77
- meta.atomics.length +
78
- meta.templates.length +
79
- meta.constants.map((c) => c.values.length).reduce((a, b) => a + b, 0);
80
- if (meta.size() !== expected || atomics.length === 0)
81
- throw error("only atomic or constant types is allowed");
82
- else if (atomics.length > 1) throw error("do not allow union type");
83
- };
62
+ if (meta.any) insert("do not allow any type");
63
+ if (meta.isRequired() === false)
64
+ insert("do not allow undefindable type");
84
65
 
85
- const get_atomic_types = (meta: Metadata): string[] => [
86
- ...new Set([
87
- ...meta.atomics,
88
- ...meta.constants.map((c) => c.type),
89
- ...(meta.templates.length ? ["string"] : []),
90
- ]),
91
- ];
66
+ const atomics = CoreMetadataUtil.atomics(meta);
67
+ const expected: number =
68
+ meta.atomics.length +
69
+ meta.templates.length +
70
+ meta.constants
71
+ .map((c) => c.values.length)
72
+ .reduce((a, b) => a + b, 0);
73
+ if (meta.size() !== expected || atomics.size === 0)
74
+ insert("only atomic or constant types are allowed");
75
+ if (atomics.size > 1) insert("do not allow union type");
92
76
 
93
- const error = (message: string) =>
94
- new Error(`Error on nestia.core.TypedParam(): ${message}.`);
77
+ return errors;
78
+ };
79
+ }
95
80
 
96
- const equals = (atomic: string, p: Metadata) => {
97
- const name: string = p.getName();
98
- if (atomic === "string")
99
- return name === `"string"` || name === `"uuid"` || name === `"date"`;
100
- return `"${atomic}"` === name;
81
+ const CASTERS = {
82
+ boolean: () =>
83
+ ts.factory.createArrowFunction(
84
+ undefined,
85
+ undefined,
86
+ [IdentifierFactory.parameter("str")],
87
+ undefined,
88
+ undefined,
89
+ ts.factory.createLogicalOr(
90
+ ts.factory.createStrictEquality(
91
+ ts.factory.createStringLiteral("true"),
92
+ ts.factory.createIdentifier("str"),
93
+ ),
94
+ ts.factory.createStrictEquality(
95
+ ts.factory.createStringLiteral("1"),
96
+ ts.factory.createIdentifier("str"),
97
+ ),
98
+ ),
99
+ ),
100
+ number: () =>
101
+ ts.factory.createArrowFunction(
102
+ undefined,
103
+ undefined,
104
+ [IdentifierFactory.parameter("str")],
105
+ undefined,
106
+ undefined,
107
+ ts.factory.createCallExpression(
108
+ ts.factory.createIdentifier("Number"),
109
+ undefined,
110
+ [ts.factory.createIdentifier("str")],
111
+ ),
112
+ ),
113
+ bigint: () =>
114
+ ts.factory.createArrowFunction(
115
+ undefined,
116
+ undefined,
117
+ [IdentifierFactory.parameter("str")],
118
+ undefined,
119
+ undefined,
120
+ ts.factory.createCallExpression(
121
+ ts.factory.createIdentifier("BigInt"),
122
+ undefined,
123
+ [ts.factory.createIdentifier("str")],
124
+ ),
125
+ ),
126
+ string: () =>
127
+ ts.factory.createArrowFunction(
128
+ undefined,
129
+ undefined,
130
+ [IdentifierFactory.parameter("str")],
131
+ undefined,
132
+ undefined,
133
+ ts.factory.createIdentifier("str"),
134
+ ),
101
135
  };
@@ -4,15 +4,18 @@ import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
4
  import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
5
5
  import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
6
6
  import { StatementFactory } from "typia/lib/factories/StatementFactory";
7
- import { Metadata } from "typia/lib/metadata/Metadata";
8
- import { MetadataObject } from "typia/lib/metadata/MetadataObject";
9
- import { MetadataProperty } from "typia/lib/metadata/MetadataProperty";
10
7
  import { AssertProgrammer } from "typia/lib/programmers/AssertProgrammer";
11
8
  import { FunctionImporter } from "typia/lib/programmers/helpers/FunctionImporeter";
9
+ import { Metadata } from "typia/lib/schemas/metadata/Metadata";
10
+ import { MetadataArray } from "typia/lib/schemas/metadata/MetadataArray";
11
+ import { MetadataObject } from "typia/lib/schemas/metadata/MetadataObject";
12
+ import { MetadataProperty } from "typia/lib/schemas/metadata/MetadataProperty";
13
+ import { TransformerError } from "typia/lib/transformers/TransformerError";
12
14
  import { Atomic } from "typia/lib/typings/Atomic";
13
15
  import { Escaper } from "typia/lib/utils/Escaper";
14
16
 
15
17
  import { INestiaTransformProject } from "../options/INestiaTransformProject";
18
+ import { CoreMetadataUtil } from "./internal/CoreMetadataUtil";
16
19
 
17
20
  export namespace TypedQueryProgrammer {
18
21
  export const generate =
@@ -23,107 +26,95 @@ export namespace TypedQueryProgrammer {
23
26
  return decode(project, modulo)(type, object);
24
27
  };
25
28
 
29
+ export const validate = (
30
+ meta: Metadata,
31
+ explore: MetadataFactory.IExplore,
32
+ ): string[] => {
33
+ const errors: string[] = [];
34
+ const insert = (msg: string) => errors.push(msg);
35
+
36
+ if (explore.top === true) {
37
+ // TOP MUST BE ONLY OBJECT
38
+ if (meta.objects.length !== 1 || meta.bucket() !== 1)
39
+ insert("only one object type is allowed.");
40
+ if (meta.nullable === true)
41
+ insert("query parameters cannot be null.");
42
+ if (meta.isRequired() === false)
43
+ insert("query parameters cannot be undefined.");
44
+ } else if (
45
+ explore.nested !== null &&
46
+ explore.nested instanceof MetadataArray
47
+ ) {
48
+ const atomics = CoreMetadataUtil.atomics(meta);
49
+ const expected: number =
50
+ meta.atomics.length +
51
+ meta.templates.length +
52
+ meta.constants
53
+ .map((c) => c.values.length)
54
+ .reduce((a, b) => a + b, 0);
55
+ if (atomics.size > 1) insert("union type is not allowed in array.");
56
+ if (meta.nullable) insert("nullable type is not allowed in array.");
57
+ if (meta.isRequired() === false)
58
+ insert("optional type is not allowed in array.");
59
+ if (meta.size() !== expected)
60
+ insert("only atomic or constant types are allowed in array.");
61
+ } else if (explore.object && explore.property !== null) {
62
+ //----
63
+ // COMMON
64
+ //----
65
+ // PROPERTY MUST BE SOLE
66
+ if (typeof explore.property === "object")
67
+ insert("dynamic property is not allowed.");
68
+ // MUST BE LOWER-CASE
69
+ if (
70
+ typeof explore.property === "string" &&
71
+ explore.property !== explore.property.toLowerCase()
72
+ )
73
+ insert("property name must be lower-case.");
74
+ // DO NOT ALLOW TUPLE TYPE
75
+ if (meta.tuples.length) insert("tuple type is not allowed.");
76
+ // DO NOT ALLOW UNION TYPE
77
+ if (CoreMetadataUtil.isUnion(meta))
78
+ insert("union type is not allowed.");
79
+ // DO NOT ALLOW NESTED OBJECT
80
+ if (
81
+ meta.objects.length ||
82
+ meta.sets.length ||
83
+ meta.maps.length ||
84
+ meta.natives.length
85
+ )
86
+ insert("nested object type is not allowed.");
87
+
88
+ //----
89
+ // ARRAY CASES
90
+ //----
91
+ const isArray: boolean =
92
+ meta.arrays.length > 1 || meta.tuples.length > 1;
93
+ // ARRAY TYPE MUST BE REQUIRED
94
+ if (isArray && meta.isRequired() === false)
95
+ insert("optional type is not allowed when array.");
96
+ // SET-COOKIE MUST BE ARRAY
97
+ if (explore.property === "set-cookie" && !isArray)
98
+ insert("set-cookie property must be array.");
99
+ }
100
+ return errors;
101
+ };
102
+
26
103
  const getObject =
27
104
  (checker: ts.TypeChecker) =>
28
105
  (type: ts.Type): MetadataObject => {
29
106
  const collection: MetadataCollection = new MetadataCollection();
30
- const metadata: Metadata = MetadataFactory.analyze(checker)({
31
- resolve: false,
107
+ const result = MetadataFactory.analyze(checker)({
108
+ escape: false,
32
109
  constant: true,
33
110
  absorb: true,
111
+ validate,
34
112
  })(collection)(type);
35
- if (metadata.objects.length !== 1 || metadata.bucket() !== 1)
36
- throw new Error(
37
- ErrorMessages.object(metadata)(
38
- "only one object type is allowed.",
39
- ),
40
- );
41
- else if (metadata.nullable === true)
42
- throw new Error(
43
- ErrorMessages.object(metadata)(
44
- "query parameter cannot be null.",
45
- ),
46
- );
47
- else if (metadata.isRequired() === false)
48
- throw new Error(
49
- ErrorMessages.object(metadata)(
50
- "query parameter cannot be undefined.",
51
- ),
113
+ if (result.success === false)
114
+ throw TransformerError.from("@core.nestia.TypedHeaders")(
115
+ result.errors,
52
116
  );
53
-
54
- const object: MetadataObject = metadata.objects[0]!;
55
- if (object.properties.some((p) => !(p.key as any).isSoleLiteral()))
56
- throw new Error(
57
- ErrorMessages.object(metadata)(
58
- "dynamic property is not allowed.",
59
- ),
60
- );
61
-
62
- for (const property of object.properties) {
63
- const key: string = property.key.constants[0]
64
- .values[0] as string;
65
- const value: Metadata = property.value;
66
- validate(object)(key)(value, 0);
67
- }
68
- return object;
69
- };
70
-
71
- const validate =
72
- (obj: MetadataObject) =>
73
- (key: string) =>
74
- (value: Metadata, depth: number): string[] => {
75
- if (depth === 1 && value.isRequired() === false)
76
- throw new Error(
77
- ErrorMessages.property(obj)(key)(
78
- "optional type is not allowed in array.",
79
- ),
80
- );
81
- else if (
82
- value.maps.length ||
83
- value.sets.length ||
84
- value.objects.length
85
- )
86
- throw new Error(
87
- ErrorMessages.property(obj)(key)(
88
- "object type is not allowed",
89
- ),
90
- );
91
-
92
- const atom: string[] = [];
93
- for (const type of value.atomics) atom.push(type);
94
- for (const { type } of value.constants) atom.push(type);
95
-
96
- if (depth === 0 && (value.arrays.length || value.arrays.length)) {
97
- if (atom.length)
98
- throw new Error(
99
- ErrorMessages.property(obj)(key)(
100
- "union type is not allowed",
101
- ),
102
- );
103
- for (const array of value.arrays)
104
- atom.push(...validate(obj)(key)(array.value, depth + 1));
105
- for (const tuple of value.tuples)
106
- for (const elem of tuple.elements)
107
- atom.push(...validate(obj)(key)(elem, depth + 1));
108
- } else if (value.arrays.length || value.tuples.length)
109
- throw new Error(
110
- ErrorMessages.property(obj)(key)(
111
- "double-array type is not allowed",
112
- ),
113
- );
114
-
115
- const size: number = new Set(atom).size;
116
- if (size === 0)
117
- throw new Error(
118
- ErrorMessages.property(obj)(key)("unknown type"),
119
- );
120
- else if (size > 1)
121
- throw new Error(
122
- ErrorMessages.property(obj)(key)(
123
- "union type is not allowed",
124
- ),
125
- );
126
- return atom;
117
+ return result.data.objects[0]!;
127
118
  };
128
119
 
129
120
  const decode =
@@ -150,7 +141,9 @@ export namespace TypedQueryProgrammer {
150
141
  })(modulo)(false)(type);
151
142
  const output: ts.Identifier = ts.factory.createIdentifier("output");
152
143
 
153
- const importer: FunctionImporter = new FunctionImporter();
144
+ const importer: FunctionImporter = new FunctionImporter(
145
+ "TypedQuery",
146
+ );
154
147
  const optionalArrays: string[] = [];
155
148
  const statements: ts.Statement[] = [
156
149
  StatementFactory.constant(
@@ -204,14 +197,15 @@ export namespace TypedQueryProgrammer {
204
197
 
205
198
  const [type, isArray]: [Atomic.Literal, boolean] = value.atomics
206
199
  .length
207
- ? [value.atomics[0], false]
200
+ ? [value.atomics[0].type, false]
208
201
  : value.constants.length
209
202
  ? [value.constants[0]!.type, false]
210
203
  : (() => {
211
204
  const meta =
212
- value.arrays[0]?.value ?? value.tuples[0].elements[0];
205
+ value.arrays[0]?.type.value ??
206
+ value.tuples[0].type.elements[0];
213
207
  return meta.atomics.length
214
- ? [meta.atomics[0], true]
208
+ ? [meta.atomics[0].type, true]
215
209
  : [meta.constants[0]!.type, true];
216
210
  })();
217
211
  return ts.factory.createPropertyAssignment(
@@ -235,13 +229,16 @@ export namespace TypedQueryProgrammer {
235
229
  [IdentifierFactory.parameter("elem")],
236
230
  undefined,
237
231
  undefined,
238
- decode_value(importer)(type)(
232
+ decode_value(importer)(type)(false)(
239
233
  ts.factory.createIdentifier("elem"),
240
234
  ),
241
235
  ),
242
236
  ],
243
237
  )
244
238
  : decode_value(importer)(type)(
239
+ value.nullable === false &&
240
+ value.isRequired() === false,
241
+ )(
245
242
  ts.factory.createCallExpression(
246
243
  ts.factory.createIdentifier("input.get"),
247
244
  undefined,
@@ -254,17 +251,21 @@ export namespace TypedQueryProgrammer {
254
251
  const decode_value =
255
252
  (importer: FunctionImporter) =>
256
253
  (type: Atomic.Literal) =>
257
- (value: ts.Expression) =>
258
- ts.factory.createCallExpression(importer.use(type), undefined, [
259
- value,
260
- ]);
261
- }
262
-
263
- namespace ErrorMessages {
264
- export const object = (type: Metadata) => (message: string) =>
265
- `Error on nestia.core.TypedQuery<${type.getName()}>(): ${message}`;
266
-
267
- export const property =
268
- (obj: MetadataObject) => (key: string) => (message: string) =>
269
- `Error on nestia.core.TypedQuery<${obj.name}>(): property "${key}" - ${message}`;
254
+ (onlyUndefindable: boolean) =>
255
+ (value: ts.Expression) => {
256
+ const call = ts.factory.createCallExpression(
257
+ importer.use(type),
258
+ undefined,
259
+ [value],
260
+ );
261
+ return onlyUndefindable
262
+ ? ts.factory.createBinaryExpression(
263
+ call,
264
+ ts.factory.createToken(
265
+ ts.SyntaxKind.QuestionQuestionToken,
266
+ ),
267
+ ts.factory.createIdentifier("undefined"),
268
+ )
269
+ : call;
270
+ };
270
271
  }
@@ -1,9 +1,9 @@
1
1
  import ts from "typescript";
2
2
 
3
- import { AssertStringifyProgrammer } from "typia/lib/programmers/AssertStringifyProgrammer";
4
- import { IsStringifyProgrammer } from "typia/lib/programmers/IsStringifyProgrammer";
5
- import { StringifyProgrammer } from "typia/lib/programmers/StringifyProgrammer";
6
- import { ValidateStringifyProgrammer } from "typia/lib/programmers/ValidateStringifyProgrammer";
3
+ import { JsonAssertStringifyProgrammer } from "typia/lib/programmers/json/JsonAssertStringifyProgrammer";
4
+ import { JsonIsStringifyProgrammer } from "typia/lib/programmers/json/JsonIsStringifyProgrammer";
5
+ import { JsonStringifyProgrammer } from "typia/lib/programmers/json/JsonStringifyProgrammer";
6
+ import { JsonValidateStringifyProgrammer } from "typia/lib/programmers/json/JsonValidateStringifyProgrammer";
7
7
  import { IProject } from "typia/lib/transformers/IProject";
8
8
 
9
9
  import { INestiaTransformProject } from "../options/INestiaTransformProject";
@@ -38,15 +38,18 @@ export namespace TypedRouteProgrammer {
38
38
 
39
39
  // RETURNS
40
40
  if (project.options.stringify === "is")
41
- return parameter("is", IsStringifyProgrammer.write);
41
+ return parameter("is", JsonIsStringifyProgrammer.write);
42
42
  else if (project.options.stringify === "validate")
43
- return parameter("validate", ValidateStringifyProgrammer.write);
43
+ return parameter(
44
+ "validate",
45
+ JsonValidateStringifyProgrammer.write,
46
+ );
44
47
  else if (project.options.stringify === "stringify")
45
- return parameter("stringify", StringifyProgrammer.write);
48
+ return parameter("stringify", JsonStringifyProgrammer.write);
46
49
  else if (project.options.stringify === null)
47
50
  return ts.factory.createNull();
48
51
 
49
52
  // ASSERT IS DEFAULT
50
- return parameter("assert", AssertStringifyProgrammer.write);
53
+ return parameter("assert", JsonAssertStringifyProgrammer.write);
51
54
  };
52
55
  }
@@ -0,0 +1,21 @@
1
+ import { Metadata } from "typia/lib/schemas/metadata/Metadata";
2
+
3
+ export namespace CoreMetadataUtil {
4
+ export const atomics = (
5
+ meta: Metadata,
6
+ ): Set<"boolean" | "bigint" | "number" | "string"> =>
7
+ new Set([
8
+ ...meta.atomics.map((a) => a.type),
9
+ ...meta.constants.map((c) => c.type),
10
+ ...(meta.templates.length ? (["string"] as const) : []),
11
+ ]);
12
+
13
+ export const isUnion = (meta: Metadata): boolean =>
14
+ atomics(meta).size +
15
+ meta.arrays.length +
16
+ meta.tuples.length +
17
+ meta.natives.length +
18
+ meta.maps.length +
19
+ meta.objects.length >
20
+ 1;
21
+ }
package/src/transform.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import ts from "typescript";
2
2
 
3
+ import { IProject } from "typia/lib/transformers/IProject";
4
+
3
5
  import { INestiaTransformOptions } from "./options/INestiaTransformOptions";
4
6
  import { FileTransformer } from "./transformers/FileTransformer";
5
7
 
6
8
  export const transform = (
7
9
  program: ts.Program,
8
- options?: INestiaTransformOptions,
10
+ options: INestiaTransformOptions | undefined,
11
+ extras: IProject["extras"],
9
12
  ): ts.TransformerFactory<ts.SourceFile> => {
10
13
  const compilerOptions: ts.CompilerOptions = program.getCompilerOptions();
11
14
  const strict: boolean =
@@ -13,15 +16,21 @@ export const transform = (
13
16
  ? !!compilerOptions.strictNullChecks
14
17
  : !!compilerOptions.strict;
15
18
  if (strict === false)
16
- throw new Error(
17
- `Error on "tsconfig.json": nestia requires \`compilerOptions.strictNullChecks\` to be true.`,
18
- );
19
+ extras.addDiagnostic({
20
+ category: ts.DiagnosticCategory.Error,
21
+ code: "(@nestia/core)" as any,
22
+ file: undefined,
23
+ start: undefined,
24
+ length: undefined,
25
+ messageText: "strict mode is required.",
26
+ });
19
27
  return FileTransformer.transform({
20
28
  program,
21
29
  compilerOptions,
22
30
  checker: program.getTypeChecker(),
23
31
  printer: ts.createPrinter(),
24
- options: options || {},
32
+ options: options ?? {},
33
+ extras,
25
34
  });
26
35
  };
27
36
  export default transform;
@@ -5,12 +5,16 @@ import { NodeTransformer } from "./NodeTransformer";
5
5
 
6
6
  export namespace FileTransformer {
7
7
  export const transform =
8
- (project: INestiaTransformProject) =>
8
+ (project: Omit<INestiaTransformProject, "context">) =>
9
9
  (context: ts.TransformationContext) =>
10
10
  (file: ts.SourceFile): ts.SourceFile =>
11
11
  ts.visitEachChild(
12
12
  file,
13
- (node) => iterate_node(project)(context)(node),
13
+ (node) =>
14
+ iterate_node({
15
+ ...project,
16
+ context,
17
+ })(context)(node),
14
18
  context,
15
19
  );
16
20
 
@@ -27,6 +31,7 @@ export namespace FileTransformer {
27
31
  const try_transform_node =
28
32
  (project: INestiaTransformProject) =>
29
33
  (node: ts.Node): ts.Node => {
34
+ if (!node) return node;
30
35
  try {
31
36
  return NodeTransformer.transform(project)(node);
32
37
  } catch (exp) {
@@ -83,7 +83,8 @@ const FUNCTORS: Record<string, Programmer> = {
83
83
  parameters.length
84
84
  ? parameters
85
85
  : [TypedHeadersProgrammer.generate(project)(modulo)(type)],
86
- TypedParam: (project) => () => TypedParamProgrammer.generate(project),
86
+ TypedParam: (project) => (modulo) =>
87
+ TypedParamProgrammer.generate(project)(modulo),
87
88
  TypedQuery: (project) => (modulo) => (parameters) => (type) =>
88
89
  parameters.length
89
90
  ? parameters
@@ -1 +0,0 @@
1
- {"version":3,"file":"TransformError.js","sourceRoot":"","sources":["../../../src/decorators/internal/TransformError.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,SAAgB,cAAc,CAAC,MAAc;IACzC,OAAO,IAAI,KAAK,CACZ,+BAAwB,MAAM,wJAAmJ,CACpL,CAAC;AACN,CAAC;AAJD,wCAIC"}