typia 5.5.5 → 5.5.6-dev.20240320

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/factories/MetadataCommentTagFactory.js +54 -0
  2. package/lib/factories/MetadataCommentTagFactory.js.map +1 -1
  3. package/lib/factories/MetadataTypeTagFactory.js +20 -0
  4. package/lib/factories/MetadataTypeTagFactory.js.map +1 -1
  5. package/lib/factories/MetadataTypeTagSchemaFactory.d.ts +4 -0
  6. package/lib/factories/MetadataTypeTagSchemaFactory.js +84 -0
  7. package/lib/factories/MetadataTypeTagSchemaFactory.js.map +1 -0
  8. package/lib/programmers/internal/application_array.js +5 -1
  9. package/lib/programmers/internal/application_array.js.map +1 -1
  10. package/lib/programmers/internal/application_boolean.js +12 -4
  11. package/lib/programmers/internal/application_boolean.js.map +1 -1
  12. package/lib/programmers/internal/application_string.js +5 -1
  13. package/lib/programmers/internal/application_string.js.map +1 -1
  14. package/lib/schemas/metadata/IMetadataTypeTag.d.ts +1 -0
  15. package/lib/schemas/metadata/MetadataAtomic.js +2 -0
  16. package/lib/schemas/metadata/MetadataAtomic.js.map +1 -1
  17. package/lib/tags/Default.d.ts +3 -0
  18. package/lib/tags/ExclusiveMaximum.d.ts +4 -0
  19. package/lib/tags/ExclusiveMinimum.d.ts +4 -0
  20. package/lib/tags/Format.d.ts +3 -0
  21. package/lib/tags/MaxItems.d.ts +3 -0
  22. package/lib/tags/MaxLength.d.ts +3 -0
  23. package/lib/tags/Maximum.d.ts +3 -0
  24. package/lib/tags/MinItems.d.ts +3 -0
  25. package/lib/tags/MinLength.d.ts +3 -0
  26. package/lib/tags/Minimum.d.ts +3 -0
  27. package/lib/tags/MultipleOf.d.ts +3 -0
  28. package/lib/tags/Pattern.d.ts +3 -0
  29. package/lib/tags/TagBase.d.ts +6 -2
  30. package/package.json +1 -1
  31. package/src/factories/MetadataCommentTagFactory.ts +64 -9
  32. package/src/factories/MetadataTypeTagFactory.ts +20 -1
  33. package/src/factories/MetadataTypeTagSchemaFactory.ts +58 -0
  34. package/src/programmers/internal/application_array.ts +5 -1
  35. package/src/programmers/internal/application_boolean.ts +12 -3
  36. package/src/programmers/internal/application_string.ts +5 -1
  37. package/src/schemas/metadata/IMetadataTypeTag.ts +1 -0
  38. package/src/schemas/metadata/MetadataAtomic.ts +1 -0
  39. package/src/tags/Default.ts +7 -4
  40. package/src/tags/ExclusiveMaximum.ts +6 -0
  41. package/src/tags/ExclusiveMinimum.ts +6 -0
  42. package/src/tags/Format.ts +3 -0
  43. package/src/tags/MaxItems.ts +3 -0
  44. package/src/tags/MaxLength.ts +3 -0
  45. package/src/tags/Maximum.ts +5 -0
  46. package/src/tags/MinItems.ts +3 -0
  47. package/src/tags/MinLength.ts +3 -0
  48. package/src/tags/Minimum.ts +5 -0
  49. package/src/tags/MultipleOf.ts +5 -0
  50. package/src/tags/Pattern.ts +3 -0
  51. package/src/tags/TagBase.ts +9 -1
@@ -5,6 +5,10 @@ export type ExclusiveMinimum<Value extends number | bigint> = TagBase<{
5
5
  value: Value;
6
6
  validate: `${Numeric<Value>} < $input`;
7
7
  exclusive: ["exclusiveMinimum", "minimum"];
8
+ schema: Value extends number ? {
9
+ exclusiveMinimum: true;
10
+ minimum: Value;
11
+ } : undefined;
8
12
  }>;
