typia 9.7.0 → 9.7.1

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 (73) hide show
  1. package/lib/programmers/json/JsonStringifyProgrammer.js +2 -2
  2. package/lib/programmers/json/JsonStringifyProgrammer.js.map +1 -1
  3. package/lib/programmers/json/JsonStringifyProgrammer.mjs +2 -2
  4. package/lib/tags/Constant.d.mts +32 -0
  5. package/lib/tags/Constant.d.ts +32 -0
  6. package/lib/tags/ContentMediaType.d.mts +17 -0
  7. package/lib/tags/ContentMediaType.d.ts +17 -0
  8. package/lib/tags/Default.d.mts +30 -0
  9. package/lib/tags/Default.d.ts +30 -0
  10. package/lib/tags/Example.d.mts +32 -0
  11. package/lib/tags/Example.d.ts +32 -0
  12. package/lib/tags/Examples.d.mts +40 -0
  13. package/lib/tags/Examples.d.ts +40 -0
  14. package/lib/tags/ExclusiveMaximum.d.mts +18 -0
  15. package/lib/tags/ExclusiveMaximum.d.ts +18 -0
  16. package/lib/tags/ExclusiveMinimum.d.mts +18 -0
  17. package/lib/tags/ExclusiveMinimum.d.ts +18 -0
  18. package/lib/tags/Format.d.mts +24 -0
  19. package/lib/tags/Format.d.ts +24 -0
  20. package/lib/tags/JsonSchemaPlugin.d.mts +26 -0
  21. package/lib/tags/JsonSchemaPlugin.d.ts +26 -0
  22. package/lib/tags/MaxItems.d.mts +19 -0
  23. package/lib/tags/MaxItems.d.ts +19 -0
  24. package/lib/tags/MaxLength.d.mts +12 -0
  25. package/lib/tags/MaxLength.d.ts +12 -0
  26. package/lib/tags/Maximum.d.mts +18 -0
  27. package/lib/tags/Maximum.d.ts +18 -0
  28. package/lib/tags/MinItems.d.mts +19 -0
  29. package/lib/tags/MinItems.d.ts +19 -0
  30. package/lib/tags/MinLength.d.mts +12 -0
  31. package/lib/tags/MinLength.d.ts +12 -0
  32. package/lib/tags/Minimum.d.mts +18 -0
  33. package/lib/tags/Minimum.d.ts +18 -0
  34. package/lib/tags/MultipleOf.d.mts +18 -0
  35. package/lib/tags/MultipleOf.d.ts +18 -0
  36. package/lib/tags/Pattern.d.mts +15 -0
  37. package/lib/tags/Pattern.d.ts +15 -0
  38. package/lib/tags/Sequence.d.mts +25 -0
  39. package/lib/tags/Sequence.d.ts +25 -0
  40. package/lib/tags/TagBase.d.mts +27 -0
  41. package/lib/tags/TagBase.d.ts +27 -0
  42. package/lib/tags/Type.d.mts +26 -0
  43. package/lib/tags/Type.d.ts +26 -0
  44. package/lib/tags/UniqueItems.d.mts +19 -0
  45. package/lib/tags/UniqueItems.d.ts +19 -0
  46. package/lib/transformers/ImportTransformer.js +119 -1
  47. package/lib/transformers/ImportTransformer.js.map +1 -1
  48. package/lib/transformers/ImportTransformer.mjs +119 -1
  49. package/package.json +1 -1
  50. package/src/IRandomGenerator.ts +13 -5
  51. package/src/programmers/json/JsonStringifyProgrammer.ts +2 -2
  52. package/src/tags/Constant.ts +32 -0
  53. package/src/tags/ContentMediaType.ts +17 -0
  54. package/src/tags/Default.ts +30 -0
  55. package/src/tags/Example.ts +32 -0
  56. package/src/tags/Examples.ts +40 -0
  57. package/src/tags/ExclusiveMaximum.ts +18 -0
  58. package/src/tags/ExclusiveMinimum.ts +18 -0
  59. package/src/tags/Format.ts +24 -0
  60. package/src/tags/JsonSchemaPlugin.ts +26 -0
  61. package/src/tags/MaxItems.ts +19 -0
  62. package/src/tags/MaxLength.ts +12 -0
  63. package/src/tags/Maximum.ts +18 -0
  64. package/src/tags/MinItems.ts +19 -0
  65. package/src/tags/MinLength.ts +12 -0
  66. package/src/tags/Minimum.ts +18 -0
  67. package/src/tags/MultipleOf.ts +18 -0
  68. package/src/tags/Pattern.ts +15 -0
  69. package/src/tags/Sequence.ts +25 -0
  70. package/src/tags/TagBase.ts +27 -0
  71. package/src/tags/Type.ts +26 -0
  72. package/src/tags/UniqueItems.ts +19 -0
  73. package/src/transformers/ImportTransformer.ts +178 -1
