n4s 6.1.12 → 6.2.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/dist/exports/date.cjs +1 -1
- package/dist/exports/date.mjs +1 -1
- package/dist/exports/email.cjs +1 -1
- package/dist/exports/email.mjs +1 -1
- package/dist/exports/isURL.cjs +1 -1
- package/dist/exports/isURL.mjs +1 -1
- package/dist/{n4s-CoDF5Fg6.cjs → n4s-BTHEz-bJ.cjs} +215 -5
- package/dist/n4s-BTHEz-bJ.cjs.map +1 -0
- package/dist/{n4s-KWquSyTb.mjs → n4s-BxrvnvKp.mjs} +218 -8
- package/dist/n4s-BxrvnvKp.mjs.map +1 -0
- package/dist/n4s.cjs +1 -1
- package/dist/n4s.mjs +1 -1
- package/package.json +5 -1
- package/src/eager/eagerTypes.ts +14 -0
- package/src/lazy.ts +24 -0
- package/src/n4s.ts +5 -0
- package/src/rules/schemaRules/__tests__/integrationSchemaRules.types.test.ts +92 -0
- package/src/rules/schemaRules/__tests__/isArrayOf.test.ts +37 -1
- package/src/rules/schemaRules/__tests__/lazy.test.ts +312 -0
- package/src/rules/schemaRules/__tests__/record.test.ts +205 -0
- package/src/rules/schemaRules/__tests__/schema.parse.integration.test.ts +79 -0
- package/src/rules/schemaRules/__tests__/tuple.test.ts +256 -0
- package/src/rules/schemaRules/lazy.ts +48 -0
- package/src/rules/schemaRules/record.ts +126 -0
- package/src/rules/schemaRules/schemaRules.ts +8 -1
- package/src/rules/schemaRules/schemaRulesLazyTypes.ts +21 -0
- package/src/rules/schemaRules/tuple.ts +157 -0
- package/types/exports/date.d.cts +1 -1
- package/types/exports/date.d.mts +1 -1
- package/types/n4s.d.cts +21 -2
- package/types/n4s.d.cts.map +1 -1
- package/types/n4s.d.mts +78 -69
- package/types/n4s.d.mts.map +1 -1
- package/types/n4s.d.ts +21 -2
- package/types/{n4sTypes-Bb1zNxyv.d.mts → n4sTypes-3THfSmAQ.d.mts} +79 -5
- package/types/n4sTypes-3THfSmAQ.d.mts.map +1 -0
- package/types/{n4sTypes-ChCugpFQ.d.cts → n4sTypes-BSTzXRsU.d.cts} +66 -2
- package/types/n4sTypes-BSTzXRsU.d.cts.map +1 -0
- package/dist/n4s-CoDF5Fg6.cjs.map +0 -1
- package/dist/n4s-KWquSyTb.mjs.map +0 -1
- package/types/n4sTypes-Bb1zNxyv.d.mts.map +0 -1
- package/types/n4sTypes-ChCugpFQ.d.cts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StringObject, asArray, assign, bindNot, dynamicValue, greaterThan, greaterThan as greaterThan$1, hasOwnProperty, invariant, isBoolean, isEmpty, isEmpty as isEmpty$2, isFailure, isNotEmpty, isNotEmpty as isNotEmpty$2, isNotNull, isNotNullish, isNotUndefined, isNull, isNullish, isNumeric, isObject, isStringValue, isUndefined, isUnsafeKey, lengthEquals, mapFirst, numberEquals, numberEquals as numberEquals$1, numberNotEquals, toNumber } from "vest-utils";
|
|
1
|
+
import { StringObject, asArray, assign, bindNot, dynamicValue, greaterThan, greaterThan as greaterThan$1, hasOwnProperty, invariant, isBoolean, isEmpty, isEmpty as isEmpty$2, isFailure, isFunction, isNotEmpty, isNotEmpty as isNotEmpty$2, isNotNull, isNotNullish, isNotUndefined, isNull, isNullish, isNumeric, isObject, isStringValue, isUndefined, isUnsafeKey, lengthEquals, longerThan, mapFirst, numberEquals, numberEquals as numberEquals$1, numberNotEquals, toNumber } from "vest-utils";
|
|
2
2
|
import { createCascade } from "context";
|
|
3
3
|
|
|
4
4
|
//#region rolldown:runtime
|
|
@@ -274,7 +274,7 @@ function notInside(value, container) {
|
|
|
274
274
|
var commonLength_exports = /* @__PURE__ */ __export({
|
|
275
275
|
lengthEquals: () => lengthEquals$1,
|
|
276
276
|
lengthNotEquals: () => lengthNotEquals,
|
|
277
|
-
longerThan: () => longerThan,
|
|
277
|
+
longerThan: () => longerThan$1,
|
|
278
278
|
longerThanOrEquals: () => longerThanOrEquals,
|
|
279
279
|
max: () => max,
|
|
280
280
|
maxLength: () => maxLength,
|
|
@@ -297,7 +297,7 @@ function lengthEquals$1(value, n) {
|
|
|
297
297
|
function lengthNotEquals(value, n) {
|
|
298
298
|
return value.length !== n;
|
|
299
299
|
}
|
|
300
|
-
function longerThan(value, n) {
|
|
300
|
+
function longerThan$1(value, n) {
|
|
301
301
|
return value.length > n;
|
|
302
302
|
}
|
|
303
303
|
function longerThanOrEquals(value, n) {
|
|
@@ -342,7 +342,7 @@ var arrayRules_exports = /* @__PURE__ */ __export({
|
|
|
342
342
|
isNotEmpty: () => isNotEmpty$2,
|
|
343
343
|
lengthEquals: () => lengthEquals$1,
|
|
344
344
|
lengthNotEquals: () => lengthNotEquals,
|
|
345
|
-
longerThan: () => longerThan,
|
|
345
|
+
longerThan: () => longerThan$1,
|
|
346
346
|
longerThanOrEquals: () => longerThanOrEquals,
|
|
347
347
|
maxLength: () => maxLength,
|
|
348
348
|
minLength: () => minLength,
|
|
@@ -1575,16 +1575,177 @@ function shape(value, schema) {
|
|
|
1575
1575
|
return RuleRunReturn.Passing(baseRes.type);
|
|
1576
1576
|
}
|
|
1577
1577
|
|
|
1578
|
+
//#endregion
|
|
1579
|
+
//#region src/rules/schemaRules/record.ts
|
|
1580
|
+
/**
|
|
1581
|
+
* Validates that an object's dynamic keys and/or values match provided rules.
|
|
1582
|
+
* Like TypeScript's Record<K, V>, it checks elements against shape rules.
|
|
1583
|
+
*
|
|
1584
|
+
* @param value - The object to validate
|
|
1585
|
+
* @param arg1 - Either the key rule (if arg2 is present) or the value rule
|
|
1586
|
+
* @param arg2 - The value rule (if arg1 is the key rule)
|
|
1587
|
+
* @returns RuleRunReturn indicating success or failure
|
|
1588
|
+
*/
|
|
1589
|
+
function record(value, arg1, arg2) {
|
|
1590
|
+
if (!isObject(value) || Array.isArray(value)) return RuleRunReturn.Failing(value);
|
|
1591
|
+
const rules = parseRules(arg1, arg2);
|
|
1592
|
+
const dangerousKey = findDangerousOwnKey(value);
|
|
1593
|
+
if (dangerousKey) return createRecordFailure(value, dangerousKey, RuleRunReturn.Failing(value));
|
|
1594
|
+
const parsedValue = safeShallowCopy(value);
|
|
1595
|
+
return mapFirst(ownKeys(value), (key, breakout) => {
|
|
1596
|
+
const errorRes = evaluateRecordEntry(key, value, rules, parsedValue);
|
|
1597
|
+
if (errorRes) breakout(true, errorRes);
|
|
1598
|
+
}) || RuleRunReturn.Passing(parsedValue);
|
|
1599
|
+
}
|
|
1600
|
+
function parseRules(arg1, arg2) {
|
|
1601
|
+
if (arg2 !== void 0) return {
|
|
1602
|
+
keyRule: arg1,
|
|
1603
|
+
valueRule: arg2
|
|
1604
|
+
};
|
|
1605
|
+
return {
|
|
1606
|
+
keyRule: void 0,
|
|
1607
|
+
valueRule: arg1
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
function validateKey(key, keyRule) {
|
|
1611
|
+
return ctx.run({
|
|
1612
|
+
value: key,
|
|
1613
|
+
set: true
|
|
1614
|
+
}, () => keyRule.run(key));
|
|
1615
|
+
}
|
|
1616
|
+
function evaluateRecordEntry(key, value, rules, parsedValue) {
|
|
1617
|
+
if (rules.keyRule) {
|
|
1618
|
+
const keyRes = validateKey(key, rules.keyRule);
|
|
1619
|
+
if (!keyRes.pass) return createRecordFailure(value, key, keyRes);
|
|
1620
|
+
if (keyRes.type !== key) {
|
|
1621
|
+
delete parsedValue[key];
|
|
1622
|
+
key = keyRes.type;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
const valRes = ctx.run({
|
|
1626
|
+
value: value[key],
|
|
1627
|
+
set: true,
|
|
1628
|
+
meta: { key }
|
|
1629
|
+
}, () => rules.valueRule.run(value[key]));
|
|
1630
|
+
if (!valRes.pass) return createRecordFailure(value, key, valRes);
|
|
1631
|
+
parsedValue[key] = valRes.type;
|
|
1632
|
+
}
|
|
1633
|
+
function createRecordFailure(value, key, ruleRes) {
|
|
1634
|
+
const currentPath = ruleRes.path || [];
|
|
1635
|
+
const newRes = RuleRunReturn.Failing(value, ruleRes.message);
|
|
1636
|
+
newRes.path = [key, ...currentPath];
|
|
1637
|
+
return newRes;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
//#endregion
|
|
1641
|
+
//#region src/rules/schemaRules/tuple.ts
|
|
1642
|
+
/**
|
|
1643
|
+
* Validates that a value is a fixed-length array (tuple) where each position
|
|
1644
|
+
* matches the corresponding rule. Enforces exact length unless trailing
|
|
1645
|
+
* elements use enforce.optional().
|
|
1646
|
+
*
|
|
1647
|
+
* Parsed values are propagated: if a rule transforms its input (e.g. toNumber),
|
|
1648
|
+
* the parsed tuple returned via `.parse()` carries the transformed values.
|
|
1649
|
+
*
|
|
1650
|
+
* @param value - The array to validate
|
|
1651
|
+
* @param rules - One RuleInstance per tuple position
|
|
1652
|
+
* @returns RuleRunReturn indicating success or failure, with `.type` holding
|
|
1653
|
+
* the parsed tuple on success
|
|
1654
|
+
*
|
|
1655
|
+
* @example
|
|
1656
|
+
* ```typescript
|
|
1657
|
+
* // Eager API
|
|
1658
|
+
* enforce(['hello', 42]).tuple(enforce.isString(), enforce.isNumber());
|
|
1659
|
+
*
|
|
1660
|
+
* // Lazy API
|
|
1661
|
+
* const coordSchema = enforce.tuple(enforce.isNumber(), enforce.isNumber());
|
|
1662
|
+
* coordSchema.test([40.7, -74.0]); // true
|
|
1663
|
+
* coordSchema.test([40.7]); // false — too few
|
|
1664
|
+
* coordSchema.test([40.7, -74, 0]);// false — too many
|
|
1665
|
+
* ```
|
|
1666
|
+
*/
|
|
1667
|
+
function tuple(value, ...rules) {
|
|
1668
|
+
if (!Array.isArray(value)) return RuleRunReturn.Failing(value);
|
|
1669
|
+
if (greaterThan(countRequired(rules), value.length) || longerThan(value, rules.length)) return RuleRunReturn.Failing(value);
|
|
1670
|
+
return validateElements(value, rules);
|
|
1671
|
+
}
|
|
1672
|
+
/**
|
|
1673
|
+
* Counts the number of required (non-optional) leading positions by scanning
|
|
1674
|
+
* backwards from the end of the rules array. Stops at the first non-optional
|
|
1675
|
+
* rule, so only *trailing* optionals reduce the required count.
|
|
1676
|
+
*/
|
|
1677
|
+
function countRequired(rules) {
|
|
1678
|
+
let count = rules.length;
|
|
1679
|
+
for (let i = rules.length - 1; i >= 0; i--) if (isOptionalRule(rules[i])) count = i;
|
|
1680
|
+
else break;
|
|
1681
|
+
return count;
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* Iterates over each rule position, validates the corresponding array element,
|
|
1685
|
+
* and collects parsed output values. Returns early on the first failing element
|
|
1686
|
+
* with an index-based error path.
|
|
1687
|
+
*/
|
|
1688
|
+
function validateElements(value, rules) {
|
|
1689
|
+
const parsedTuple = [];
|
|
1690
|
+
for (let i = 0; i < rules.length; i++) {
|
|
1691
|
+
if (isBeyondArrayEnd(value, i, rules[i])) continue;
|
|
1692
|
+
const res = runElementRule(value[i], rules[i], i);
|
|
1693
|
+
if (!res.pass) return elementFailure(value, res, i);
|
|
1694
|
+
parsedTuple.push(res.type ?? value[i]);
|
|
1695
|
+
}
|
|
1696
|
+
return RuleRunReturn.Passing(parsedTuple);
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* Checks whether the given index is past the array's actual length
|
|
1700
|
+
* and the corresponding rule is optional, meaning it can be skipped.
|
|
1701
|
+
*/
|
|
1702
|
+
function isBeyondArrayEnd(value, index, rule) {
|
|
1703
|
+
return index >= value.length && isOptionalRule(rule);
|
|
1704
|
+
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Runs a single element's rule within an enforce context that carries
|
|
1707
|
+
* the element value and its positional index as metadata.
|
|
1708
|
+
*/
|
|
1709
|
+
function runElementRule(item, rule, index) {
|
|
1710
|
+
return ctx.run({
|
|
1711
|
+
value: item,
|
|
1712
|
+
set: true,
|
|
1713
|
+
meta: { index }
|
|
1714
|
+
}, () => rule.run(item));
|
|
1715
|
+
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Builds a failing RuleRunReturn with an error path that includes the
|
|
1718
|
+
* tuple index, prepended to any nested path from the inner rule failure.
|
|
1719
|
+
* For example, a shape failure at index 1 on key "id" yields path ["1", "id"].
|
|
1720
|
+
*/
|
|
1721
|
+
function elementFailure(value, res, index) {
|
|
1722
|
+
const failure = RuleRunReturn.Failing(value, res.message);
|
|
1723
|
+
failure.path = [index.toString(), ...res.path || []];
|
|
1724
|
+
return failure;
|
|
1725
|
+
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Determines whether a rule is optional by testing if it passes with undefined.
|
|
1728
|
+
* This mirrors how shape/loose detect optional fields — a rule wrapping
|
|
1729
|
+
* enforce.optional() will pass for undefined, while required rules will not.
|
|
1730
|
+
*/
|
|
1731
|
+
function isOptionalRule(rule) {
|
|
1732
|
+
if (!rule || !isFunction(rule.test)) return false;
|
|
1733
|
+
return rule.test(void 0);
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1578
1736
|
//#endregion
|
|
1579
1737
|
//#region src/rules/schemaRules/schemaRules.ts
|
|
1580
1738
|
var schemaRules_exports = /* @__PURE__ */ __export({
|
|
1581
1739
|
isArrayOf: () => isArrayOf,
|
|
1740
|
+
list: () => isArrayOf,
|
|
1582
1741
|
loose: () => loose,
|
|
1583
1742
|
omit: () => omit,
|
|
1584
1743
|
optional: () => optional,
|
|
1585
1744
|
partial: () => partial,
|
|
1586
1745
|
pick: () => pick,
|
|
1587
|
-
|
|
1746
|
+
record: () => record,
|
|
1747
|
+
shape: () => shape,
|
|
1748
|
+
tuple: () => tuple
|
|
1588
1749
|
});
|
|
1589
1750
|
|
|
1590
1751
|
//#endregion
|
|
@@ -1685,7 +1846,7 @@ var stringRules_exports = /* @__PURE__ */ __export({
|
|
|
1685
1846
|
isString: () => isString,
|
|
1686
1847
|
lengthEquals: () => lengthEquals$1,
|
|
1687
1848
|
lengthNotEquals: () => lengthNotEquals,
|
|
1688
|
-
longerThan: () => longerThan,
|
|
1849
|
+
longerThan: () => longerThan$1,
|
|
1689
1850
|
longerThanOrEquals: () => longerThanOrEquals,
|
|
1690
1851
|
matches: () => matches,
|
|
1691
1852
|
maxLength: () => maxLength,
|
|
@@ -2229,6 +2390,44 @@ const typeRules = {
|
|
|
2229
2390
|
isUndefined: () => addToChain({}, isUndefined$1)
|
|
2230
2391
|
};
|
|
2231
2392
|
|
|
2393
|
+
//#endregion
|
|
2394
|
+
//#region src/rules/schemaRules/lazy.ts
|
|
2395
|
+
/**
|
|
2396
|
+
* Creates a lazy schema wrapper for recursive/self-referencing schemas.
|
|
2397
|
+
* The factory function is called on first validation and cached.
|
|
2398
|
+
*
|
|
2399
|
+
* @param factory - A function that returns the RuleInstance to delegate to
|
|
2400
|
+
* @returns A RuleInstance that defers schema resolution to validation time
|
|
2401
|
+
*
|
|
2402
|
+
* @example
|
|
2403
|
+
* ```typescript
|
|
2404
|
+
* type Category = { name: string; children: Category[] };
|
|
2405
|
+
*
|
|
2406
|
+
* const categorySchema = enforce.shape({
|
|
2407
|
+
* name: enforce.isString(),
|
|
2408
|
+
* children: enforce.isArrayOf(enforce.lazy(() => categorySchema)),
|
|
2409
|
+
* });
|
|
2410
|
+
*
|
|
2411
|
+
* categorySchema.test({
|
|
2412
|
+
* name: 'Root',
|
|
2413
|
+
* children: [
|
|
2414
|
+
* { name: 'Child', children: [] },
|
|
2415
|
+
* ],
|
|
2416
|
+
* }); // true
|
|
2417
|
+
* ```
|
|
2418
|
+
*/
|
|
2419
|
+
function lazy(factory) {
|
|
2420
|
+
let cached = null;
|
|
2421
|
+
const resolve = () => {
|
|
2422
|
+
if (!cached) cached = factory();
|
|
2423
|
+
return cached;
|
|
2424
|
+
};
|
|
2425
|
+
return addToChain({}, (value) => {
|
|
2426
|
+
const result = ctx.run({ value }, () => resolve().run(value));
|
|
2427
|
+
return RuleRunReturn.create(result, value);
|
|
2428
|
+
});
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2232
2431
|
//#endregion
|
|
2233
2432
|
//#region src/lazy.ts
|
|
2234
2433
|
const schemaModifiers = adaptDynamicRules({
|
|
@@ -2241,6 +2440,7 @@ const schemaEvaluators = adaptDynamicRules({
|
|
|
2241
2440
|
shape,
|
|
2242
2441
|
loose
|
|
2243
2442
|
});
|
|
2443
|
+
const recordEvaluators = adaptDynamicRules({ record });
|
|
2244
2444
|
/**
|
|
2245
2445
|
* Wraps a lazy schema evaluator so the resulting RuleInstance carries
|
|
2246
2446
|
* a `__schema` reference to the original schema definition.
|
|
@@ -2258,8 +2458,18 @@ const schemaRulesWithArrayChaining = {
|
|
|
2258
2458
|
const result = ctx.run({ value }, () => isArrayOf(value, ...rules));
|
|
2259
2459
|
return RuleRunReturn.create(result, value);
|
|
2260
2460
|
}),
|
|
2461
|
+
lazy,
|
|
2462
|
+
list: (...rules) => addToChain(arrayRules_exports, (value) => {
|
|
2463
|
+
const result = ctx.run({ value }, () => isArrayOf(value, ...rules));
|
|
2464
|
+
return RuleRunReturn.create(result, value);
|
|
2465
|
+
}),
|
|
2261
2466
|
loose: schemaAttacher(schemaEvaluators.loose),
|
|
2262
|
-
|
|
2467
|
+
record: recordEvaluators.record,
|
|
2468
|
+
shape: schemaAttacher(schemaEvaluators.shape),
|
|
2469
|
+
tuple: (...rules) => addToChain(arrayRules_exports, (value) => {
|
|
2470
|
+
const result = ctx.run({ value }, () => tuple(value, ...rules));
|
|
2471
|
+
return RuleRunReturn.create(result, value);
|
|
2472
|
+
})
|
|
2263
2473
|
};
|
|
2264
2474
|
const baseEnforceLazy = {
|
|
2265
2475
|
...adaptDynamicRules(compoundRules_exports),
|
|
@@ -2450,4 +2660,4 @@ enforce.extend = function extend(rules) {
|
|
|
2450
2660
|
|
|
2451
2661
|
//#endregion
|
|
2452
2662
|
export { compose as n, ctx as r, enforce as t };
|
|
2453
|
-
//# sourceMappingURL=n4s-
|
|
2663
|
+
//# sourceMappingURL=n4s-BxrvnvKp.mjs.map
|