9
13
  type Numeric<Value extends number | bigint> = Value extends number ? Value : `BigInt(${Value})`;
10
14
  export {};
@@ -6,6 +6,9 @@ export type Format<Value extends keyof Format.Validator> = TagBase<{
6
6
  value: Value;
7
7
  validate: Format.Validator[Value];
8
8
  exclusive: ["format", "pattern"];
9
+ schema: {
10
+ format: Value;
11
+ };
9
12
  }>;
10
13
  export declare namespace Format {
11
14
  type Validator = typeof FormatCheatSheet;
@@ -5,4 +5,7 @@ export type MaxItems<Value extends number> = TagBase<{
5
5
  value: Value;
6
6
  validate: `$input.length <= ${Value}`;
7
7
  exclusive: true;
8
+ schema: {
9
+ maxItems: Value;
10
+ };
8
11
  }>;
@@ -5,4 +5,7 @@ export type MaxLength<Value extends number> = TagBase<{
5
5
  value: Value;
6
6
  validate: `$input.length <= ${Value}`;
7
7
  exclusive: true;
8
+ schema: {
9
+ maxLength: Value;
10
+ };
8
11
  }>;
@@ -5,6 +5,9 @@ export type Maximum<Value extends number | bigint> = TagBase<{
5
5
  value: Value;
6
6
  validate: `$input <= ${Numeric<Value>}`;
7
7
  exclusive: ["maximum", "exclusiveMaximum"];
8
+ schema: Value extends number ? {
9
+ maximum: Value;
10
+ } : undefined;
8
11
  }>;
9
12
  type Numeric<Value extends number | bigint> = Value extends number ? Value : `BigInt(${Value})`;
10
13
  export {};
@@ -5,4 +5,7 @@ export type MinItems<Value extends number> = TagBase<{
5
5
  value: Value;
6
6
  validate: `${Value} <= $input.length`;
7
7
  exclusive: true;
8
+ schema: {
9
+ minItems: Value;
10
+ };
8
11
  }>;
@@ -5,4 +5,7 @@ export type MinLength<Value extends number> = TagBase<{
5
5
  value: Value;
6
6
  validate: `${Value} <= $input.length`;
7
7
  exclusive: true;
8
+ schema: {
9
+ minLength: Value;
10
+ };
8
11
  }>;
@@ -5,6 +5,9 @@ export type Minimum<Value extends number | bigint> = TagBase<{
5
5
  value: Value;
6
6
  validate: `${Numeric<Value>} <= $input`;
7
7
  exclusive: ["minimum", "exclusiveMinimum"];
8
+ schema: Value extends number ? {
9
+ minimum: Value;
10
+ } : undefined;
8
11
  }>;
9
12
  type Numeric<Value extends number | bigint> = Value extends number ? Value : `BigInt(${Value})`;
10
13
  export {};
@@ -5,6 +5,9 @@ export type MultipleOf<Value extends number | bigint> = TagBase<{
5
5
  value: Value;
6
6
  validate: `$input % ${Numeric<Value>} === ${Value extends bigint ? Numeric<0n> : 0}`;
7
7
  exclusive: true;
8
+ schema: Value extends number ? {
9
+ multipleOf: Value;
10
+ } : undefined;
8
11
  }>;
9
12
  type Numeric<Value extends number | bigint> = Value extends number ? Value : `BigInt(${Value})`;
10
13
  export {};
@@ -5,4 +5,7 @@ export type Pattern<Value extends string> = TagBase<{
5
5
  value: Value;
6
6
  validate: `/${Value}/.test($input)`;
7
7
  exclusive: ["format", "pattern"];
8
+ schema: {
9
+ pattern: Value;
10
+ };
8
11
  }>;
@@ -1,4 +1,4 @@
1
- export type TagBase<Props extends TagBase.IProps<any, any, any, any, any>> = {
1
+ export type TagBase<Props extends TagBase.IProps<any, any, any, any, any, any>> = {
2
2
  /**
3
3
  * This is a dummy property for compilation.
4
4
  *
@@ -9,7 +9,7 @@ export type TagBase<Props extends TagBase.IProps<any, any, any, any, any>> = {
9
9
  export declare namespace TagBase {
10
10
  interface IProps<Target extends "boolean" | "bigint" | "number" | "string" | "array", Kind extends string, Value extends boolean | bigint | number | string | undefined, Validate extends string | {
11
11
  [key in Target]?: string;
12
- }, Exclusive extends boolean | string[]> {
12
+ }, Exclusive extends boolean | string[], Schema extends object | undefined> {
13
13
  /**
14
14
  * Target type.
15
15
  *
@@ -52,5 +52,9 @@ export declare namespace TagBase {
52
52
  * @default false
53
53
  */
54
54
  exclusive?: Exclusive | string[];
55
+ /**
56
+ * Additional schema info assigned to the {@link IJsonSchema} object.
57
+ */
58
+ schema?: Schema;
55
59
  }
56
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typia",
3
- "version": "5.5.5",
3
+ "version": "5.5.6-dev.20240320",
4
4
  "description": "Superfast runtime validators with only one line",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -117,8 +117,9 @@ type TagRecord = {
117
117
  [P in Target]?: NotDeterminedTypeTag[];
118
118
  };
119
119
  type Target = "bigint" | "number" | "string" | "array";
120
- type NotDeterminedTypeTag = Omit<IMetadataTypeTag, "validate"> & {
120
+ type NotDeterminedTypeTag = Omit<IMetadataTypeTag, "validate" | "schema"> & {
121
121
  validate: string | null;
122
+ schema: object | undefined;
122
123
  };
123
124
 
124
125
  const PARSER: Record<
@@ -139,6 +140,9 @@ const PARSER: Record<
139
140
  value: parse_integer(report)(true)(Value),
140
141
  validate: `${Value} <= $input.length`,
141
142
  exclusive: true,
143
+ schema: {
144
+ minItems: parse_integer(report)(true)(Value),
145
+ },
142
146
  },
143
147
  {
144
148
  name: `MaxItems<${Value}>`,
@@ -147,6 +151,9 @@ const PARSER: Record<
147
151
  value: parse_integer(report)(true)(Value),
148
152
  validate: `$input.length <= ${Value}`,
149
153
  exclusive: true,
154
+ schema: {
155
+ maxItems: parse_integer(report)(true)(Value),
156
+ },
150
157
  },
151
158
  ],
152
159
  }),
