@kravc/schema 2.7.5 → 2.8.0-alpha.0

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 (170) hide show
  1. package/README.md +19 -14
  2. package/dist/CredentialFactory.d.ts +345 -0
  3. package/dist/CredentialFactory.d.ts.map +1 -0
  4. package/dist/CredentialFactory.js +381 -0
  5. package/dist/CredentialFactory.js.map +1 -0
  6. package/dist/Schema.d.ts +448 -0
  7. package/dist/Schema.d.ts.map +1 -0
  8. package/dist/Schema.js +506 -0
  9. package/dist/Schema.js.map +1 -0
  10. package/dist/ValidationError.d.ts +70 -0
  11. package/dist/ValidationError.d.ts.map +1 -0
  12. package/dist/ValidationError.js +78 -0
  13. package/dist/ValidationError.js.map +1 -0
  14. package/dist/Validator.d.ts +483 -0
  15. package/dist/Validator.d.ts.map +1 -0
  16. package/dist/Validator.js +570 -0
  17. package/dist/Validator.js.map +1 -0
  18. package/dist/helpers/JsonSchema.d.ts +99 -0
  19. package/dist/helpers/JsonSchema.d.ts.map +1 -0
  20. package/dist/helpers/JsonSchema.js +3 -0
  21. package/dist/helpers/JsonSchema.js.map +1 -0
  22. package/dist/helpers/cleanupAttributes.d.ts +34 -0
  23. package/dist/helpers/cleanupAttributes.d.ts.map +1 -0
  24. package/dist/helpers/cleanupAttributes.js +113 -0
  25. package/dist/helpers/cleanupAttributes.js.map +1 -0
  26. package/dist/helpers/cleanupNulls.d.ts +27 -0
  27. package/dist/helpers/cleanupNulls.d.ts.map +1 -0
  28. package/dist/helpers/cleanupNulls.js +96 -0
  29. package/dist/helpers/cleanupNulls.js.map +1 -0
  30. package/dist/helpers/getReferenceIds.d.ts +169 -0
  31. package/dist/helpers/getReferenceIds.d.ts.map +1 -0
  32. package/dist/helpers/getReferenceIds.js +241 -0
  33. package/dist/helpers/getReferenceIds.js.map +1 -0
  34. package/dist/helpers/got.d.ts +60 -0
  35. package/dist/helpers/got.d.ts.map +1 -0
  36. package/dist/helpers/got.js +72 -0
  37. package/dist/helpers/got.js.map +1 -0
  38. package/dist/helpers/mapObjectProperties.d.ts +150 -0
  39. package/dist/helpers/mapObjectProperties.d.ts.map +1 -0
  40. package/dist/helpers/mapObjectProperties.js +229 -0
  41. package/dist/helpers/mapObjectProperties.js.map +1 -0
  42. package/dist/helpers/normalizeAttributes.d.ts +213 -0
  43. package/dist/helpers/normalizeAttributes.d.ts.map +1 -0
  44. package/dist/helpers/normalizeAttributes.js +243 -0
  45. package/dist/helpers/normalizeAttributes.js.map +1 -0
  46. package/dist/helpers/normalizeProperties.d.ts +168 -0
  47. package/dist/helpers/normalizeProperties.d.ts.map +1 -0
  48. package/dist/helpers/normalizeProperties.js +223 -0
  49. package/dist/helpers/normalizeProperties.js.map +1 -0
  50. package/dist/helpers/normalizeRequired.d.ts +159 -0
  51. package/dist/helpers/normalizeRequired.d.ts.map +1 -0
  52. package/dist/helpers/normalizeRequired.js +206 -0
  53. package/dist/helpers/normalizeRequired.js.map +1 -0
  54. package/dist/helpers/normalizeType.d.ts +81 -0
  55. package/dist/helpers/normalizeType.d.ts.map +1 -0
  56. package/dist/helpers/normalizeType.js +210 -0
  57. package/dist/helpers/normalizeType.js.map +1 -0
  58. package/dist/helpers/nullifyEmptyValues.d.ts +139 -0
  59. package/dist/helpers/nullifyEmptyValues.d.ts.map +1 -0
  60. package/dist/helpers/nullifyEmptyValues.js +191 -0
  61. package/dist/helpers/nullifyEmptyValues.js.map +1 -0
  62. package/dist/helpers/removeRequiredAndDefault.d.ts +106 -0
  63. package/dist/helpers/removeRequiredAndDefault.d.ts.map +1 -0
  64. package/dist/helpers/removeRequiredAndDefault.js +138 -0
  65. package/dist/helpers/removeRequiredAndDefault.js.map +1 -0
  66. package/dist/helpers/validateId.d.ts +39 -0
  67. package/dist/helpers/validateId.d.ts.map +1 -0
  68. package/dist/helpers/validateId.js +51 -0
  69. package/dist/helpers/validateId.js.map +1 -0
  70. package/dist/index.d.ts +7 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +17 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/ld/documentLoader.d.ts +8 -0
  75. package/dist/ld/documentLoader.d.ts.map +1 -0
  76. package/dist/ld/documentLoader.js +24 -0
  77. package/dist/ld/documentLoader.js.map +1 -0
  78. package/dist/ld/getLinkedDataAttributeType.d.ts +10 -0
  79. package/dist/ld/getLinkedDataAttributeType.d.ts.map +1 -0
  80. package/dist/ld/getLinkedDataAttributeType.js +32 -0
  81. package/dist/ld/getLinkedDataAttributeType.js.map +1 -0
  82. package/dist/ld/getLinkedDataContext.d.ts +19 -0
  83. package/dist/ld/getLinkedDataContext.d.ts.map +1 -0
  84. package/dist/ld/getLinkedDataContext.js +50 -0
  85. package/dist/ld/getLinkedDataContext.js.map +1 -0
  86. package/eslint.config.mjs +32 -52
  87. package/examples/credentials/createAccountCredential.ts +27 -0
  88. package/examples/credentials/createMineSweeperScoreCredential.ts +115 -0
  89. package/examples/index.ts +7 -0
  90. package/examples/schemas/FavoriteItemSchema.ts +27 -0
  91. package/examples/{Preferences.yaml → schemas/Preferences.yaml} +2 -0
  92. package/examples/schemas/PreferencesSchema.ts +29 -0
  93. package/examples/schemas/ProfileSchema.ts +91 -0
  94. package/examples/schemas/Status.yaml +3 -0
  95. package/examples/schemas/StatusSchema.ts +12 -0
  96. package/jest.config.mjs +5 -0
  97. package/package.json +28 -21
  98. package/src/CredentialFactory.ts +392 -0
  99. package/src/Schema.ts +583 -0
  100. package/src/ValidationError.ts +90 -0
  101. package/src/Validator.ts +603 -0
  102. package/src/__tests__/CredentialFactory.test.ts +588 -0
  103. package/src/__tests__/Schema.test.ts +371 -0
  104. package/src/__tests__/ValidationError.test.ts +235 -0
  105. package/src/__tests__/Validator.test.ts +787 -0
  106. package/src/helpers/JsonSchema.ts +119 -0
  107. package/src/helpers/__tests__/cleanupAttributes.test.ts +943 -0
  108. package/src/helpers/__tests__/cleanupNulls.test.ts +772 -0
  109. package/src/helpers/__tests__/getReferenceIds.test.ts +975 -0
  110. package/src/helpers/__tests__/got.test.ts +193 -0
  111. package/src/helpers/__tests__/mapObjectProperties.test.ts +1126 -0
  112. package/src/helpers/__tests__/normalizeAttributes.test.ts +1435 -0
  113. package/src/helpers/__tests__/normalizeProperties.test.ts +727 -0
  114. package/src/helpers/__tests__/normalizeRequired.test.ts +669 -0
  115. package/src/helpers/__tests__/normalizeType.test.ts +772 -0
  116. package/src/helpers/__tests__/nullifyEmptyValues.test.ts +735 -0
  117. package/src/helpers/__tests__/removeRequiredAndDefault.test.ts +734 -0
  118. package/src/helpers/__tests__/validateId.test.ts +118 -0
  119. package/src/helpers/cleanupAttributes.ts +151 -0
  120. package/src/helpers/cleanupNulls.ts +106 -0
  121. package/src/helpers/getReferenceIds.ts +273 -0
  122. package/src/helpers/got.ts +73 -0
  123. package/src/helpers/mapObjectProperties.ts +272 -0
  124. package/src/helpers/normalizeAttributes.ts +247 -0
  125. package/src/helpers/normalizeProperties.ts +249 -0
  126. package/src/helpers/normalizeRequired.ts +233 -0
  127. package/src/helpers/normalizeType.ts +235 -0
  128. package/src/helpers/nullifyEmptyValues.ts +207 -0
  129. package/src/helpers/removeRequiredAndDefault.ts +151 -0
  130. package/src/helpers/validateId.ts +53 -0
  131. package/src/index.ts +13 -0
  132. package/src/ld/__tests__/documentLoader.test.ts +57 -0
  133. package/src/ld/__tests__/getLinkedDataAttributeType.test.ts +212 -0
  134. package/src/ld/__tests__/getLinkedDataContext.test.ts +378 -0
  135. package/src/ld/documentLoader.ts +28 -0
  136. package/src/ld/getLinkedDataAttributeType.ts +46 -0
  137. package/src/ld/getLinkedDataContext.ts +80 -0
  138. package/tsconfig.json +27 -0
  139. package/types/credentials-context.d.ts +14 -0
  140. package/types/security-context.d.ts +6 -0
  141. package/examples/Status.yaml +0 -3
  142. package/examples/createAccountCredential.js +0 -27
  143. package/examples/createMineSweeperScoreCredential.js +0 -63
  144. package/examples/index.js +0 -9
  145. package/src/CredentialFactory.js +0 -67
  146. package/src/CredentialFactory.spec.js +0 -131
  147. package/src/Schema.js +0 -104
  148. package/src/Schema.spec.js +0 -172
  149. package/src/ValidationError.js +0 -31
  150. package/src/Validator.js +0 -128
  151. package/src/Validator.spec.js +0 -355
  152. package/src/helpers/cleanupAttributes.js +0 -71
  153. package/src/helpers/cleanupNulls.js +0 -42
  154. package/src/helpers/getReferenceIds.js +0 -71
  155. package/src/helpers/mapObject.js +0 -65
  156. package/src/helpers/normalizeAttributes.js +0 -28
  157. package/src/helpers/normalizeProperties.js +0 -61
  158. package/src/helpers/normalizeRequired.js +0 -37
  159. package/src/helpers/normalizeType.js +0 -41
  160. package/src/helpers/nullifyEmptyValues.js +0 -57
  161. package/src/helpers/removeRequiredAndDefault.js +0 -30
  162. package/src/helpers/validateId.js +0 -19
  163. package/src/index.d.ts +0 -25
  164. package/src/index.js +0 -8
  165. package/src/ld/documentLoader.js +0 -25
  166. package/src/ld/documentLoader.spec.js +0 -12
  167. package/src/ld/getLinkedDataContext.js +0 -63
  168. package/src/ld/getLinkedDataType.js +0 -38
  169. /package/examples/{FavoriteItem.yaml → schemas/FavoriteItem.yaml} +0 -0
  170. /package/examples/{Profile.yaml → schemas/Profile.yaml} +0 -0
