typia 3.7.0-dev.20230331 → 3.7.0-dev.20230401-2

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 (51) hide show
  1. package/lib/functional/$dictionary.d.ts +1 -1
  2. package/lib/module.d.ts +13 -1
  3. package/lib/module.js +4 -2
  4. package/lib/module.js.map +1 -1
  5. package/lib/programmers/AssertProgrammer.js +11 -0
  6. package/lib/programmers/AssertProgrammer.js.map +1 -1
  7. package/lib/programmers/CheckerProgrammer.d.ts +2 -0
  8. package/lib/programmers/CheckerProgrammer.js +11 -12
  9. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  10. package/lib/programmers/IsProgrammer.js +30 -0
  11. package/lib/programmers/IsProgrammer.js.map +1 -1
  12. package/lib/programmers/ValidateProgrammer.js +11 -0
  13. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  14. package/lib/programmers/helpers/ICheckEntry.d.ts +11 -0
  15. package/lib/programmers/helpers/ICheckEntry.js +3 -0
  16. package/lib/programmers/helpers/ICheckEntry.js.map +1 -0
  17. package/lib/programmers/internal/check_array.js +7 -11
  18. package/lib/programmers/internal/check_array.js.map +1 -1
  19. package/lib/programmers/internal/check_array_length.js +23 -36
  20. package/lib/programmers/internal/check_array_length.js.map +1 -1
  21. package/lib/programmers/internal/check_bigint.d.ts +1 -5
  22. package/lib/programmers/internal/check_bigint.js +67 -61
  23. package/lib/programmers/internal/check_bigint.js.map +1 -1
  24. package/lib/programmers/internal/check_custom.d.ts +2 -1
  25. package/lib/programmers/internal/check_custom.js +26 -16
  26. package/lib/programmers/internal/check_custom.js.map +1 -1
  27. package/lib/programmers/internal/check_number.js +88 -64
  28. package/lib/programmers/internal/check_number.js.map +1 -1
  29. package/lib/programmers/internal/check_string.js +9 -9
  30. package/lib/programmers/internal/check_string.js.map +1 -1
  31. package/lib/programmers/internal/check_string_tags.js +63 -24
  32. package/lib/programmers/internal/check_string_tags.js.map +1 -1
  33. package/lib/programmers/internal/check_template.js +23 -11
  34. package/lib/programmers/internal/check_template.js.map +1 -1
  35. package/lib/typings/Customizable.d.ts +0 -1
  36. package/package.json +1 -1
  37. package/src/module.ts +16 -1
  38. package/src/programmers/AssertProgrammer.ts +24 -0
  39. package/src/programmers/CheckerProgrammer.ts +45 -46
  40. package/src/programmers/IsProgrammer.ts +5 -0
  41. package/src/programmers/ValidateProgrammer.ts +24 -0
  42. package/src/programmers/helpers/ICheckEntry.ts +12 -0
  43. package/src/programmers/internal/check_array.ts +10 -15
  44. package/src/programmers/internal/check_array_length.ts +31 -35
  45. package/src/programmers/internal/check_bigint.ts +60 -62
  46. package/src/programmers/internal/check_custom.ts +41 -32
  47. package/src/programmers/internal/check_number.ts +102 -83
  48. package/src/programmers/internal/check_string.ts +14 -19
  49. package/src/programmers/internal/check_string_tags.ts +23 -13
  50. package/src/programmers/internal/check_template.ts +16 -7
  51. package/src/typings/Customizable.ts +0 -1
@@ -30,20 +30,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
31
  exports.check_template = void 0;
32
32
  var typescript_1 = __importDefault(require("typescript"));
33
+ var check_custom_1 = require("./check_custom");
33
34
  var check_string_tags_1 = require("./check_string_tags");
34
35
  var template_to_pattern_1 = require("./template_to_pattern");