@@ -159,6 +166,9 @@ const PARSER: Record<
159
166
  value: parse_integer(report)(true)(Value),
160
167
  validate: `${Value} <= $input.length`,
161
168
  exclusive: true,
169
+ schema: {
170
+ minItems: parse_integer(report)(true)(Value),
171
+ },
162
172
  },
163
173
  ],
164
174
  }),
@@ -171,6 +181,9 @@ const PARSER: Record<
171
181
  value: parse_integer(report)(true)(Value),
172
182
  validate: `$input.length <= ${Value}`,
173
183
  exclusive: true,
184
+ schema: {
185
+ maxItems: parse_integer(report)(true)(Value),
186
+ },
174
187
  },
175
188
  ],
176
189
  }),
@@ -203,15 +216,16 @@ const PARSER: Record<
203
216
  Value === "int32"
204
217
  ? `Math.floor($input) === $input && -2147483648 <= $input && $input <= 2147483647`
205
218
  : Value === "uint32"
206
- ? `Math.floor($input) === $input && 0 <= $input && $input <= 4294967295`
207
- : Value === "int64"
208
- ? `Math.floor($input) === $input && -9223372036854775808 <= $input && $input <= 9223372036854775807`
209
- : Value === "uint64"
210
- ? `Math.floor($input) === $input && 0 <= $input && $input <= 18446744073709551615`
211
- : Value === "float"
212
- ? `-1.175494351e38 <= $input && $input <= 3.4028235e38`
213
- : `true`,
219
+ ? `Math.floor($input) === $input && 0 <= $input && $input <= 4294967295`
220
+ : Value === "int64"
221
+ ? `Math.floor($input) === $input && -9223372036854775808 <= $input && $input <= 9223372036854775807`
222
+ : Value === "uint64"
223
+ ? `Math.floor($input) === $input && 0 <= $input && $input <= 18446744073709551615`
224
+ : Value === "float"
225
+ ? `-1.175494351e38 <= $input && $input <= 3.4028235e38`
226
+ : `true`,
214
227
  exclusive: true,
