@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
@@ -0,0 +1,159 @@
1
+ import type { JsonSchema, ObjectPropertySchema, ReferencePropertySchema } from './JsonSchema';
2
+ /**
3
+ * Normalizes required field declarations in JSON schemas by converting property-level
4
+ * `required` flags to schema-level `required` arrays and `x-required` metadata flags.
5
+ *
6
+ * **Intent:**
7
+ * This function transforms JSON schemas from a property-centric required field model
8
+ * (where each property has its own `required: true/false` flag) to the standard JSON Schema
9
+ * format (where required fields are listed in a top-level `required` array). This normalization
10
+ * ensures compatibility with JSON Schema validators while preserving the original required
11
+ * field information through the `x-required` extension attribute.
12
+ *
13
+ * **Use Cases:**
14
+ * 1. **Schema Standardization**: Convert custom schema formats to standard JSON Schema format
15
+ * for validator compatibility
16
+ * 2. **Schema Transformation**: Prepare schemas for validation libraries that expect
17
+ * required fields in array format
18
+ * 3. **Metadata Preservation**: Maintain required field information in both standard format
19
+ * (`required` array) and extension format (`x-required` flag) for different use cases
20
+ * 4. **Schema Processing Pipeline**: Normalize schemas before validation, credential generation,
21
+ * or API documentation generation
22
+ *
23
+ * **Behavior:**
24
+ * - Mutates the input schema in-place
25
+ * - Moves `required: true` from property level to schema-level `required` array
26
+ * - Sets `x-required: true` on properties that were marked as required
27
+ * - Deletes the `required` property from individual property schemas
28
+ * - Recursively processes nested object properties
29
+ * - Recursively processes array items (including nested objects within arrays)
30
+ * - Skips reference properties (`$ref`) as they are resolved elsewhere
31
+ * - Skips EnumSchema (returns early)
32
+ * - Only sets `required` array if at least one field is required
33
+ *
34
+ * **Examples:**
35
+ *
36
+ * ```typescript
37
+ * // Example 1: Simple object schema
38
+ * const schema = {
39
+ * id: 'User',
40
+ * properties: {
41
+ * name: { type: 'string', required: true },
42
+ * email: { type: 'string', required: true },
43
+ * age: { type: 'number', required: false }
44
+ * }
45
+ * };
46
+ *
47
+ * normalizeRequired(schema);
48
+ * // Result:
49
+ * // schema.required = ['name', 'email']
50
+ * // schema.properties.name['x-required'] = true
51
+ * // schema.properties.email['x-required'] = true
52
+ * // schema.properties.name.required = undefined (deleted)
53
+ * // schema.properties.email.required = undefined (deleted)
54
+ * ```
55
+ *
56
+ * ```typescript
57
+ * // Example 2: Nested objects
58
+ * const schema = {
59
+ * id: 'Order',
60
+ * properties: {
61
+ * user: {
62
+ * type: 'object',
63
+ * required: true,
64
+ * properties: {
65
+ * name: { type: 'string', required: true },
66
+ * address: {
67
+ * type: 'object',
68
+ * properties: {
69
+ * street: { type: 'string', required: true }
70
+ * }
71
+ * }
72
+ * }
73
+ * }
74
+ * }
75
+ * };
76
+ *
77
+ * normalizeRequired(schema);
78
+ * // Result:
79
+ * // schema.required = ['user']
80
+ * // schema.properties.user['x-required'] = true
81
+ * // schema.properties.user.required = ['name']
82
+ * // schema.properties.user.properties.name['x-required'] = true
83
+ * // schema.properties.user.properties.address.required = ['street']
84
+ * // schema.properties.user.properties.address.properties.street['x-required'] = true
85
+ * ```
86
+ *
87
+ * ```typescript
88
+ * // Example 3: Arrays with object items
89
+ * const schema = {
90
+ * id: 'Order',
91
+ * properties: {
92
+ * items: {
93
+ * type: 'array',
94
+ * required: true,
95
+ * items: {
96
+ * type: 'object',
97
+ * properties: {
98
+ * productId: { type: 'string', required: true },
99
+ * quantity: { type: 'number', required: true }
100
+ * }
101
+ * }
102
+ * }
103
+ * }
104
+ * };
105
+ *
106
+ * normalizeRequired(schema);
107
+ * // Result:
108
+ * // schema.required = ['items']
109
+ * // schema.properties.items['x-required'] = true
110
+ * // schema.properties.items.items.required = ['productId', 'quantity']
111
+ * // schema.properties.items.items.properties.productId['x-required'] = true
112
+ * // schema.properties.items.items.properties.quantity['x-required'] = true
113
+ * ```
114
+ *
115
+ * ```typescript
116
+ * // Example 4: Mixed structure
117
+ * const schema = {
118
+ * id: 'Profile',
119
+ * properties: {
120
+ * name: { type: 'string', required: true },
121
+ * address: {
122
+ * type: 'object',
123
+ * required: true,
124
+ * properties: {
125
+ * street: { type: 'string', required: true },
126
+ * city: { type: 'string' }
127
+ * }
128
+ * },
129
+ * tags: {
130
+ * type: 'array',
131
+ * items: {
132
+ * type: 'object',
133
+ * properties: {
134
+ * label: { type: 'string', required: true }
135
+ * }
136
+ * }
137
+ * }
138
+ * }
139
+ * };
140
+ *
141
+ * normalizeRequired(schema);
142
+ * // Result:
143
+ * // schema.required = ['name', 'address']
144
+ * // All nested required fields are normalized recursively
145
+ * ```
146
+ *
147
+ * **Limitations:**
148
+ * - Only processes schemas with a `properties` field (ObjectSchema or ObjectPropertySchema)
149
+ * - EnumSchema is accepted but returns early without processing
150
+ * - Reference properties (`$ref`) are skipped and not processed
151
+ * - The function mutates the input schema object
152
+ * - Does not resolve `$ref` references (they must be resolved separately)
153
+ *
154
+ * @param jsonSchema - The JSON schema to normalize (ObjectSchema, ObjectPropertySchema, or ReferencePropertySchema)
155
+ * @returns void (mutates the input schema in-place)
156
+ */
157
+ declare const normalizeRequired: (jsonSchema: JsonSchema | ObjectPropertySchema | ReferencePropertySchema) => void;
158
+ export default normalizeRequired;
159
+ //# sourceMappingURL=normalizeRequired.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeRequired.d.ts","sourceRoot":"","sources":["../../src/helpers/normalizeRequired.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EAIV,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0JG;AACH,QAAA,MAAM,iBAAiB,GAAI,YAAY,UAAU,GAAG,oBAAoB,GAAG,uBAAuB,SAgEjG,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lodash_1 = require("lodash");
4
+ /**
5
+ * Normalizes required field declarations in JSON schemas by converting property-level
6
+ * `required` flags to schema-level `required` arrays and `x-required` metadata flags.
7
+ *
8
+ * **Intent:**
9
+ * This function transforms JSON schemas from a property-centric required field model
10
+ * (where each property has its own `required: true/false` flag) to the standard JSON Schema
11
+ * format (where required fields are listed in a top-level `required` array). This normalization
12
+ * ensures compatibility with JSON Schema validators while preserving the original required
13
+ * field information through the `x-required` extension attribute.
14
+ *
15
+ * **Use Cases:**
16
+ * 1. **Schema Standardization**: Convert custom schema formats to standard JSON Schema format
17
+ * for validator compatibility
18
+ * 2. **Schema Transformation**: Prepare schemas for validation libraries that expect
19
+ * required fields in array format
20
+ * 3. **Metadata Preservation**: Maintain required field information in both standard format
21
+ * (`required` array) and extension format (`x-required` flag) for different use cases
22
+ * 4. **Schema Processing Pipeline**: Normalize schemas before validation, credential generation,
23
+ * or API documentation generation
24
+ *
25
+ * **Behavior:**
26
+ * - Mutates the input schema in-place
27
+ * - Moves `required: true` from property level to schema-level `required` array
28
+ * - Sets `x-required: true` on properties that were marked as required
29
+ * - Deletes the `required` property from individual property schemas
30
+ * - Recursively processes nested object properties
31
+ * - Recursively processes array items (including nested objects within arrays)
32
+ * - Skips reference properties (`$ref`) as they are resolved elsewhere
33
+ * - Skips EnumSchema (returns early)
34
+ * - Only sets `required` array if at least one field is required
35
+ *
36
+ * **Examples:**
37
+ *
38
+ * ```typescript
39
+ * // Example 1: Simple object schema
40
+ * const schema = {
41
+ * id: 'User',
42
+ * properties: {
43
+ * name: { type: 'string', required: true },
44
+ * email: { type: 'string', required: true },
45
+ * age: { type: 'number', required: false }
46
+ * }
47
+ * };
48
+ *
49
+ * normalizeRequired(schema);
50
+ * // Result:
51
+ * // schema.required = ['name', 'email']
52
+ * // schema.properties.name['x-required'] = true
53
+ * // schema.properties.email['x-required'] = true
54
+ * // schema.properties.name.required = undefined (deleted)
55
+ * // schema.properties.email.required = undefined (deleted)
56
+ * ```
57
+ *
58
+ * ```typescript
59
+ * // Example 2: Nested objects
60
+ * const schema = {
61
+ * id: 'Order',
62
+ * properties: {
63
+ * user: {
64
+ * type: 'object',
65
+ * required: true,
66
+ * properties: {
67
+ * name: { type: 'string', required: true },
68
+ * address: {
69
+ * type: 'object',
70
+ * properties: {
71
+ * street: { type: 'string', required: true }
72
+ * }
73
+ * }
74
+ * }
75
+ * }
76
+ * }
77
+ * };
78
+ *
79
+ * normalizeRequired(schema);
80
+ * // Result:
81
+ * // schema.required = ['user']
82
+ * // schema.properties.user['x-required'] = true
83
+ * // schema.properties.user.required = ['name']
84
+ * // schema.properties.user.properties.name['x-required'] = true
85
+ * // schema.properties.user.properties.address.required = ['street']
86
+ * // schema.properties.user.properties.address.properties.street['x-required'] = true
87
+ * ```
88
+ *
89
+ * ```typescript
90
+ * // Example 3: Arrays with object items
91
+ * const schema = {
92
+ * id: 'Order',
93
+ * properties: {
94
+ * items: {
95
+ * type: 'array',
96
+ * required: true,
97
+ * items: {
98
+ * type: 'object',
99
+ * properties: {
100
+ * productId: { type: 'string', required: true },
101
+ * quantity: { type: 'number', required: true }
102
+ * }
103
+ * }
104
+ * }
105
+ * }
106
+ * };
107
+ *
108
+ * normalizeRequired(schema);
109
+ * // Result:
110
+ * // schema.required = ['items']
111
+ * // schema.properties.items['x-required'] = true
112
+ * // schema.properties.items.items.required = ['productId', 'quantity']
113
+ * // schema.properties.items.items.properties.productId['x-required'] = true
114
+ * // schema.properties.items.items.properties.quantity['x-required'] = true
115
+ * ```
116
+ *
117
+ * ```typescript
118
+ * // Example 4: Mixed structure
119
+ * const schema = {
120
+ * id: 'Profile',
121
+ * properties: {
122
+ * name: { type: 'string', required: true },
123
+ * address: {
124
+ * type: 'object',
125
+ * required: true,
126
+ * properties: {
127
+ * street: { type: 'string', required: true },
128
+ * city: { type: 'string' }
129
+ * }
130
+ * },
131
+ * tags: {
132
+ * type: 'array',
133
+ * items: {
134
+ * type: 'object',
135
+ * properties: {
136
+ * label: { type: 'string', required: true }
137
+ * }
138
+ * }
139
+ * }
140
+ * }
141
+ * };
142
+ *
143
+ * normalizeRequired(schema);
144
+ * // Result:
145
+ * // schema.required = ['name', 'address']
146
+ * // All nested required fields are normalized recursively
147
+ * ```
148
+ *
149
+ * **Limitations:**
150
+ * - Only processes schemas with a `properties` field (ObjectSchema or ObjectPropertySchema)
151
+ * - EnumSchema is accepted but returns early without processing
152
+ * - Reference properties (`$ref`) are skipped and not processed
153
+ * - The function mutates the input schema object
154
+ * - Does not resolve `$ref` references (they must be resolved separately)
155
+ *
156
+ * @param jsonSchema - The JSON schema to normalize (ObjectSchema, ObjectPropertySchema, or ReferencePropertySchema)
157
+ * @returns void (mutates the input schema in-place)
158
+ */
159
+ const normalizeRequired = (jsonSchema) => {
160
+ const { enum: enumItems } = jsonSchema;
161
+ const isEnum = !!enumItems;
162
+ if (isEnum) {
163
+ return;
164
+ }
165
+ const objectSchema = jsonSchema;
166
+ const { properties } = objectSchema;
167
+ if (!properties) {
168
+ return;
169
+ }
170
+ const required = [];
171
+ for (const propertyName in properties) {
172
+ const property = properties[propertyName];
173
+ const { $ref: refSchemaId } = property;
174
+ const isReference = !(0, lodash_1.isUndefined)(refSchemaId);
175
+ // Handle required flag for all properties (including references)
176
+ if (property.required) {
177
+ property['x-required'] = true;
178
+ required.push(propertyName);
179
+ }
180
+ // Delete required property for all properties (whether true or false)
181
+ delete property.required;
182
+ // Skip recursive processing for reference properties
183
+ if (isReference) {
184
+ continue;
185
+ }
186
+ const { type } = property;
187
+ const isObject = type === 'object';
188
+ if (isObject) {
189
+ normalizeRequired(property);
190
+ continue;
191
+ }
192
+ const isArray = type === 'array';
193
+ if (isArray) {
194
+ const { items } = property;
195
+ if (items) {
196
+ normalizeRequired(items);
197
+ }
198
+ continue;
199
+ }
200
+ }
201
+ if (required.length > 0) {
202
+ objectSchema.required = required;
203
+ }
204
+ };
205
+ exports.default = normalizeRequired;
206
+ //# sourceMappingURL=normalizeRequired.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeRequired.js","sourceRoot":"","sources":["../../src/helpers/normalizeRequired.ts"],"names":[],"mappings":";;AAAA,mCAAqC;AAWrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0JG;AACH,MAAM,iBAAiB,GAAG,CAAC,UAAuE,EAAE,EAAE;IACpG,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAI,UAAyB,CAAC;IAEvD,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC;IAE3B,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAI,UAA2B,CAAC;IAClD,MAAM,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC;IAEpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC;IAEpB,KAAK,MAAM,YAAY,IAAI,UAAU,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QAE1C,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAI,QAAoC,CAAC;QAEpE,MAAM,WAAW,GAAG,CAAC,IAAA,oBAAW,EAAC,WAAW,CAAC,CAAC;QAE9C,iEAAiE;QACjE,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACtB,QAAQ,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9B,CAAC;QAED,sEAAsE;QACtE,OAAO,QAAQ,CAAC,QAAQ,CAAC;QAEzB,qDAAqD;QACrD,IAAI,WAAW,EAAE,CAAC;YAChB,SAAS;QACX,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,GAAI,QAAuD,CAAC;QAE1E,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,CAAC;QAEnC,IAAI,QAAQ,EAAE,CAAC;YACb,iBAAiB,CAAC,QAAgC,CAAC,CAAC;YACpD,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,KAAK,OAAO,CAAC;QAEjC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,EAAE,KAAK,EAAE,GAAI,QAAgC,CAAC;YAEpD,IAAI,KAAK,EAAE,CAAC;gBACV,iBAAiB,CAAC,KAAuD,CAAC,CAAC;YAC7E,CAAC;YAED,SAAS;QACX,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,YAAY,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACnC,CAAC;AACH,CAAC,CAAC;AAEF,kBAAe,iBAAiB,CAAC"}
@@ -0,0 +1,81 @@
1
+ type ValueType = 'number' | 'integer' | 'boolean' | 'string' | 'object' | 'array';
2
+ /**
3
+ * Normalizes a value to match a specified JSON Schema type.
4
+ *
5
+ * ## Intent
6
+ *
7
+ * This function is designed to coerce values into their expected types based on JSON Schema
8
+ * type definitions. It's particularly useful when processing data from external sources (like
9
+ * form inputs, query parameters, or API responses) where values may arrive as strings but
10
+ * need to be converted to their proper types according to a schema definition.
11
+ *
12
+ * The function performs type coercion where appropriate, but preserves the original value
13
+ * when conversion is not possible or when the value is already of the correct type. This
14
+ * makes it safe to use in data normalization pipelines without losing information.
15
+ *
16
+ * ## Use Cases
17
+ *
18
+ * 1. **Schema-based data normalization**: When processing objects against JSON Schema
19
+ * definitions, ensuring property values match their declared types.
20
+ *
21
+ * 2. **Form data processing**: Converting string values from HTML forms (which are always
22
+ * strings) to their expected types (numbers, booleans) based on schema definitions.
23
+ *
24
+ * 3. **API response normalization**: Normalizing API responses where types may be ambiguous
25
+ * or incorrectly serialized (e.g., numbers as strings, booleans as strings).
26
+ *
27
+ * 4. **Configuration parsing**: Parsing configuration values from environment variables or
28
+ * config files where everything is initially a string but needs type coercion.
29
+ *
30
+ * ## Behavior by Type
31
+ *
32
+ * - **number/integer**: Attempts to convert strings and booleans to numbers. Preserves
33
+ * original value if conversion fails or value is already a number.
34
+ *
35
+ * - **boolean**: Converts numbers (0 → false, non-zero → true) and recognized string
36
+ * values ('yes', 'true', '1' → true; 'no', 'false', '0' → false). Preserves original
37
+ * value for unrecognized strings or non-convertible types.
38
+ *
39
+ * - **string/object/array**: Returns the value as-is (no conversion performed).
40
+ *
41
+ * - **null/undefined**: Always preserved regardless of target type.
42
+ *
43
+ * ## Examples
44
+ *
45
+ * ### Number Conversion
46
+ * ```typescript
47
+ * normalizeType('number', '123') // → 123
48
+ * normalizeType('number', '45.67') // → 45.67
49
+ * normalizeType('number', '0') // → 0
50
+ * normalizeType('number', true) // → 1
51
+ * normalizeType('number', 'abc') // → 'abc' (conversion failed, original preserved)
52
+ * ```
53
+ *
54
+ * ### Boolean Conversion
55
+ * ```typescript
56
+ * normalizeType('boolean', 0) // → false
57
+ * normalizeType('boolean', 1) // → true
58
+ * normalizeType('boolean', 'yes') // → true
59
+ * normalizeType('boolean', 'true') // → true
60
+ * normalizeType('boolean', '1') // → true
61
+ * normalizeType('boolean', 'no') // → false
62
+ * normalizeType('boolean', 'false') // → false
63
+ * normalizeType('boolean', 'maybe') // → 'maybe' (unrecognized, original preserved)
64
+ * ```
65
+ *
66
+ * ### Type Preservation
67
+ * ```typescript
68
+ * normalizeType('string', 'hello') // → 'hello'
69
+ * normalizeType('string', 123) // → 123 (no conversion for string type)
70
+ * normalizeType('object', { a: 1 }) // → { a: 1 }
71
+ * normalizeType('array', [1, 2, 3]) // → [1, 2, 3]
72
+ * normalizeType('number', null) // → null (null always preserved)
73
+ * ```
74
+ *
75
+ * @param type - The target JSON Schema type ('number', 'integer', 'boolean', 'string', 'object', 'array')
76
+ * @param value - The value to normalize (can be any type)
77
+ * @returns The normalized value, or the original value if normalization is not applicable
78
+ */
79
+ declare const normalizeType: (type: ValueType, value: unknown) => string | number | boolean | unknown;
80
+ export default normalizeType;
81
+ //# sourceMappingURL=normalizeType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeType.d.ts","sourceRoot":"","sources":["../../src/helpers/normalizeType.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AA2FlF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AACH,QAAA,MAAM,aAAa,GAAI,MAAM,SAAS,EAAE,OAAO,OAAO,KAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAgEpF,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,210 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const BOOLEAN_STRING_TRUE_VALUES = ['yes', 'true', '1'];
4
+ const BOOLEAN_STRING_FALSE_VALUES = ['no', 'false', '0'];
5
+ /**
6
+ * Checks if a value is null or undefined.
7
+ *
8
+ * @param value - The value to check
9
+ * @returns True if the value is null or undefined, false otherwise
10
+ */
11
+ const isNullOrUndefined = (value) => value === null || value === undefined;
12
+ /**
13
+ * Checks if a JSON Schema type is numeric (number or integer).
14
+ *
15
+ * @param type - The JSON Schema type to check
16
+ * @returns True if the type is 'number' or 'integer', false otherwise
17
+ */
18
+ const isNumericType = (type) => type === 'number' || type === 'integer';
19
+ /**
20
+ * Checks if a JSON Schema type is boolean.
21
+ *
22
+ * @param type - The JSON Schema type to check
23
+ * @returns True if the type is 'boolean', false otherwise
24
+ */
25
+ const isBooleanType = (type) => type === 'boolean';
26
+ /**
27
+ * Type guard that checks if a value is a number.
28
+ *
29
+ * @param value - The value to check
30
+ * @returns True if the value is a number, false otherwise
31
+ */
32
+ const isNumberValue = (value) => typeof value === 'number';
33
+ /**
34
+ * Type guard that checks if a value is a boolean.
35
+ *
36
+ * @param value - The value to check
37
+ * @returns True if the value is a boolean, false otherwise
38
+ */
39
+ const isBooleanValue = (value) => typeof value === 'boolean';
40
+ /**
41
+ * Type guard that checks if a value is a string.
42
+ *
43
+ * @param value - The value to check
44
+ * @returns True if the value is a string, false otherwise
45
+ */
46
+ const isStringValue = (value) => typeof value === 'string';
47
+ /**
48
+ * Checks if a string is empty or contains only whitespace characters.
49
+ *
50
+ * @param value - The string to check
51
+ * @returns True if the string is empty or whitespace-only, false otherwise
52
+ */
53
+ const isEmptyOrWhitespaceString = (value) => value === '' || value.trim() === '';
54
+ /**
55
+ * Checks if a number is valid (not NaN).
56
+ *
57
+ * @param value - The number to check
58
+ * @returns True if the number is valid (not NaN), false otherwise
59
+ */
60
+ const isValidNumber = (value) => !isNaN(value);
61
+ /**
62
+ * Checks if a string represents a boolean true value.
63
+ * Recognized values (case-insensitive): 'yes', 'true', '1'.
64
+ *
65
+ * @param value - The string to check
66
+ * @returns True if the string represents a boolean true value, false otherwise
67
+ */
68
+ const isBooleanTrueString = (value) => BOOLEAN_STRING_TRUE_VALUES.includes(value.toLowerCase());
69
+ /**
70
+ * Checks if a string represents a boolean false value.
71
+ * Recognized values (case-insensitive): 'no', 'false', '0'.
72
+ *
73
+ * @param value - The string to check
74
+ * @returns True if the string represents a boolean false value, false otherwise
75
+ */
76
+ const isBooleanFalseString = (value) => BOOLEAN_STRING_FALSE_VALUES.includes(value.toLowerCase());
77
+ /**
78
+ * Normalizes a value to match a specified JSON Schema type.
79
+ *
80
+ * ## Intent
81
+ *
82
+ * This function is designed to coerce values into their expected types based on JSON Schema
83
+ * type definitions. It's particularly useful when processing data from external sources (like
84
+ * form inputs, query parameters, or API responses) where values may arrive as strings but
85
+ * need to be converted to their proper types according to a schema definition.
86
+ *
87
+ * The function performs type coercion where appropriate, but preserves the original value
88
+ * when conversion is not possible or when the value is already of the correct type. This
89
+ * makes it safe to use in data normalization pipelines without losing information.
90
+ *
91
+ * ## Use Cases
92
+ *
93
+ * 1. **Schema-based data normalization**: When processing objects against JSON Schema
94
+ * definitions, ensuring property values match their declared types.
95
+ *
96
+ * 2. **Form data processing**: Converting string values from HTML forms (which are always
97
+ * strings) to their expected types (numbers, booleans) based on schema definitions.
98
+ *
99
+ * 3. **API response normalization**: Normalizing API responses where types may be ambiguous
100
+ * or incorrectly serialized (e.g., numbers as strings, booleans as strings).
101
+ *
102
+ * 4. **Configuration parsing**: Parsing configuration values from environment variables or
103
+ * config files where everything is initially a string but needs type coercion.
104
+ *
105
+ * ## Behavior by Type
106
+ *
107
+ * - **number/integer**: Attempts to convert strings and booleans to numbers. Preserves
108
+ * original value if conversion fails or value is already a number.
109
+ *
110
+ * - **boolean**: Converts numbers (0 → false, non-zero → true) and recognized string
111
+ * values ('yes', 'true', '1' → true; 'no', 'false', '0' → false). Preserves original
112
+ * value for unrecognized strings or non-convertible types.
113
+ *
114
+ * - **string/object/array**: Returns the value as-is (no conversion performed).
115
+ *
116
+ * - **null/undefined**: Always preserved regardless of target type.
117
+ *
118
+ * ## Examples
119
+ *
120
+ * ### Number Conversion
121
+ * ```typescript
122
+ * normalizeType('number', '123') // → 123
123
+ * normalizeType('number', '45.67') // → 45.67
124
+ * normalizeType('number', '0') // → 0
125
+ * normalizeType('number', true) // → 1
126
+ * normalizeType('number', 'abc') // → 'abc' (conversion failed, original preserved)
127
+ * ```
128
+ *
129
+ * ### Boolean Conversion
130
+ * ```typescript
131
+ * normalizeType('boolean', 0) // → false
132
+ * normalizeType('boolean', 1) // → true
133
+ * normalizeType('boolean', 'yes') // → true
134
+ * normalizeType('boolean', 'true') // → true
135
+ * normalizeType('boolean', '1') // → true
136
+ * normalizeType('boolean', 'no') // → false
137
+ * normalizeType('boolean', 'false') // → false
138
+ * normalizeType('boolean', 'maybe') // → 'maybe' (unrecognized, original preserved)
139
+ * ```
140
+ *
141
+ * ### Type Preservation
142
+ * ```typescript
143
+ * normalizeType('string', 'hello') // → 'hello'
144
+ * normalizeType('string', 123) // → 123 (no conversion for string type)
145
+ * normalizeType('object', { a: 1 }) // → { a: 1 }
146
+ * normalizeType('array', [1, 2, 3]) // → [1, 2, 3]
147
+ * normalizeType('number', null) // → null (null always preserved)
148
+ * ```
149
+ *
150
+ * @param type - The target JSON Schema type ('number', 'integer', 'boolean', 'string', 'object', 'array')
151
+ * @param value - The value to normalize (can be any type)
152
+ * @returns The normalized value, or the original value if normalization is not applicable
153
+ */
154
+ const normalizeType = (type, value) => {
155
+ // Preserve null and undefined values regardless of target type
156
+ if (isNullOrUndefined(value)) {
157
+ return value;
158
+ }
159
+ // Handle number and integer types
160
+ if (isNumericType(type)) {
161
+ // If already a number, return as-is
162
+ if (isNumberValue(value)) {
163
+ return value;
164
+ }
165
+ // Convert booleans to numbers: true → 1, false → 0
166
+ if (isBooleanValue(value)) {
167
+ return value ? 1 : 0;
168
+ }
169
+ // Attempt conversion for strings
170
+ if (isStringValue(value)) {
171
+ // Preserve empty strings and whitespace-only strings
172
+ if (isEmptyOrWhitespaceString(value)) {
173
+ return value;
174
+ }
175
+ const converted = Number(value);
176
+ // Check if conversion was successful (not NaN)
177
+ if (isValidNumber(converted)) {
178
+ return converted;
179
+ }
180
+ }
181
+ // Return original value if conversion failed or type is not convertible
182
+ return value;
183
+ }
184
+ // Handle boolean type
185
+ if (isBooleanType(type)) {
186
+ // If already a boolean, return as-is
187
+ if (isBooleanValue(value)) {
188
+ return value;
189
+ }
190
+ // Convert numbers: 0 → false, non-zero → true
191
+ if (isNumberValue(value)) {
192
+ return Boolean(value);
193
+ }
194
+ // Convert recognized string values
195
+ if (isStringValue(value)) {
196
+ if (isBooleanTrueString(value)) {
197
+ return true;
198
+ }
199
+ if (isBooleanFalseString(value)) {
200
+ return false;
201
+ }
202
+ }
203
+ // Return original value for unrecognized strings or non-convertible types
204
+ return value;
205
+ }
206
+ // For string, object, and array types, return value as-is (no conversion)
207
+ return value;
208
+ };
209
+ exports.default = normalizeType;
210
+ //# sourceMappingURL=normalizeType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeType.js","sourceRoot":"","sources":["../../src/helpers/normalizeType.ts"],"names":[],"mappings":"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"}