@kravc/schema 2.7.6 → 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 +27 -20
  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
@@ -0,0 +1,229 @@
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 got_1 = __importDefault(require("./got"));
8
+ /**
9
+ * Recursively traverses an object's properties based on a JSON schema and applies a callback
10
+ * function to each property. Handles nested objects, arrays, and schema references ($ref).
11
+ *
12
+ * **Intent:**
13
+ * This function provides a generic way to iterate over object properties in a schema-aware manner,
14
+ * enabling operations like normalization, validation, transformation, or cleanup to be applied
15
+ * consistently across complex nested data structures. It abstracts away the complexity of
16
+ * traversing nested objects, arrays, and schema references, allowing callers to focus on
17
+ * implementing their specific property-level logic.
18
+ *
19
+ * **Use Cases:**
20
+ * - **Normalization**: Apply type conversions or default values to properties based on schema definitions
21
+ * (see `normalizeAttributes.ts` for example)
22
+ * - **Validation**: Check property values against schema constraints
23
+ * - **Transformation**: Modify or transform property values based on schema metadata
24
+ * - **Cleanup**: Remove invalid properties or sanitize data structures
25
+ * - **Data Processing**: Extract, aggregate, or analyze properties across nested structures
26
+ * - **Schema-driven Operations**: Any operation that needs to process object properties according
27
+ * to their schema definitions
28
+ *
29
+ * **Behavior:**
30
+ * - Skips enum schemas (returns immediately without calling callback)
31
+ * - Calls callback for all properties defined in the schema, even if their values are null
32
+ * - Skips recursion into undefined values (callback is still called, but nested traversal stops)
33
+ * - Recursively processes nested objects by creating nested schema contexts
34
+ * - Recursively processes array items, handling both inline object schemas and references
35
+ * - Resolves schema references ($ref) using the provided schemasMap
36
+ *
37
+ * **Examples:**
38
+ *
39
+ * @example
40
+ * // Example 1: Normalize property values based on schema types
41
+ * const schema = new Schema({
42
+ * name: { type: 'string' },
43
+ * age: { type: 'number' },
44
+ * active: { type: 'boolean' }
45
+ * }, 'user-schema');
46
+ *
47
+ * const user = {
48
+ * name: 'John',
49
+ * age: '30', // string that should be number
50
+ * active: 'true' // string that should be boolean
51
+ * };
52
+ *
53
+ * mapObjectProperties(user, schema.jsonSchema, {}, (propName, propSchema, obj) => {
54
+ * if (propSchema.type === 'number') {
55
+ * obj[propName] = Number(obj[propName]);
56
+ * } else if (propSchema.type === 'boolean') {
57
+ * obj[propName] = obj[propName] === 'true' || obj[propName] === true;
58
+ * }
59
+ * });
60
+ * // Result: { name: 'John', age: 30, active: true }
61
+ *
62
+ * @example
63
+ * // Example 2: Process nested objects
64
+ * const schema = new Schema({
65
+ * profile: {
66
+ * type: 'object',
67
+ * properties: {
68
+ * firstName: { type: 'string' },
69
+ * lastName: { type: 'string' }
70
+ * }
71
+ * }
72
+ * }, 'user-schema');
73
+ *
74
+ * const user = {
75
+ * profile: {
76
+ * firstName: 'John',
77
+ * lastName: 'Doe'
78
+ * }
79
+ * };
80
+ *
81
+ * const processedProps: string[] = [];
82
+ * mapObjectProperties(user, schema.jsonSchema, {}, (propName) => {
83
+ * processedProps.push(propName);
84
+ * });
85
+ * // processedProps: ['profile', 'firstName', 'lastName']
86
+ *
87
+ * @example
88
+ * // Example 3: Handle schema references ($ref)
89
+ * const addressSchema = new Schema({
90
+ * street: { type: 'string' },
91
+ * city: { type: 'string' }
92
+ * }, 'address-schema');
93
+ *
94
+ * const userSchema = new Schema({
95
+ * name: { type: 'string' },
96
+ * address: { $ref: 'address-schema' }
97
+ * }, 'user-schema');
98
+ *
99
+ * const user = {
100
+ * name: 'John',
101
+ * address: {
102
+ * street: '123 Main St',
103
+ * city: 'New York'
104
+ * }
105
+ * };
106
+ *
107
+ * const schemasMap = {
108
+ * 'address-schema': addressSchema.jsonSchema
109
+ * };
110
+ *
111
+ * mapObjectProperties(user, userSchema.jsonSchema, schemasMap, (propName) => {
112
+ * console.log(`Processing: ${propName}`);
113
+ * });
114
+ * // Output:
115
+ * // Processing: name
116
+ * // Processing: address
117
+ * // Processing: street
118
+ * // Processing: city
119
+ *
120
+ * @example
121
+ * // Example 4: Process arrays with object items
122
+ * const schema = new Schema({
123
+ * tags: {
124
+ * type: 'array',
125
+ * items: {
126
+ * type: 'object',
127
+ * properties: {
128
+ * name: { type: 'string' },
129
+ * value: { type: 'string' }
130
+ * }
131
+ * }
132
+ * }
133
+ * }, 'item-schema');
134
+ *
135
+ * const item = {
136
+ * tags: [
137
+ * { name: 'tag1', value: 'value1' },
138
+ * { name: 'tag2', value: 'value2' }
139
+ * ]
140
+ * };
141
+ *
142
+ * mapObjectProperties(item, schema.jsonSchema, {}, (propName, propSchema, obj) => {
143
+ * if (propSchema.type === 'string') {
144
+ * obj[propName] = String(obj[propName]).toUpperCase();
145
+ * }
146
+ * });
147
+ * // Result: tags array items have uppercase name and value properties
148
+ *
149
+ * @param object - The target object to traverse
150
+ * @param jsonSchema - The JSON schema defining the object structure
151
+ * @param schemasMap - Map of schema IDs to schema objects for resolving $ref references
152
+ * @param callback - Function called for each property with (propertyName, propertySchema, object)
153
+ */
154
+ const mapObjectProperties = (object, jsonSchema, schemasMap, callback) => {
155
+ const { enum: enumItems } = jsonSchema;
156
+ const isEnum = !!enumItems;
157
+ if (isEnum) {
158
+ return;
159
+ }
160
+ const objectSchema = jsonSchema;
161
+ const hasProperties = !!objectSchema.properties;
162
+ // Guard against malformed schemas without properties
163
+ if (!hasProperties) {
164
+ return;
165
+ }
166
+ const { properties: objectProperties } = objectSchema;
167
+ for (const propertyName in objectProperties) {
168
+ const property = objectProperties[propertyName];
169
+ callback(propertyName, property, object);
170
+ const value = object[propertyName];
171
+ const isValueUndefined = (0, lodash_1.isUndefined)(value);
172
+ if (isValueUndefined) {
173
+ continue;
174
+ }
175
+ const { $ref: refSchemaId } = property;
176
+ const isReference = !(0, lodash_1.isUndefined)(refSchemaId);
177
+ if (isReference) {
178
+ const referenceSchema = (0, got_1.default)(schemasMap, refSchemaId, 'Schema "$PATH" not found');
179
+ const isObjectValue = value && typeof value === 'object' && !Array.isArray(value);
180
+ // Only recursively process if the value is an object (not null, undefined, or primitive)
181
+ if (isObjectValue) {
182
+ mapObjectProperties(value, referenceSchema, schemasMap, callback);
183
+ }
184
+ continue;
185
+ }
186
+ const { type } = property;
187
+ const isObject = type === 'object';
188
+ if (isObject) {
189
+ const { properties = {} } = property;
190
+ const isObjectValue = value && typeof value === 'object' && !Array.isArray(value);
191
+ // Only recursively process if the value is an object (not null, undefined, or primitive)
192
+ if (isObjectValue) {
193
+ const nestedJsonSchema = {
194
+ id: `${objectSchema.id}.${propertyName}.properties`,
195
+ properties
196
+ };
197
+ mapObjectProperties(value, nestedJsonSchema, schemasMap, callback);
198
+ }
199
+ continue;
200
+ }
201
+ const isArray = type === 'array';
202
+ if (isArray) {
203
+ const { items } = property;
204
+ const hasItems = !!items;
205
+ const isArrayValue = Array.isArray(value);
206
+ // Only process if value is an array and items schema is defined
207
+ if (isArrayValue && hasItems) {
208
+ const { $ref: itemRefSchemaId } = items;
209
+ const { properties: itemObjectProperties = {} } = items;
210
+ const isItemReference = !(0, lodash_1.isUndefined)(itemRefSchemaId);
211
+ const itemSchema = isItemReference
212
+ ? (0, got_1.default)(schemasMap, itemRefSchemaId, 'Schema "$PATH" not found')
213
+ : {
214
+ id: `${objectSchema.id}.${propertyName}.items.properties`,
215
+ properties: itemObjectProperties
216
+ };
217
+ for (const valueItem of value) {
218
+ const isObjectItem = valueItem && typeof valueItem === 'object' && !Array.isArray(valueItem);
219
+ // Only recursively process if the item is an object (not null, undefined, or primitive)
220
+ if (isObjectItem) {
221
+ mapObjectProperties(valueItem, itemSchema, schemasMap, callback);
222
+ }
223
+ }
224
+ }
225
+ }
226
+ }
227
+ };
228
+ exports.default = mapObjectProperties;
229
+ //# sourceMappingURL=mapObjectProperties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapObjectProperties.js","sourceRoot":"","sources":["../../src/helpers/mapObjectProperties.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,213 @@
1
+ import type { TargetObject, JsonSchema, JsonSchemasMap } from './JsonSchema';
2
+ /**
3
+ * Normalizes object attribute values based on a JSON Schema definition.
4
+ *
5
+ * ## Intent
6
+ *
7
+ * This function ensures that object properties conform to their schema definitions by:
8
+ * 1. Setting default values for properties that are undefined (but not null)
9
+ * 2. Normalizing existing values to match their schema-defined types (e.g., converting
10
+ * string "123" to number 123, or string "true" to boolean true)
11
+ *
12
+ * The function operates recursively, processing nested objects, arrays, and referenced
13
+ * schemas ($ref) to ensure all properties throughout the object tree are normalized
14
+ * according to their respective schema definitions.
15
+ *
16
+ * This is particularly useful in data processing pipelines where data may come from
17
+ * external sources (forms, APIs, databases) with inconsistent types, but needs to be
18
+ * normalized before validation or further processing.
19
+ *
20
+ * ## Use Cases
21
+ *
22
+ * 1. **Form data processing**: HTML forms submit all values as strings. This function
23
+ * converts them to their expected types (numbers, booleans) based on schema definitions
24
+ * and fills in default values for missing fields.
25
+ *
26
+ * 2. **API response normalization**: When consuming APIs that return loosely-typed data
27
+ * (e.g., numbers as strings, booleans as strings), this function ensures values match
28
+ * the expected schema types before validation or business logic processing.
29
+ *
30
+ * 3. **Configuration object initialization**: Setting default values and normalizing types
31
+ * for configuration objects based on their schema definitions, ensuring consistent
32
+ * structure and types throughout the application.
33
+ *
34
+ * 4. **Data migration and transformation**: Normalizing data structures during migration
35
+ * or transformation processes where source data may have inconsistent types but target
36
+ * schema requires specific types.
37
+ *
38
+ * 5. **Pre-validation normalization**: Preparing objects for schema validation by ensuring
39
+ * types are correct and defaults are applied, reducing validation errors and improving
40
+ * data quality.
41
+ *
42
+ * ## Behavior
43
+ *
44
+ * - **Default values**: Properties that are `undefined` will be set to their schema-defined
45
+ * default value (if one exists). Properties that are `null` are left as `null` and will
46
+ * not receive default values. Default values are also normalized according to their type
47
+ * (e.g., a default string "123" with type "number" will be converted to the number 123).
48
+ *
49
+ * - **Type normalization**: Properties with existing values (including default values that
50
+ * were just set) are normalized to match their schema type using `normalizeType`. This
51
+ * includes converting strings to numbers/booleans where appropriate, while preserving the
52
+ * original value if conversion is not possible.
53
+ *
54
+ * - **Recursive processing**: The function processes nested objects, arrays, and schema
55
+ * references ($ref) recursively, ensuring all nested properties are normalized.
56
+ *
57
+ * - **Non-destructive**: The function mutates the input object in place. If you need to
58
+ * preserve the original, create a deep copy before calling this function.
59
+ *
60
+ * ## Examples
61
+ *
62
+ * ### Basic Usage: Default Values and Type Normalization
63
+ * ```typescript
64
+ * import Schema from './Schema';
65
+ * import normalizeAttributes from './normalizeAttributes';
66
+ *
67
+ * const schema = new Schema({
68
+ * name: { type: 'string', default: 'Anonymous' },
69
+ * age: { type: 'number' },
70
+ * isActive: { type: 'boolean', default: false }
71
+ * }, 'user-schema');
72
+ *
73
+ * const user = {
74
+ * age: '25' // string that should be a number
75
+ * };
76
+ *
77
+ * normalizeAttributes(user, schema.jsonSchema, {});
78
+ *
79
+ * // Result:
80
+ * // {
81
+ * // name: 'Anonymous', // default value applied
82
+ * // age: 25, // string converted to number
83
+ * // isActive: false // default value applied
84
+ * // }
85
+ * ```
86
+ *
87
+ * ### Nested Objects
88
+ * ```typescript
89
+ * const schema = new Schema({
90
+ * address: {
91
+ * type: 'object',
92
+ * properties: {
93
+ * street: { type: 'string', default: 'Unknown' },
94
+ * zipCode: { type: 'number' }
95
+ * }
96
+ * }
97
+ * }, 'profile-schema');
98
+ *
99
+ * const profile = {
100
+ * address: {
101
+ * zipCode: '12345' // string that should be a number
102
+ * }
103
+ * };
104
+ *
105
+ * normalizeAttributes(profile, schema.jsonSchema, {});
106
+ *
107
+ * // Result:
108
+ * // {
109
+ * // address: {
110
+ * // street: 'Unknown', // default value applied
111
+ * // zipCode: 12345 // string converted to number
112
+ * // }
113
+ * // }
114
+ * ```
115
+ *
116
+ * ### Arrays with Schema References
117
+ * ```typescript
118
+ * const itemSchema = new Schema({
119
+ * id: { type: 'number' },
120
+ * name: { type: 'string', default: 'Unnamed' }
121
+ * }, 'item-schema');
122
+ *
123
+ * const schema = new Schema({
124
+ * items: {
125
+ * type: 'array',
126
+ * items: { $ref: 'item-schema' }
127
+ * }
128
+ * }, 'collection-schema');
129
+ *
130
+ * const collection = {
131
+ * items: [
132
+ * { id: '1' }, // id is a string, should be number
133
+ * { id: '2', name: 'Item 2' }
134
+ * ]
135
+ * };
136
+ *
137
+ * const schemasMap = {
138
+ * 'item-schema': itemSchema.jsonSchema
139
+ * };
140
+ *
141
+ * normalizeAttributes(collection, schema.jsonSchema, schemasMap);
142
+ *
143
+ * // Result:
144
+ * // {
145
+ * // items: [
146
+ * // { id: 1, name: 'Unnamed' }, // id normalized, default name applied
147
+ * // { id: 2, name: 'Item 2' } // id normalized, existing name preserved
148
+ * // ]
149
+ * // }
150
+ * ```
151
+ *
152
+ * ### Boolean Normalization
153
+ * ```typescript
154
+ * const schema = new Schema({
155
+ * enabled: { type: 'boolean', default: false },
156
+ * verified: { type: 'boolean' }
157
+ * }, 'settings-schema');
158
+ *
159
+ * const settings = {
160
+ * verified: 'yes' // string that should be boolean
161
+ * };
162
+ *
163
+ * normalizeAttributes(settings, schema.jsonSchema, {});
164
+ *
165
+ * // Result:
166
+ * // {
167
+ * // enabled: false, // default value applied
168
+ * // verified: true // string "yes" converted to boolean true
169
+ * // }
170
+ * ```
171
+ *
172
+ * ### Handling Null Values
173
+ * ```typescript
174
+ * const schema = new Schema({
175
+ * optionalField: { type: 'string', default: 'default-value' }
176
+ * }, 'test-schema');
177
+ *
178
+ * const obj1 = {}; // undefined → default applied
179
+ * const obj2 = { optionalField: null }; // null → no default applied
180
+ *
181
+ * normalizeAttributes(obj1, schema.jsonSchema, {});
182
+ * normalizeAttributes(obj2, schema.jsonSchema, {});
183
+ *
184
+ * // obj1: { optionalField: 'default-value' }
185
+ * // obj2: { optionalField: null } // null preserved, default not applied
186
+ * ```
187
+ *
188
+ * ### Default Value Normalization
189
+ * ```typescript
190
+ * const schema = new Schema({
191
+ * count: { type: 'number', default: '42' }, // default is string, type is number
192
+ * enabled: { type: 'boolean', default: 'true' } // default is string, type is boolean
193
+ * }, 'config-schema');
194
+ *
195
+ * const config = {};
196
+ *
197
+ * normalizeAttributes(config, schema.jsonSchema, {});
198
+ *
199
+ * // Result:
200
+ * // {
201
+ * // count: 42, // default string "42" normalized to number
202
+ * // enabled: true // default string "true" normalized to boolean
203
+ * // }
204
+ * ```
205
+ *
206
+ * @param object - The target object to normalize (mutated in place)
207
+ * @param jsonSchema - The JSON Schema definition describing the object structure
208
+ * @param jsonSchemasMap - Map of schema IDs to schema definitions, used for resolving $ref references
209
+ * @returns void (mutates the input object)
210
+ */
211
+ declare const normalizeAttributes: (object: TargetObject, jsonSchema: JsonSchema, jsonSchemasMap: JsonSchemasMap) => void;
212
+ export default normalizeAttributes;
213
+ //# sourceMappingURL=normalizeAttributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeAttributes.d.ts","sourceRoot":"","sources":["../../src/helpers/normalizeAttributes.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAkB,MAAM,cAAc,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgNG;AACH,QAAA,MAAM,mBAAmB,GAAI,QAAQ,YAAY,EAAE,YAAY,UAAU,EAAE,gBAAgB,cAAc,SA6BxG,CAAC;AAEF,eAAe,mBAAmB,CAAC"}