228
+ schema: undefined,
215
229
  },
216
230
  ],
217
231
  bigint:
@@ -224,6 +238,7 @@ const PARSER: Record<
224
238
  value: Value,
225
239
  validate: Value === "int64" ? "true" : "BigInt(0) <= $input",
226
240
  exclusive: true,
241
+ schema: undefined,
227
242
  },
228
243
  ]
229
244
  : [],
@@ -238,6 +253,9 @@ const PARSER: Record<
238
253
  value: parse_number(report)(Value),
239
254
  validate: `${Value} <= $input`,
240
255
  exclusive: ["minimum", "exclusiveMinimum"],
256
+ schema: {
257
+ minimum: parse_number(report)(Value),
258
+ },
241
259
  },
242
260
  ],
243
261
  bigint: [
@@ -251,6 +269,7 @@ const PARSER: Record<
251
269
  })(),
252
270
  validate: `${Value} <= $input`,
253
271
  exclusive: ["minimum", "exclusiveMinimum"],
272
+ schema: undefined,
254
273
  },
255
274
  ],
256
275
  }),
@@ -263,6 +282,9 @@ const PARSER: Record<
263
282
  value: parse_number(report)(Value),
264
283
  validate: `$input <= ${Value}`,
265
284
  exclusive: ["maximum", "exclusiveMaximum"],
285
+ schema: {
286
+ maximum: parse_number(report)(Value),
287
+ },
266
288
  },
267
289
  ],
268
290
  bigint: [
@@ -276,6 +298,7 @@ const PARSER: Record<
276
298
  })(),
277
299
  validate: `$input <= ${Value}`,
278
300
  exclusive: ["maximum", "exclusiveMaximum"],
301
+ schema: undefined,
279
302
  },
280
303
  ],
281
304
  }),
@@ -288,6 +311,10 @@ const PARSER: Record<
288
311
  value: parse_number(report)(Value),
289
312
  validate: `${Value} < $input`,
290
313
  exclusive: ["minimum", "exclusiveMinimum"],
314
+ schema: {
315
+ exclusiveMinimum: true,
316
+ minimum: parse_number(report)(Value),
317
+ },
291
318
  },
292
319
  ],
293
320
  bigint: [
@@ -301,6 +328,7 @@ const PARSER: Record<
301
328
  })(),
302
329
  validate: `${Value} < $input`,
303
330
  exclusive: ["minimum", "exclusiveMinimum"],
331
+ schema: undefined,
304
332
  },
305
333
  ],
306
334
  }),
@@ -313,6 +341,10 @@ const PARSER: Record<
313
341
  value: parse_number(report)(Value),
314
342
  validate: `$input < ${Value}`,
315
343
  exclusive: ["maximum", "exclusiveMaximum"],
344
+ schema: {
345
+ exclusiveMaximum: true,
346
+ maximum: parse_number(report)(Value),
347
+ },
316
348
  },
317
349
  ],
318
350
  bigint: [
@@ -326,6 +358,7 @@ const PARSER: Record<
326
358
  })(),
