@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.
- package/README.md +19 -14
- package/dist/CredentialFactory.d.ts +345 -0
- package/dist/CredentialFactory.d.ts.map +1 -0
- package/dist/CredentialFactory.js +381 -0
- package/dist/CredentialFactory.js.map +1 -0
- package/dist/Schema.d.ts +448 -0
- package/dist/Schema.d.ts.map +1 -0
- package/dist/Schema.js +506 -0
- package/dist/Schema.js.map +1 -0
- package/dist/ValidationError.d.ts +70 -0
- package/dist/ValidationError.d.ts.map +1 -0
- package/dist/ValidationError.js +78 -0
- package/dist/ValidationError.js.map +1 -0
- package/dist/Validator.d.ts +483 -0
- package/dist/Validator.d.ts.map +1 -0
- package/dist/Validator.js +570 -0
- package/dist/Validator.js.map +1 -0
- package/dist/helpers/JsonSchema.d.ts +99 -0
- package/dist/helpers/JsonSchema.d.ts.map +1 -0
- package/dist/helpers/JsonSchema.js +3 -0
- package/dist/helpers/JsonSchema.js.map +1 -0
- package/dist/helpers/cleanupAttributes.d.ts +34 -0
- package/dist/helpers/cleanupAttributes.d.ts.map +1 -0
- package/dist/helpers/cleanupAttributes.js +113 -0
- package/dist/helpers/cleanupAttributes.js.map +1 -0
- package/dist/helpers/cleanupNulls.d.ts +27 -0
- package/dist/helpers/cleanupNulls.d.ts.map +1 -0
- package/dist/helpers/cleanupNulls.js +96 -0
- package/dist/helpers/cleanupNulls.js.map +1 -0
- package/dist/helpers/getReferenceIds.d.ts +169 -0
- package/dist/helpers/getReferenceIds.d.ts.map +1 -0
- package/dist/helpers/getReferenceIds.js +241 -0
- package/dist/helpers/getReferenceIds.js.map +1 -0
- package/dist/helpers/got.d.ts +60 -0
- package/dist/helpers/got.d.ts.map +1 -0
- package/dist/helpers/got.js +72 -0
- package/dist/helpers/got.js.map +1 -0
- package/dist/helpers/mapObjectProperties.d.ts +150 -0
- package/dist/helpers/mapObjectProperties.d.ts.map +1 -0
- package/dist/helpers/mapObjectProperties.js +229 -0
- package/dist/helpers/mapObjectProperties.js.map +1 -0
- package/dist/helpers/normalizeAttributes.d.ts +213 -0
- package/dist/helpers/normalizeAttributes.d.ts.map +1 -0
- package/dist/helpers/normalizeAttributes.js +243 -0
- package/dist/helpers/normalizeAttributes.js.map +1 -0
- package/dist/helpers/normalizeProperties.d.ts +168 -0
- package/dist/helpers/normalizeProperties.d.ts.map +1 -0
- package/dist/helpers/normalizeProperties.js +223 -0
- package/dist/helpers/normalizeProperties.js.map +1 -0
- package/dist/helpers/normalizeRequired.d.ts +159 -0
- package/dist/helpers/normalizeRequired.d.ts.map +1 -0
- package/dist/helpers/normalizeRequired.js +206 -0
- package/dist/helpers/normalizeRequired.js.map +1 -0
- package/dist/helpers/normalizeType.d.ts +81 -0
- package/dist/helpers/normalizeType.d.ts.map +1 -0
- package/dist/helpers/normalizeType.js +210 -0
- package/dist/helpers/normalizeType.js.map +1 -0
- package/dist/helpers/nullifyEmptyValues.d.ts +139 -0
- package/dist/helpers/nullifyEmptyValues.d.ts.map +1 -0
- package/dist/helpers/nullifyEmptyValues.js +191 -0
- package/dist/helpers/nullifyEmptyValues.js.map +1 -0
- package/dist/helpers/removeRequiredAndDefault.d.ts +106 -0
- package/dist/helpers/removeRequiredAndDefault.d.ts.map +1 -0
- package/dist/helpers/removeRequiredAndDefault.js +138 -0
- package/dist/helpers/removeRequiredAndDefault.js.map +1 -0
- package/dist/helpers/validateId.d.ts +39 -0
- package/dist/helpers/validateId.d.ts.map +1 -0
- package/dist/helpers/validateId.js +51 -0
- package/dist/helpers/validateId.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/ld/documentLoader.d.ts +8 -0
- package/dist/ld/documentLoader.d.ts.map +1 -0
- package/dist/ld/documentLoader.js +24 -0
- package/dist/ld/documentLoader.js.map +1 -0
- package/dist/ld/getLinkedDataAttributeType.d.ts +10 -0
- package/dist/ld/getLinkedDataAttributeType.d.ts.map +1 -0
- package/dist/ld/getLinkedDataAttributeType.js +32 -0
- package/dist/ld/getLinkedDataAttributeType.js.map +1 -0
- package/dist/ld/getLinkedDataContext.d.ts +19 -0
- package/dist/ld/getLinkedDataContext.d.ts.map +1 -0
- package/dist/ld/getLinkedDataContext.js +50 -0
- package/dist/ld/getLinkedDataContext.js.map +1 -0
- package/eslint.config.mjs +32 -52
- package/examples/credentials/createAccountCredential.ts +27 -0
- package/examples/credentials/createMineSweeperScoreCredential.ts +115 -0
- package/examples/index.ts +7 -0
- package/examples/schemas/FavoriteItemSchema.ts +27 -0
- package/examples/{Preferences.yaml → schemas/Preferences.yaml} +2 -0
- package/examples/schemas/PreferencesSchema.ts +29 -0
- package/examples/schemas/ProfileSchema.ts +91 -0
- package/examples/schemas/Status.yaml +3 -0
- package/examples/schemas/StatusSchema.ts +12 -0
- package/jest.config.mjs +5 -0
- package/package.json +28 -21
- package/src/CredentialFactory.ts +392 -0
- package/src/Schema.ts +583 -0
- package/src/ValidationError.ts +90 -0
- package/src/Validator.ts +603 -0
- package/src/__tests__/CredentialFactory.test.ts +588 -0
- package/src/__tests__/Schema.test.ts +371 -0
- package/src/__tests__/ValidationError.test.ts +235 -0
- package/src/__tests__/Validator.test.ts +787 -0
- package/src/helpers/JsonSchema.ts +119 -0
- package/src/helpers/__tests__/cleanupAttributes.test.ts +943 -0
- package/src/helpers/__tests__/cleanupNulls.test.ts +772 -0
- package/src/helpers/__tests__/getReferenceIds.test.ts +975 -0
- package/src/helpers/__tests__/got.test.ts +193 -0
- package/src/helpers/__tests__/mapObjectProperties.test.ts +1126 -0
- package/src/helpers/__tests__/normalizeAttributes.test.ts +1435 -0
- package/src/helpers/__tests__/normalizeProperties.test.ts +727 -0
- package/src/helpers/__tests__/normalizeRequired.test.ts +669 -0
- package/src/helpers/__tests__/normalizeType.test.ts +772 -0
- package/src/helpers/__tests__/nullifyEmptyValues.test.ts +735 -0
- package/src/helpers/__tests__/removeRequiredAndDefault.test.ts +734 -0
- package/src/helpers/__tests__/validateId.test.ts +118 -0
- package/src/helpers/cleanupAttributes.ts +151 -0
- package/src/helpers/cleanupNulls.ts +106 -0
- package/src/helpers/getReferenceIds.ts +273 -0
- package/src/helpers/got.ts +73 -0
- package/src/helpers/mapObjectProperties.ts +272 -0
- package/src/helpers/normalizeAttributes.ts +247 -0
- package/src/helpers/normalizeProperties.ts +249 -0
- package/src/helpers/normalizeRequired.ts +233 -0
- package/src/helpers/normalizeType.ts +235 -0
- package/src/helpers/nullifyEmptyValues.ts +207 -0
- package/src/helpers/removeRequiredAndDefault.ts +151 -0
- package/src/helpers/validateId.ts +53 -0
- package/src/index.ts +13 -0
- package/src/ld/__tests__/documentLoader.test.ts +57 -0
- package/src/ld/__tests__/getLinkedDataAttributeType.test.ts +212 -0
- package/src/ld/__tests__/getLinkedDataContext.test.ts +378 -0
- package/src/ld/documentLoader.ts +28 -0
- package/src/ld/getLinkedDataAttributeType.ts +46 -0
- package/src/ld/getLinkedDataContext.ts +80 -0
- package/tsconfig.json +27 -0
- package/types/credentials-context.d.ts +14 -0
- package/types/security-context.d.ts +6 -0
- package/examples/Status.yaml +0 -3
- package/examples/createAccountCredential.js +0 -27
- package/examples/createMineSweeperScoreCredential.js +0 -63
- package/examples/index.js +0 -9
- package/src/CredentialFactory.js +0 -67
- package/src/CredentialFactory.spec.js +0 -131
- package/src/Schema.js +0 -104
- package/src/Schema.spec.js +0 -172
- package/src/ValidationError.js +0 -31
- package/src/Validator.js +0 -128
- package/src/Validator.spec.js +0 -355
- package/src/helpers/cleanupAttributes.js +0 -71
- package/src/helpers/cleanupNulls.js +0 -42
- package/src/helpers/getReferenceIds.js +0 -71
- package/src/helpers/mapObject.js +0 -65
- package/src/helpers/normalizeAttributes.js +0 -28
- package/src/helpers/normalizeProperties.js +0 -61
- package/src/helpers/normalizeRequired.js +0 -37
- package/src/helpers/normalizeType.js +0 -41
- package/src/helpers/nullifyEmptyValues.js +0 -57
- package/src/helpers/removeRequiredAndDefault.js +0 -30
- package/src/helpers/validateId.js +0 -19
- package/src/index.d.ts +0 -25
- package/src/index.js +0 -8
- package/src/ld/documentLoader.js +0 -25
- package/src/ld/documentLoader.spec.js +0 -12
- package/src/ld/getLinkedDataContext.js +0 -63
- package/src/ld/getLinkedDataType.js +0 -38
- /package/examples/{FavoriteItem.yaml → schemas/FavoriteItem.yaml} +0 -0
- /package/examples/{Profile.yaml → schemas/Profile.yaml} +0 -0
|
@@ -0,0 +1,241 @@
|
|
|
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 Schema_1 = __importDefault(require("../Schema"));
|
|
8
|
+
const got_1 = __importDefault(require("./got"));
|
|
9
|
+
/**
|
|
10
|
+
* Recursively extracts all referenced schema IDs from a schema structure.
|
|
11
|
+
*
|
|
12
|
+
* **Intent:** Traverse a schema's entire structure (including nested objects and arrays)
|
|
13
|
+
* to collect all schema IDs that are referenced via `$ref` properties. This enables
|
|
14
|
+
* dependency resolution, schema bundling, and validation of schema completeness.
|
|
15
|
+
*
|
|
16
|
+
* **Use Cases:**
|
|
17
|
+
* - **Dependency Resolution:** Identify all schemas that a given schema depends on,
|
|
18
|
+
* ensuring they are loaded before validation
|
|
19
|
+
* - **Schema Bundling:** Collect all related schemas into a single bundle for
|
|
20
|
+
* distribution or storage
|
|
21
|
+
* - **Validation Preparation:** Pre-load all referenced schemas to ensure complete
|
|
22
|
+
* validation context
|
|
23
|
+
* - **Dependency Graph Building:** Understand the relationships and dependencies
|
|
24
|
+
* between schemas in a schema registry
|
|
25
|
+
* - **Schema Analysis:** Analyze schema complexity by identifying all dependencies
|
|
26
|
+
* - **Circular Reference Detection:** (Note: current implementation does not handle
|
|
27
|
+
* circular references and will recurse infinitely)
|
|
28
|
+
*
|
|
29
|
+
* **Behavior:**
|
|
30
|
+
* - Returns an empty array for enum schemas (they don't reference other schemas)
|
|
31
|
+
* - Recursively traverses nested object properties
|
|
32
|
+
* - Handles array items that reference schemas or contain object properties
|
|
33
|
+
* - Follows nested references to collect transitive dependencies
|
|
34
|
+
* - Returns unique schema IDs (deduplicates if same schema is referenced multiple times)
|
|
35
|
+
* - Throws an error if a referenced schema is not found in the schemasMap
|
|
36
|
+
*
|
|
37
|
+
* **Example - Simple Reference:**
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const userSchema = new Schema({
|
|
40
|
+
* profile: { $ref: 'Profile' }
|
|
41
|
+
* }, 'User');
|
|
42
|
+
*
|
|
43
|
+
* const profileSchema = new Schema({
|
|
44
|
+
* name: { type: 'string' }
|
|
45
|
+
* }, 'Profile');
|
|
46
|
+
*
|
|
47
|
+
* const schemasMap = { 'Profile': profileSchema };
|
|
48
|
+
* const referenceIds = getReferenceIds(userSchema, schemasMap);
|
|
49
|
+
* // Returns: ['Profile']
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* **Example - Multiple References:**
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const orderSchema = new Schema({
|
|
55
|
+
* customer: { $ref: 'Customer' },
|
|
56
|
+
* product: { $ref: 'Product' },
|
|
57
|
+
* shipping: { $ref: 'Address' }
|
|
58
|
+
* }, 'Order');
|
|
59
|
+
*
|
|
60
|
+
* const schemasMap = {
|
|
61
|
+
* 'Customer': customerSchema,
|
|
62
|
+
* 'Product': productSchema,
|
|
63
|
+
* 'Address': addressSchema
|
|
64
|
+
* };
|
|
65
|
+
* const referenceIds = getReferenceIds(orderSchema, schemasMap);
|
|
66
|
+
* // Returns: ['Customer', 'Product', 'Address']
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* **Example - Nested References:**
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const userSchema = new Schema({
|
|
72
|
+
* profile: { $ref: 'Profile' }
|
|
73
|
+
* }, 'User');
|
|
74
|
+
*
|
|
75
|
+
* const profileSchema = new Schema({
|
|
76
|
+
* address: { $ref: 'Address' }
|
|
77
|
+
* }, 'Profile');
|
|
78
|
+
*
|
|
79
|
+
* const addressSchema = new Schema({
|
|
80
|
+
* street: { type: 'string' }
|
|
81
|
+
* }, 'Address');
|
|
82
|
+
*
|
|
83
|
+
* const schemasMap = {
|
|
84
|
+
* 'Profile': profileSchema,
|
|
85
|
+
* 'Address': addressSchema
|
|
86
|
+
* };
|
|
87
|
+
* const referenceIds = getReferenceIds(userSchema, schemasMap);
|
|
88
|
+
* // Returns: ['Profile', 'Address'] (includes transitive dependencies)
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* **Example - Array with Reference Items:**
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const orderSchema = new Schema({
|
|
94
|
+
* items: {
|
|
95
|
+
* type: 'array',
|
|
96
|
+
* items: { $ref: 'OrderItem' }
|
|
97
|
+
* }
|
|
98
|
+
* }, 'Order');
|
|
99
|
+
*
|
|
100
|
+
* const schemasMap = { 'OrderItem': orderItemSchema };
|
|
101
|
+
* const referenceIds = getReferenceIds(orderSchema, schemasMap);
|
|
102
|
+
* // Returns: ['OrderItem']
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* **Example - Nested Object Properties:**
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const userSchema = new Schema({
|
|
108
|
+
* contact: {
|
|
109
|
+
* type: 'object',
|
|
110
|
+
* properties: {
|
|
111
|
+
* address: { $ref: 'Address' }
|
|
112
|
+
* }
|
|
113
|
+
* }
|
|
114
|
+
* }, 'User');
|
|
115
|
+
*
|
|
116
|
+
* const schemasMap = { 'Address': addressSchema };
|
|
117
|
+
* const referenceIds = getReferenceIds(userSchema, schemasMap);
|
|
118
|
+
* // Returns: ['Address']
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* **Example - Complex Mixed Structure:**
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const orderSchema = new Schema({
|
|
124
|
+
* customer: { $ref: 'Customer' },
|
|
125
|
+
* items: {
|
|
126
|
+
* type: 'array',
|
|
127
|
+
* items: {
|
|
128
|
+
* type: 'object',
|
|
129
|
+
* properties: {
|
|
130
|
+
* product: { $ref: 'Product' }
|
|
131
|
+
* }
|
|
132
|
+
* }
|
|
133
|
+
* },
|
|
134
|
+
* shipping: {
|
|
135
|
+
* type: 'object',
|
|
136
|
+
* properties: {
|
|
137
|
+
* address: { $ref: 'Address' }
|
|
138
|
+
* }
|
|
139
|
+
* }
|
|
140
|
+
* }, 'Order');
|
|
141
|
+
*
|
|
142
|
+
* const schemasMap = {
|
|
143
|
+
* 'Customer': customerSchema,
|
|
144
|
+
* 'Product': productSchema,
|
|
145
|
+
* 'Address': addressSchema
|
|
146
|
+
* };
|
|
147
|
+
* const referenceIds = getReferenceIds(orderSchema, schemasMap);
|
|
148
|
+
* // Returns: ['Customer', 'Product', 'Address']
|
|
149
|
+
* ```
|
|
150
|
+
*
|
|
151
|
+
* **Example - Duplicate References:**
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const schema = new Schema({
|
|
154
|
+
* field1: { $ref: 'SharedSchema' },
|
|
155
|
+
* field2: { $ref: 'SharedSchema' }
|
|
156
|
+
* }, 'Test');
|
|
157
|
+
*
|
|
158
|
+
* const schemasMap = { 'SharedSchema': sharedSchema };
|
|
159
|
+
* const referenceIds = getReferenceIds(schema, schemasMap);
|
|
160
|
+
* // Returns: ['SharedSchema'] (deduplicated)
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @param schema - The schema to extract references from
|
|
164
|
+
* @param schemasMap - A map of schema IDs to Schema instances, used to resolve
|
|
165
|
+
* referenced schemas and traverse nested references
|
|
166
|
+
* @returns An array of unique schema IDs that are referenced (directly or indirectly)
|
|
167
|
+
* by the given schema
|
|
168
|
+
* @throws Error if a referenced schema is not found in the schemasMap
|
|
169
|
+
*
|
|
170
|
+
* **Limitations:**
|
|
171
|
+
* - Does not handle circular references (will cause infinite recursion)
|
|
172
|
+
* - Requires all referenced schemas to be present in schemasMap
|
|
173
|
+
*/
|
|
174
|
+
const getReferenceIds = (schema, schemasMap) => {
|
|
175
|
+
/** Returns schema from the map by ID */
|
|
176
|
+
const getSchema = (id) => (0, got_1.default)(schemasMap, id, 'Schema "$PATH" not found');
|
|
177
|
+
let referenceIds = [];
|
|
178
|
+
const { jsonSchema } = schema;
|
|
179
|
+
const { enum: isEnum } = jsonSchema;
|
|
180
|
+
if (isEnum) {
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
const objectSchema = jsonSchema;
|
|
184
|
+
for (const propertyName in objectSchema.properties) {
|
|
185
|
+
const property = objectSchema.properties[propertyName];
|
|
186
|
+
const { $ref: refSchemaId } = property;
|
|
187
|
+
const isReference = !(0, lodash_1.isUndefined)(refSchemaId);
|
|
188
|
+
if (isReference) {
|
|
189
|
+
const refJsonSchema = getSchema(refSchemaId);
|
|
190
|
+
const nestedReferenceIds = getReferenceIds(refJsonSchema, schemasMap);
|
|
191
|
+
referenceIds = [
|
|
192
|
+
refSchemaId,
|
|
193
|
+
...referenceIds,
|
|
194
|
+
...nestedReferenceIds
|
|
195
|
+
];
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const { type } = property;
|
|
199
|
+
const isObject = type === 'object';
|
|
200
|
+
if (isObject) {
|
|
201
|
+
// istanbul ignore next - unreachable defensive code: properties is always set by normalizeProperties in Schema constructor
|
|
202
|
+
const { properties = {} } = property;
|
|
203
|
+
const nestedSchema = new Schema_1.default(properties, `${objectSchema.id}.${propertyName}.properties`);
|
|
204
|
+
const nestedReferenceIds = getReferenceIds(nestedSchema, schemasMap);
|
|
205
|
+
referenceIds = [
|
|
206
|
+
...referenceIds,
|
|
207
|
+
...nestedReferenceIds
|
|
208
|
+
];
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
const isArray = type === 'array';
|
|
212
|
+
if (!isArray) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
const { items } = property;
|
|
216
|
+
const itemRefSchemaId = items.$ref;
|
|
217
|
+
if (itemRefSchemaId) {
|
|
218
|
+
const itemJsonSchema = getSchema(itemRefSchemaId);
|
|
219
|
+
const nestedReferenceIds = getReferenceIds(itemJsonSchema, schemasMap);
|
|
220
|
+
referenceIds = [
|
|
221
|
+
itemRefSchemaId,
|
|
222
|
+
...referenceIds,
|
|
223
|
+
...nestedReferenceIds
|
|
224
|
+
];
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const itemProperties = items.properties;
|
|
228
|
+
if (itemProperties) {
|
|
229
|
+
const itemSchema = new Schema_1.default(itemProperties, `${objectSchema.id}.${propertyName}.items.properties`);
|
|
230
|
+
const itemReferenceIds = getReferenceIds(itemSchema, schemasMap);
|
|
231
|
+
referenceIds = [
|
|
232
|
+
...referenceIds,
|
|
233
|
+
...itemReferenceIds
|
|
234
|
+
];
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return (0, lodash_1.uniq)(referenceIds);
|
|
239
|
+
};
|
|
240
|
+
exports.default = getReferenceIds;
|
|
241
|
+
//# sourceMappingURL=getReferenceIds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getReferenceIds.js","sourceRoot":"","sources":["../../src/helpers/getReferenceIds.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe required property access: returns a value at `path` or throws if it is `undefined`.
|
|
3
|
+
*
|
|
4
|
+
* **Intent:** Provide strict, fail-fast access to nested object properties. Unlike `lodash/get`,
|
|
5
|
+
* which returns `undefined` for missing keys, `got` treats missing data as an error and throws
|
|
6
|
+
* with a clear message including the path. Use it when the property is required and absence
|
|
7
|
+
* indicates a bug or invalid input.
|
|
8
|
+
*
|
|
9
|
+
* **Use cases:**
|
|
10
|
+
* - **Schema / config lookups:** Fetching a schema or config by ID from a map where absence
|
|
11
|
+
* means invalid reference (e.g. `got(schemasMap, schemaId, 'Schema "$PATH" not found')`).
|
|
12
|
+
* - **Validated config access:** Reading required config or options after validation, when
|
|
13
|
+
* you want to avoid `undefined` checks downstream.
|
|
14
|
+
* - **Strict data traversal:** Walking nested structures (APIs, parsed JSON) where missing
|
|
15
|
+
* keys should fail immediately with a descriptive error instead of propagating `undefined`.
|
|
16
|
+
*
|
|
17
|
+
* **Behavior:** Only `undefined` triggers an error. Falsy but defined values (`null`, `0`,
|
|
18
|
+
* `false`, `''`, `[]`, `{}`) are returned as-is. Uses lodash `get` path syntax: dot notation
|
|
19
|
+
* (`a.b.c`), bracket notation (`items[0]`), or mixed (`data.items[0].id`).
|
|
20
|
+
*
|
|
21
|
+
* @param object - Root object to read from.
|
|
22
|
+
* @param path - Lodash-style path (e.g. `'user.profile.name'`, `'items[0].id'`).
|
|
23
|
+
* @param errorTemplate - Error message template; `$PATH` is replaced with `path`. Default:
|
|
24
|
+
* `'Value is undefined for "$PATH"'`.
|
|
25
|
+
* @returns The value at `path`.
|
|
26
|
+
* @throws {Error} When the value at `path` is `undefined`.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // Simple property
|
|
30
|
+
* got({ name: 'Jane' }, 'name');
|
|
31
|
+
* // => 'Jane'
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Nested path
|
|
35
|
+
* got({ user: { profile: { role: 'admin' } } }, 'user.profile.role');
|
|
36
|
+
* // => 'admin'
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Array index
|
|
40
|
+
* got({ items: ['a', 'b'] }, 'items[0]');
|
|
41
|
+
* // => 'a'
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Falsy but defined values are returned
|
|
45
|
+
* got({ count: 0, enabled: false }, 'count');
|
|
46
|
+
* // => 0
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // Custom error for schema lookups
|
|
50
|
+
* got(schemasMap, schemaId, 'Schema "$PATH" not found');
|
|
51
|
+
* // => schema for schemaId, or throws with that message
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Missing property throws
|
|
55
|
+
* got({ name: 'Jane' }, 'age');
|
|
56
|
+
* // throws Error('Value is undefined for "age"')
|
|
57
|
+
*/
|
|
58
|
+
declare function got<T>(object: Record<string, T>, path: string, errorTemplate?: string): T;
|
|
59
|
+
export default got;
|
|
60
|
+
//# sourceMappingURL=got.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"got.d.ts","sourceRoot":"","sources":["../../src/helpers/got.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,iBAAS,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAE,MAA+B,GAAG,CAAC,CAS1G;AAED,eAAe,GAAG,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const lodash_1 = require("lodash");
|
|
4
|
+
const DEFAULT_ERROR_TEMPLATE = 'Value is undefined for "$PATH"';
|
|
5
|
+
/**
|
|
6
|
+
* Safe required property access: returns a value at `path` or throws if it is `undefined`.
|
|
7
|
+
*
|
|
8
|
+
* **Intent:** Provide strict, fail-fast access to nested object properties. Unlike `lodash/get`,
|
|
9
|
+
* which returns `undefined` for missing keys, `got` treats missing data as an error and throws
|
|
10
|
+
* with a clear message including the path. Use it when the property is required and absence
|
|
11
|
+
* indicates a bug or invalid input.
|
|
12
|
+
*
|
|
13
|
+
* **Use cases:**
|
|
14
|
+
* - **Schema / config lookups:** Fetching a schema or config by ID from a map where absence
|
|
15
|
+
* means invalid reference (e.g. `got(schemasMap, schemaId, 'Schema "$PATH" not found')`).
|
|
16
|
+
* - **Validated config access:** Reading required config or options after validation, when
|
|
17
|
+
* you want to avoid `undefined` checks downstream.
|
|
18
|
+
* - **Strict data traversal:** Walking nested structures (APIs, parsed JSON) where missing
|
|
19
|
+
* keys should fail immediately with a descriptive error instead of propagating `undefined`.
|
|
20
|
+
*
|
|
21
|
+
* **Behavior:** Only `undefined` triggers an error. Falsy but defined values (`null`, `0`,
|
|
22
|
+
* `false`, `''`, `[]`, `{}`) are returned as-is. Uses lodash `get` path syntax: dot notation
|
|
23
|
+
* (`a.b.c`), bracket notation (`items[0]`), or mixed (`data.items[0].id`).
|
|
24
|
+
*
|
|
25
|
+
* @param object - Root object to read from.
|
|
26
|
+
* @param path - Lodash-style path (e.g. `'user.profile.name'`, `'items[0].id'`).
|
|
27
|
+
* @param errorTemplate - Error message template; `$PATH` is replaced with `path`. Default:
|
|
28
|
+
* `'Value is undefined for "$PATH"'`.
|
|
29
|
+
* @returns The value at `path`.
|
|
30
|
+
* @throws {Error} When the value at `path` is `undefined`.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Simple property
|
|
34
|
+
* got({ name: 'Jane' }, 'name');
|
|
35
|
+
* // => 'Jane'
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Nested path
|
|
39
|
+
* got({ user: { profile: { role: 'admin' } } }, 'user.profile.role');
|
|
40
|
+
* // => 'admin'
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Array index
|
|
44
|
+
* got({ items: ['a', 'b'] }, 'items[0]');
|
|
45
|
+
* // => 'a'
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // Falsy but defined values are returned
|
|
49
|
+
* got({ count: 0, enabled: false }, 'count');
|
|
50
|
+
* // => 0
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // Custom error for schema lookups
|
|
54
|
+
* got(schemasMap, schemaId, 'Schema "$PATH" not found');
|
|
55
|
+
* // => schema for schemaId, or throws with that message
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* // Missing property throws
|
|
59
|
+
* got({ name: 'Jane' }, 'age');
|
|
60
|
+
* // throws Error('Value is undefined for "age"')
|
|
61
|
+
*/
|
|
62
|
+
function got(object, path, errorTemplate = DEFAULT_ERROR_TEMPLATE) {
|
|
63
|
+
const value = (0, lodash_1.get)(object, path);
|
|
64
|
+
const shouldThrow = (0, lodash_1.isUndefined)(value);
|
|
65
|
+
if (!shouldThrow) {
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
throw Error(errorTemplate.replace('$PATH', path));
|
|
69
|
+
}
|
|
70
|
+
;
|
|
71
|
+
exports.default = got;
|
|
72
|
+
//# sourceMappingURL=got.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"got.js","sourceRoot":"","sources":["../../src/helpers/got.ts"],"names":[],"mappings":";;AAAA,mCAA0C;AAE1C,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,SAAS,GAAG,CAAI,MAAyB,EAAE,IAAY,EAAE,gBAAwB,sBAAsB;IACrG,MAAM,KAAK,GAAG,IAAA,YAAG,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChC,MAAM,WAAW,GAAG,IAAA,oBAAW,EAAC,KAAK,CAAC,CAAC;IAEvC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;AACpD,CAAC;AAAA,CAAC;AAEF,kBAAe,GAAG,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { JsonSchema, TargetObject, PropertySchema, JsonSchemasMap } from './JsonSchema';
|
|
2
|
+
/**
|
|
3
|
+
* Recursively traverses an object's properties based on a JSON schema and applies a callback
|
|
4
|
+
* function to each property. Handles nested objects, arrays, and schema references ($ref).
|
|
5
|
+
*
|
|
6
|
+
* **Intent:**
|
|
7
|
+
* This function provides a generic way to iterate over object properties in a schema-aware manner,
|
|
8
|
+
* enabling operations like normalization, validation, transformation, or cleanup to be applied
|
|
9
|
+
* consistently across complex nested data structures. It abstracts away the complexity of
|
|
10
|
+
* traversing nested objects, arrays, and schema references, allowing callers to focus on
|
|
11
|
+
* implementing their specific property-level logic.
|
|
12
|
+
*
|
|
13
|
+
* **Use Cases:**
|
|
14
|
+
* - **Normalization**: Apply type conversions or default values to properties based on schema definitions
|
|
15
|
+
* (see `normalizeAttributes.ts` for example)
|
|
16
|
+
* - **Validation**: Check property values against schema constraints
|
|
17
|
+
* - **Transformation**: Modify or transform property values based on schema metadata
|
|
18
|
+
* - **Cleanup**: Remove invalid properties or sanitize data structures
|
|
19
|
+
* - **Data Processing**: Extract, aggregate, or analyze properties across nested structures
|
|
20
|
+
* - **Schema-driven Operations**: Any operation that needs to process object properties according
|
|
21
|
+
* to their schema definitions
|
|
22
|
+
*
|
|
23
|
+
* **Behavior:**
|
|
24
|
+
* - Skips enum schemas (returns immediately without calling callback)
|
|
25
|
+
* - Calls callback for all properties defined in the schema, even if their values are null
|
|
26
|
+
* - Skips recursion into undefined values (callback is still called, but nested traversal stops)
|
|
27
|
+
* - Recursively processes nested objects by creating nested schema contexts
|
|
28
|
+
* - Recursively processes array items, handling both inline object schemas and references
|
|
29
|
+
* - Resolves schema references ($ref) using the provided schemasMap
|
|
30
|
+
*
|
|
31
|
+
* **Examples:**
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Example 1: Normalize property values based on schema types
|
|
35
|
+
* const schema = new Schema({
|
|
36
|
+
* name: { type: 'string' },
|
|
37
|
+
* age: { type: 'number' },
|
|
38
|
+
* active: { type: 'boolean' }
|
|
39
|
+
* }, 'user-schema');
|
|
40
|
+
*
|
|
41
|
+
* const user = {
|
|
42
|
+
* name: 'John',
|
|
43
|
+
* age: '30', // string that should be number
|
|
44
|
+
* active: 'true' // string that should be boolean
|
|
45
|
+
* };
|
|
46
|
+
*
|
|
47
|
+
* mapObjectProperties(user, schema.jsonSchema, {}, (propName, propSchema, obj) => {
|
|
48
|
+
* if (propSchema.type === 'number') {
|
|
49
|
+
* obj[propName] = Number(obj[propName]);
|
|
50
|
+
* } else if (propSchema.type === 'boolean') {
|
|
51
|
+
* obj[propName] = obj[propName] === 'true' || obj[propName] === true;
|
|
52
|
+
* }
|
|
53
|
+
* });
|
|
54
|
+
* // Result: { name: 'John', age: 30, active: true }
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* // Example 2: Process nested objects
|
|
58
|
+
* const schema = new Schema({
|
|
59
|
+
* profile: {
|
|
60
|
+
* type: 'object',
|
|
61
|
+
* properties: {
|
|
62
|
+
* firstName: { type: 'string' },
|
|
63
|
+
* lastName: { type: 'string' }
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
* }, 'user-schema');
|
|
67
|
+
*
|
|
68
|
+
* const user = {
|
|
69
|
+
* profile: {
|
|
70
|
+
* firstName: 'John',
|
|
71
|
+
* lastName: 'Doe'
|
|
72
|
+
* }
|
|
73
|
+
* };
|
|
74
|
+
*
|
|
75
|
+
* const processedProps: string[] = [];
|
|
76
|
+
* mapObjectProperties(user, schema.jsonSchema, {}, (propName) => {
|
|
77
|
+
* processedProps.push(propName);
|
|
78
|
+
* });
|
|
79
|
+
* // processedProps: ['profile', 'firstName', 'lastName']
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* // Example 3: Handle schema references ($ref)
|
|
83
|
+
* const addressSchema = new Schema({
|
|
84
|
+
* street: { type: 'string' },
|
|
85
|
+
* city: { type: 'string' }
|
|
86
|
+
* }, 'address-schema');
|
|
87
|
+
*
|
|
88
|
+
* const userSchema = new Schema({
|
|
89
|
+
* name: { type: 'string' },
|
|
90
|
+
* address: { $ref: 'address-schema' }
|
|
91
|
+
* }, 'user-schema');
|
|
92
|
+
*
|
|
93
|
+
* const user = {
|
|
94
|
+
* name: 'John',
|
|
95
|
+
* address: {
|
|
96
|
+
* street: '123 Main St',
|
|
97
|
+
* city: 'New York'
|
|
98
|
+
* }
|
|
99
|
+
* };
|
|
100
|
+
*
|
|
101
|
+
* const schemasMap = {
|
|
102
|
+
* 'address-schema': addressSchema.jsonSchema
|
|
103
|
+
* };
|
|
104
|
+
*
|
|
105
|
+
* mapObjectProperties(user, userSchema.jsonSchema, schemasMap, (propName) => {
|
|
106
|
+
* console.log(`Processing: ${propName}`);
|
|
107
|
+
* });
|
|
108
|
+
* // Output:
|
|
109
|
+
* // Processing: name
|
|
110
|
+
* // Processing: address
|
|
111
|
+
* // Processing: street
|
|
112
|
+
* // Processing: city
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* // Example 4: Process arrays with object items
|
|
116
|
+
* const schema = new Schema({
|
|
117
|
+
* tags: {
|
|
118
|
+
* type: 'array',
|
|
119
|
+
* items: {
|
|
120
|
+
* type: 'object',
|
|
121
|
+
* properties: {
|
|
122
|
+
* name: { type: 'string' },
|
|
123
|
+
* value: { type: 'string' }
|
|
124
|
+
* }
|
|
125
|
+
* }
|
|
126
|
+
* }
|
|
127
|
+
* }, 'item-schema');
|
|
128
|
+
*
|
|
129
|
+
* const item = {
|
|
130
|
+
* tags: [
|
|
131
|
+
* { name: 'tag1', value: 'value1' },
|
|
132
|
+
* { name: 'tag2', value: 'value2' }
|
|
133
|
+
* ]
|
|
134
|
+
* };
|
|
135
|
+
*
|
|
136
|
+
* mapObjectProperties(item, schema.jsonSchema, {}, (propName, propSchema, obj) => {
|
|
137
|
+
* if (propSchema.type === 'string') {
|
|
138
|
+
* obj[propName] = String(obj[propName]).toUpperCase();
|
|
139
|
+
* }
|
|
140
|
+
* });
|
|
141
|
+
* // Result: tags array items have uppercase name and value properties
|
|
142
|
+
*
|
|
143
|
+
* @param object - The target object to traverse
|
|
144
|
+
* @param jsonSchema - The JSON schema defining the object structure
|
|
145
|
+
* @param schemasMap - Map of schema IDs to schema objects for resolving $ref references
|
|
146
|
+
* @param callback - Function called for each property with (propertyName, propertySchema, object)
|
|
147
|
+
*/
|
|
148
|
+
declare const mapObjectProperties: (object: TargetObject, jsonSchema: JsonSchema, schemasMap: JsonSchemasMap, callback: (propertyName: string, propertySchema: PropertySchema, object: TargetObject) => void) => void;
|
|
149
|
+
export default mapObjectProperties;
|
|
150
|
+
//# sourceMappingURL=mapObjectProperties.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapObjectProperties.d.ts","sourceRoot":"","sources":["../../src/helpers/mapObjectProperties.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,UAAU,EAGV,YAAY,EACZ,cAAc,EACd,cAAc,EAIf,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiJG;AACH,QAAA,MAAM,mBAAmB,GACvB,QAAQ,YAAY,EACpB,YAAY,UAAU,EACtB,YAAY,cAAc,EAC1B,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,SAwG/F,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|