@@ -1,4 +1,23 @@
1
1
  import { TagBase } from "./TagBase";
2
+ /**
3
+ * Unique items validation tag for arrays.
4
+ *
5
+ * Enforces that all items in an array are unique, preventing duplicate values.
6
+ * Uniqueness is determined using strict equality (===) for primitives and
7
+ * deep structural comparison for objects and arrays. This means two objects
8
+ * with the same properties and values are considered duplicates.
9
+ *
10
+ * @example
11
+ * // Ensure all IDs are unique
12
+ * type UserIds = number[] & UniqueItems;
13
+ *
14
+ * @example
15
+ * // Prevent duplicate email addresses
16
+ * type EmailList = string[] & UniqueItems;
17
+ *
18
+ * @template Value - Boolean flag to enable/disable uniqueness validation (defaults to true)
19
+ * @author Jeongho Nam - https://github.com/samchon
20
+ */
2
21
  export type UniqueItems<Value extends boolean = true> = TagBase<{
3
22
  target: "array";
4
23
  kind: "uniqueItems";
@@ -1,4 +1,23 @@
1
1
  import { TagBase } from "./TagBase";
2
+ /**
3
+ * Unique items validation tag for arrays.
4
+ *
5
+ * Enforces that all items in an array are unique, preventing duplicate values.
6
+ * Uniqueness is determined using strict equality (===) for primitives and
7
+ * deep structural comparison for objects and arrays. This means two objects
8
+ * with the same properties and values are considered duplicates.
9
+ *
10
+ * @example
11
+ * // Ensure all IDs are unique
12
+ * type UserIds = number[] & UniqueItems;
13
+ *
14
+ * @example
15
+ * // Prevent duplicate email addresses
16
+ * type EmailList = string[] & UniqueItems;
17
+ *
18
+ * @template Value - Boolean flag to enable/disable uniqueness validation (defaults to true)
19
+ * @author Jeongho Nam - https://github.com/samchon
20
+ */
2
21
  export type UniqueItems<Value extends boolean = true> = TagBase<{
3
22
  target: "array";
4
23
  kind: "uniqueItems";
@@ -19,12 +19,16 @@ var ImportTransformer;
19
19
  return props.file;
20
20
  const from = get_directory_path(path_1.default.resolve(props.file.getSourceFile().fileName));
21
21
  const to = from.replace(props.top, props.to);
22
- return typescript_1.default.visitEachChild(props.file, (node) => transform_node({
22
+ // First pass: transform relative imports
23
+ let transformedFile = typescript_1.default.visitEachChild(props.file, (node) => transform_node({
23
24
  top: props.top,
24
25
  from,
25
26
  to,
26
27
  node,
27
28
  }), props.context);
29
+ // Second pass: remove unused typia imports
30
+ transformedFile = removeUnusedTypiaImports(transformedFile);
31
+ return transformedFile;
28
32
  };
29
33
  const transform_node = (props) => {
30
34
  if (!typescript_1.default.isImportDeclaration(props.node) ||
@@ -51,4 +55,118 @@ const get_directory_path = (file) => {
51
55
  split.pop();
52
56
  return path_1.default.resolve(split.join(path_1.default.sep));
53
57
  };
58
+ /**
59
+ * Remove unused typia imports that are only used in transformable calls
60
+ */
61
+ const removeUnusedTypiaImports = (file) => {
62
+ const imports = new Map();
63
+ for (const stmt of file.statements) {
64
+ if (typescript_1.default.isImportDeclaration(stmt) === false ||
65
+ typescript_1.default.isStringLiteral(stmt.moduleSpecifier) === false ||
66
+ stmt.moduleSpecifier.text !== "typia" ||
67
+ stmt.importClause === undefined)
68
+ continue;
69
+ // Track default import (import typia from 'typia')
70
+ if (stmt.importClause.name)
71
+ imports.set(stmt.importClause.name.text, {
72
+ declaration: stmt,
73
+ default: true,
74
+ });
75
+ // Track named imports (import { tags } from 'typia') - keep these
76
+ if (stmt.importClause.namedBindings &&
77
+ typescript_1.default.isNamedImports(stmt.importClause.namedBindings))
78
+ for (const element of stmt.importClause.namedBindings.elements)
79
+ imports.set(element.name.text, {
80
+ declaration: stmt,
81
+ default: false,
82
+ });
83
+ }
84
+ if (imports.size === 0)
85
+ return file; // No typia imports to check
86
+ // Find usage of typia identifiers that are NOT transformable calls
87
+ const nonTransformableUsage = new Set();
88
+ const checkUsage = (node) => {
89
+ if (typescript_1.default.isIdentifier(node) && imports.has(node.text)) {
90
+ const identifier = node.text;
91
+ // Check if this identifier is being used as part of a property access
92
+ if (node.parent &&
93
+ typescript_1.default.isPropertyAccessExpression(node.parent) &&
94
+ node.parent.expression === node) {
95
+ // This is typia.something - check if it's a transformable call pattern
96
+ if (!isLikelyTransformableCall(node.parent))
97
+ nonTransformableUsage.add(identifier);
98
+ }
99
+ else
100
+ // Direct usage of the typia identifier (not as property access)
101
+ // This is definitely non-transformable usage
102
+ nonTransformableUsage.add(identifier);
103
+ }
104
+ typescript_1.default.forEachChild(node, checkUsage);
105
+ };
106
+ // Check all statements except import declarations
107
+ for (const stmt of file.statements)
108
+ if (!typescript_1.default.isImportDeclaration(stmt) ||
109
+ !typescript_1.default.isStringLiteral(stmt.moduleSpecifier) ||
110
+ stmt.moduleSpecifier.text !== "typia")
111
+ checkUsage(stmt);
112
+ // Update import statements
113
+ const newStatements = file.statements
114
+ .map((stmt) => {
115
+ if (typescript_1.default.isImportDeclaration(stmt) &&
116
+ typescript_1.default.isStringLiteral(stmt.moduleSpecifier) &&
117
+ stmt.moduleSpecifier.text === "typia" &&
118
+ stmt.importClause) {
119
+ const newImportClause = filterTypiaImportClause(stmt.importClause, nonTransformableUsage);
120
+ if (newImportClause)
121
+ return typescript_1.default.factory.createImportDeclaration(stmt.modifiers, newImportClause, stmt.moduleSpecifier, stmt.attributes);
122
+ return null; // Skip adding the import if all imports are unused
123
+ }
124
+ return stmt;
125
+ })
126
+ .filter((stmt) => stmt !== null);
127
+ return typescript_1.default.factory.updateSourceFile(file, newStatements, file.isDeclarationFile, file.referencedFiles, file.typeReferenceDirectives, file.hasNoDefaultLib, file.libReferenceDirectives);
128
+ };
129
+ /**
130
+ * Check if a property access expression looks like a transformable typia call
131
+ * This uses heuristics to detect patterns like typia.xxx(), typia.namespace.xxx()
132
+ */
133
+ const isLikelyTransformableCall = (node) => {
134
+ // Check if this is eventually part of a call expression
135
+ let current = node;
136
+ // Walk up the chain to find if this leads to a call expression
137
+ // Handle patterns like: typia.xxx(), typia.namespace.xxx()
138
+ while (typescript_1.default.isPropertyAccessExpression(current)) {
139
+ current = current.parent;
140
+ }
141
+ // If the final result is a call expression, this is likely transformable
142
+ if (typescript_1.default.isCallExpression(current) &&
143
+ (current.expression === node ||
144
+ (typescript_1.default.isPropertyAccessExpression(current.expression) &&
145
+ isTypiaPropertyChain(current.expression)))) {
146
+ return true;
147
+ }
148
+ return false;
149
+ };
150
+ /**
151
+ * Check if a property access expression is part of a typia.xxx.yyy chain
152
+ */
153
+ const isTypiaPropertyChain = (node) => {
154
+ let current = node;
155
+ while (typescript_1.default.isPropertyAccessExpression(current)) {
156
+ current = current.expression;
157
+ }
158
+ return typescript_1.default.isIdentifier(current) && current.text === "typia";
159
+ };
160
+ /**
161
+ * Filter import clause to remove unused default imports
162
+ */
163
+ const filterTypiaImportClause = (importClause, usedImports) => {
164
+ const hasDefaultImport = importClause.name && usedImports.has(importClause.name.text);
165
+ const namedBindings = importClause.namedBindings; // Always keep named bindings like { tags }
166
+ // Return undefined if no imports are used
167
+ if (!hasDefaultImport && !namedBindings) {
168
+ return undefined;
169
+ }
170
+ return typescript_1.default.factory.createImportClause(importClause.isTypeOnly, hasDefaultImport ? importClause.name : undefined, namedBindings);
171
+ };
54
172
  //# sourceMappingURL=ImportTransformer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImportTransformer.js","sourceRoot":"","sources":["../../src/transformers/ImportTransformer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ImportTransformer.js","sourceRoot":"","sources":["../../src/transformers/ImportTransformer.ts"],"names":[],"mappings":"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"}
@@ -14,12 +14,16 @@ var ImportTransformer;
14
14
  return props.file;
15
15
  const from = get_directory_path(path.resolve(props.file.getSourceFile().fileName));
16
16
  const to = from.replace(props.top, props.to);
17
- return ts.visitEachChild(props.file, (node) => transform_node({
17
+ // First pass: transform relative imports
18
+ let transformedFile = ts.visitEachChild(props.file, (node) => transform_node({
18
19
  top: props.top,
19
20
  from,
20
21
  to,
21
22
  node,
22
23
  }), props.context);
24
+ // Second pass: remove unused typia imports
25
+ transformedFile = removeUnusedTypiaImports(transformedFile);
26
+ return transformedFile;
23
27
  };
24
28
  const transform_node = (props) => {
25
29
  if (!ts.isImportDeclaration(props.node) ||
@@ -46,6 +50,120 @@ const get_directory_path = (file) => {
46
50
  split.pop();
47
51
  return path.resolve(split.join(path.sep));
48
52
  };
53
+ /**
54
+ * Remove unused typia imports that are only used in transformable calls
55
+ */
56
+ const removeUnusedTypiaImports = (file) => {
57
+ const imports = new Map();
58
+ for (const stmt of file.statements) {
59
+ if (ts.isImportDeclaration(stmt) === false ||
60
+ ts.isStringLiteral(stmt.moduleSpecifier) === false ||
61
+ stmt.moduleSpecifier.text !== "typia" ||
62
+ stmt.importClause === undefined)
63
+ continue;
64
+ // Track default import (import typia from 'typia')
65
+ if (stmt.importClause.name)
66
+ imports.set(stmt.importClause.name.text, {
67
+ declaration: stmt,
68
+ default: true,
69
+ });
70
+ // Track named imports (import { tags } from 'typia') - keep these
71
+ if (stmt.importClause.namedBindings &&
72
+ ts.isNamedImports(stmt.importClause.namedBindings))
73
+ for (const element of stmt.importClause.namedBindings.elements)
74
+ imports.set(element.name.text, {
75
+ declaration: stmt,
76
+ default: false,
77
+ });
78
+ }
79
+ if (imports.size === 0)
80
+ return file; // No typia imports to check
81
+ // Find usage of typia identifiers that are NOT transformable calls
82
+ const nonTransformableUsage = new Set();
83
+ const checkUsage = (node) => {
84
+ if (ts.isIdentifier(node) && imports.has(node.text)) {
85
+ const identifier = node.text;
86
+ // Check if this identifier is being used as part of a property access
87
+ if (node.parent &&
88
+ ts.isPropertyAccessExpression(node.parent) &&
89
+ node.parent.expression === node) {
90
+ // This is typia.something - check if it's a transformable call pattern
91
+ if (!isLikelyTransformableCall(node.parent))
92
+ nonTransformableUsage.add(identifier);
93
+ }
94
+ else
95
+ // Direct usage of the typia identifier (not as property access)
96
+ // This is definitely non-transformable usage
97
+ nonTransformableUsage.add(identifier);
98
+ }
99
+ ts.forEachChild(node, checkUsage);
100
+ };
101
+ // Check all statements except import declarations
102
+ for (const stmt of file.statements)
103
+ if (!ts.isImportDeclaration(stmt) ||
104
+ !ts.isStringLiteral(stmt.moduleSpecifier) ||
105
+ stmt.moduleSpecifier.text !== "typia")
106
+ checkUsage(stmt);
107
+ // Update import statements
108
+ const newStatements = file.statements
109
+ .map((stmt) => {
110
+ if (ts.isImportDeclaration(stmt) &&
111
+ ts.isStringLiteral(stmt.moduleSpecifier) &&
112
+ stmt.moduleSpecifier.text === "typia" &&
113
+ stmt.importClause) {
114
+ const newImportClause = filterTypiaImportClause(stmt.importClause, nonTransformableUsage);
115
+ if (newImportClause)
116
+ return ts.factory.createImportDeclaration(stmt.modifiers, newImportClause, stmt.moduleSpecifier, stmt.attributes);
117
+ return null; // Skip adding the import if all imports are unused
118
+ }
119
+ return stmt;
120
+ })
121
+ .filter((stmt) => stmt !== null);
122
+ return ts.factory.updateSourceFile(file, newStatements, file.isDeclarationFile, file.referencedFiles, file.typeReferenceDirectives, file.hasNoDefaultLib, file.libReferenceDirectives);
123
+ };
124
+ /**
125
+ * Check if a property access expression looks like a transformable typia call
126
+ * This uses heuristics to detect patterns like typia.xxx(), typia.namespace.xxx()
127
+ */
128
+ const isLikelyTransformableCall = (node) => {
129
+ // Check if this is eventually part of a call expression
130
+ let current = node;
131
+ // Walk up the chain to find if this leads to a call expression
132
+ // Handle patterns like: typia.xxx(), typia.namespace.xxx()
133
+ while (ts.isPropertyAccessExpression(current)) {
134
+ current = current.parent;
135
+ }
136
+ // If the final result is a call expression, this is likely transformable
137
+ if (ts.isCallExpression(current) &&
138
+ (current.expression === node ||
139
+ (ts.isPropertyAccessExpression(current.expression) &&
140
+ isTypiaPropertyChain(current.expression)))) {
141
+ return true;
142
+ }
143
+ return false;
144
+ };
145
+ /**
146
+ * Check if a property access expression is part of a typia.xxx.yyy chain
147
+ */
148
+ const isTypiaPropertyChain = (node) => {
149
+ let current = node;
150
+ while (ts.isPropertyAccessExpression(current)) {
151
+ current = current.expression;
152
+ }
153
+ return ts.isIdentifier(current) && current.text === "typia";
154
+ };
155
+ /**
156
+ * Filter import clause to remove unused default imports
157
+ */
158
+ const filterTypiaImportClause = (importClause, usedImports) => {
159
+ const hasDefaultImport = importClause.name && usedImports.has(importClause.name.text);
160
+ const namedBindings = importClause.namedBindings; // Always keep named bindings like { tags }
161
+ // Return undefined if no imports are used
162
+ if (!hasDefaultImport && !namedBindings) {
163
+ return undefined;
164
+ }
165
+ return ts.factory.createImportClause(importClause.isTypeOnly, hasDefaultImport ? importClause.name : undefined, namedBindings);
166
+ };
49
167
 
50
168
  export { ImportTransformer };
51
169
  //# sourceMappingURL=ImportTransformer.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typia",
3
- "version": "9.7.0",
3
+ "version": "9.7.1",
4
4
  "description": "Superfast runtime validators with only one line",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -288,25 +288,33 @@ export namespace IRandomGenerator {
288
288
  * Custom string generator that can handle special string formats
289
289
  * based on schema properties.
290
290
  */
291
- string?: (schema: OpenApi.IJsonSchema.IString & Record<string, any>) => string;
291
+ string?: (
292
+ schema: OpenApi.IJsonSchema.IString & Record<string, any>,
293
+ ) => string;
292
294
 
293
295
  /**
294
296
  * Custom number generator that can handle special number constraints
295
297
  * based on schema properties.
296
298
  */
297
- number?: (schema: OpenApi.IJsonSchema.INumber & Record<string, any>) => number;
299
+ number?: (
300
+ schema: OpenApi.IJsonSchema.INumber & Record<string, any>,
301
+ ) => number;
298
302
 
299
303
  /**
300
304
  * Custom integer generator that can handle special integer constraints
301
305
  * based on schema properties.
302
306
  */
303
- integer?: (schema: OpenApi.IJsonSchema.IInteger & Record<string, any>) => number;
307
+ integer?: (
308
+ schema: OpenApi.IJsonSchema.IInteger & Record<string, any>,
309
+ ) => number;
304
310
 
305
311
  /**
306
312
  * Custom bigint generator that can handle special bigint constraints
307
313
  * based on schema properties.
308
314
  */
309
- bigint?: (schema: OpenApi.IJsonSchema.IInteger & Record<string, any>) => bigint;
315
+ bigint?: (
316
+ schema: OpenApi.IJsonSchema.IInteger & Record<string, any>,
317
+ ) => bigint;
310
318
 
311
319
  /**
312
320
  * Custom boolean generator that can handle special boolean constraints
@@ -321,7 +329,7 @@ export namespace IRandomGenerator {
321
329
  array?: <T>(
322
330
  schema: Omit<OpenApi.IJsonSchema.IArray, "items"> & {
323
331
  element: (index: number, count: number) => T;
324
- } & Record<string, any>
332
+ } & Record<string, any>,
325
333
  ) => T[];
326
334
  }
327
335
  }
@@ -263,7 +263,7 @@ export namespace JsonStringifyProgrammer {
263
263
  if (props.metadata.templates.length)
264
264
  if (AtomicPredicator.template(props.metadata)) {
265
265
  const partial = Metadata.initialize();
266
- partial.atomics.push(
266
+ (partial.atomics.push(
267
267
  MetadataAtomic.create({ type: "string", tags: [] }),
268
268
  ),
269
269
  unions.push({
@@ -278,7 +278,7 @@ export namespace JsonStringifyProgrammer {
278
278
  ...props,
279
279
  type: "string",
280
280
  }),
281
- });
281
+ }));
282
282
  }
283
283
 
284
284
  // CONSTANTS
@@ -1,5 +1,37 @@
1
1
  import { TagBase } from "./TagBase";
2
2
 
3
+ /**
4
+ * Constant tag that adds title and description metadata to literal types.
5
+ *
6
+ * This tag enhances literal values with human-readable documentation without
7
+ * changing their runtime type. It's particularly useful for enum-like values
8
+ * where you want to provide context about what each value represents.
9
+ *
10
+ * The metadata appears in generated JSON Schema, making API documentation
11
+ * more descriptive and helping developers understand the meaning of specific
12
+ * constant values.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * type Status =
17
+ * | Constant<"active", { title: "Active", description: "User is currently active" }>
18
+ * | Constant<"inactive", { title: "Inactive", description: "User account is disabled" }>
19
+ * | Constant<"pending", { title: "Pending", description: "Awaiting verification" }>;
20
+ * ```
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * interface Config {
25
+ * debugLevel: Constant<0, { title: "Off", description: "No debug output" }>
26
+ * | Constant<1, { title: "Basic", description: "Basic logging" }>
27
+ * | Constant<2, { title: "Verbose", description: "Detailed debug info" }>;
28
+ * }
29
+ * ```
30
+ *
31
+ * @template Value The literal value (boolean, number, string, or bigint)
32
+ * @template Content Metadata with optional title and description
33
+ * @author Jeongho Nam - https://github.com/samchon
34
+ */
3
35
  export type Constant<
4
36
  Value extends boolean | number | string | bigint,
5
37
  Content extends {
@@ -1,5 +1,22 @@
1
1
  import { TagBase } from "./TagBase";
2
2
 
3
+ /**
4
+ * String content media type constraint tag.
5
+ *
6
+ * Specifies the MIME type of string content for proper interpretation.
7
+ * This tag serves as metadata to indicate how the string content should be
8
+ * interpreted, but does not perform validation on the content itself.
9
+ *
10
+ * Examples:
11
+ * type JsonData = string & ContentMediaType<"application/json">; // JSON string
12
+ * type Base64Image = string & ContentMediaType<"image/png">; // Base64 PNG
13
+ * type XmlContent = string & ContentMediaType<"application/xml">; // XML data
14
+ *
15
+ * Common MIME types: application/json, text/html, image/jpeg, image/png,
16
+ * application/pdf, text/plain, application/xml, and many more.
17
+ *
18
+ * @author Jeongho Nam - https://github.com/samchon
19
+ */
3
20
  export type ContentMediaType<Value extends string> = TagBase<{
4
21
  target: "string";
5
22
  kind: "contentMediaType";
@@ -1,5 +1,35 @@
1
1
  import { TagBase } from "./TagBase";
2
2
 
3
+ /**
4
+ * Default value tag that specifies a default value for properties.
5
+ *
6
+ * When a property is not provided during validation, this tag instructs
7
+ * typia to use the specified default value. This is useful for optional
8
+ * properties that should have a specific fallback value.
9
+ *
10
+ * Supported types: boolean, bigint, number, and string primitives.
11
+ * Note: Default values are applied during validation, not at compile time.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * interface User {
16
+ * name: string;
17
+ * active: boolean & Default<true>; // defaults to true if not provided
18
+ * retries: number & Default<3>; // defaults to 3 if not provided
19
+ * }
20
+ * ```
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * interface Config {
25
+ * timeout: bigint & Default<5000n>; // defaults to 5000n
26
+ * prefix: string & Default<"user_">; // defaults to "user_"
27
+ * }
28
+ * ```
29
+ *
30
+ * @template Value The default value (boolean, bigint, number, or string)
31
+ * @author Jeongho Nam - https://github.com/samchon
32
+ */
3
33
  export type Default<Value extends boolean | bigint | number | string> =
4
34
  TagBase<{
5
35
  target: Value extends boolean
@@ -1,5 +1,37 @@
1
1
  import { TagBase } from "./TagBase";
2
2
 
3
+ /**
4
+ * Example value tag that provides a single example value for documentation.
5
+ *
6
+ * This tag adds an example value to your JSON Schema, which is useful for
7
+ * API documentation, client code generation, and helping developers understand
8
+ * expected data formats. The example doesn't affect runtime validation.
9
+ *
10
+ * Use Example for a single representative value. For multiple named examples,
11
+ * use the Examples tag instead.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * interface Product {
16
+ * name: string & Example<"iPhone 15 Pro">;
17
+ * price: number & Example<999.99>;
18
+ * inStock: boolean & Example<true>;
19
+ * }
20
+ * ```
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * interface User {
25
+ * profile: {
26
+ * bio: string;
27
+ * tags: string[];
28
+ * } & Example<{ bio: "Software engineer", tags: ["typescript", "react"] }>;
29
+ * }
30
+ * ```
31
+ *
32
+ * @template Value The example value (primitives, objects, arrays, or null)
33
+ * @author Jeongho Nam - https://github.com/samchon
34
+ */
3
35
  export type Example<
4
36
  Value extends
5
37
  | boolean
@@ -1,5 +1,45 @@
1
1
  import { TagBase } from "./TagBase";
2
2
 
3
+ /**
4
+ * Multiple examples tag that provides named example values for documentation.
5
+ *
6
+ * Unlike the Example tag which provides a single example, Examples allows you
7
+ * to provide multiple labeled examples. This is particularly useful when you
8
+ * want to show different scenarios or use cases for the same type.
9
+ *
10
+ * The examples are added to JSON Schema as an object where keys are descriptive
11
+ * names and values are the example data. This helps in API documentation and
12
+ * test case generation.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * interface PaymentRequest {
17
+ * amount: number & Examples<{
18
+ * small: 10.50,
19
+ * medium: 99.99,
20
+ * large: 1000.00
21
+ * }>;
22
+ * }
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * interface UserStatus {
28
+ * state: string & Examples<{
29
+ * active: "active",
30
+ * inactive: "inactive",
31
+ * suspended: "suspended"
32
+ * }>;
33
+ * profile: object & Examples<{
34
+ * basic: { name: "John", age: 25 },
35
+ * detailed: { name: "Jane", age: 30, bio: "Developer", verified: true }
36
+ * }>;
37
+ * }
38
+ * ```
39
+ *
40
+ * @template Value A record object mapping example names to example values
41
+ * @author Jeongho Nam - https://github.com/samchon
42
+ */
3
43
  export type Examples<
4
44
  Value extends Record<
5
45
  string,
@@ -1,5 +1,23 @@
1
1
  import { TagBase } from "./TagBase";
2
2
 
3
+ /**
4
+ * Exclusive maximum value constraint tag.
5
+ *
6
+ * Enforces that a numeric value must be strictly less than the specified maximum (not equal).
7
+ * This constraint validates that the input value satisfies: input < maximum.
8
+ *
9
+ * Example usage:
10
+ * ```typescript
11
+ * type Discount = number & tags.ExclusiveMaximum<100>; // Must be < 100
12
+ * type ByteValue = bigint & tags.ExclusiveMaximum<256n>; // Must be < 256
13
+ * ```
14
+ *
15
+ * Note: This tag is mutually exclusive with Maximum. You cannot apply both
16
+ * ExclusiveMaximum and Maximum constraints to the same property.
17
+ *
18
+ * @template Value - The exclusive maximum value constraint (number or bigint literal)
19
+ * @author Jeongho Nam - https://github.com/samchon
20
+ */
3
21
  export type ExclusiveMaximum<Value extends number | bigint> = TagBase<{
4
22
  target: Value extends bigint ? "bigint" : "number";
5
23
  kind: "exclusiveMaximum";
@@ -1,5 +1,23 @@
1
1
  import { TagBase } from "./TagBase";
2
2
 
3
+ /**
4
+ * Exclusive minimum value constraint tag.
5
+ *
6
+ * Enforces that a numeric value must be strictly greater than the specified minimum (not equal).
7
+ * This constraint validates that the input value satisfies: input > minimum.
8
+ *
9
+ * Example usage:
10
+ * ```typescript
11
+ * type PositiveNumber = number & tags.ExclusiveMinimum<0>; // Must be > 0
12
+ * type LargeCount = bigint & tags.ExclusiveMinimum<999n>; // Must be > 999
13
+ * ```
14
+ *
15
+ * Note: This tag is mutually exclusive with Minimum. You cannot apply both
16
+ * ExclusiveMinimum and Minimum constraints to the same property.
17
+ *
18
+ * @template Value - The exclusive minimum value constraint (number or bigint literal)
19
+ * @author Jeongho Nam - https://github.com/samchon
20
+ */
3
21
  export type ExclusiveMinimum<Value extends number | bigint> = TagBase<{
4
22
  target: Value extends bigint ? "bigint" : "number";
5
23
  kind: "exclusiveMinimum";