35
36
  var check_template = function (importer) {
36
- return function (input, templates, tagList) {
37
- var conditions = __spreadArray([
38
- typescript_1.default.factory.createStrictEquality(typescript_1.default.factory.createStringLiteral("string"), typescript_1.default.factory.createTypeOfExpression(input))
39
- ], __read((0, check_string_tags_1.check_string_tags)(importer)(input, tagList)), false);
40
- var internal = templates.map(function (tpl) {
41
- return typescript_1.default.factory.createStrictEquality(typescript_1.default.factory.createTrue(), typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier("RegExp(/".concat((0, template_to_pattern_1.template_to_pattern)(true)(tpl), "/).test")), undefined, [input]));
42
- });
43
- conditions.push(internal.length === 1
44
- ? internal[0]
45
- : internal.reduce(function (x, y) { return typescript_1.default.factory.createLogicalOr(x, y); }));
46
- return conditions.reduce(function (x, y) { return typescript_1.default.factory.createLogicalAnd(x, y); });
37
+ return function (metaTags) {
38
+ return function (jsDocTags) {
39
+ return function (templates) {
40
+ return function (input) {
41
+ var conditions = [
42
+ typescript_1.default.factory.createStrictEquality(typescript_1.default.factory.createStringLiteral("string"), typescript_1.default.factory.createTypeOfExpression(input)),
43
+ ];
44
+ var internal = templates.map(function (tpl) {
45
+ return typescript_1.default.factory.createStrictEquality(typescript_1.default.factory.createTrue(), typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier("RegExp(/".concat((0, template_to_pattern_1.template_to_pattern)(true)(tpl), "/).test")), undefined, [input]));
46
+ });
47
+ conditions.push(internal.length === 1
48
+ ? internal[0]
49
+ : internal.reduce(function (x, y) { return typescript_1.default.factory.createLogicalOr(x, y); }));
50
+ return {
51
+ expression: conditions.reduce(function (x, y) {
52
+ return typescript_1.default.factory.createLogicalAnd(x, y);
53
+ }),
54
+ tags: __spreadArray(__spreadArray([], __read((0, check_string_tags_1.check_string_tags)(importer)(metaTags)(input)), false), __read((0, check_custom_1.check_custom)("string")(importer)(jsDocTags)(input)), false),
55
+ };
56
+ };
57
+ };
58
+ };
47
59
  };
48
60
  };
49
61
  exports.check_template = check_template;
