typia 5.5.0-dev.20240301 → 5.5.0-dev.20240303

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 (36) hide show
  1. package/lib/functional/$guard.js +11 -49
  2. package/lib/functional/$guard.js.map +1 -1
  3. package/lib/functional/Namespace/index.d.ts +1 -1
  4. package/lib/functional.d.ts +353 -0
  5. package/lib/functional.js +130 -0
  6. package/lib/functional.js.map +1 -0
  7. package/lib/module.d.ts +1 -0
  8. package/lib/module.js +2 -1
  9. package/lib/module.js.map +1 -1
  10. package/lib/programmers/AssertProgrammer.js +24 -20
  11. package/lib/programmers/AssertProgrammer.js.map +1 -1
  12. package/lib/programmers/functional/FunctionalAssertFunctionProgrammer.d.ts +6 -0
  13. package/lib/programmers/functional/FunctionalAssertFunctionProgrammer.js +33 -0
  14. package/lib/programmers/functional/FunctionalAssertFunctionProgrammer.js.map +1 -0
  15. package/lib/programmers/functional/FunctionalAssertParametersProgrammer.d.ts +11 -0
  16. package/lib/programmers/functional/FunctionalAssertParametersProgrammer.js +58 -0
  17. package/lib/programmers/functional/FunctionalAssertParametersProgrammer.js.map +1 -0
  18. package/lib/programmers/functional/FunctionalAssertReturnProgrammer.d.ts +14 -0
  19. package/lib/programmers/functional/FunctionalAssertReturnProgrammer.js +67 -0
  20. package/lib/programmers/functional/FunctionalAssertReturnProgrammer.js.map +1 -0
  21. package/lib/transformers/CallExpressionTransformer.d.ts +1 -1
  22. package/lib/transformers/CallExpressionTransformer.js +49 -0
  23. package/lib/transformers/CallExpressionTransformer.js.map +1 -1
  24. package/lib/transformers/features/functional/FunctionalGenericTransformer.d.ts +10 -0
  25. package/lib/transformers/features/functional/FunctionalGenericTransformer.js +32 -0
  26. package/lib/transformers/features/functional/FunctionalGenericTransformer.js.map +1 -0
  27. package/package.json +1 -1
  28. package/src/functional/$guard.ts +7 -35
  29. package/src/functional.ts +561 -0
  30. package/src/module.ts +1 -0
  31. package/src/programmers/AssertProgrammer.ts +49 -50
  32. package/src/programmers/functional/FunctionalAssertFunctionProgrammer.ts +44 -0
  33. package/src/programmers/functional/FunctionalAssertParametersProgrammer.ts +100 -0
  34. package/src/programmers/functional/FunctionalAssertReturnProgrammer.ts +84 -0
  35. package/src/transformers/CallExpressionTransformer.ts +52 -5
  36. package/src/transformers/features/functional/FunctionalGenericTransformer.ts +41 -0
