typia 6.7.3-dev.20240808 → 6.8.0-dev.20240811

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 (109) hide show
  1. package/lib/factories/TypeFactory.d.ts +0 -2
  2. package/lib/factories/TypeFactory.js +4 -83
  3. package/lib/factories/TypeFactory.js.map +1 -1
  4. package/lib/factories/internal/metadata/emplace_metadata_array_type.js +1 -5
  5. package/lib/factories/internal/metadata/emplace_metadata_array_type.js.map +1 -1
  6. package/lib/factories/internal/metadata/emplace_metadata_object.js +3 -4
  7. package/lib/factories/internal/metadata/emplace_metadata_object.js.map +1 -1
  8. package/lib/factories/internal/metadata/iterate_metadata.js +1 -2
  9. package/lib/factories/internal/metadata/iterate_metadata.js.map +1 -1
  10. package/lib/factories/internal/metadata/iterate_metadata_array.js +1 -2
  11. package/lib/factories/internal/metadata/iterate_metadata_array.js.map +1 -1
  12. package/lib/factories/internal/metadata/iterate_metadata_atomic.js +1 -1
  13. package/lib/factories/internal/metadata/iterate_metadata_atomic.js.map +1 -1
  14. package/lib/factories/internal/metadata/iterate_metadata_coalesce.js +1 -1
  15. package/lib/factories/internal/metadata/iterate_metadata_coalesce.js.map +1 -1
  16. package/lib/factories/internal/metadata/iterate_metadata_constant.js +2 -3
  17. package/lib/factories/internal/metadata/iterate_metadata_constant.js.map +1 -1
  18. package/lib/factories/internal/metadata/iterate_metadata_intersection.js +2 -3
  19. package/lib/factories/internal/metadata/iterate_metadata_intersection.js.map +1 -1
  20. package/lib/factories/internal/metadata/iterate_metadata_map.js +1 -1
  21. package/lib/factories/internal/metadata/iterate_metadata_map.js.map +1 -1
  22. package/lib/factories/internal/metadata/iterate_metadata_native.js +1 -1
  23. package/lib/factories/internal/metadata/iterate_metadata_native.js.map +1 -1
  24. package/lib/factories/internal/metadata/iterate_metadata_object.js +2 -3
  25. package/lib/factories/internal/metadata/iterate_metadata_object.js.map +1 -1
  26. package/lib/factories/internal/metadata/iterate_metadata_set.js +1 -1
  27. package/lib/factories/internal/metadata/iterate_metadata_set.js.map +1 -1
  28. package/lib/factories/internal/metadata/iterate_metadata_template.js +1 -1
  29. package/lib/factories/internal/metadata/iterate_metadata_template.js.map +1 -1
  30. package/lib/factories/internal/metadata/iterate_metadata_union.js +1 -2
  31. package/lib/factories/internal/metadata/iterate_metadata_union.js.map +1 -1
  32. package/lib/programmers/internal/application_bigint.d.ts +1 -0
  33. package/lib/programmers/internal/application_bigint.js +14 -0
  34. package/lib/programmers/internal/application_bigint.js.map +1 -0
  35. package/lib/programmers/internal/application_v30_schema.js +10 -12
  36. package/lib/programmers/internal/application_v30_schema.js.map +1 -1
  37. package/lib/programmers/internal/application_v31_constant.js +3 -1
  38. package/lib/programmers/internal/application_v31_constant.js.map +1 -1
  39. package/lib/programmers/internal/application_v31_schema.js +10 -12
  40. package/lib/programmers/internal/application_v31_schema.js.map +1 -1
  41. package/lib/tags/Constant.d.ts +2 -2
  42. package/lib/tags/Default.d.ts +5 -1
  43. package/lib/tags/ExclusiveMaximum.d.ts +9 -5
  44. package/lib/tags/ExclusiveMinimum.d.ts +9 -5
  45. package/lib/tags/JsonSchemaPlugin.d.ts +1 -1
  46. package/lib/tags/Maximum.d.ts +8 -5
  47. package/lib/tags/Minimum.d.ts +8 -5
  48. package/lib/tags/MultipleOf.d.ts +7 -4
  49. package/lib/transformers/features/CreateRandomTransformer.js +1 -2
  50. package/lib/transformers/features/CreateRandomTransformer.js.map +1 -1
  51. package/lib/transformers/features/RandomTransformer.js +1 -2
  52. package/lib/transformers/features/RandomTransformer.js.map +1 -1
  53. package/lib/transformers/features/json/JsonApplicationTransformer.js +4 -5
  54. package/lib/transformers/features/json/JsonApplicationTransformer.js.map +1 -1
  55. package/lib/transformers/features/misc/MiscLiteralsTransformer.js +1 -2
  56. package/lib/transformers/features/misc/MiscLiteralsTransformer.js.map +1 -1
  57. package/lib/transformers/features/protobuf/ProtobufMessageTransformer.js +1 -2
  58. package/lib/transformers/features/protobuf/ProtobufMessageTransformer.js.map +1 -1
  59. package/lib/transformers/features/reflect/ReflectMetadataTransformer.js +1 -2
  60. package/lib/transformers/features/reflect/ReflectMetadataTransformer.js.map +1 -1
  61. package/lib/transformers/internal/GenericTransformer.js +2 -3
  62. package/lib/transformers/internal/GenericTransformer.js.map +1 -1
  63. package/package.json +2 -2
  64. package/src/factories/CommentFactory.ts +79 -79
  65. package/src/factories/MetadataCollection.ts +274 -274
  66. package/src/factories/MetadataFactory.ts +272 -272
  67. package/src/factories/TypeFactory.ts +118 -190
  68. package/src/factories/internal/metadata/emplace_metadata_array_type.ts +42 -42
  69. package/src/factories/internal/metadata/emplace_metadata_object.ts +176 -179
  70. package/src/factories/internal/metadata/iterate_metadata.ts +94 -96
  71. package/src/factories/internal/metadata/iterate_metadata_array.ts +63 -64
  72. package/src/factories/internal/metadata/iterate_metadata_atomic.ts +62 -62
  73. package/src/factories/internal/metadata/iterate_metadata_coalesce.ts +33 -33
  74. package/src/factories/internal/metadata/iterate_metadata_constant.ts +76 -77
  75. package/src/factories/internal/metadata/iterate_metadata_intersection.ts +213 -214
  76. package/src/factories/internal/metadata/iterate_metadata_map.ts +50 -50
  77. package/src/factories/internal/metadata/iterate_metadata_native.ts +220 -217
  78. package/src/factories/internal/metadata/iterate_metadata_object.ts +33 -34
  79. package/src/factories/internal/metadata/iterate_metadata_set.ts +41 -41
  80. package/src/factories/internal/metadata/iterate_metadata_template.ts +44 -44
  81. package/src/factories/internal/metadata/iterate_metadata_union.ts +27 -29
  82. package/src/programmers/internal/application_bigint.ts +25 -0
  83. package/src/programmers/internal/application_v30_alias.ts +52 -52
  84. package/src/programmers/internal/application_v30_object.ts +149 -149
  85. package/src/programmers/internal/application_v30_schema.ts +162 -159
  86. package/src/programmers/internal/application_v30_tuple.ts +33 -33
  87. package/src/programmers/internal/application_v31_constant.ts +4 -1
  88. package/src/programmers/internal/application_v31_schema.ts +159 -157
  89. package/src/programmers/json/JsonApplicationProgrammer.ts +82 -82
  90. package/src/tags/Constant.ts +2 -2
  91. package/src/tags/Default.ts +7 -3
  92. package/src/tags/ExclusiveMaximum.ts +12 -6
  93. package/src/tags/ExclusiveMinimum.ts +12 -6
  94. package/src/tags/JsonSchemaPlugin.ts +1 -1
  95. package/src/tags/Maximum.ts +9 -8
  96. package/src/tags/Minimum.ts +9 -8
  97. package/src/tags/MultipleOf.ts +9 -8
  98. package/src/transformers/FileTransformer.ts +91 -91
  99. package/src/transformers/features/CreateRandomTransformer.ts +40 -42
  100. package/src/transformers/features/RandomTransformer.ts +44 -46
  101. package/src/transformers/features/json/JsonApplicationTransformer.ts +124 -126
  102. package/src/transformers/features/misc/MiscLiteralsTransformer.ts +32 -34
  103. package/src/transformers/features/protobuf/ProtobufMessageTransformer.ts +33 -35
  104. package/src/transformers/features/reflect/ReflectMetadataTransformer.ts +62 -64
  105. package/src/transformers/internal/GenericTransformer.ts +2 -4
  106. package/lib/utils/TypePredicator.d.ts +0 -10
  107. package/lib/utils/TypePredicator.js +0 -36
  108. package/lib/utils/TypePredicator.js.map +0 -1
  109. package/src/utils/TypePredicator.ts +0 -32