327
359
  validate: `$input < ${Value}`,
328
360
  exclusive: ["maximum", "exclusiveMaximum"],
361
+ schema: undefined,
329
362
  },
330
363
  ],
331
364
  }),
@@ -338,6 +371,9 @@ const PARSER: Record<
338
371
  value: parse_number(report)(Value),
339
372
  validate: `$input % ${Value} === 0`,
340
373
  exclusive: true,
374
+ schema: {
375
+ multipleOf: parse_number(report)(Value),
376
+ },
341
377
  },
342
378
  ],
343
379
  bigint: [
@@ -351,6 +387,7 @@ const PARSER: Record<
351
387
  })(),
352
388
  validate: `$input % ${Value}n === 0n`,
353
389
  exclusive: true,
390
+ schema: undefined,
354
391
  },
355
392
  ],
356
393
  }),
@@ -370,6 +407,9 @@ const PARSER: Record<
370
407
  value: matched[0],
371
408
  validate: matched[1],
372
409
  exclusive: true,
410
+ schema: {
411
+ format: matched[0],
412
+ },
373
413
  },
374
414
  ],
375
415
  };
@@ -383,6 +423,9 @@ const PARSER: Record<
383
423
  value: Value,
384
424
  validate: `RegExp(/${Value}/).test($input)`,
385
425
  exclusive: ["format"],
426
+ schema: {
427
+ pattern: Value,
428
+ },
386
429
  },
387
430
  ],
388
431
  }),
@@ -395,6 +438,9 @@ const PARSER: Record<
395
438
  value: parse_number(report)(Value),
396
439
  validate: `${Value} <= $input.length`,
397
440
  exclusive: true,
441
+ schema: {
442
+ minLength: parse_number(report)(Value),
443
+ },
398
444
  },
399
445
  {
400
446
  name: `MaxLength<${Value}>`,
@@ -403,6 +449,9 @@ const PARSER: Record<
403
449
  value: parse_number(report)(Value),
404
450
  validate: `$input.length <= ${Value}`,
405
451
  exclusive: true,
452
+ schema: {
453
+ maxLength: parse_number(report)(Value),
454
+ },
406
455
  },
407
456
  ],
408
457
  }),
@@ -415,6 +464,9 @@ const PARSER: Record<
415
464
  value: parse_number(report)(Value),
416
465
  validate: `${Value} <= $input.length`,
417
466
  exclusive: true,
467
+ schema: {
468
+ minLength: parse_number(report)(Value),
469
+ },
418
470
  },
419
471
  ],
420
472
  }),
@@ -427,6 +479,9 @@ const PARSER: Record<
427
479
  value: parse_number(report)(Value),
428
480
  validate: `$input.length <= ${Value}`,
429
481
  exclusive: true,
482
+ schema: {
483
+ maxLength: parse_number(report)(Value),
484
+ },
430
485
  },
431
486
  ],
432
487
  }),
@@ -4,6 +4,7 @@ import { MetadataObject } from "../schemas/metadata/MetadataObject";
4
4
  import { MetadataProperty } from "../schemas/metadata/MetadataProperty";
5
5
 
6
6
  import { MetadataFactory } from "./MetadataFactory";
7
+ import { MetadataTypeTagSchemaFactory } from "./MetadataTypeTagSchemaFactory";
7
8
 
8
9
  export namespace MetadataTypeTagFactory {
9
10
  export const analyze =
@@ -83,6 +84,7 @@ export namespace MetadataTypeTagFactory {
83
84
  value: tag.value,
84
85
  validate: tag.validate[type]!,
85
86
  exclusive: tag.exclusive,
87
+ schema: tag.schema,
86
88
  });
87
89
  validate(report)(type)(output);
88
90
 
@@ -256,7 +258,22 @@ export namespace MetadataTypeTagFactory {
256
258
  ]),
257
259
  );
258
260
  })();
