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

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 (47) hide show
  1. package/lib/functional/$dictionary.d.ts +1 -1
  2. package/lib/programmers/AssertProgrammer.js +11 -0
  3. package/lib/programmers/AssertProgrammer.js.map +1 -1
  4. package/lib/programmers/CheckerProgrammer.d.ts +2 -0
  5. package/lib/programmers/CheckerProgrammer.js +11 -12
  6. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  7. package/lib/programmers/IsProgrammer.js +30 -0
  8. package/lib/programmers/IsProgrammer.js.map +1 -1
  9. package/lib/programmers/ValidateProgrammer.js +11 -0
  10. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  11. package/lib/programmers/helpers/ICheckEntry.d.ts +11 -0
  12. package/lib/programmers/helpers/ICheckEntry.js +3 -0
  13. package/lib/programmers/helpers/ICheckEntry.js.map +1 -0
  14. package/lib/programmers/internal/check_array.js +7 -11
  15. package/lib/programmers/internal/check_array.js.map +1 -1
  16. package/lib/programmers/internal/check_array_length.js +23 -36
  17. package/lib/programmers/internal/check_array_length.js.map +1 -1
  18. package/lib/programmers/internal/check_bigint.d.ts +1 -5
  19. package/lib/programmers/internal/check_bigint.js +67 -61
  20. package/lib/programmers/internal/check_bigint.js.map +1 -1
  21. package/lib/programmers/internal/check_custom.d.ts +2 -1
  22. package/lib/programmers/internal/check_custom.js +26 -16
  23. package/lib/programmers/internal/check_custom.js.map +1 -1
  24. package/lib/programmers/internal/check_number.js +88 -64
  25. package/lib/programmers/internal/check_number.js.map +1 -1
  26. package/lib/programmers/internal/check_string.js +9 -9
  27. package/lib/programmers/internal/check_string.js.map +1 -1
  28. package/lib/programmers/internal/check_string_tags.js +63 -24
  29. package/lib/programmers/internal/check_string_tags.js.map +1 -1
  30. package/lib/programmers/internal/check_template.js +23 -11
  31. package/lib/programmers/internal/check_template.js.map +1 -1
  32. package/lib/typings/Customizable.d.ts +0 -1
  33. package/package.json +1 -1
  34. package/src/programmers/AssertProgrammer.ts +24 -0
  35. package/src/programmers/CheckerProgrammer.ts +45 -46
  36. package/src/programmers/IsProgrammer.ts +5 -0
  37. package/src/programmers/ValidateProgrammer.ts +24 -0
  38. package/src/programmers/helpers/ICheckEntry.ts +12 -0
  39. package/src/programmers/internal/check_array.ts +10 -15
  40. package/src/programmers/internal/check_array_length.ts +31 -35
  41. package/src/programmers/internal/check_bigint.ts +60 -62
  42. package/src/programmers/internal/check_custom.ts +25 -16
  43. package/src/programmers/internal/check_number.ts +102 -83
  44. package/src/programmers/internal/check_string.ts +14 -19
  45. package/src/programmers/internal/check_string_tags.ts +23 -13
  46. package/src/programmers/internal/check_template.ts +16 -7
  47. 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",
4
4
  "description": "Superfast runtime validators with only one line",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -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`);
@@ -5,28 +5,37 @@ import { MetadataTagFactory } from "../../factories/MetadataTagFactory";
5
5
  import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
6
6
 
7
7
  import { FunctionImporter } from "../helpers/FunctionImporeter";
8
+ import { ICheckEntry } from "../helpers/ICheckEntry";
8
9
 
9
10
  export const check_custom =
10
- (type: string) =>
11
+ (type: string, alias?: string) =>
11
12
  (importer: FunctionImporter) =>
12
- (input: ts.Expression, jsDocTags: IJsDocTagInfo[]) =>
13
+ (jsDocTags: IJsDocTagInfo[]) =>
14
+ (input: ts.Expression): ICheckEntry.ITag[] =>
13
15
  jsDocTags
14
16
  .filter(
15
17
  (tag) =>
16
18
  tag.name !== "random" &&
19
+ (!tag.text?.length ||
20
+ (tag.text?.length === 1 &&
21
+ tag.text?.[0]?.kind === "text")) &&
17
22
  MetadataTagFactory._PARSER[tag.name] === undefined,
18
23
  )
19
- .map((tag) =>
20
- ts.factory.createCallExpression(
21
- importer.use("is_custom"),
22
- undefined,
23
- [
24
- ts.factory.createStringLiteral(tag.name),
25
- ts.factory.createStringLiteral(type),
26
- ts.factory.createStringLiteral(
27
- tag.text?.[0]?.text ?? "",
28
- ),
29
- input,
30
- ],
31
- ),
32
- );
24
+ .map((tag) => {
25
+ const text: string | undefined = tag.text?.[0]?.text ?? "";
26
+ return {
27
+ expected: `${alias ?? type} (@${tag.name}${
28
+ text.length ? ` ${text}` : ""
29
+ })`,
30
+ expression: ts.factory.createCallExpression(
31
+ importer.use("is_custom"),
32
+ undefined,
33
+ [
34
+ ts.factory.createStringLiteral(tag.name),
35
+ ts.factory.createStringLiteral(type),
36
+ ts.factory.createStringLiteral(text),
37
+ input,
38
+ ],
39
+ ),
40
+ };
41
+ });