@schema-ts/core 0.1.2 → 0.1.3
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/dist/index.cjs +87 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -10
- package/dist/index.d.ts +29 -10
- package/dist/index.js +87 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1400,7 +1400,6 @@ function resolveEffectiveSchema(validator, schema, value, keywordLocation, insta
|
|
|
1400
1400
|
instanceLocation
|
|
1401
1401
|
);
|
|
1402
1402
|
effective = mergeSchema(effective, res.effectiveSchema);
|
|
1403
|
-
break;
|
|
1404
1403
|
}
|
|
1405
1404
|
}
|
|
1406
1405
|
const { anyOf: _, ...rest } = effective;
|
|
@@ -1472,6 +1471,19 @@ function mergeSchemaArrays(a, b) {
|
|
|
1472
1471
|
if (b === void 0) return a;
|
|
1473
1472
|
return [...a, ...b];
|
|
1474
1473
|
}
|
|
1474
|
+
function mergeSchemaMap(base, override) {
|
|
1475
|
+
if (base === void 0) return override;
|
|
1476
|
+
if (override === void 0) return base;
|
|
1477
|
+
const merged = { ...base };
|
|
1478
|
+
for (const [key, schema] of Object.entries(override)) {
|
|
1479
|
+
if (merged[key]) {
|
|
1480
|
+
merged[key] = mergeSchema(merged[key], schema);
|
|
1481
|
+
} else {
|
|
1482
|
+
merged[key] = schema;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
return merged;
|
|
1486
|
+
}
|
|
1475
1487
|
function mergeSchema(base, override) {
|
|
1476
1488
|
if (!override) return base;
|
|
1477
1489
|
const merged = {
|
|
@@ -1498,17 +1510,16 @@ function mergeSchema(base, override) {
|
|
|
1498
1510
|
...override.dependentRequired
|
|
1499
1511
|
};
|
|
1500
1512
|
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
...override.properties
|
|
1505
|
-
};
|
|
1513
|
+
const mergedProperties = mergeSchemaMap(base.properties, override.properties);
|
|
1514
|
+
if (mergedProperties !== void 0) {
|
|
1515
|
+
merged.properties = mergedProperties;
|
|
1506
1516
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1517
|
+
const mergedPatternProperties = mergeSchemaMap(
|
|
1518
|
+
base.patternProperties,
|
|
1519
|
+
override.patternProperties
|
|
1520
|
+
);
|
|
1521
|
+
if (mergedPatternProperties !== void 0) {
|
|
1522
|
+
merged.patternProperties = mergedPatternProperties;
|
|
1512
1523
|
}
|
|
1513
1524
|
if (base.items && override.items) {
|
|
1514
1525
|
merged.items = mergeSchema(base.items, override.items);
|
|
@@ -1543,11 +1554,12 @@ function mergeSchema(base, override) {
|
|
|
1543
1554
|
merged[keyword] = mergedArray;
|
|
1544
1555
|
}
|
|
1545
1556
|
}
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1557
|
+
const mergedDependentSchemas = mergeSchemaMap(
|
|
1558
|
+
base.dependentSchemas,
|
|
1559
|
+
override.dependentSchemas
|
|
1560
|
+
);
|
|
1561
|
+
if (mergedDependentSchemas !== void 0) {
|
|
1562
|
+
merged.dependentSchemas = mergedDependentSchemas;
|
|
1551
1563
|
}
|
|
1552
1564
|
return merged;
|
|
1553
1565
|
}
|
|
@@ -1768,10 +1780,11 @@ function getSubSchema(schema, key) {
|
|
|
1768
1780
|
}
|
|
1769
1781
|
|
|
1770
1782
|
// src/default.ts
|
|
1771
|
-
function getDefaultValue(schema, value) {
|
|
1783
|
+
function getDefaultValue(schema, value, strategy = "explicit") {
|
|
1772
1784
|
if (value === void 0) {
|
|
1773
1785
|
if (schema.const !== void 0) return schema.const;
|
|
1774
1786
|
if (schema.default !== void 0) return schema.default;
|
|
1787
|
+
if (strategy === "explicit") return void 0;
|
|
1775
1788
|
}
|
|
1776
1789
|
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
1777
1790
|
if (type === "object" || !type && schema.properties) {
|
|
@@ -1786,9 +1799,9 @@ function getDefaultValue(schema, value) {
|
|
|
1786
1799
|
if (schema.properties) {
|
|
1787
1800
|
for (const [key, subschema] of Object.entries(schema.properties)) {
|
|
1788
1801
|
if (obj[key] !== void 0) {
|
|
1789
|
-
obj[key] = getDefaultValue(subschema, obj[key]);
|
|
1802
|
+
obj[key] = getDefaultValue(subschema, obj[key], strategy);
|
|
1790
1803
|
} else if (schema.required?.includes(key)) {
|
|
1791
|
-
obj[key] = getDefaultValue(subschema);
|
|
1804
|
+
obj[key] = getDefaultValue(subschema, void 0, strategy);
|
|
1792
1805
|
}
|
|
1793
1806
|
}
|
|
1794
1807
|
}
|
|
@@ -1806,16 +1819,16 @@ function getDefaultValue(schema, value) {
|
|
|
1806
1819
|
if (schema.prefixItems) {
|
|
1807
1820
|
schema.prefixItems.forEach((subschema, index) => {
|
|
1808
1821
|
if (index < arr.length) {
|
|
1809
|
-
arr[index] = getDefaultValue(subschema, arr[index]);
|
|
1822
|
+
arr[index] = getDefaultValue(subschema, arr[index], strategy);
|
|
1810
1823
|
} else if (value === void 0) {
|
|
1811
|
-
arr.push(getDefaultValue(subschema));
|
|
1824
|
+
arr.push(getDefaultValue(subschema, void 0, strategy));
|
|
1812
1825
|
}
|
|
1813
1826
|
});
|
|
1814
1827
|
}
|
|
1815
1828
|
if (value !== void 0 && schema.items) {
|
|
1816
1829
|
const startIndex = schema.prefixItems ? schema.prefixItems.length : 0;
|
|
1817
1830
|
for (let i = startIndex; i < arr.length; i++) {
|
|
1818
|
-
arr[i] = getDefaultValue(schema.items, arr[i]);
|
|
1831
|
+
arr[i] = getDefaultValue(schema.items, arr[i], strategy);
|
|
1819
1832
|
}
|
|
1820
1833
|
}
|
|
1821
1834
|
return arr;
|
|
@@ -2029,21 +2042,24 @@ var SchemaRuntime = class {
|
|
|
2029
2042
|
value;
|
|
2030
2043
|
version = 0;
|
|
2031
2044
|
rootSchema = {};
|
|
2045
|
+
options;
|
|
2032
2046
|
/**
|
|
2033
2047
|
* Create a new SchemaRuntime instance.
|
|
2034
2048
|
*
|
|
2035
2049
|
* @param validator - The validator instance for schema validation
|
|
2036
2050
|
* @param schema - The JSON Schema definition (will be normalized and dereferenced)
|
|
2037
2051
|
* @param value - The initial data value to manage
|
|
2052
|
+
* @param options - Runtime configuration options
|
|
2038
2053
|
*
|
|
2039
2054
|
* @example
|
|
2040
2055
|
* const validator = new Validator();
|
|
2041
2056
|
* const schema = { type: "object", properties: { name: { type: "string" } } };
|
|
2042
2057
|
* const runtime = new SchemaRuntime(validator, schema, { name: "Alice" });
|
|
2043
2058
|
*/
|
|
2044
|
-
constructor(validator, schema, value) {
|
|
2059
|
+
constructor(validator, schema, value, options = {}) {
|
|
2045
2060
|
this.validator = validator;
|
|
2046
2061
|
this.value = value;
|
|
2062
|
+
this.options = { autoFillDefaults: "explicit", ...options };
|
|
2047
2063
|
const normalized = normalizeSchema(schema);
|
|
2048
2064
|
this.rootSchema = dereferenceSchemaDeep(normalized, normalized);
|
|
2049
2065
|
this.root = this.createEmptyNode("", "#");
|
|
@@ -2225,6 +2241,21 @@ var SchemaRuntime = class {
|
|
|
2225
2241
|
if (normalizedPath === ROOT_PATH) return this.value;
|
|
2226
2242
|
return getJsonPointer(this.value, normalizedPath);
|
|
2227
2243
|
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Internal helper to set a value at a normalized path.
|
|
2246
|
+
* Handles both root and non-root paths.
|
|
2247
|
+
*
|
|
2248
|
+
* @param normalizedPath - The normalized JSON Pointer path
|
|
2249
|
+
* @param value - The value to set
|
|
2250
|
+
* @returns true if successful, false if the path cannot be set
|
|
2251
|
+
*/
|
|
2252
|
+
setValueAtPath(normalizedPath, value) {
|
|
2253
|
+
if (normalizedPath === ROOT_PATH) {
|
|
2254
|
+
this.value = value;
|
|
2255
|
+
return true;
|
|
2256
|
+
}
|
|
2257
|
+
return setJsonPointer(this.value, normalizedPath, value);
|
|
2258
|
+
}
|
|
2228
2259
|
/**
|
|
2229
2260
|
* Remove a node at the specified path.
|
|
2230
2261
|
* This deletes the value from the data structure (array splice or object delete).
|
|
@@ -2265,8 +2296,23 @@ var SchemaRuntime = class {
|
|
|
2265
2296
|
if (!parentNode || !parentNode.canAdd) {
|
|
2266
2297
|
return false;
|
|
2267
2298
|
}
|
|
2268
|
-
|
|
2299
|
+
let parentValue = this.getValue(normalizedPath);
|
|
2269
2300
|
const parentSchema = parentNode.schema;
|
|
2301
|
+
if (parentNode.type === "array") {
|
|
2302
|
+
if (Array.isArray(parentValue)) ; else if (parentValue === void 0 || parentValue === null) {
|
|
2303
|
+
parentValue = [];
|
|
2304
|
+
this.setValueAtPath(normalizedPath, parentValue);
|
|
2305
|
+
} else {
|
|
2306
|
+
return false;
|
|
2307
|
+
}
|
|
2308
|
+
} else if (parentNode.type === "object") {
|
|
2309
|
+
if (parentValue && typeof parentValue === "object") ; else if (parentValue === void 0 || parentValue === null) {
|
|
2310
|
+
parentValue = {};
|
|
2311
|
+
this.setValueAtPath(normalizedPath, parentValue);
|
|
2312
|
+
} else {
|
|
2313
|
+
return false;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2270
2316
|
if (parentNode.type === "array" && Array.isArray(parentValue)) {
|
|
2271
2317
|
const newIndex = parentValue.length;
|
|
2272
2318
|
const { schema: subschema, keywordLocationToken } = getSubSchema(
|
|
@@ -2283,7 +2329,7 @@ var SchemaRuntime = class {
|
|
|
2283
2329
|
this.reconcile(normalizedPath);
|
|
2284
2330
|
this.notify({ type: "value", path: normalizedPath });
|
|
2285
2331
|
return true;
|
|
2286
|
-
} else if (parentNode.type === "object" &&
|
|
2332
|
+
} else if (parentNode.type === "object" && typeof parentValue === "object") {
|
|
2287
2333
|
if (!key) {
|
|
2288
2334
|
return false;
|
|
2289
2335
|
}
|
|
@@ -2319,12 +2365,8 @@ var SchemaRuntime = class {
|
|
|
2319
2365
|
*/
|
|
2320
2366
|
setValue(path, value) {
|
|
2321
2367
|
const normalizedPath = normalizeRootPath(path);
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
} else {
|
|
2325
|
-
const success = setJsonPointer(this.value, normalizedPath, value);
|
|
2326
|
-
if (!success) return false;
|
|
2327
|
-
}
|
|
2368
|
+
const success = this.setValueAtPath(normalizedPath, value);
|
|
2369
|
+
if (!success) return false;
|
|
2328
2370
|
this.reconcile(normalizedPath);
|
|
2329
2371
|
this.notify({ type: "value", path: normalizedPath });
|
|
2330
2372
|
return true;
|
|
@@ -2393,6 +2435,9 @@ var SchemaRuntime = class {
|
|
|
2393
2435
|
* @param type - The schema type
|
|
2394
2436
|
*/
|
|
2395
2437
|
applySchemaDefaults(instanceLocation, newSchema, type) {
|
|
2438
|
+
if (this.options.autoFillDefaults === "never") {
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2396
2441
|
const value = this.getValue(instanceLocation);
|
|
2397
2442
|
if (type === "object" && newSchema.properties) {
|
|
2398
2443
|
const obj = value && typeof value === "object" ? value : null;
|
|
@@ -2400,7 +2445,11 @@ var SchemaRuntime = class {
|
|
|
2400
2445
|
for (const [key, subschema] of Object.entries(newSchema.properties)) {
|
|
2401
2446
|
const hasValue = obj[key] !== void 0;
|
|
2402
2447
|
if (!hasValue) {
|
|
2403
|
-
const defaultValue = getDefaultValue(
|
|
2448
|
+
const defaultValue = getDefaultValue(
|
|
2449
|
+
subschema,
|
|
2450
|
+
void 0,
|
|
2451
|
+
this.options.autoFillDefaults
|
|
2452
|
+
);
|
|
2404
2453
|
if (defaultValue !== void 0) {
|
|
2405
2454
|
const propertyPath = jsonPointerJoin(instanceLocation, key);
|
|
2406
2455
|
setJsonPointer(this.value, propertyPath, defaultValue);
|
|
@@ -2414,7 +2463,12 @@ var SchemaRuntime = class {
|
|
|
2414
2463
|
if (!arr) return;
|
|
2415
2464
|
for (let i = 0; i < newSchema.prefixItems.length; i++) {
|
|
2416
2465
|
if (arr[i] === void 0) {
|
|
2417
|
-
const
|
|
2466
|
+
const itemSchema = newSchema.prefixItems[i];
|
|
2467
|
+
const defaultValue = getDefaultValue(
|
|
2468
|
+
itemSchema,
|
|
2469
|
+
void 0,
|
|
2470
|
+
this.options.autoFillDefaults
|
|
2471
|
+
);
|
|
2418
2472
|
if (defaultValue !== void 0) {
|
|
2419
2473
|
const itemPath = jsonPointerJoin(instanceLocation, String(i));
|
|
2420
2474
|
setJsonPointer(this.value, itemPath, defaultValue);
|