259
-
261
+ const schema: object | undefined = (() => {
262
+ const p: Metadata | undefined = find("schema")?.value;
263
+ if (p === undefined) return undefined;
264
+ else if (p.size() === 0 && p.isRequired() === false) return undefined;
265
+ else if (
266
+ p.size() === 1 &&
267
+ p.nullable === false &&
268
+ p.isRequired() === true &&
269
+ p.any === false
270
+ )
271
+ return MetadataTypeTagSchemaFactory.object((msg) =>
272
+ report("schema")(msg),
273
+ )(p.objects[0]!);
274
+ report("schema")("must be an object type");
275
+ return undefined;
276
+ })();
260
277
  return {
261
278
  name: obj.name,
262
279
  target,
@@ -264,6 +281,7 @@ export namespace MetadataTypeTagFactory {
264
281
  value,
265
282
  validate,
266
283
  exclusive: exclusive ?? false,
284
+ schema,
267
285
  };
268
286
  };
269
287
 
@@ -307,6 +325,7 @@ interface ITypeTag {
307
325
  value?: undefined | boolean | bigint | number | string;
308
326
  validate: Record<string, string>;
309
327
  exclusive: boolean | string[];
328
+ schema?: undefined | any;
310
329
  }
311
330
 
312
331
  const ESSENTIAL_FIELDS = ["target", "kind", "value"];
@@ -0,0 +1,58 @@
1
+ import { Metadata } from "../schemas/metadata/Metadata";
2
+ import { MetadataObject } from "../schemas/metadata/MetadataObject";
3
+
4
+ export namespace MetadataTypeTagSchemaFactory {
5
+ export const object =
6
+ (report: (msg: string) => false) =>
7
+ (obj: MetadataObject): object | undefined => {
8
+ if (obj.recursive) {
9
+ report(`${obj.name} has recursive type`);
10
+ return undefined;
11
+ }
12
+ const output: any = {};
13
+ for (const p of obj.properties) {
14
+ const key: string | null = p.key.getSoleLiteral()!;
15
+ if (key === null) {
16
+ report(`${obj.name} has non-literal key type: ${p.key.getName()}`);
17
+ continue;
18
+ }
19
+ output[key] = iterate(report)({ object: obj, key })(p.value);
20
+ }
21
+ return output;
22
+ };
23
+
24
+ const iterate =
25
+ (report: (msg: string) => false) =>
26
+ (parent: { object: MetadataObject; key: string }) =>
27
+ (meta: Metadata): any => {
28
+ if (
29
+ meta.any ||
30
+ meta.atomics.length ||
31
+ meta.arrays.length ||
32
+ meta.natives.length ||
33
+ meta.functional
34
+ )
35
+ report(`${parent.object.name}.${parent.key} has non-literal type`);
36
+ else if (meta.size() > 1)
37
+ report(`${parent.object.name}.${parent.key} has union type`);
38
+ else if (meta.size() === 0)
39
+ if (meta.nullable) return null;
40
+ else if (meta.isRequired() === true)
41
+ report(`${parent.object.name}.${parent.key} has non-literal type`);
42
+ else return undefined;
43
+ else if (meta.constants.length) return meta.constants[0]!.values[0]!;
44
+ else if (meta.tuples.length) {
45
+ const tuple = meta.tuples[0]!;
46
+ if (tuple.type.isRest())
47
+ report(`${parent.object.name}.${parent.key} has rest tuple type`);
48
+ else if (tuple.type.recursive)
49
+ report(
50
+ `${parent.object.name}.${parent.key} has recursive tuple type`,
51
+ );
52
+ else if (tuple.type.elements.some((e) => e.required === false))
53
+ report(`${parent.object.name}.${parent.key} has optional tuple type`);
54
+ return tuple.type.elements.map(iterate(report)(parent));
55
+ } else if (meta.objects.length) return object(report)(meta.objects[0]!);
56
+ else report(`${parent.object.name}.${parent.key} has non-literal type`);
57
+ };
58
+ }
@@ -41,11 +41,15 @@ const application_array_tags =
41
41
  (options: JsonApplicationProgrammer.IOptions) =>