@@ -1 +1 @@
1
- {"version":3,"file":"check_template.js","sourceRoot":"","sources":["../../../src/programmers/internal/check_template.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0DAA4B;AAM5B,yDAAwD;AACxD,6DAA4D;AAKrD,IAAM,cAAc,GACvB,UAAC,QAA0B;IAC3B,OAAA,UACI,KAAoB,EACpB,SAAuB,EACvB,OAAuB;QAGvB,IAAM,UAAU;YACZ,oBAAE,CAAC,OAAO,CAAC,oBAAoB,CAC3B,oBAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EACxC,oBAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAC3C;kBACE,IAAA,qCAAiB,EAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,SACjD,CAAC;QAGF,IAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,UAAC,GAAG;YAC/B,OAAA,oBAAE,CAAC,OAAO,CAAC,oBAAoB,CAC3B,oBAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EACvB,oBAAE,CAAC,OAAO,CAAC,oBAAoB,CAC3B,oBAAE,CAAC,OAAO,CAAC,gBAAgB,CACvB,kBAAW,IAAA,yCAAmB,EAAC,IAAI,CAAC,CAAC,GAAG,CAAC,YAAS,CACrD,EACD,SAAS,EACT,CAAC,KAAK,CAAC,CACV,CACJ;QATD,CASC,CACJ,CAAC;QACF,UAAU,CAAC,IAAI,CACX,QAAQ,CAAC,MAAM,KAAK,CAAC;YACjB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE;YACd,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,oBAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAAhC,CAAgC,CAAC,CACpE,CAAC;QAGF,OAAO,UAAU,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,oBAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAjC,CAAiC,CAAC,CAAC;IAC1E,CAAC;AAnCD,CAmCC,CAAC;AArCO,QAAA,cAAc,kBAqCrB"}
1
+ {"version":3,"file":"check_template.js","sourceRoot":"","sources":["../../../src/programmers/internal/check_template.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0DAA4B;AAQ5B,+CAA8C;AAC9C,yDAAwD;AACxD,6DAA4D;AAKrD,IAAM,cAAc,GACvB,UAAC,QAA0B;IAC3B,OAAA,UAAC,QAAwB;QACzB,OAAA,UAAC,SAA0B;YAC3B,OAAA,UAAC,SAAuB;gBACxB,OAAA,UAAC,KAAoB;oBAEjB,IAAM,UAAU,GAAoB;wBAChC,oBAAE,CAAC,OAAO,CAAC,oBAAoB,CAC3B,oBAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EACxC,oBAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAC3C;qBACJ,CAAC;oBAGF,IAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,UAAC,GAAG;wBAC/B,OAAA,oBAAE,CAAC,OAAO,CAAC,oBAAoB,CAC3B,oBAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EACvB,oBAAE,CAAC,OAAO,CAAC,oBAAoB,CAC3B,oBAAE,CAAC,OAAO,CAAC,gBAAgB,CACvB,kBAAW,IAAA,yCAAmB,EAAC,IAAI,CAAC,CAAC,GAAG,CAAC,YAAS,CACrD,EACD,SAAS,EACT,CAAC,KAAK,CAAC,CACV,CACJ;oBATD,CASC,CACJ,CAAC;oBACF,UAAU,CAAC,IAAI,CACX,QAAQ,CAAC,MAAM,KAAK,CAAC;wBACjB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE;wBACd,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,oBAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAAhC,CAAgC,CAAC,CACpE,CAAC;oBAGF,OAAO;wBACH,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC;4BAC/B,OAAA,oBAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC;wBAAjC,CAAiC,CACpC;wBACD,IAAI,yCACG,IAAA,qCAAiB,EAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,kBAC5C,IAAA,2BAAY,EAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,SACxD;qBACJ,CAAC;gBACN,CAAC;YAtCD,CAsCC;QAvCD,CAuCC;IAxCD,CAwCC;AAzCD,CAyCC,CAAC;AA3CO,QAAA,cAAc,kBA2CrB"}
@@ -1,5 +1,4 @@
1
1
  export type Customizable = {
2
- boolean: boolean;
3
2
  number: number;
4
3
  string: string;
5
4
  bigint: bigint;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typia",
3
- "version": "3.7.0-dev.20230331",
3
+ "version": "3.7.0-dev.20230401-2",
4
4
  "description": "Superfast runtime validators with only one line",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
package/src/module.ts CHANGED
@@ -431,6 +431,18 @@ Object.assign(validateEquals, Namespace.validate());
431
431
  * typia.addValidationTag("dollar")("string")(
432
432
  * () => (value: string) => value.startsWith("$"),
433
433
  * );
434
+ *
435
+ * interface TagCustom {
436
+ * /**
437
+ * * @powerOf 10
438
+ * *\/
439
+ * powerOf: number;
440
+ *
441
+ * /**
442
+ * * @dollar
443
+ * *\/
444
+ * dollar: string;
445
+ * }
434
446
  * ```
435
447
  *
436
448
  * @param name Name of tag (`@name`)
@@ -447,7 +459,10 @@ export const addValidationTag =
447
459
  */
448
460
  (closure: (text: string) => (value: Customizable[Type]) => boolean) => {
449
461
  const key = `${name}:${type}` as const;
450
- if (!$dictionary.has(key)) $dictionary.set(key, closure);
462
+ if ($dictionary.has(key)) return false;
463
+
464
+ $dictionary.set(key, closure);
465
+ return true;
451
466
  };
452
467
 
453
468
  /* -----------------------------------------------------------
@@ -30,6 +30,30 @@ export namespace AssertProgrammer {
30
30
  trace: true,
31
31
  numeric: OptionPredicator.numeric(project.options),
32
32
  equals,
33
+ atomist: (explore) => (tuple) => (input) =>
34
+ [
35
+ tuple.expression,
36
+ ...tuple.tags.map((tag) =>
37
+ ts.factory.createLogicalOr(
38
+ tag.expression,
39
+ create_guard_call(importer)(
40
+ explore.from === "top"
41
+ ? ts.factory.createTrue()
42
+ : ts.factory.createIdentifier(
43
+ "_exceptionable",
44
+ ),
45
+ )(
46
+ ts.factory.createIdentifier(
47
+ explore.postfix
48
+ ? `_path + ${explore.postfix}`
49
+ : "_path",
50
+ ),
51
+ tag.expected,
52
+ input,
53
+ ),
54
+ ),
55
+ ),
56
+ ].reduce((x, y) => ts.factory.createLogicalAnd(x, y)),
33
57
  combiner: combiner(equals)(importer),
34
58
  joiner: joiner(equals)(importer),
35
59
  success: ts.factory.createTrue(),
@@ -16,6 +16,7 @@ import { IProject } from "../transformers/IProject";
16
16
  import { FeatureProgrammer } from "./FeatureProgrammer";
17
17
  import { AtomicPredicator } from "./helpers/AtomicPredicator";
18
18
  import { FunctionImporter } from "./helpers/FunctionImporeter";
19
+ import { ICheckEntry } from "./helpers/ICheckEntry";
19
20
  import { IExpressionEntry } from "./helpers/IExpressionEntry";
20
21
  import { OptionPredicator } from "./helpers/OptionPredicator";
21
22
  import { UnionExplorer } from "./helpers/UnionExplorer";
@@ -39,6 +40,9 @@ export namespace CheckerProgrammer {
39
40
  numeric: boolean;
40
41
  combiner: IConfig.Combiner;
41
42
  decoder?: FeatureProgrammer.Decoder<Metadata, ts.Expression>;
43
+ atomist: (
44
+ explore: IExplore,
45
+ ) => (check: ICheckEntry) => (input: ts.Expression) => ts.Expression;
42
46
  joiner: IConfig.IJoiner;
43
47
  success: ts.Expression;
44
48
  }
@@ -318,28 +322,25 @@ export namespace CheckerProgrammer {
318
322
  if (AtomicPredicator.atomic(meta)(type) === false) continue;
319
323
  else if (type === "number")
320
324
  binaries.push({
321
- expression: check_number(
322
- project,
323
- config.numeric,
324
- )(importer)(input, metaTags, jsDocTags),
325
+ expression: config.atomist(explore)(
326
+ check_number(project, config.numeric)(importer)(
327
+ metaTags,
328
+ )(jsDocTags)(input),
329
+ )(input),
325
330
  combined: false,
326
331
  });
327
332
  else if (type === "bigint")
328
333
  binaries.push({
329
- expression: check_bigint(importer)(
330
- input,
331
- metaTags,
332
- jsDocTags,
333
- ),
334
+ expression: config.atomist(explore)(
335
+ check_bigint(importer)(metaTags)(jsDocTags)(input),
336
+ )(input),
334
337
  combined: false,
335
338
  });
336
339
  else if (type === "string")
337
340
  binaries.push({
338
- expression: check_string(importer)(
339
- input,
340
- metaTags,
341
- jsDocTags,
342
- ),
341
+ expression: config.atomist(explore)(
342
+ check_string(importer)(metaTags)(jsDocTags)(input),
343
+ )(input),
343
344
  combined: false,
344
345
  });
345
346
  else
@@ -353,11 +354,11 @@ export namespace CheckerProgrammer {
353
354
  if (meta.templates.length)
354
355
  if (AtomicPredicator.template(meta))
355
356
  binaries.push({
356
- expression: check_template(importer)(
357
- input,
358
- meta.templates,
359
- metaTags,
360
- ),
357
+ expression: config.atomist(explore)(
358
+ check_template(importer)(metaTags)(jsDocTags)(
359
+ meta.templates,
360
+ )(input),
361
+ )(input),
361
362
  combined: false,
362
363
  });
363
364
 
@@ -438,11 +439,11 @@ export namespace CheckerProgrammer {
438
439
  // ARRAYS AND TUPLES
439
440
  if (meta.tuples.length + meta.arrays.length > 0) {
440
441
  const install = prepare(
441
- check_array(importer)(
442
- input,
443
- meta.tuples.length === 0 ? metaTags : [],
444
- jsDocTags,
445
- ),
442
+ config.atomist(explore)(
443
+ check_array(importer)(
444
+ meta.tuples.length === 0 ? metaTags : [],
445
+ )(jsDocTags)(input),
446
+ )(input),
446
447
  [...meta.tuples, ...meta.arrays]
447
448
  .map((elem) =>
448
449
  Array.isArray(elem)
@@ -832,28 +833,26 @@ export namespace CheckerProgrammer {
832
833
  importer: FunctionImporter,
833
834
  ) =>
834
835
  UnionExplorer.array_or_tuple({
835
- checker: (front, target, explore, tags, jsDocTags, array) => {
836
- if (Array.isArray(target))
837
- return check_union_tuple(project, config, importer)(
838
- front,
839
- target,
840
- explore,
841
- tags,
842
- jsDocTags,
843
- array,
844
- );
845
- const condition = decode(project, config, importer)(
846
- front,
847
- target,
848
- explore,
849
- tags,
850
- jsDocTags,
851
- );
852
- const length = check_array_length(array, tags);
853
- return length !== null
854
- ? ts.factory.createBitwiseAnd(condition, length)
855
- : condition;
856
- },
836
+ checker: (front, target, explore, tags, jsDocTags, array) =>
837
+ Array.isArray(target)
838
+ ? check_union_tuple(project, config, importer)(
839
+ front,
840
+ target,
841
+ explore,
842
+ tags,
843
+ jsDocTags,
844
+ array,
845
+ )
846
+ : config.atomist(explore)({
847
+ expression: decode(project, config, importer)(
848
+ front,
849
+ target,
850
+ explore,
851
+ tags,
852
+ jsDocTags,
853
+ ),
854
+ tags: check_array_length(tags)(array),
855
+ })(array),
857
856
  decoder: (input, target, explore, tags, jsDocTags) =>
858
857
  Array.isArray(target)
859
858
  ? decode_tuple(project, config, importer, true)(
@@ -27,6 +27,11 @@ export namespace IsProgrammer {
27
27
  numeric: OptionPredicator.numeric({
28
28
  numeric: options?.numeric,
29
29
  }),
30
+ atomist: () => (entry) => () =>
31
+ [
32
+ entry.expression,
33
+ ...entry.tags.map((tag) => tag.expression),
34
+ ].reduce((x, y) => ts.factory.createLogicalAnd(x, y)),
30
35
  combiner: () => (type: "and" | "or") => {
31
36
  const initial: ts.TrueLiteral | ts.FalseLiteral =
32
37
  type === "and"
@@ -31,6 +31,30 @@ export namespace ValidateProgrammer {
31
31
  trace: true,
32
32
  numeric: OptionPredicator.numeric(project.options),
33
33
  equals,
34
+ atomist: (explore) => (tuple) => (input) =>
35
+ [
36
+ tuple.expression,
37
+ ...tuple.tags.map((tag) =>
38
+ ts.factory.createLogicalOr(
39
+ tag.expression,
40
+ create_report_call(
41
+ explore.from === "top"
42
+ ? ts.factory.createTrue()
43
+ : ts.factory.createIdentifier(
44
+ "_exceptionable",
45
+ ),
46
+ )(
47
+ ts.factory.createIdentifier(
48
+ explore.postfix
49
+ ? `_path + ${explore.postfix}`
50
+ : "_path",
51
+ ),
52
+ tag.expected,
53
+ input,
54
+ ),
55
+ ),
56
+ ),
57
+ ].reduce((x, y) => ts.factory.createLogicalAnd(x, y)),
34
58
  combiner: combine(equals)(importer),
35
59
  joiner: joiner(equals)(importer),
36
60
  success: ts.factory.createTrue(),
@@ -0,0 +1,12 @@
1
+ import ts from "typescript";
2
+
3
+ export interface ICheckEntry {
4
+ expression: ts.Expression;
5
+ tags: ICheckEntry.ITag[];
6
+ }
7
+ export namespace ICheckEntry {
8
+ export interface ITag {
9
+ expected: string;
10
+ expression: ts.Expression;
11
+ }
12
+ }
@@ -6,6 +6,7 @@ import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
6
6
  import { IMetadataTag } from "../../metadata/IMetadataTag";
7
7
 
8
8
  import { FunctionImporter } from "../helpers/FunctionImporeter";
9
+ import { ICheckEntry } from "../helpers/ICheckEntry";
9
10
  import { check_array_length } from "./check_array_length";
10
11
  import { check_custom } from "./check_custom";
11
12
 
@@ -14,18 +15,12 @@ import { check_custom } from "./check_custom";
14
15
  */
15
16
  export const check_array =
16
17
  (importer: FunctionImporter) =>
17
- (
18
- input: ts.Expression,
19
- metaTags: IMetadataTag[],
20
- jsDocTags: IJsDocTagInfo[],
21
- ): ts.Expression => {
22
- const conditions: ts.Expression[] = [ExpressionFactory.isArray(input)];
23
-
24
- const length: ts.Expression | null = check_array_length(
25
- input,
26
- metaTags,
27
- );
28
- if (length !== null) conditions.push(length);
29
- conditions.push(...check_custom("array")(importer)(input, jsDocTags));
30
- return conditions.reduce((x, y) => ts.factory.createLogicalAnd(x, y));
31
- };
18
+ (metaTags: IMetadataTag[]) =>
19
+ (jsDocTags: IJsDocTagInfo[]) =>
20
+ (input: ts.Expression): ICheckEntry => ({
21
+ expression: ExpressionFactory.isArray(input),
22
+ tags: [
23
+ ...check_array_length(metaTags)(input),
24
+ ...check_custom("array", "Array")(importer)(jsDocTags)(input),
25
+ ],
26
+ });
@@ -4,41 +4,37 @@ import { IdentifierFactory } from "../../factories/IdentifierFactory";
4
4
 
5
5
  import { IMetadataTag } from "../../metadata/IMetadataTag";
6
6
 
7
+ import { ICheckEntry } from "../helpers/ICheckEntry";
8
+
7
9
  /**
8
10
  * @internal
9
11
  */
10
- export function check_array_length(
11
- input: ts.Expression,
12
- tagList: IMetadataTag[],
13
- ): ts.Expression | null {
14
- const conditions: ts.Expression[] = [];
15
-
16
- // CHECK TAGS
17
- for (const tag of tagList)
18
- if (tag.kind === "items")
19
- conditions.push(
20
- ts.factory.createStrictEquality(
21
- ts.factory.createNumericLiteral(tag.value),
22
- IdentifierFactory.join(input, "length"),
23
- ),
24
- );
25
- else if (tag.kind === "minItems")
26
- conditions.push(
27
- ts.factory.createLessThanEquals(
28
- ts.factory.createNumericLiteral(tag.value),
29
- IdentifierFactory.join(input, "length"),
30
- ),
31
- );
32
- else if (tag.kind === "maxItems")
33
- conditions.push(
34
- ts.factory.createGreaterThanEquals(
35
- ts.factory.createNumericLiteral(tag.value),
36
- IdentifierFactory.join(input, "length"),
37
- ),
38
- );
39
-
40
- // COMBINATION
41
- return conditions.length
42
- ? conditions.reduce((x, y) => ts.factory.createLogicalAnd(x, y))
43
- : null;
44
- }
12
+ export const check_array_length =
13
+ (tagList: IMetadataTag[]) =>
14
+ (input: ts.Expression): ICheckEntry.ITag[] =>
15
+ tagList
16
+ .map((tag) => ({
17
+ tag,
18
+ expression:
19
+ tag.kind === "items"
20
+ ? ts.factory.createStrictEquality(
21
+ ts.factory.createNumericLiteral(tag.value),
22
+ IdentifierFactory.join(input, "length"),
23
+ )
24
+ : tag.kind === "minItems"
25
+ ? ts.factory.createLessThanEquals(
26
+ ts.factory.createNumericLiteral(tag.value),
27
+ IdentifierFactory.join(input, "length"),
28
+ )
29
+ : tag.kind === "maxItems"
30
+ ? ts.factory.createGreaterThanEquals(
31
+ ts.factory.createNumericLiteral(tag.value),
32
+ IdentifierFactory.join(input, "length"),
33
+ )
34
+ : null!,
35
+ }))
36
+ .filter((tuple) => tuple.expression !== null)
37
+ .map(({ tag, expression }) => ({
38
+ expected: `Array.length (@${tag.kind} ${tag.value})`,
39
+ expression,
40
+ }));
@@ -4,81 +4,79 @@ import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
4
4
  import { IMetadataTag } from "../../metadata/IMetadataTag";
5
5
 
6
6
  import { FunctionImporter } from "../helpers/FunctionImporeter";
7
+ import { ICheckEntry } from "../helpers/ICheckEntry";
7
8
  import { check_custom } from "./check_custom";
8
9
 
10
+ /**
11
+ * @internal
12
+ */
9
13
  export const check_bigint =
10
14
  (importer: FunctionImporter) =>
11
- (
12
- input: ts.Expression,
13
- metaTags: IMetadataTag[],
14
- jsDocTags: IJsDocTagInfo[],
15
- ): ts.Expression => {
16
- const caster = (value: number) =>
17
- ts.factory.createIdentifier(`${Math.floor(value)}n`);
18
-
19
- // TYPEOF STATEMENT
20
- const conditions: ts.Expression[] = [
21
- ts.factory.createStrictEquality(
22
- ts.factory.createStringLiteral("bigint"),
23
- ts.factory.createTypeOfExpression(input),
24
- ),
25
- ];
26
-
27
- // TAG (RANGE)
28
- for (const tag of metaTags)
15
+ (metaTags: IMetadataTag[]) =>
16
+ (jsDocTag: IJsDocTagInfo[]) =>
17
+ (input: ts.Expression): ICheckEntry => {
18
+ const entries: [IMetadataTag, ts.Expression][] = [];
19
+ for (const tag of metaTags) {
29
20
  if (tag.kind === "multipleOf")
30
- conditions.push(
21
+ entries.push([
22
+ tag,
31
23
  ts.factory.createStrictEquality(
32
- caster(0),
33
- ts.factory.createModulo(input, caster(tag.value)),
24
+ cast(0),
25
+ ts.factory.createModulo(input, cast(tag.value)),
34
26
  ),
35
- );
27
+ ]);
36
28
  else if (tag.kind === "step") {
37
- const modulo = () =>
38
- ts.factory.createModulo(input, caster(tag.value));
39
- const minimum = (() => {
40
- for (const tag of metaTags)
41
- if (tag.kind === "minimum") return tag.value;
42
- else if (tag.kind === "exclusiveMinimum")
43
- return tag.value;
44
- return undefined;
45
- })();
46
- conditions.push(
29
+ const modulo = ts.factory.createModulo(input, cast(tag.value));
30
+ const minimum =
31
+ (metaTags.find(
32
+ (tag) =>
33
+ tag.kind === "minimum" ||
34
+ tag.kind === "exclusiveMinimum",
35
+ )?.value as number | undefined) ?? undefined;
36
+ entries.push([
37
+ tag,
47
38
  ts.factory.createStrictEquality(
48
- caster(0),
39
+ cast(0),
49
40
  minimum !== undefined
50
- ? ts.factory.createSubtract(
51
- modulo(),
52
- caster(minimum),
53
- )
54
- : modulo(),
41
+ ? ts.factory.createSubtract(modulo, cast(minimum))
42
+ : modulo,
55
43
  ),
56
- );
44
+ ]);
57
45
  } else if (tag.kind === "minimum")
58
- conditions.push(
59
- ts.factory.createLessThanEquals(caster(tag.value), input),
60
- );
46
+ entries.push([
47
+ tag,
48
+ ts.factory.createLessThanEquals(cast(tag.value), input),
49
+ ]);
61
50
  else if (tag.kind === "maximum")
62
- conditions.push(
63
- ts.factory.createGreaterThanEquals(
64
- caster(tag.value),
65
- input,
66
- ),
67
- );
51
+ entries.push([
52
+ tag,
53
+ ts.factory.createGreaterThanEquals(cast(tag.value), input),
54
+ ]);
68
55
  else if (tag.kind === "exclusiveMinimum")
69
- conditions.push(
70
- ts.factory.createLessThan(caster(tag.value), input),
71
- );
56
+ entries.push([
57
+ tag,
58
+ ts.factory.createLessThan(cast(tag.value), input),
59
+ ]);
72
60
  else if (tag.kind === "exclusiveMaximum")
73
- conditions.push(
74
- ts.factory.createGreaterThan(caster(tag.value), input),
75
- );
76
-
77
- // CUSTOM TAGS
78
- conditions.push(...check_custom("bigint")(importer)(input, jsDocTags));
79
-
80
- // COMBINATION
81
- return conditions.length === 1
82
- ? conditions[0]!
83
- : conditions.reduce((x, y) => ts.factory.createLogicalAnd(x, y));
61
+ entries.push([
62
+ tag,
63
+ ts.factory.createGreaterThan(cast(tag.value), input),
64
+ ]);
65
+ }
66
+ return {
67
+ expression: ts.factory.createStrictEquality(
68
+ ts.factory.createStringLiteral("bigint"),
69
+ ts.factory.createTypeOfExpression(input),
70
+ ),
71
+ tags: [
72
+ ...entries.map(([tag, expression]) => ({
73
+ expected: `bigint (@${tag.kind} ${tag.value})`,
74
+ expression,
75
+ })),
76
+ ...check_custom("bigint")(importer)(jsDocTag)(input),
77
+ ],
78
+ };
84
79
  };
80
+
81
+ const cast = (value: number) =>
82
+ ts.factory.createIdentifier(`${Math.floor(value)}n`);