@plasius/schema 1.4.1 → 1.4.2
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 -2
- package/dist/{chunk-UQHPDQZX.js → chunk-GNL2RBO5.js} +133 -32
- package/dist/chunk-GNL2RBO5.js.map +1 -0
- package/dist/feedback-diagnostics.cjs +132 -31
- package/dist/feedback-diagnostics.cjs.map +1 -1
- package/dist/feedback-diagnostics.js +1 -1
- package/dist/index.cjs +184 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -1
- package/dist/index.d.ts +39 -1
- package/dist/index.js +51 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-UQHPDQZX.js.map +0 -1
|
@@ -1570,45 +1570,113 @@ function getShape(def) {
|
|
|
1570
1570
|
var MAX_STRICT_VALIDATION_NODES = 1e4;
|
|
1571
1571
|
var MAX_STRICT_VALIDATION_DEPTH = 256;
|
|
1572
1572
|
var MAX_STRICT_VALIDATION_OBJECTS = MAX_STRICT_VALIDATION_NODES;
|
|
1573
|
-
function
|
|
1574
|
-
const
|
|
1575
|
-
|
|
1576
|
-
];
|
|
1573
|
+
function snapshotStrictInput(input) {
|
|
1574
|
+
const snapshot = Array.isArray(input) ? [] : {};
|
|
1575
|
+
const pending = [{ source: input, target: snapshot, depth: 0 }];
|
|
1577
1576
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
1578
|
-
let visitedNodes =
|
|
1577
|
+
let visitedNodes = 1;
|
|
1579
1578
|
try {
|
|
1580
1579
|
while (pending.length > 0) {
|
|
1581
1580
|
const current = pending.pop();
|
|
1582
1581
|
if (!current) {
|
|
1583
1582
|
continue;
|
|
1584
1583
|
}
|
|
1585
|
-
visitedNodes += 1;
|
|
1586
1584
|
if (visitedNodes > MAX_STRICT_VALIDATION_NODES || current.depth > MAX_STRICT_VALIDATION_DEPTH) {
|
|
1587
|
-
return false;
|
|
1585
|
+
return { valid: false };
|
|
1588
1586
|
}
|
|
1589
|
-
if (
|
|
1590
|
-
|
|
1587
|
+
if (seen.has(current.source)) {
|
|
1588
|
+
return { valid: false };
|
|
1589
|
+
}
|
|
1590
|
+
seen.add(current.source);
|
|
1591
|
+
const isArray = Array.isArray(current.source);
|
|
1592
|
+
const prototype = Object.getPrototypeOf(current.source);
|
|
1593
|
+
if (isArray && prototype !== Array.prototype || !isArray && prototype !== Object.prototype && prototype !== null) {
|
|
1594
|
+
return { valid: false };
|
|
1595
|
+
}
|
|
1596
|
+
const ownKeys = Reflect.ownKeys(current.source);
|
|
1597
|
+
if (visitedNodes + ownKeys.length > MAX_STRICT_VALIDATION_NODES) {
|
|
1598
|
+
return { valid: false };
|
|
1591
1599
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1600
|
+
const descriptors = /* @__PURE__ */ new Map();
|
|
1601
|
+
for (const key of ownKeys) {
|
|
1602
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
1603
|
+
current.source,
|
|
1604
|
+
key
|
|
1605
|
+
);
|
|
1606
|
+
if (descriptor === void 0) {
|
|
1607
|
+
return { valid: false };
|
|
1608
|
+
}
|
|
1609
|
+
descriptors.set(key, descriptor);
|
|
1594
1610
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1611
|
+
if (isArray) {
|
|
1612
|
+
const lengthDescriptor = descriptors.get("length");
|
|
1613
|
+
if (lengthDescriptor === void 0 || !("value" in lengthDescriptor) || !Number.isSafeInteger(lengthDescriptor.value) || lengthDescriptor.value < 0 || lengthDescriptor.value > MAX_STRICT_VALIDATION_NODES) {
|
|
1614
|
+
return { valid: false };
|
|
1615
|
+
}
|
|
1616
|
+
let elementCount = 0;
|
|
1617
|
+
for (const key of ownKeys) {
|
|
1618
|
+
if (key === "length") {
|
|
1619
|
+
continue;
|
|
1620
|
+
}
|
|
1621
|
+
if (typeof key !== "string" || !/^(?:0|[1-9]\d*)$/.test(key)) {
|
|
1622
|
+
return { valid: false };
|
|
1623
|
+
}
|
|
1624
|
+
const descriptor = descriptors.get(key);
|
|
1625
|
+
if (descriptor === void 0 || descriptor.enumerable !== true || Number(key) >= lengthDescriptor.value) {
|
|
1626
|
+
return { valid: false };
|
|
1627
|
+
}
|
|
1628
|
+
elementCount += 1;
|
|
1629
|
+
}
|
|
1630
|
+
if (elementCount !== lengthDescriptor.value) {
|
|
1631
|
+
return { valid: false };
|
|
1632
|
+
}
|
|
1599
1633
|
}
|
|
1600
|
-
|
|
1634
|
+
visitedNodes += ownKeys.length;
|
|
1635
|
+
const keys = ownKeys.filter(
|
|
1636
|
+
(key) => descriptors.get(key)?.enumerable
|
|
1637
|
+
);
|
|
1601
1638
|
for (const key of keys) {
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1639
|
+
if (typeof key !== "string") {
|
|
1640
|
+
return { valid: false };
|
|
1641
|
+
}
|
|
1642
|
+
if (isArray && !/^(?:0|[1-9]\d*)$/.test(key)) {
|
|
1643
|
+
return { valid: false };
|
|
1644
|
+
}
|
|
1645
|
+
const descriptor = descriptors.get(key);
|
|
1646
|
+
if (descriptor === void 0 || !("value" in descriptor) || descriptor.get !== void 0 || descriptor.set !== void 0) {
|
|
1647
|
+
return { valid: false };
|
|
1648
|
+
}
|
|
1649
|
+
const child = descriptor.value;
|
|
1650
|
+
if (typeof child === "function") {
|
|
1651
|
+
return { valid: false };
|
|
1652
|
+
}
|
|
1653
|
+
if (typeof child === "object" && child !== null) {
|
|
1654
|
+
const childSnapshot = Array.isArray(child) ? [] : {};
|
|
1655
|
+
Object.defineProperty(current.target, key, {
|
|
1656
|
+
value: childSnapshot,
|
|
1657
|
+
enumerable: true,
|
|
1658
|
+
configurable: true,
|
|
1659
|
+
writable: true
|
|
1660
|
+
});
|
|
1661
|
+
pending.push({
|
|
1662
|
+
source: child,
|
|
1663
|
+
target: childSnapshot,
|
|
1664
|
+
depth: current.depth + 1
|
|
1665
|
+
});
|
|
1666
|
+
continue;
|
|
1667
|
+
}
|
|
1668
|
+
Object.defineProperty(current.target, key, {
|
|
1669
|
+
value: child,
|
|
1670
|
+
enumerable: true,
|
|
1671
|
+
configurable: true,
|
|
1672
|
+
writable: true
|
|
1605
1673
|
});
|
|
1606
1674
|
}
|
|
1607
1675
|
}
|
|
1608
1676
|
} catch {
|
|
1609
|
-
return false;
|
|
1677
|
+
return { valid: false };
|
|
1610
1678
|
}
|
|
1611
|
-
return true;
|
|
1679
|
+
return { valid: true, value: snapshot };
|
|
1612
1680
|
}
|
|
1613
1681
|
function strictReferenceShape(def) {
|
|
1614
1682
|
return {
|
|
@@ -2175,8 +2243,10 @@ function createSchema(_shape, entityType, options = {
|
|
|
2175
2243
|
if (typeof input !== "object" || input === null) {
|
|
2176
2244
|
return { valid: false, errors: ["Input must be an object"] };
|
|
2177
2245
|
}
|
|
2246
|
+
let strictInputSnapshot;
|
|
2178
2247
|
if (options.unknownFields === "reject") {
|
|
2179
|
-
|
|
2248
|
+
const snapshot = snapshotStrictInput(input);
|
|
2249
|
+
if (!snapshot.valid) {
|
|
2180
2250
|
return {
|
|
2181
2251
|
valid: false,
|
|
2182
2252
|
errors: ["Strict validation complexity limit exceeded."],
|
|
@@ -2189,16 +2259,32 @@ function createSchema(_shape, entityType, options = {
|
|
|
2189
2259
|
]
|
|
2190
2260
|
};
|
|
2191
2261
|
}
|
|
2262
|
+
strictInputSnapshot = snapshot.value;
|
|
2192
2263
|
const scanState = {
|
|
2193
2264
|
remainingObjects: MAX_STRICT_VALIDATION_OBJECTS,
|
|
2194
2265
|
limitExceeded: false
|
|
2195
2266
|
};
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2267
|
+
let locations;
|
|
2268
|
+
try {
|
|
2269
|
+
locations = unknownFieldLocations(
|
|
2270
|
+
strictInputSnapshot,
|
|
2271
|
+
schema._shape,
|
|
2272
|
+
"root",
|
|
2273
|
+
scanState
|
|
2274
|
+
);
|
|
2275
|
+
} catch {
|
|
2276
|
+
return {
|
|
2277
|
+
valid: false,
|
|
2278
|
+
errors: ["Strict validation complexity limit exceeded."],
|
|
2279
|
+
issues: [
|
|
2280
|
+
{
|
|
2281
|
+
path: "root",
|
|
2282
|
+
code: "validation_complexity_limit",
|
|
2283
|
+
message: "Strict validation complexity limit exceeded."
|
|
2284
|
+
}
|
|
2285
|
+
]
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2202
2288
|
if (scanState.limitExceeded) {
|
|
2203
2289
|
return {
|
|
2204
2290
|
valid: false,
|
|
@@ -2226,7 +2312,23 @@ function createSchema(_shape, entityType, options = {
|
|
|
2226
2312
|
};
|
|
2227
2313
|
}
|
|
2228
2314
|
}
|
|
2229
|
-
|
|
2315
|
+
let working;
|
|
2316
|
+
try {
|
|
2317
|
+
working = strictInputSnapshot ?? (typeof input === "object" && input !== null ? deepClone(input) : { ...input });
|
|
2318
|
+
} catch {
|
|
2319
|
+
return {
|
|
2320
|
+
valid: false,
|
|
2321
|
+
errors: ["Input could not be safely cloned."],
|
|
2322
|
+
issues: [
|
|
2323
|
+
{
|
|
2324
|
+
path: "root",
|
|
2325
|
+
code: "unsafe_input",
|
|
2326
|
+
message: "Input could not be safely cloned."
|
|
2327
|
+
}
|
|
2328
|
+
]
|
|
2329
|
+
};
|
|
2330
|
+
}
|
|
2331
|
+
const providedFieldNames = new Set(Object.keys(working));
|
|
2230
2332
|
if (working.type == null) working.type = entityType;
|
|
2231
2333
|
if (working.version == null) working.version = version;
|
|
2232
2334
|
const fromVersion = String(working.version ?? "0.0.0");
|
|
@@ -2343,9 +2445,8 @@ function createSchema(_shape, entityType, options = {
|
|
|
2343
2445
|
}
|
|
2344
2446
|
if (errors.length === 0 && options.schemaValidator) {
|
|
2345
2447
|
const castValue = result;
|
|
2346
|
-
const source = input;
|
|
2347
2448
|
const validationContext = Object.freeze({
|
|
2348
|
-
wasProvided: (fieldName) =>
|
|
2449
|
+
wasProvided: (fieldName) => providedFieldNames.has(fieldName)
|
|
2349
2450
|
});
|
|
2350
2451
|
if (!options.schemaValidator(castValue, validationContext)) {
|
|
2351
2452
|
errors.push("Schema-level validation failed.");
|