@@ -40,7 +40,7 @@ export namespace AssertProgrammer {
40
40
  ? entry.conditions[0]!.map((cond) =>
41
41
  ts.factory.createLogicalOr(
42
42
  cond.expression,
43
- create_guard_call(
43
+ create_guard_call(importer)(
44
44
  explore.from === "top"
45
45
  ? ts.factory.createTrue()
46
46
  : ts.factory.createIdentifier("_exceptionable"),
@@ -64,7 +64,7 @@ export namespace AssertProgrammer {
64
64
  .reduce((a, b) => ts.factory.createLogicalAnd(a, b)),
65
65
  )
66
66
  .reduce((a, b) => ts.factory.createLogicalOr(a, b)),
67
- create_guard_call(
67
+ create_guard_call(importer)(
68
68
  explore.from === "top"
69
69
  ? ts.factory.createTrue()
70
70
  : ts.factory.createIdentifier("_exceptionable"),
@@ -107,21 +107,6 @@ export namespace AssertProgrammer {
107
107
  undefined,
108
108
  ts.factory.createBlock(
109
109
  [
110
- StatementFactory.constant(
111
- "$guard",
112
- ts.factory.createCallExpression(
113
- IdentifierFactory.access(
114
- ts.factory.createParenthesizedExpression(
115
- ts.factory.createAsExpression(
116
- modulo,
117
- TypeFactory.keyword("any"),
118
- ),
119
- ),
120
- )("guard"),
121
- undefined,
122
- [Guardian.identifier()],
123
- ),
124
- ),
125
110
  StatementFactory.constant("__is", is),
126
111
  ts.factory.createIfStatement(
127
112
  ts.factory.createStrictEquality(
@@ -176,7 +161,7 @@ export namespace AssertProgrammer {
176
161
  ? binary.expression
177
162
  : ts.factory.createLogicalOr(
178
163
  binary.expression,
179
- create_guard_call(
164
+ create_guard_call(importer)(
180
165
  explore.source === "top"
181
166
  ? ts.factory.createTrue()
182
167
  : ts.factory.createIdentifier("_exceptionable"),
@@ -188,7 +173,7 @@ export namespace AssertProgrammer {
188
173
  binaries
189
174
  .map((binary) => binary.expression)
190
175
  .reduce(ts.factory.createLogicalOr),
191
- create_guard_call(
176
+ create_guard_call(importer)(
192
177
  explore.source === "top"
193
178
  ? ts.factory.createTrue()
194
179
  : ts.factory.createIdentifier("_exceptionable"),
@@ -201,7 +186,7 @@ export namespace AssertProgrammer {
201
186
  // ) {
202
187
  // addicted.push({
203
188
  // combined: true,
204
- // expression: create_guard_call(
189
+ // expression: create_guard_call(importer)(
205
190
  // explore.source === "top"
206
191
  // ? ts.factory.createTrue()
207
192
  // : ts.factory.createIdentifier(
@@ -229,7 +214,7 @@ export namespace AssertProgrammer {
229
214
  reduce: ts.factory.createLogicalAnd,
230
215
  positive: ts.factory.createTrue(),
231
216
  superfluous: (value) =>
232
- create_guard_call()(
217
+ create_guard_call(importer)()(
233
218
  ts.factory.createAdd(
234
219
  ts.factory.createIdentifier("_path"),
235
220
  ts.factory.createCallExpression(importer.use("join"), undefined, [
@@ -261,7 +246,7 @@ export namespace AssertProgrammer {
261
246
  [arrow],
262
247
  ),
263
248
  failure: (value, expected, explore) =>
264
- create_guard_call(
249
+ create_guard_call(importer)(
265
250
  explore?.from === "top"
266
251
  ? ts.factory.createTrue()
267
252
  : ts.factory.createIdentifier("_exceptionable"),
@@ -277,7 +262,7 @@ export namespace AssertProgrammer {
277
262
  : (condition) => (input, expected, explore) =>
278
263
  ts.factory.createLogicalOr(
279
264
  condition,
280
- create_guard_call(
265
+ create_guard_call(importer)(
281
266
  explore.from === "top"
282
267
  ? ts.factory.createTrue()
283
268
  : ts.factory.createIdentifier("_exceptionable"),
@@ -286,47 +271,61 @@ export namespace AssertProgrammer {
286
271
  });
287
272
 
288
273
  const create_guard_call =
274
+ (importer: FunctionImporter) =>
289
275
  (exceptionable?: ts.Expression) =>
290
276
  (
291
277
  path: ts.Expression,
292
278
  expected: string,
293
279
  value: ts.Expression,
294
280
  ): ts.Expression =>
295
- ts.factory.createCallExpression(
296
- ts.factory.createIdentifier("$guard"),
297
- undefined,
298
- [
299
- exceptionable ?? ts.factory.createIdentifier("_exceptionable"),
300
- ts.factory.createObjectLiteralExpression(
301
- [
302
- ts.factory.createPropertyAssignment("path", path),
303
- ts.factory.createPropertyAssignment(
304
- "expected",
305
- ts.factory.createStringLiteral(expected),
306
- ),
307
- ts.factory.createPropertyAssignment("value", value),
308
- ],
309
- true,
310
- ),
311
- ],
312
- );
281
+ ts.factory.createCallExpression(importer.use("guard"), undefined, [
282
+ exceptionable ?? ts.factory.createIdentifier("_exceptionable"),
283
+ ts.factory.createObjectLiteralExpression(
284
+ [
285
+ ts.factory.createPropertyAssignment("path", path),
286
+ ts.factory.createPropertyAssignment(
287
+ "expected",
288
+ ts.factory.createStringLiteral(expected),
289
+ ),
290
+ ts.factory.createPropertyAssignment("value", value),
291
+ ],
292
+ true,
293
+ ),
294
+ Guardian.identifier(),
295
+ ]);
313
296
 
314
297
  export namespace Guardian {
315
298
  export const identifier = () => ts.factory.createIdentifier("errorFactory");
316
299
  export const parameter = (init: ts.Expression | undefined) =>
317
300
  IdentifierFactory.parameter(
318
301
  "errorFactory",
319
- ts.factory.createImportTypeNode(
320
- ts.factory.createLiteralTypeNode(
321
- ts.factory.createStringLiteral("typia"),
322
- ),
302
+ ts.factory.createFunctionTypeNode(
323
303
  undefined,
324
- ts.factory.createQualifiedName(
325
- ts.factory.createIdentifier("TypeGuardError"),
326
- ts.factory.createIdentifier("IProps"),
304
+ [
305
+ ts.factory.createParameterDeclaration(
306
+ undefined,
307
+ undefined,
308
+ ts.factory.createIdentifier("p"),
309
+ undefined,
310
+ ts.factory.createImportTypeNode(
311
+ ts.factory.createLiteralTypeNode(
312
+ ts.factory.createStringLiteral("typia"),
313
+ ),
314
+ undefined,
315
+ ts.factory.createQualifiedName(
316
+ ts.factory.createIdentifier("TypeGuardError"),
317
+ ts.factory.createIdentifier("IProps"),
318
+ ),
319
+ undefined,
320
+ false,
321
+ ),
322
+ undefined,
323
+ ),
324
+ ],
325
+ ts.factory.createTypeReferenceNode(
326
+ ts.factory.createIdentifier("Error"),
327
+ undefined,
327
328
  ),
328
- undefined,
329
- false,
330
329
  ),
331
330
  init ?? ts.factory.createToken(ts.SyntaxKind.QuestionToken),
332
331
  );
@@ -0,0 +1,44 @@
1
+ import ts from "typescript";
2
+ import { IProject } from "../../transformers/IProject";
3
+ import { FunctionalAssertParametersProgrammer } from "./FunctionalAssertParametersProgrammer";
4
+ import { FunctionAssertReturnProgrammer } from "./FunctionalAssertReturnProgrammer";
5
+
6
+ export namespace FunctionalAssertFunctionProgrammer {
7
+ export const write =
8
+ (project: IProject) =>
9
+ (modulo: ts.LeftHandSideExpression) =>
10
+ (equals: boolean) =>
11
+ (
12
+ expression: ts.Expression,
13
+ declaration: ts.FunctionDeclaration,
14
+ init?: ts.Expression,
15
+ ) => {
16
+ const params = FunctionalAssertParametersProgrammer.prepare(project)(
17
+ modulo,
18
+ )(equals)(declaration, init);
19
+ const output = FunctionAssertReturnProgrammer.prepare(project)(modulo)(
20
+ equals,
21
+ )(expression, declaration, init);
22
+ return ts.factory.createFunctionDeclaration(
23
+ output.async
24
+ ? [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)]
25
+ : undefined,
26
+ undefined,
27
+ undefined,
28
+ undefined,
29
+ declaration.parameters,
30
+ declaration.type,
31
+ ts.factory.createBlock(
32
+ [
33
+ params.assert,
34
+ output.assert,
35
+ params.call,
36
+ output.variable,
37
+ output.call,
38
+ output.returns,
39
+ ],
40
+ true,
41
+ ),
42
+ );
43
+ };
44
+ }
@@ -0,0 +1,100 @@
1
+ import ts from "typescript";
2
+ import { IProject } from "../../transformers/IProject";
3
+ import { StatementFactory } from "../../factories/StatementFactory";
4
+ import { AssertProgrammer } from "../AssertProgrammer";
5
+
6
+ export namespace FunctionalAssertParametersProgrammer {
7
+ export const write =
8
+ (project: IProject) =>
9
+ (modulo: ts.LeftHandSideExpression) =>
10
+ (equals: boolean) =>
11
+ (
12
+ expression: ts.Expression,
13
+ declaration: ts.FunctionDeclaration,
14
+ init?: ts.Expression,
15
+ ) => {
16
+ const { assert, call } = prepare(project)(modulo)(equals)(
17
+ declaration,
18
+ init,
19
+ );
20
+ const async: boolean = (() => {
21
+ if (declaration.type === undefined) return false;
22
+ const type: ts.Type = project.checker.getTypeFromTypeNode(
23
+ declaration.type,
24
+ );
25
+ return type.isTypeParameter() && type.symbol.name === "Promise";
26
+ })();
27
+
28
+ return ts.factory.createFunctionDeclaration(
29
+ async
30
+ ? [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)]
31
+ : undefined,
32
+ undefined,
33
+ undefined,
34
+ undefined,
35
+ declaration.parameters,
36
+ declaration.type,
37
+ ts.factory.createBlock(
38
+ [
39
+ assert,
40
+ call,
41
+ ts.factory.createReturnStatement(
42
+ ts.factory.createCallExpression(
43
+ expression,
44
+ undefined,
45
+ declaration.parameters.map((p) =>
46
+ ts.factory.createIdentifier(p.name.getText()),
47
+ ),
48
+ ),
49
+ ),
50
+ ],
51
+ true,
52
+ ),
53
+ );
54
+ };
55
+
56
+ export const prepare =
57
+ (project: IProject) =>
58
+ (modulo: ts.LeftHandSideExpression) =>
59
+ (equals: boolean) =>
60
+ (declaration: ts.FunctionDeclaration, init?: ts.Expression) => {
61
+ const typeNode: ts.TypeNode = ts.factory.createTypeLiteralNode([
62
+ ts.factory.createPropertySignature(
63
+ undefined,
64
+ "parameters",
65
+ undefined,
66
+ ts.factory.createTupleTypeNode(
67
+ declaration.parameters.map((p) => p.type!),
68
+ ),
69
+ ),
70
+ ]);
71
+ const type: ts.Type = project.checker.getTypeFromTypeNode(typeNode);
72
+
73
+ const assert = StatementFactory.constant(
74
+ "assert",
75
+ AssertProgrammer.write(project)(modulo)(equals)(type, undefined, init),
76
+ );
77
+ const call = ts.factory.createExpressionStatement(
78
+ ts.factory.createCallExpression(
79
+ ts.factory.createIdentifier("assert"),
80
+ undefined,
81
+ [
82
+ ts.factory.createObjectLiteralExpression(
83
+ [
84
+ ts.factory.createPropertyAssignment(
85
+ "parameters",
86
+ ts.factory.createArrayLiteralExpression(
87
+ declaration.parameters.map((p) =>
88
+ ts.factory.createIdentifier(p.name.getText()),
89
+ ),
90
+ ),
91
+ ),
92
+ ],
93
+ true,
94
+ ),
95
+ ],
96
+ ),
97
+ );
98
+ return { assert, call, type };
99
+ };
100
+ }
@@ -0,0 +1,84 @@
1
+ import ts from "typescript";
2
+ import { IProject } from "../../transformers/IProject";
3
+ import { StatementFactory } from "../../factories/StatementFactory";
4
+ import { AssertProgrammer } from "../AssertProgrammer";
5
+
6
+ export namespace FunctionAssertReturnProgrammer {
7
+ export const write =
8
+ (project: IProject) =>
9
+ (modulo: ts.LeftHandSideExpression) =>
10
+ (equals: boolean) =>
11
+ (
12
+ expression: ts.Expression,
13
+ declaration: ts.FunctionDeclaration,
14
+ init?: ts.Expression,
15
+ ) => {
16
+ const { async, assert, variable, call, returns } = prepare(project)(
17
+ modulo,
18
+ )(equals)(expression, declaration, init);
19
+ return ts.factory.createFunctionDeclaration(
20
+ async
21
+ ? [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)]
22
+ : undefined,
23
+ undefined,
24
+ undefined,
25
+ undefined,
26
+ declaration.parameters,
27
+ declaration.type,
28
+ ts.factory.createBlock([assert, variable, call, returns], true),
29
+ );
30
+ };
31
+
32
+ export const prepare =
33
+ (project: IProject) =>
34
+ (modulo: ts.LeftHandSideExpression) =>
35
+ (equals: boolean) =>
36
+ (
37
+ expression: ts.Expression,
38
+ declaration: ts.FunctionDeclaration,
39
+ init?: ts.Expression,
40
+ ) => {
41
+ const [type, async]: [ts.Type, boolean] = (() => {
42
+ const type: ts.Type = project.checker.getTypeFromTypeNode(
43
+ declaration.type!,
44
+ );
45
+ return type.isTypeParameter() && type.symbol.name === "Promise"
46
+ ? [type.aliasTypeArguments![0]!, true]
47
+ : [type, false];
48
+ })();
49
+ const assert = StatementFactory.constant(
50
+ "assert",
51
+ AssertProgrammer.write(project)(modulo)(equals)(type, undefined, init),
52
+ );
53
+ const funcCaller = ts.factory.createCallExpression(
54
+ expression,
55
+ undefined,
56
+ declaration.parameters.map((p) =>
57
+ ts.factory.createIdentifier(p.name.getText()),
58
+ ),
59
+ );
60
+ const variable = StatementFactory.constant(
61
+ "output",
62
+ async ? ts.factory.createAwaitExpression(funcCaller) : funcCaller,
63
+ );
64
+
65
+ const call = ts.factory.createExpressionStatement(
66
+ ts.factory.createCallExpression(
67
+ ts.factory.createIdentifier("assert"),
68
+ undefined,
69
+ [
70
+ ts.factory.createObjectLiteralExpression([
71
+ ts.factory.createPropertyAssignment(
72
+ "return",
73
+ ts.factory.createIdentifier("output"),
74
+ ),
75
+ ]),
76
+ ],
77
+ ),
78
+ );
79
+ const returns = ts.factory.createReturnStatement(
80
+ ts.factory.createIdentifier("output"),
81
+ );
82
+ return { async, type, assert, variable, call, returns };
83
+ };
84
+ }
@@ -96,11 +96,17 @@ import { CreateHttpAssertFormDataTransformer } from "./features/http/CreateHttpA
96
96
  import { CreateHttpFormDataTransformer } from "./features/http/CreateHttpFormDataTransformer";
97
97
  import { CreateHttpIsFormDataTransformer } from "./features/http/CreateHttpIsFormDataTransformer";
98
98
  import { CreateHttpValidateFormDataTransformer } from "./features/http/CreateHttpValidateFormDataTransformer";
99
+ import { FunctionalGenericTransformer } from "./features/functional/FunctionalGenericTransformer";
100
+ import { FunctionalAssertFunctionProgrammer } from "../programmers/functional/FunctionalAssertFunctionProgrammer";
101
+ import { FunctionalAssertParametersProgrammer } from "../programmers/functional/FunctionalAssertParametersProgrammer";
102
+ import { FunctionAssertReturnProgrammer } from "../programmers/functional/FunctionalAssertReturnProgrammer";
99
103
 
100
104
  export namespace CallExpressionTransformer {
101
105
  export const transform =
102
106
  (project: IProject) =>
103
- (expression: ts.CallExpression): ts.Expression | null => {
107
+ (
108
+ expression: ts.CallExpression,
109
+ ): ts.Expression | ts.FunctionDeclaration | null => {
104
110
  //----
105
111
  // VALIDATIONS
106
112
  //----
@@ -127,9 +133,9 @@ export namespace CallExpressionTransformer {
127
133
  if (functor === undefined) return expression;
128
134
 
129
135
  // RETURNS WITH TRANSFORMATION
130
- const result: ts.Expression | null = functor()(project)(
131
- expression.expression,
132
- )(expression);
136
+ const result: ts.Expression | ts.FunctionDeclaration | null = functor()(
137
+ project,
138
+ )(expression.expression)(expression);
133
139
  return result ?? expression;
134
140
  };
135
141
 
@@ -145,7 +151,9 @@ type Task = (
145
151
  project: IProject,
146
152
  ) => (
147
153
  modulo: ts.LeftHandSideExpression,
148
- ) => (expression: ts.CallExpression) => ts.Expression | null;
154
+ ) => (
155
+ expression: ts.CallExpression,
156
+ ) => ts.Expression | ts.FunctionDeclaration | null;
149
157
 
150
158
  const FUNCTORS: Record<string, Record<string, () => Task>> = {
151
159
  module: {
@@ -187,6 +195,45 @@ const FUNCTORS: Record<string, Record<string, () => Task>> = {
187
195
  createValidateEquals: () => CreateValidateTransformer.transform(true),
188
196
  createRandom: () => CreateRandomTransformer.transform,
189
197
  },
198
+ functional: {
199
+ // ASSERTIONS
200
+ assertFunction: () =>
201
+ FunctionalGenericTransformer.transform({
202
+ method: "assertFunction",
203
+ equals: false,
204
+ programmer: FunctionalAssertFunctionProgrammer.write,
205
+ }),
206
+ assertParameters: () =>
207
+ FunctionalGenericTransformer.transform({
208
+ method: "assertParameters",
209
+ equals: false,
210
+ programmer: FunctionalAssertParametersProgrammer.write,
211
+ }),
212
+ assertReturn: () =>
213
+ FunctionalGenericTransformer.transform({
214
+ method: "assertReturn",
215
+ equals: false,
216
+ programmer: FunctionAssertReturnProgrammer.write,
217
+ }),
218
+ assertEqualsFunction: () =>
219
+ FunctionalGenericTransformer.transform({
220
+ method: "assertEqualsFunction",
221
+ equals: true,
222
+ programmer: FunctionalAssertFunctionProgrammer.write,
223
+ }),
224
+ assertEqualsParameters: () =>
225
+ FunctionalGenericTransformer.transform({
226
+ method: "assertEqualsParameters",
227
+ equals: true,
228
+ programmer: FunctionalAssertParametersProgrammer.write,
229
+ }),
230
+ assertEqualsReturn: () =>
231
+ FunctionalGenericTransformer.transform({
232
+ method: "assertEqualsReturn",
233
+ equals: true,
234
+ programmer: FunctionAssertReturnProgrammer.write,
235
+ }),
236
+ },
190
237
  http: {
191
238
  // FORM-DATA
192
239
  formData: () => HttpFormDataTransformer.transform,
@@ -0,0 +1,41 @@
1
+ import ts from "typescript";
2
+ import { IProject } from "../../IProject";
3
+ import { TransformerError } from "../../TransformerError";
4
+
5
+ export namespace FunctionalGenericTransformer {
6
+ export const transform =
7
+ (props: {
8
+ method: string;
9
+ programmer: (
10
+ project: IProject,
11
+ ) => (
12
+ modulo: ts.LeftHandSideExpression,
13
+ ) => (
14
+ equals: boolean,
15
+ ) => (
16
+ expression: ts.CallExpression,
17
+ declaration: ts.FunctionDeclaration,
18
+ init?: ts.Expression,
19
+ ) => ts.FunctionDeclaration;
20
+ equals: boolean;
21
+ }) =>
22
+ (project: IProject) =>
23
+ (modulo: ts.LeftHandSideExpression) =>
24
+ (expression: ts.CallExpression) => {
25
+ // CHECK PARAMETER
26
+ if (expression.arguments.length === 0)
27
+ throw new TransformerError({
28
+ code: `typia.functional.${props.method}`,
29
+ message: `no input value.`,
30
+ });
31
+ else if (false === ts.isFunctionDeclaration(expression.arguments[0]!))
32
+ throw new TransformerError({
33
+ code: `typia.functional.${props.method}`,
34
+ message: `input value is not a function.`,
35
+ });
36
+ return props.programmer(project)(modulo)(props.equals)(
37
+ expression,
38
+ expression.arguments[0]!,
39
+ );
40
+ };
41
+ }