package/dist/Schema.js ADDED
@@ -0,0 +1,506 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const lodash_1 = require("lodash");
7
+ const validateId_1 = __importDefault(require("./helpers/validateId"));
8
+ const normalizeRequired_1 = __importDefault(require("./helpers/normalizeRequired"));
9
+ const normalizeProperties_1 = __importDefault(require("./helpers/normalizeProperties"));
10
+ const getLinkedDataContext_1 = __importDefault(require("./ld/getLinkedDataContext"));
11
+ const removeRequiredAndDefault_1 = __importDefault(require("./helpers/removeRequiredAndDefault"));
12
+ const UNDEFINED_SCHEMA_ID = 'UNDEFINED_SCHEMA_ID';
13
+ /**
14
+ * Schema class for defining and manipulating JSON schemas for object validation.
15
+ *
16
+ * This class provides a flexible API for creating, transforming, and composing JSON schemas.
17
+ * It supports both property-based schemas (for objects) and enum schemas (for value sets).
18
+ *
19
+ * **Use Cases:**
20
+ * - Define validation schemas for API request/response objects
21
+ * - Create reusable schema components that can be extended or composed
22
+ * - Generate JSON-LD linked data types for semantic web applications
23
+ * - Transform schemas for different use cases (e.g., create update schemas from create schemas)
24
+ *
25
+ * **Example - Basic Usage:**
26
+ * ```typescript
27
+ * const userSchema = new Schema({
28
+ * firstName: { type: 'string', required: true },
29
+ * lastName: { type: 'string', required: true },
30
+ * email: { type: 'string', format: 'email', required: true }
31
+ * }, 'User');
32
+ * ```
33
+ *
34
+ * **Example - Schema Composition:**
35
+ * ```typescript
36
+ * const baseSchema = new Schema({ name: { required: true } }, 'Base');
37
+ * const extendedSchema = baseSchema.extend({ status: { enum: ['Active', 'Inactive'] } }, 'Extended');
38
+ * ```
39
+ *
40
+ * **Example - Linked Data Types:**
41
+ * ```typescript
42
+ * const schema = new Schema(
43
+ * { id: { type: 'string' }, name: { type: 'string' } },
44
+ * 'Person',
45
+ * 'https://schema.org/'
46
+ * );
47
+ * // schema.linkedDataType will contain JSON-LD context
48
+ * ```
49
+ */
50
+ class Schema {
51
+ _id;
52
+ _url;
53
+ _source;
54
+ _linkedDataType;
55
+ /**
56
+ * Creates a new Schema instance.
57
+ *
58
+ * **Intent:** Initialize a schema with properties, enum values, or clone from another schema.
59
+ * Automatically normalizes properties, infers types, and optionally creates JSON-LD linked data types.
60
+ *
61
+ * **Use Cases:**
62
+ * - Create a new schema from scratch with property definitions
63
+ * - Create an enum schema for value validation
64
+ * - Clone an existing schema with a new ID
65
+ * - Create a schema with JSON-LD context for semantic web applications
66
+ *
67
+ * @param propertiesOrSchema - Property definitions, enum schema, or existing Schema instance to clone
68
+ * @param id - Unique identifier for the schema (defaults to 'UNDEFINED_SCHEMA_ID' if not provided)
69
+ * @param url - Optional URL for generating JSON-LD linked data types (only for property schemas, not enums)
70
+ *
71
+ * **Example - Property Schema:**
72
+ * ```typescript
73
+ * const schema = new Schema({
74
+ * name: { type: 'string', required: true },
75
+ * age: { type: 'number', minimum: 0 }
76
+ * }, 'Person');
77
+ * ```
78
+ *
79
+ * **Example - Enum Schema:**
80
+ * ```typescript
81
+ * const sizeSchema = new Schema({ enum: ['S', 'M', 'L'], type: 'string' }, 'Size');
82
+ * ```
83
+ *
84
+ * **Example - Clone Schema:**
85
+ * ```typescript
86
+ * const original = new Schema({ name: { type: 'string' } }, 'Original');
87
+ * const cloned = new Schema(original, 'Cloned');
88
+ * ```
89
+ *
90
+ * **Example - With Linked Data URL:**
91
+ * ```typescript
92
+ * const schema = new Schema(
93
+ * { name: { type: 'string' } },
94
+ * 'Person',
95
+ * 'https://schema.org/'
96
+ * );
97
+ * // Automatically creates linkedDataType with @id and @context
98
+ * ```
99
+ */
100
+ constructor(propertiesOrSchema, id, url) {
101
+ this._id = id || UNDEFINED_SCHEMA_ID;
102
+ this._url = url;
103
+ const isSchema = propertiesOrSchema instanceof Schema;
104
+ this._source = isSchema
105
+ ? propertiesOrSchema.source
106
+ : propertiesOrSchema;
107
+ const isLinkedDataType = !!url && !this._source.enum;
108
+ if (isLinkedDataType) {
109
+ (0, validateId_1.default)('url', url);
110
+ const source = this._source;
111
+ source.type = {
112
+ type: 'string',
113
+ default: id,
114
+ required: true,
115
+ };
116
+ if (source.id) {
117
+ source.id = {
118
+ type: 'string',
119
+ format: 'url',
120
+ required: true,
121
+ };
122
+ }
123
+ const uri = (url.endsWith('/') || url.endsWith('#'))
124
+ ? `${url}${id}`
125
+ : `${url}#${id}`;
126
+ this._linkedDataType = {
127
+ '@id': uri,
128
+ '@context': (0, getLinkedDataContext_1.default)(source, url)
129
+ };
130
+ }
131
+ (0, normalizeProperties_1.default)(this._source);
132
+ }
133
+ /**
134
+ * Returns the unique identifier for this schema.
135
+ *
136
+ * **Intent:** Provide a way to reference and identify schemas in collections or validators.
137
+ *
138
+ * **Use Cases:**
139
+ * - Reference schemas in Validator instances
140
+ * - Track schema lineage when cloning/extending
141
+ * - Generate schema identifiers for JSON Schema output
142
+ *
143
+ * @returns The schema ID, or 'UNDEFINED_SCHEMA_ID' if not specified during construction
144
+ *
145
+ * **Example:**
146
+ * ```typescript
147
+ * const schema = new Schema({ name: { type: 'string' } }, 'User');
148
+ * console.log(schema.id); // 'User'
149
+ * ```
150
+ */
151
+ get id() {
152
+ return this._id;
153
+ }
154
+ /**
155
+ * Returns the URL associated with this schema for JSON-LD linked data generation.
156
+ *
157
+ * **Intent:** Provide access to the base URL used for generating semantic web identifiers.
158
+ *
159
+ * **Use Cases:**
160
+ * - Check if a schema has linked data support
161
+ * - Access the base URL for constructing related URIs
162
+ * - Debug linked data type generation
163
+ *
164
+ * @returns The schema URL if provided during construction, undefined otherwise
165
+ *
166
+ * **Example:**
167
+ * ```typescript
168
+ * const schema = new Schema({ name: { type: 'string' } }, 'Person', 'https://schema.org/');
169
+ * console.log(schema.url); // 'https://schema.org/'
170
+ * ```
171
+ */
172
+ get url() {
173
+ return this._url;
174
+ }
175
+ /**
176
+ * Returns a deep clone of the schema's source properties or enum definition.
177
+ *
178
+ * **Intent:** Provide immutable access to schema definitions to prevent accidental mutations.
179
+ *
180
+ * **Use Cases:**
181
+ * - Inspect schema structure without modifying the original
182
+ * - Clone schemas manually for custom transformations
183
+ * - Debug schema definitions
184
+ * - Pass schema definitions to other functions safely
185
+ *
186
+ * @returns A deep copy of the schema source (PropertiesSchema or EnumSchema)
187
+ *
188
+ * **Example:**
189
+ * ```typescript
190
+ * const schema = new Schema({ name: { type: 'string', required: true } }, 'User');
191
+ * const source = schema.source;
192
+ * // source is a clone, modifying it won't affect the original schema
193
+ * ```
194
+ */
195
+ get source() {
196
+ return (0, lodash_1.cloneDeep)(this._source);
197
+ }
198
+ /**
199
+ * Checks if this schema is an enum schema (defines a set of allowed values).
200
+ *
201
+ * **Intent:** Enable type-safe branching logic based on schema type.
202
+ *
203
+ * **Use Cases:**
204
+ * - Conditionally apply methods that only work on property schemas
205
+ * - Validate schema type before operations
206
+ * - Implement different serialization logic for enums vs objects
207
+ *
208
+ * @returns true if the schema is an enum schema, false if it's a properties schema
209
+ *
210
+ * **Example:**
211
+ * ```typescript
212
+ * const enumSchema = new Schema({ enum: ['A', 'B', 'C'] }, 'Letters');
213
+ * const propSchema = new Schema({ name: { type: 'string' } }, 'Person');
214
+ *
215
+ * console.log(enumSchema.isEnum); // true
216
+ * console.log(propSchema.isEnum); // false
217
+ * ```
218
+ */
219
+ get isEnum() {
220
+ return !!this._source.enum;
221
+ }
222
+ /**
223
+ * Returns a normalized JSON Schema representation of this schema.
224
+ *
225
+ * **Intent:** Convert the internal schema representation to standard JSON Schema format
226
+ * with normalized required arrays and proper structure for validation libraries.
227
+ *
228
+ * **Use Cases:**
229
+ * - Export schemas for use with JSON Schema validators (e.g., z-schema)
230
+ * - Generate API documentation from schemas
231
+ * - Serialize schemas to JSON for storage or transmission
232
+ * - Integrate with tools that expect standard JSON Schema format
233
+ *
234
+ * @returns A JsonSchema object (ObjectSchema for property schemas, EnumSchema for enum schemas)
235
+ *
236
+ * **Example - Property Schema:**
237
+ * ```typescript
238
+ * const schema = new Schema({
239
+ * name: { type: 'string', required: true },
240
+ * age: { type: 'number' }
241
+ * }, 'Person');
242
+ *
243
+ * const jsonSchema = schema.jsonSchema;
244
+ * // {
245
+ * // id: 'Person',
246
+ * // type: 'object',
247
+ * // properties: { name: {...}, age: {...} },
248
+ * // required: ['name']
249
+ * // }
250
+ * ```
251
+ *
252
+ * **Example - Enum Schema:**
253
+ * ```typescript
254
+ * const enumSchema = new Schema({ enum: ['S', 'M', 'L'], type: 'string' }, 'Size');
255
+ * const jsonSchema = enumSchema.jsonSchema;
256
+ * // { id: 'Size', enum: ['S', 'M', 'L'], type: 'string' }
257
+ * ```
258
+ */
259
+ get jsonSchema() {
260
+ if (this.isEnum) {
261
+ return {
262
+ id: this._id,
263
+ ...this.source
264
+ };
265
+ }
266
+ const jsonSchema = {
267
+ id: this._id,
268
+ type: 'object',
269
+ properties: this.source
270
+ };
271
+ (0, normalizeRequired_1.default)(jsonSchema);
272
+ return jsonSchema;
273
+ }
274
+ /**
275
+ * Returns the JSON-LD linked data type if a URL was provided during construction.
276
+ *
277
+ * **Intent:** Provide semantic web identifiers and context for schemas, enabling
278
+ * integration with Linked Data and Verifiable Credentials standards.
279
+ *
280
+ * **Use Cases:**
281
+ * - Generate Verifiable Credentials with proper semantic context
282
+ * - Create JSON-LD documents with schema.org or custom vocabularies
283
+ * - Enable semantic interoperability between systems
284
+ * - Support decentralized identity and credential systems
285
+ *
286
+ * @returns LinkedDataType object with @id and @context, or undefined if no URL was provided
287
+ *
288
+ * **Example:**
289
+ * ```typescript
290
+ * const schema = new Schema(
291
+ * { name: { type: 'string' }, email: { type: 'string', format: 'email' } },
292
+ * 'Person',
293
+ * 'https://schema.org/'
294
+ * );
295
+ *
296
+ * const linkedData = schema.linkedDataType;
297
+ * // {
298
+ * // '@id': 'https://schema.org/Person',
299
+ * // '@context': { ... } // Generated context mapping types to schema.org
300
+ * // }
301
+ * ```
302
+ *
303
+ * **Note:** Linked data types are only generated for property schemas, not enum schemas.
304
+ */
305
+ get linkedDataType() {
306
+ return this._linkedDataType;
307
+ }
308
+ /**
309
+ * Creates a complete clone of the schema with a new identifier.
310
+ *
311
+ * **Intent:** Duplicate a schema while maintaining all properties and structure,
312
+ * useful for creating variations or versioning schemas.
313
+ *
314
+ * **Use Cases:**
315
+ * - Create schema versions (e.g., 'UserV1', 'UserV2')
316
+ * - Duplicate schemas for different contexts
317
+ * - Create base schemas that can be independently extended
318
+ * - Maintain schema history or branching
319
+ *
320
+ * @param id - The new unique identifier for the cloned schema
321
+ * @returns A new Schema instance with identical structure but different ID
322
+ *
323
+ * **Example:**
324
+ * ```typescript
325
+ * const userSchema = new Schema({ name: { type: 'string' } }, 'User');
326
+ * const userV2Schema = userSchema.clone('UserV2');
327
+ * // Both schemas have identical properties but different IDs
328
+ * ```
329
+ */
330
+ clone(id) {
331
+ return new Schema(this.source, id);
332
+ }
333
+ /**
334
+ * Creates a schema clone without required constraints and default values.
335
+ *
336
+ * **Intent:** Generate update/patch schemas from create schemas by removing
337
+ * validation constraints that make sense for creation but not for updates.
338
+ *
339
+ * **Use Cases:**
340
+ * - Create update schemas where all fields are optional
341
+ * - Generate PATCH endpoint schemas from POST endpoint schemas
342
+ * - Allow partial updates without requiring all original fields
343
+ * - Create flexible input schemas for editing operations
344
+ *
345
+ * @param id - The new unique identifier for the pure schema
346
+ * @returns A new Schema instance with all required flags and defaults removed
347
+ * @throws Error if called on an enum schema
348
+ *
349
+ * **Example:**
350
+ * ```typescript
351
+ * const createSchema = new Schema({
352
+ * name: { type: 'string', required: true },
353
+ * email: { type: 'string', required: true, default: 'user@example.com' }
354
+ * }, 'CreateUser');
355
+ *
356
+ * const updateSchema = createSchema.pure('UpdateUser');
357
+ * // updateSchema has no required fields and no defaults
358
+ * // All fields are optional for updates
359
+ * ```
360
+ */
361
+ pure(id) {
362
+ if (this.isEnum) {
363
+ throw new Error('The "pure" method is not supported for enum schemas.');
364
+ }
365
+ const { properties: source } = (0, removeRequiredAndDefault_1.default)({
366
+ type: 'object',
367
+ properties: this.source
368
+ });
369
+ return new Schema(source, id);
370
+ }
371
+ /**
372
+ * Creates a schema clone containing only the specified properties.
373
+ *
374
+ * **Intent:** Create focused schemas that expose only a subset of properties,
375
+ * useful for different API views or security contexts.
376
+ *
377
+ * **Use Cases:**
378
+ * - Create public-facing schemas that hide sensitive fields
379
+ * - Generate response schemas with only necessary fields
380
+ * - Create view-specific schemas (e.g., 'UserSummary', 'UserDetail')
381
+ * - Implement field-level access control in schemas
382
+ * - Create lightweight schemas for list views
383
+ *
384
+ * @param propertyNames - Array of property names to include in the new schema
385
+ * @param id - The new unique identifier for the filtered schema
386
+ * @returns A new Schema instance containing only the specified properties
387
+ * @throws Error if called on an enum schema
388
+ *
389
+ * **Example:**
390
+ * ```typescript
391
+ * const fullSchema = new Schema({
392
+ * name: { type: 'string' },
393
+ * email: { type: 'string' },
394
+ * password: { type: 'string' },
395
+ * ssn: { type: 'string' }
396
+ * }, 'User');
397
+ *
398
+ * const publicSchema = fullSchema.only(['name', 'email'], 'PublicUser');
399
+ * // publicSchema only contains name and email, hiding sensitive fields
400
+ * ```
401
+ */
402
+ only(propertyNames, id) {
403
+ if (this.isEnum) {
404
+ throw new Error('The "only" method is not supported for enum schemas.');
405
+ }
406
+ const source = (0, lodash_1.pick)(this.source, propertyNames);
407
+ return new Schema(source, id);
408
+ }
409
+ /**
410
+ * Creates a schema clone extended with additional properties.
411
+ *
412
+ * **Intent:** Build complex schemas incrementally by composing base schemas
413
+ * with additional fields, enabling schema inheritance and composition patterns.
414
+ *
415
+ * **Use Cases:**
416
+ * - Extend base schemas with domain-specific fields
417
+ * - Create schema hierarchies (e.g., BaseEntity -> User -> AdminUser)
418
+ * - Add computed or derived fields to existing schemas
419
+ * - Compose schemas from multiple sources
420
+ * - Build versioned schemas that add new fields
421
+ *
422
+ * @param properties - Additional properties to merge into the schema
423
+ * @param id - The new unique identifier for the extended schema
424
+ * @returns A new Schema instance with merged properties (new properties override existing ones)
425
+ * @throws Error if called on an enum schema
426
+ *
427
+ * **Example:**
428
+ * ```typescript
429
+ * const baseSchema = new Schema({
430
+ * id: { type: 'string', required: true },
431
+ * createdAt: { type: 'string', format: 'date-time', required: true }
432
+ * }, 'BaseEntity');
433
+ *
434
+ * const userSchema = baseSchema.extend({
435
+ * name: { type: 'string', required: true },
436
+ * email: { type: 'string', format: 'email', required: true }
437
+ * }, 'User');
438
+ *
439
+ * // userSchema contains id, createdAt, name, and email
440
+ * ```
441
+ */
442
+ extend(properties, id) {
443
+ if (this.isEnum) {
444
+ throw new Error('The "extend" method is not supported for enum schemas.');
445
+ }
446
+ return new Schema({ ...this.source, ...properties }, id);
447
+ }
448
+ /**
449
+ * Creates a new schema that wraps the current schema as a nested property.
450
+ *
451
+ * **Intent:** Transform a flat schema into a nested structure, useful for
452
+ * API response formatting or when data needs to be wrapped in a container object.
453
+ *
454
+ * **Use Cases:**
455
+ * - Wrap schemas for API responses (e.g., { data: { ...schema } })
456
+ * - Create nested data structures from flat schemas
457
+ * - Format schemas for specific API conventions
458
+ * - Generate wrapper schemas for pagination or metadata containers
459
+ * - Transform schemas for different API versions or formats
460
+ *
461
+ * @param propertyName - The name of the property that will contain the wrapped schema
462
+ * @param attributes - Optional attributes for the wrapper property (default: { required: true })
463
+ * @param id - The new unique identifier for the wrapped schema
464
+ * @returns A new Schema instance where the original schema is nested under the specified property
465
+ * @throws Error if called on an enum schema
466
+ *
467
+ * **Example:**
468
+ * ```typescript
469
+ * const userSchema = new Schema({
470
+ * name: { type: 'string', required: true },
471
+ * email: { type: 'string', required: true }
472
+ * }, 'User');
473
+ *
474
+ * const wrappedSchema = userSchema.wrap('data', { required: true }, 'UserResponse');
475
+ * // Resulting schema structure:
476
+ * // {
477
+ * // data: {
478
+ * // type: 'object',
479
+ * // properties: { name: {...}, email: {...} },
480
+ * // required: true
481
+ * // }
482
+ * // }
483
+ * ```
484
+ *
485
+ * **Example - With Default Value:**
486
+ * ```typescript
487
+ * const wrappedSchema = userSchema.wrap('data', { default: '{}' }, 'OptionalUserResponse');
488
+ * // The 'data' property has a default value and is not required
489
+ * ```
490
+ */
491
+ wrap(propertyName, attributes, id) {
492
+ if (this.isEnum) {
493
+ throw new Error('The "wrap" method is not supported for enum schemas.');
494
+ }
495
+ const source = {
496
+ [propertyName]: {
497
+ type: 'object',
498
+ properties: this.source,
499
+ ...(attributes || { required: true })
500
+ }
501
+ };
502
+ return new Schema(source, id);
503
+ }
504
+ }
505
+ exports.default = Schema;
506
+ //# sourceMappingURL=Schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Schema.js","sourceRoot":"","sources":["../src/Schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import type { SchemaErrorDetail } from 'z-schema';
2
+ import { TargetObject } from './helpers/JsonSchema';
3
+ /**
4
+ * Normalized validation error thrown when object validation fails against a schema.
5
+ *
6
+ * This error is thrown by the Validator when an object does not conform to its schema.
7
+ * It extends the standard Error class and provides structured access to validation
8
+ * failure details, including the schema ID, the invalid object, and normalized error
9
+ * information for each validation failure.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * try {
14
+ * validator.validate(userData, 'UserSchema');
15
+ * } catch (error) {
16
+ * if (error instanceof ValidationError) {
17
+ * const errorDetails = error.toJSON();
18
+ * console.error(errorDetails.schemaId); // 'UserSchema'
19
+ * console.error(errorDetails.validationErrors); // Array of validation failures
20
+ * }
21
+ * }
22
+ * ```
23
+ */
24
+ declare class ValidationError extends Error {
25
+ private _object;
26
+ private _schemaId;
27
+ private _validationErrors;
28
+ /**
29
+ * Creates a validation error instance.
30
+ *
31
+ * @param schemaId - The identifier of the schema that failed validation
32
+ * @param invalidObject - The object that failed validation (may be partially processed)
33
+ * @param validationErrors - Array of validation error details from z-schema, which will be
34
+ * normalized to extract only path, code, params, and message
35
+ */
36
+ constructor(schemaId: string, invalidObject: TargetObject, validationErrors: SchemaErrorDetail[]);
37
+ /**
38
+ * Returns a JSON serializable representation of the validation error.
39
+ *
40
+ * This method is useful for:
41
+ * - API error responses (can be directly serialized and sent to clients)
42
+ * - Logging validation failures in a structured format
43
+ * - Error reporting and debugging
44
+ *
45
+ * @returns An object containing:
46
+ * - `code`: The error class name ('ValidationError')
47
+ * - `object`: The invalid object that failed validation
48
+ * - `message`: The error message (e.g., '"SchemaId" validation failed')
49
+ * - `schemaId`: The identifier of the schema that failed validation
50
+ * - `validationErrors`: Array of normalized validation errors, each containing:
51
+ * - `path`: JSON path to the invalid field (e.g., '#/user/email')
52
+ * - `code`: Error code from z-schema (e.g., 'INVALID_TYPE', 'REQUIRED')
53
+ * - `params`: Array of error-specific parameters
54
+ * - `message`: Human-readable error message
55
+ */
56
+ toJSON(): {
57
+ code: string;
58
+ object: TargetObject;
59
+ message: string;
60
+ schemaId: string;
61
+ validationErrors: {
62
+ path: string;
63
+ code: string;
64
+ params: string[];
65
+ message: string;
66
+ }[];
67
+ };
68
+ }
69
+ export default ValidationError;
70
+ //# sourceMappingURL=ValidationError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationError.d.ts","sourceRoot":"","sources":["../src/ValidationError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,cAAM,eAAgB,SAAQ,KAAK;IACjC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,iBAAiB,CAKrB;IAEJ;;;;;;;OAOG;gBACS,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE;IAgBhG;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM;;;;;;kBAjDE,MAAM;kBACN,MAAM;oBACJ,MAAM,EAAE;qBACP,MAAM;;;CAuDlB;AAED,eAAe,eAAe,CAAC"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Normalized validation error thrown when object validation fails against a schema.
5
+ *
6
+ * This error is thrown by the Validator when an object does not conform to its schema.
7
+ * It extends the standard Error class and provides structured access to validation
8
+ * failure details, including the schema ID, the invalid object, and normalized error
9
+ * information for each validation failure.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * try {
14
+ * validator.validate(userData, 'UserSchema');
15
+ * } catch (error) {
16
+ * if (error instanceof ValidationError) {
17
+ * const errorDetails = error.toJSON();
18
+ * console.error(errorDetails.schemaId); // 'UserSchema'
19
+ * console.error(errorDetails.validationErrors); // Array of validation failures
20
+ * }
21
+ * }
22
+ * ```
23
+ */
24
+ class ValidationError extends Error {
25
+ _object;
26
+ _schemaId;
27
+ _validationErrors;
28
+ /**
29
+ * Creates a validation error instance.
30
+ *
31
+ * @param schemaId - The identifier of the schema that failed validation
32
+ * @param invalidObject - The object that failed validation (may be partially processed)
33
+ * @param validationErrors - Array of validation error details from z-schema, which will be
34
+ * normalized to extract only path, code, params, and message
35
+ */
36
+ constructor(schemaId, invalidObject, validationErrors) {
37
+ super(`"${schemaId}" validation failed`);
38
+ this._object = invalidObject;
39
+ this._schemaId = schemaId;
40
+ this._validationErrors = validationErrors
41
+ .map(error => ({
42
+ path: error.path,
43
+ code: error.code,
44
+ params: error.params,
45
+ message: error.message,
46
+ }));
47
+ }
48
+ /**
49
+ * Returns a JSON serializable representation of the validation error.
50
+ *
51
+ * This method is useful for:
52
+ * - API error responses (can be directly serialized and sent to clients)
53
+ * - Logging validation failures in a structured format
54
+ * - Error reporting and debugging
55
+ *
56
+ * @returns An object containing:
57
+ * - `code`: The error class name ('ValidationError')
58
+ * - `object`: The invalid object that failed validation
59
+ * - `message`: The error message (e.g., '"SchemaId" validation failed')
60
+ * - `schemaId`: The identifier of the schema that failed validation
61
+ * - `validationErrors`: Array of normalized validation errors, each containing:
62
+ * - `path`: JSON path to the invalid field (e.g., '#/user/email')
63
+ * - `code`: Error code from z-schema (e.g., 'INVALID_TYPE', 'REQUIRED')
64
+ * - `params`: Array of error-specific parameters
65
+ * - `message`: Human-readable error message
66
+ */
67
+ toJSON() {
68
+ return {
69
+ code: this.constructor.name,
70
+ object: this._object,
71
+ message: this.message,
72
+ schemaId: this._schemaId,
73
+ validationErrors: this._validationErrors
74
+ };
75
+ }
76
+ }
77
+ exports.default = ValidationError;
78
+ //# sourceMappingURL=ValidationError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationError.js","sourceRoot":"","sources":["../src/ValidationError.ts"],"names":[],"mappings":";;AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,eAAgB,SAAQ,KAAK;IACzB,OAAO,CAAe;IACtB,SAAS,CAAS;IAClB,iBAAiB,CAKrB;IAEJ;;;;;;;OAOG;IACH,YAAY,QAAgB,EAAE,aAA2B,EAAE,gBAAqC;QAC9F,KAAK,CAAC,IAAI,QAAQ,qBAAqB,CAAC,CAAC;QAEzC,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC;QAE7B,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE1B,IAAI,CAAC,iBAAiB,GAAG,gBAAgB;aACtC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YAC3B,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,gBAAgB,EAAE,IAAI,CAAC,iBAAiB;SACzC,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,eAAe,CAAC"}