@@ -4,17 +4,18 @@ export type MultipleOf<Value extends number | bigint> = TagBase<{
4
4
  target: Value extends bigint ? "bigint" : "number";
5
5
  kind: "multipleOf";
6
6
  value: Value;
7
- validate: `$input % ${Numeric<Value>} === ${Value extends bigint
8
- ? Numeric<0n>
7
+ validate: `$input % ${Cast<Value>} === ${Value extends bigint
8
+ ? Cast<0n>
9
9
  : 0}`;
10
10
  exclusive: true;
11
- schema: Value extends number
12
- ? {
13
- multipleOf: Value;
14
- }
15
- : undefined;
11
+ schema: Value extends bigint
12
+ ? { multipleOf: Numeric<Value> }
13
+ : { multipleOf: Value };
16
14
  }>;
17
15
 
18
- type Numeric<Value extends number | bigint> = Value extends number
16
+ type Cast<Value extends number | bigint> = Value extends number
19
17
  ? Value
20
18
  : `BigInt(${Value})`;
19
+ type Numeric<T extends bigint> = `${T}` extends `${infer N extends number}`
20
+ ? N
21
+ : never;
@@ -1,91 +1,91 @@
1
- import ts from "typescript";
2
-
3
- import { Singleton } from "../utils/Singleton";
4
-
5
- import { IProject } from "./IProject";
6
- import { NodeTransformer } from "./NodeTransformer";
7
- import { TransformerError } from "./TransformerError";
8
-
9
- export namespace FileTransformer {
10
- export const transform =
11
- (environments: Omit<IProject, "context">) =>
12
- (context: ts.TransformationContext) =>
13
- (file: ts.SourceFile): ts.SourceFile => {
14
- if (file.isDeclarationFile) return file;
15
-
16
- const project: IProject = {
17
- ...environments,
18
- context,
19
- };
20
- checkJsDocParsingMode.get(project, file);
21
-
22
- return ts.visitEachChild(
23
- file,
24
- (node) => iterate_node(project)(node),
25
- context,
26
- );
27
- };
28
-
29
- const iterate_node =
30
- (project: IProject) =>
31
- (node: ts.Node): ts.Node =>
32
- ts.visitEachChild(
33
- try_transform_node(project)(node) ?? node,
34
- (child) => iterate_node(project)(child),
35
- project.context,
36
- );
37
-
38
- const try_transform_node =
39
- (project: IProject) =>
40
- (node: ts.Node): ts.Node | null => {
41
- try {
42
- return NodeTransformer.transform(project)(node);
43
- } catch (exp) {
44
- // ONLY ACCEPT TRANSFORMER-ERROR
45
- if (!isTransformerError(exp)) throw exp;
46
-
47
- // REPORT DIAGNOSTIC
48
- const diagnostic = ts.createDiagnosticForNode(node, {
49
- key: exp.code,
50
- category: ts.DiagnosticCategory.Error,
51
- message: exp.message,
52
- code: `(${exp.code})` as any,
53
- });
54
- project.extras.addDiagnostic(diagnostic);
55
- return null;
56
- }
57
- };
58
- }
59
-
60
- const isTransformerError = (error: any): error is TransformerError =>
61
- typeof error === "object" &&
62
- error !== null &&
63
- error.constructor.name === "TransformerError" &&
64
- typeof error.code === "string" &&
65
- typeof error.message === "string";
66
-
67
- const checkJsDocParsingMode = new Singleton(
68
- (project: IProject, file: ts.SourceFile) => {
69
- if (
70
- typeof file.jsDocParsingMode === "number" &&
71
- file.jsDocParsingMode !== 0
72
- ) {
73
- project.extras.addDiagnostic(
74
- ts.createDiagnosticForNode(file, {
75
- code: `(typia setup)` as any,
76
- key: "jsDocParsingMode",
77
- category: ts.DiagnosticCategory.Warning,
78
- message: [
79
- `Run "npx typia setup" or "npx typia patch" command again.`,
80
- ``,
81
- `Since TypeScript v5.3 update, "tsc" no more parses JSDoc comments. Therefore, "typia" also cannot utilize those JSDoc comments too, and it damages on some features of "typia" like "comment tags" or "JSON schema" generator.`,
82
- ``,
83
- `To solve this problem, run "npx typia setup" or "npx typia patch" command to hack the TypeScript compiler to revive the JSDoc parsing feature.`,
84
- ``,
85
- ` - reference: https://github.com/microsoft/TypeScript/pull/55739`,
86
- ].join("\n"),
87
- }),
88
- );
89
- }
90
- },
91
- );
1
+ import ts from "typescript";
2
+
3
+ import { Singleton } from "../utils/Singleton";
4
+
5
+ import { IProject } from "./IProject";
6
+ import { NodeTransformer } from "./NodeTransformer";
7
+ import { TransformerError } from "./TransformerError";
8
+
9
+ export namespace FileTransformer {
10
+ export const transform =
11
+ (environments: Omit<IProject, "context">) =>
12
+ (context: ts.TransformationContext) =>
13
+ (file: ts.SourceFile): ts.SourceFile => {
14
+ if (file.isDeclarationFile) return file;
15
+
16
+ const project: IProject = {
17
+ ...environments,
18
+ context,
19
+ };
20
+ checkJsDocParsingMode.get(project, file);
21
+
22
+ return ts.visitEachChild(
23
+ file,
24
+ (node) => iterate_node(project)(node),
25
+ context,
26
+ );
27
+ };
28
+
29
+ const iterate_node =
30
+ (project: IProject) =>
31
+ (node: ts.Node): ts.Node =>
32
+ ts.visitEachChild(
33
+ try_transform_node(project)(node) ?? node,
34
+ (child) => iterate_node(project)(child),
35
+ project.context,
36
+ );
37
+
38
+ const try_transform_node =
39
+ (project: IProject) =>
40
+ (node: ts.Node): ts.Node | null => {
41
+ try {
42
+ return NodeTransformer.transform(project)(node);
43
+ } catch (exp) {
44
+ // ONLY ACCEPT TRANSFORMER-ERROR
45
+ if (!isTransformerError(exp)) throw exp;
46
+
47
+ // REPORT DIAGNOSTIC
48
+ const diagnostic = ts.createDiagnosticForNode(node, {
49
+ key: exp.code,
50
+ category: ts.DiagnosticCategory.Error,
51
+ message: exp.message,
52
+ code: `(${exp.code})` as any,
53
+ });
54
+ project.extras.addDiagnostic(diagnostic);
55
+ return null;
56
+ }
57
+ };
58
+ }
59
+
60
+ const isTransformerError = (error: any): error is TransformerError =>
61
+ typeof error === "object" &&
62
+ error !== null &&
63
+ error.constructor.name === "TransformerError" &&
64
+ typeof error.code === "string" &&
65
+ typeof error.message === "string";
66
+
67
+ const checkJsDocParsingMode = new Singleton(
68
+ (project: IProject, file: ts.SourceFile) => {
69
+ if (
70
+ typeof file.jsDocParsingMode === "number" &&
71
+ file.jsDocParsingMode !== 0
72
+ ) {
73
+ project.extras.addDiagnostic(
74
+ ts.createDiagnosticForNode(file, {
75
+ code: `(typia setup)` as any,
76
+ key: "jsDocParsingMode",
77
+ category: ts.DiagnosticCategory.Warning,
78
+ message: [
79
+ `Run "npx typia setup" or "npx typia patch" command again.`,
80
+ ``,
81
+ `Since TypeScript v5.3 update, "tsc" no more parses JSDoc comments. Therefore, "typia" also cannot utilize those JSDoc comments too, and it damages on some features of "typia" like "comment tags" or "JSON schema" generator.`,
82
+ ``,
83
+ `To solve this problem, run "npx typia setup" or "npx typia patch" command to hack the TypeScript compiler to revive the JSDoc parsing feature.`,
84
+ ``,
85
+ ` - reference: https://github.com/microsoft/TypeScript/pull/55739`,
86
+ ].join("\n"),
87
+ }),
88
+ );
89
+ }
90
+ },
91
+ );
@@ -1,42 +1,40 @@
1
- import ts from "typescript";
2
-
3
- import { RandomProgrammer } from "../../programmers/RandomProgrammer";
4
-
5
- import { TypePredicator } from "../../utils/TypePredicator";
6
-
7
- import { IProject } from "../IProject";
8
- import { TransformerError } from "../TransformerError";
9
-
10
- export namespace CreateRandomTransformer {
11
- export const transform =
12
- (project: IProject) =>
13
- (modulo: ts.LeftHandSideExpression) =>
14
- (expression: ts.CallExpression): ts.Expression => {
15
- // CHECK GENERIC ARGUMENT EXISTENCE
16
- if (!expression.typeArguments?.[0])
17
- throw new TransformerError({
18
- code: "typia.createRandom",
19
- message: "generic argument is not specified.",
20
- });
21
-
22
- // GET TYPE INFO
23
- const node: ts.TypeNode = expression.typeArguments[0];
24
- const type: ts.Type = project.checker.getTypeFromTypeNode(node);
25
-
26
- if (TypePredicator.isTypeParameter(type))
27
- throw new TransformerError({
28
- code: "typia.createRandom",
29
- message: "non-specified generic argument.",
30
- });
31
-
32
- // DO TRANSFORM
33
- return RandomProgrammer.write({
34
- ...project,
35
- options: {
36
- ...project.options,
37
- functional: false,
38
- numeric: false,
39
- },
40
- })(modulo)(expression.arguments?.[0])(type, node.getFullText().trim());
41
- };
42
- }
1
+ import ts from "typescript";
2
+
3
+ import { RandomProgrammer } from "../../programmers/RandomProgrammer";
4
+
5
+ import { IProject } from "../IProject";
6
+ import { TransformerError } from "../TransformerError";
7
+
8
+ export namespace CreateRandomTransformer {
9
+ export const transform =
10
+ (project: IProject) =>
11
+ (modulo: ts.LeftHandSideExpression) =>
12
+ (expression: ts.CallExpression): ts.Expression => {
13
+ // CHECK GENERIC ARGUMENT EXISTENCE
14
+ if (!expression.typeArguments?.[0])
15
+ throw new TransformerError({
16
+ code: "typia.createRandom",
17
+ message: "generic argument is not specified.",
18
+ });
19
+
20
+ // GET TYPE INFO
21
+ const node: ts.TypeNode = expression.typeArguments[0];
22
+ const type: ts.Type = project.checker.getTypeFromTypeNode(node);
23
+
24
+ if (type.isTypeParameter())
25
+ throw new TransformerError({
26
+ code: "typia.createRandom",
27
+ message: "non-specified generic argument.",
28
+ });
29
+
30
+ // DO TRANSFORM
31
+ return RandomProgrammer.write({
32
+ ...project,
33
+ options: {
34
+ ...project.options,
35
+ functional: false,
36
+ numeric: false,
37
+ },
38
+ })(modulo)(expression.arguments?.[0])(type, node.getFullText().trim());
39
+ };
40
+ }
@@ -1,46 +1,44 @@
1
- import ts from "typescript";
2
-
3
- import { RandomProgrammer } from "../../programmers/RandomProgrammer";
4
-
5
- import { TypePredicator } from "../../utils/TypePredicator";
6
-
7
- import { IProject } from "../IProject";
8
- import { TransformerError } from "../TransformerError";
9
-
10
- export namespace RandomTransformer {
11
- export const transform =
12
- (project: IProject) =>
13
- (modulo: ts.LeftHandSideExpression) =>
14
- (expression: ts.CallExpression): ts.Expression => {
15
- // CHECK GENERIC ARGUMENT EXISTENCE
16
- if (!expression.typeArguments?.[0])
17
- throw new TransformerError({
18
- code: `typia.${modulo.getText()}`,
19
- message: "generic argument is not specified.",
20
- });
21
-
22
- // GET TYPE INFO
23
- const node: ts.TypeNode = expression.typeArguments[0];
24
- const type: ts.Type = project.checker.getTypeFromTypeNode(node);
25
-
26
- if (TypePredicator.isTypeParameter(type))
27
- throw new TransformerError({
28
- code: `typia.${modulo.getText()}`,
29
- message: "non-specified generic argument.",
30
- });
31
-
32
- // DO TRANSFORM
33
- return ts.factory.createCallExpression(
34
- RandomProgrammer.write({
35
- ...project,
36
- options: {
37
- ...project.options,
38
- functional: false,
39
- numeric: false,
40
- },
41
- })(modulo)()(type, node.getFullText().trim()),
42
- undefined,
43
- expression.arguments.length ? [expression.arguments[0]!] : undefined,
44
- );
45
- };
46
- }
1
+ import ts from "typescript";
2
+
3
+ import { RandomProgrammer } from "../../programmers/RandomProgrammer";
4
+
5
+ import { IProject } from "../IProject";
6
+ import { TransformerError } from "../TransformerError";
7
+
8
+ export namespace RandomTransformer {
9
+ export const transform =
10
+ (project: IProject) =>
11
+ (modulo: ts.LeftHandSideExpression) =>
12
+ (expression: ts.CallExpression): ts.Expression => {
13
+ // CHECK GENERIC ARGUMENT EXISTENCE
14
+ if (!expression.typeArguments?.[0])
15
+ throw new TransformerError({
16
+ code: `typia.${modulo.getText()}`,
17
+ message: "generic argument is not specified.",
18
+ });
19
+
20
+ // GET TYPE INFO
21
+ const node: ts.TypeNode = expression.typeArguments[0];
22
+ const type: ts.Type = project.checker.getTypeFromTypeNode(node);
23
+
24
+ if (type.isTypeParameter())
25
+ throw new TransformerError({
26
+ code: `typia.${modulo.getText()}`,
27
+ message: "non-specified generic argument.",
28
+ });
29
+
30
+ // DO TRANSFORM
31
+ return ts.factory.createCallExpression(
32
+ RandomProgrammer.write({
33
+ ...project,
34
+ options: {
35
+ ...project.options,
36
+ functional: false,
37
+ numeric: false,
38
+ },
39
+ })(modulo)()(type, node.getFullText().trim()),
40
+ undefined,
41
+ expression.arguments.length ? [expression.arguments[0]!] : undefined,
42
+ );
43
+ };
44
+ }
@@ -1,126 +1,124 @@
1
- import ts from "typescript";
2
-
3
- import { LiteralFactory } from "../../../factories/LiteralFactory";
4
- import { MetadataCollection } from "../../../factories/MetadataCollection";
5
- import { MetadataFactory } from "../../../factories/MetadataFactory";
6
-
7
- import { IJsonApplication } from "../../../schemas/json/IJsonApplication";
8
- import { Metadata } from "../../../schemas/metadata/Metadata";
9
-
10
- import { JsonApplicationProgrammer } from "../../../programmers/json/JsonApplicationProgrammer";
11
-
12
- import { ValidationPipe } from "../../../typings/ValidationPipe";
13
-
14
- import { TypePredicator } from "../../../utils/TypePredicator";
15
-
16
- import { IProject } from "../../IProject";
17
- import { TransformerError } from "../../TransformerError";
18
-
19
- export namespace JsonApplicationTransformer {
20
- export const transform =
21
- (project: IProject) =>
22
- (expression: ts.CallExpression): ts.Expression => {
23
- if (!expression.typeArguments?.length)
24
- throw new TransformerError({
25
- code: "typia.json.application",
26
- message: "no generic argument.",
27
- });
28
-
29
- //----
30
- // GET ARGUMENTS
31
- //----
32
- // VALIDATE TUPLE ARGUMENTS
33
- const top: ts.Node = expression.typeArguments[0]!;
34
- if (!ts.isTupleTypeNode(top)) return expression;
35
- else if (top.elements.some((child) => !ts.isTypeNode(child)))
36
- return expression;
37
-
38
- // GET TYPES
39
- const types: ts.Type[] = top.elements.map((child) =>
40
- project.checker.getTypeFromTypeNode(child as ts.TypeNode),
41
- );
42
- if (types.some(TypePredicator.isTypeParameter))
43
- throw new TransformerError({
44
- code: "typia.json.application",
45
- message: "non-specified generic argument(s).",
46
- });
47
-
48
- // ADDITIONAL PARAMETERS
49
- const version: "3.0" | "3.1" = get_parameter<"3.0" | "3.1">({
50
- checker: project.checker,
51
- name: "Version",
52
- is: (str) => str === "3.0" || str === "3.1",
53
- cast: (str) => str as "3.0" | "3.1",
54
- default: () => "3.1",
55
- })(expression.typeArguments[1]);
56
-
57
- //----
58
- // GENERATORS
59
- //----
60
- // METADATA
61
- const collection: MetadataCollection = new MetadataCollection({
62
- replace: MetadataCollection.replace,
63
- });
64
- const results: ValidationPipe<Metadata, MetadataFactory.IError>[] =
65
- types.map((type) =>
66
- MetadataFactory.analyze(
67
- project.checker,
68
- project.context,
69
- )({
70
- escape: true,
71
- constant: true,
72
- absorb: false,
73
- validate: JsonApplicationProgrammer.validate,
74
- })(collection)(type),
75
- );
76
-
77
- // REPORT BUG IF REQUIRED
78
- const metadatas: Metadata[] = [];
79
- const errors: MetadataFactory.IError[] = [];
80
- for (const r of results) {
81
- if (r.success === false) errors.push(...r.errors);
82
- else metadatas.push(r.data);
83
- }
84
- if (errors.length)
85
- throw TransformerError.from("typia.json.application")(errors);
86
-
87
- // APPLICATION
88
- const app: IJsonApplication<any> =
89
- JsonApplicationProgrammer.write(version)(metadatas);
90
- return LiteralFactory.generate(app);
91
- };
92
-
93
- const get_parameter =
94
- <Value>(props: {
95
- checker: ts.TypeChecker;
96
- name: string;
97
- is: (value: string) => boolean;
98
- cast: (value: string) => Value;
99
- default: () => Value;
100
- }) =>
101
- (node: ts.TypeNode | undefined): Value => {
102
- if (!node) return props.default();
103
-
104
- // CHECK LITERAL TYPE
105
- const type: ts.Type = props.checker.getTypeFromTypeNode(node);
106
- if (
107
- !TypePredicator.isLiteral(type) &&
108
- (type.flags & ts.TypeFlags.BooleanLiteral) === 0
109
- )
110
- throw new TransformerError({
111
- code: "typia.json.application",
112
- message: `generic argument "${props.name}" must be constant.`,
113
- });
114
-
115
- // GET VALUE AND VALIDATE IT
116
- const value = TypePredicator.isLiteral(type)
117
- ? type.value
118
- : props.checker.typeToString(type);
119
- if (typeof value !== "string" || props.is(value) === false)
120
- throw new TransformerError({
121
- code: "typia.json.application",
122
- message: `invalid value on generic argument "${props.name}".`,
123
- });
124
- return props.cast(value);
125
- };
126
- }
1
+ import ts from "typescript";
2
+
3
+ import { LiteralFactory } from "../../../factories/LiteralFactory";
4
+ import { MetadataCollection } from "../../../factories/MetadataCollection";
5
+ import { MetadataFactory } from "../../../factories/MetadataFactory";
6
+
7
+ import { IJsonApplication } from "../../../schemas/json/IJsonApplication";
8
+ import { Metadata } from "../../../schemas/metadata/Metadata";
9
+
10
+ import { JsonApplicationProgrammer } from "../../../programmers/json/JsonApplicationProgrammer";
11
+
12
+ import { ValidationPipe } from "../../../typings/ValidationPipe";
13
+
14
+ import { IProject } from "../../IProject";
15
+ import { TransformerError } from "../../TransformerError";
16
+
17
+ export namespace JsonApplicationTransformer {
18
+ export const transform =
19
+ (project: IProject) =>
20
+ (expression: ts.CallExpression): ts.Expression => {
21
+ if (!expression.typeArguments?.length)
22
+ throw new TransformerError({
23
+ code: "typia.json.application",
24
+ message: "no generic argument.",
25
+ });
26
+
27
+ //----
28
+ // GET ARGUMENTS
29
+ //----
30
+ // VALIDATE TUPLE ARGUMENTS
31
+ const top: ts.Node = expression.typeArguments[0]!;
32
+ if (!ts.isTupleTypeNode(top)) return expression;
33
+ else if (top.elements.some((child) => !ts.isTypeNode(child)))
34
+ return expression;
35
+
36
+ // GET TYPES
37
+ const types: ts.Type[] = top.elements.map((child) =>
38
+ project.checker.getTypeFromTypeNode(child as ts.TypeNode),
39
+ );
40
+ if (types.some((t) => t.isTypeParameter()))
41
+ throw new TransformerError({
42
+ code: "typia.json.application",
43
+ message: "non-specified generic argument(s).",
44
+ });
45
+
46
+ // ADDITIONAL PARAMETERS
47
+ const version: "3.0" | "3.1" = get_parameter<"3.0" | "3.1">({
48
+ checker: project.checker,
49
+ name: "Version",
50
+ is: (str) => str === "3.0" || str === "3.1",
51
+ cast: (str) => str as "3.0" | "3.1",
52
+ default: () => "3.1",
53
+ })(expression.typeArguments[1]);
54
+
55
+ //----
56
+ // GENERATORS
57
+ //----
58
+ // METADATA
59
+ const collection: MetadataCollection = new MetadataCollection({
60
+ replace: MetadataCollection.replace,
61
+ });
62
+ const results: ValidationPipe<Metadata, MetadataFactory.IError>[] =
63
+ types.map((type) =>
64
+ MetadataFactory.analyze(
65
+ project.checker,
66
+ project.context,
67
+ )({
68
+ escape: true,
69
+ constant: true,
70
+ absorb: false,
71
+ validate: JsonApplicationProgrammer.validate,
72
+ })(collection)(type),
73
+ );
74
+
75
+ // REPORT BUG IF REQUIRED
76
+ const metadatas: Metadata[] = [];
77
+ const errors: MetadataFactory.IError[] = [];
78
+ for (const r of results) {
79
+ if (r.success === false) errors.push(...r.errors);
80
+ else metadatas.push(r.data);
81
+ }
82
+ if (errors.length)
83
+ throw TransformerError.from("typia.json.application")(errors);
84
+
85
+ // APPLICATION
86
+ const app: IJsonApplication<any> =
87
+ JsonApplicationProgrammer.write(version)(metadatas);
88
+ return LiteralFactory.generate(app);
89
+ };
90
+
91
+ const get_parameter =
92
+ <Value>(props: {
93
+ checker: ts.TypeChecker;
94
+ name: string;
95
+ is: (value: string) => boolean;
96
+ cast: (value: string) => Value;
97
+ default: () => Value;
98
+ }) =>
99
+ (node: ts.TypeNode | undefined): Value => {
100
+ if (!node) return props.default();
101
+
102
+ // CHECK LITERAL TYPE
103
+ const type: ts.Type = props.checker.getTypeFromTypeNode(node);
104
+ if (
105
+ !type.isLiteral() &&
106
+ (type.getFlags() & ts.TypeFlags.BooleanLiteral) === 0
107
+ )
108
+ throw new TransformerError({
109
+ code: "typia.json.application",
110
+ message: `generic argument "${props.name}" must be constant.`,
111
+ });
112
+
113
+ // GET VALUE AND VALIDATE IT
114
+ const value = type.isLiteral()
115
+ ? type.value
116
+ : props.checker.typeToString(type);
117
+ if (typeof value !== "string" || props.is(value) === false)
118
+ throw new TransformerError({
119
+ code: "typia.json.application",
120
+ message: `invalid value on generic argument "${props.name}".`,
121
+ });
122
+ return props.cast(value);
123
+ };
124
+ }