42
42
  (schema: IJsonSchema.IArray) =>
43
43
  (row: IMetadataTypeTag[]): IJsonSchema.IArray => {
44
- for (const tag of row.slice().sort((a, b) => a.kind.localeCompare(b.kind)))
44
+ for (const tag of row
45
+ .slice()
46
+ .sort((a, b) => a.kind.localeCompare(b.kind))) {
45
47
  if (tag.kind === "minItems" && typeof tag.value === "number")
46
48
  schema.minItems = tag.value;
47
49
  else if (tag.kind === "maxItems" && typeof tag.value === "number")
48
50
  schema.maxItems = tag.value;
51
+ if (tag.schema) Object.assign(schema, tag.schema);
52
+ }
49
53
  if (options.surplus)
50
54
  schema["x-typia-typeTags"] = row.map((tag) => ({
51
55
  target: tag.target,
@@ -19,17 +19,26 @@ export const application_boolean =
19
19
  type: "boolean",
20
20
  };
21
21
  const defaultTags: IMetadataTypeTag[] = atomic.tags
22
- .filter((row) => row.some((tag) => tag.kind === "default"))
23
- .map((row) => row.filter((tag) => tag.kind === "default"))
22
+ .filter((row) =>
23
+ row.some((tag) => tag.kind === "default" || tag.schema !== undefined),
24
+ )
25
+ .map((row) =>
26
+ row.filter((tag) => tag.kind === "default" || tag.schema !== undefined),
27
+ )
24
28
  .flat();
25
29
  if (defaultTags.length === 0) return [base];
26
30
  return defaultTags.map((tag) => ({
27
31
  ...base,
28
- default: tag.value,
32
+ ...(tag.kind === "default"
33
+ ? {
34
+ default: tag.value,
35
+ }
36
+ : {}),
29
37
  ...(options.surplus
30
38
  ? {
31
39
  "x-typia-typeTags": defaultTags,
32
40
  }
33
41
  : {}),
42
+ ...tag.schema,
34
43
  }));
35
44
  };
@@ -38,7 +38,9 @@ const application_string_tags =
38
38
  (options: JsonApplicationProgrammer.IOptions) =>
39
39
  (base: IJsonSchema.IString) =>
40
40
  (row: IMetadataTypeTag[]): IJsonSchema.IString | null => {
41
- for (const tag of row.slice().sort((a, b) => a.kind.localeCompare(b.kind)))
41
+ for (const tag of row
42
+ .slice()
43
+ .sort((a, b) => a.kind.localeCompare(b.kind))) {
42
44
  if (tag.kind === "minLength" && typeof tag.value === "number")
43
45
  base.minLength = tag.value;
44
46
  else if (tag.kind === "maxLength" && typeof tag.value === "number")
@@ -48,6 +50,8 @@ const application_string_tags =
48
50
  else if (tag.kind === "pattern") base.pattern = tag.value;
49
51
  else if (tag.kind === "default" && typeof tag.value === "string")
50
52
  base.default = tag.value;
53
+ if (tag.schema) Object.assign(base, tag.schema);
54
+ }
51
55
  if (options.surplus)
52
56
  base["x-typia-typeTags"] = row.map((tag) => ({
53
57
  target: tag.target,
@@ -7,6 +7,7 @@ export interface IMetadataTypeTag {
7
7
  exclusive: boolean | string[];
8
8
  value?: any;
9
9
  validate?: string | undefined;
10
+ schema?: object | undefined;
10
11
 
11
12
  /**
12
13
  * @internal
@@ -77,6 +77,7 @@ export class MetadataAtomic {
77
77
  : tag.value,
78
78
  validate: tag.validate,
79
79
  exclusive: tag.exclusive,
80
+ schema: this.type !== "bigint" ? tag.schema : undefined,
80
81
  })),
81
82
  ),
82
83
  };
@@ -5,11 +5,14 @@ export type Default<Value extends boolean | bigint | number | string> =
5
5
  target: Value extends boolean
6
6
  ? "boolean"
7
7
  : Value extends bigint
8
- ? "bigint"
9
- : Value extends number
10
- ? "number"
11
- : "string";
8
+ ? "bigint"
9
+ : Value extends number
10
+ ? "number"
11
+ : "string";
12
12
  kind: "default";
13
13
  value: Value;
14
14
  exclusive: true;
15
+ schema: {
16
+ default: Value;
17
+ };
15
18
  }>;
@@ -6,6 +6,12 @@ export type ExclusiveMaximum<Value extends number | bigint> = TagBase<{
6
6
  value: Value;
7
7
  validate: `$input < ${Numeric<Value>}`;
8
8
  exclusive: ["exclusiveMaximum", "maximum"];
9
+ schema: Value extends number
10
+ ? {
11
+ exclusiveMaximum: true;
12
+ maximum: Value;
13
+ }
14
+ : undefined;
9
15
  }>;
10
16
 
11
17
  type Numeric<Value extends number | bigint> = Value extends number
@@ -6,6 +6,12 @@ export type ExclusiveMinimum<Value extends number | bigint> = TagBase<{
6
6
  value: Value;
7
7
  validate: `${Numeric<Value>} < $input`;
8
8
  exclusive: ["exclusiveMinimum", "minimum"];
9
+ schema: Value extends number
10
+ ? {
11
+ exclusiveMinimum: true;
12
+ minimum: Value;
13
+ }
14
+ : undefined;
9
15
  }>;
10
16
 
11
17
  type Numeric<Value extends number | bigint> = Value extends number
@@ -7,6 +7,9 @@ export type Format<Value extends keyof Format.Validator> = TagBase<{
7
7
  value: Value;
8
8
  validate: Format.Validator[Value];
9
9
  exclusive: ["format", "pattern"];
10
+ schema: {
11
+ format: Value;
12
+ };
10
13
  }>;
11
14
  export namespace Format {
12
15
  export type Validator = typeof FormatCheatSheet;
@@ -6,4 +6,7 @@ export type MaxItems<Value extends number> = TagBase<{
6
6
  value: Value;
7
7
  validate: `$input.length <= ${Value}`;
8
8
  exclusive: true;
9
+ schema: {
10
+ maxItems: Value;
11
+ };
9
12
  }>;
@@ -6,4 +6,7 @@ export type MaxLength<Value extends number> = TagBase<{
6
6
  value: Value;
7
7
  validate: `$input.length <= ${Value}`;
8
8
  exclusive: true;
9
+ schema: {
10
+ maxLength: Value;
11
+ };
9
12
  }>;
@@ -6,6 +6,11 @@ export type Maximum<Value extends number | bigint> = TagBase<{
6
6
  value: Value;
7
7
  validate: `$input <= ${Numeric<Value>}`;
8
8
  exclusive: ["maximum", "exclusiveMaximum"];
9
+ schema: Value extends number
10
+ ? {
11
+ maximum: Value;
12
+ }
13
+ : undefined;
9
14
  }>;
10
15
 
11
16
  type Numeric<Value extends number | bigint> = Value extends number
@@ -6,4 +6,7 @@ export type MinItems<Value extends number> = TagBase<{
6
6
  value: Value;
7
7
  validate: `${Value} <= $input.length`;
8
8
  exclusive: true;
9
+ schema: {
10
+ minItems: Value;
11
+ };
9
12
  }>;
@@ -6,4 +6,7 @@ export type MinLength<Value extends number> = TagBase<{
6
6
  value: Value;
7
7
  validate: `${Value} <= $input.length`;
8
8
  exclusive: true;
9
+ schema: {
10
+ minLength: Value;
11
+ };
9
12
  }>;