typesea 0.2.0 → 0.3.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/CHANGELOG.md +18 -0
- package/README.md +45 -11
- package/dist/aot/index.d.ts +1 -1
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +22 -3
- package/dist/builders/composite.d.ts +6 -3
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +22 -13
- package/dist/builders/index.d.ts +6 -5
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +5 -4
- package/dist/builders/modifier.d.ts +6 -0
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +14 -0
- package/dist/builders/object/guard.d.ts +54 -2
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +117 -7
- package/dist/builders/object/index.d.ts +2 -2
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +1 -1
- package/dist/builders/object/schema.d.ts +33 -2
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +198 -8
- package/dist/builders/object/types.d.ts +15 -0
- package/dist/builders/object/types.d.ts.map +1 -1
- package/dist/builders/runtime.d.ts +40 -0
- package/dist/builders/runtime.d.ts.map +1 -0
- package/dist/builders/runtime.js +150 -0
- package/dist/builders/scalar.d.ts +20 -1
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +54 -1
- package/dist/builders/table.d.ts +31 -5
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +31 -5
- package/dist/builders/types.d.ts +6 -0
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/compile/check-composite.d.ts +3 -1
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +143 -11
- package/dist/compile/check-scalar.d.ts +10 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +138 -2
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +25 -3
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +2 -0
- package/dist/compile/first.d.ts +26 -0
- package/dist/compile/first.d.ts.map +1 -0
- package/dist/compile/first.js +850 -0
- package/dist/compile/graph-predicate.d.ts.map +1 -1
- package/dist/compile/graph-predicate.js +389 -18
- package/dist/compile/guard.d.ts +2 -1
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +54 -8
- package/dist/compile/predicate.d.ts.map +1 -1
- package/dist/compile/predicate.js +156 -5
- package/dist/compile/runtime.d.ts +20 -1
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +31 -0
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +27 -3
- package/dist/compile/types.d.ts +2 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/decoder/index.d.ts +60 -0
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +164 -1
- package/dist/evaluate/check-composite.d.ts +52 -2
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +193 -6
- package/dist/evaluate/check-scalar.d.ts +9 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +92 -3
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +19 -4
- package/dist/evaluate/shared.d.ts +19 -0
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +35 -0
- package/dist/guard/array.d.ts +48 -0
- package/dist/guard/array.d.ts.map +1 -0
- package/dist/guard/array.js +84 -0
- package/dist/guard/base.d.ts +32 -2
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +74 -3
- package/dist/guard/date.d.ts +34 -0
- package/dist/guard/date.d.ts.map +1 -0
- package/dist/guard/date.js +60 -0
- package/dist/guard/index.d.ts +2 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +2 -0
- package/dist/guard/number.d.ts +60 -0
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +129 -0
- package/dist/guard/read.d.ts +53 -1
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +102 -0
- package/dist/guard/string.d.ts +82 -0
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +213 -0
- package/dist/guard/types.d.ts +18 -0
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/ir/builder.d.ts +3 -3
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +5 -2
- package/dist/ir/freeze.js +7 -0
- package/dist/ir/types.d.ts +4 -1
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/validate.d.ts.map +1 -1
- package/dist/ir/validate.js +35 -1
- package/dist/issue/index.d.ts +1 -1
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +4 -0
- package/dist/json-schema/emit-composite.d.ts +6 -2
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +66 -12
- package/dist/json-schema/emit-scalar.d.ts.map +1 -1
- package/dist/json-schema/emit-scalar.js +54 -1
- package/dist/json-schema/emit.d.ts.map +1 -1
- package/dist/json-schema/emit.js +11 -2
- package/dist/json-schema/types.d.ts +7 -1
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/kind/index.d.ts +25 -0
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +26 -3
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +52 -3
- package/dist/message/index.d.ts +18 -0
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +67 -0
- package/dist/optimize/domain.js +6 -2
- package/dist/optimize/map-node.d.ts.map +1 -1
- package/dist/optimize/map-node.js +3 -0
- package/dist/plan/cache.js +13 -1
- package/dist/plan/predicate.d.ts.map +1 -1
- package/dist/plan/predicate.js +33 -3
- package/dist/plan/schema-predicate.d.ts.map +1 -1
- package/dist/plan/schema-predicate.js +267 -8
- package/dist/schema/freeze.js +22 -0
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -1
- package/dist/schema/types.d.ts +89 -4
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +8 -1
- package/dist/schema/undefined.d.ts.map +1 -1
- package/dist/schema/undefined.js +5 -0
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +111 -4
- package/docs/api.md +71 -8
- package/docs/engine-notes.md +4 -0
- package/docs/index.html +1340 -722
- package/docs/ko/api.md +375 -0
- package/docs/ko/engine-notes.md +156 -0
- package/docs/ko/readme.md +378 -0
- package/package.json +3 -2
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file array.ts
|
|
3
|
+
* @brief Array guard implementation.
|
|
4
|
+
* @details Array helpers append immutable length constraints while preserving
|
|
5
|
+
* the item schema owned by the original guard.
|
|
6
|
+
*/
|
|
7
|
+
import { ArrayCheckTag, SchemaTag } from "../kind/index.js";
|
|
8
|
+
import { BaseGuard, setArrayGuardFactory } from "./base.js";
|
|
9
|
+
import { checkArrayLengthBound, readArrayConstructorSchema, readArrayMethodSchema } from "./read.js";
|
|
10
|
+
/**
|
|
11
|
+
* @brief Persistent builder for homogeneous array predicates.
|
|
12
|
+
* @details Length methods allocate a fresh schema record. The item schema is
|
|
13
|
+
* reused by identity because guard construction has already frozen it.
|
|
14
|
+
*/
|
|
15
|
+
export class ArrayGuard extends BaseGuard {
|
|
16
|
+
/**
|
|
17
|
+
* @brief Construct a frozen array guard.
|
|
18
|
+
* @param schema Array schema backing this guard.
|
|
19
|
+
* @post The receiver has no mutable instance state after construction.
|
|
20
|
+
*/
|
|
21
|
+
constructor(schema) {
|
|
22
|
+
super(readArrayConstructorSchema(schema));
|
|
23
|
+
Object.freeze(this);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @brief Require an inclusive minimum array length.
|
|
27
|
+
* @param value Non-negative integer lower bound.
|
|
28
|
+
* @returns Fresh ArrayGuard with an appended minimum length check.
|
|
29
|
+
*/
|
|
30
|
+
min(value) {
|
|
31
|
+
const schema = readArrayMethodSchema(this, "array min receiver");
|
|
32
|
+
const bound = checkArrayLengthBound(value, "min");
|
|
33
|
+
return new ArrayGuard({
|
|
34
|
+
tag: SchemaTag.Array,
|
|
35
|
+
item: schema.item,
|
|
36
|
+
checks: [
|
|
37
|
+
...schema.checks,
|
|
38
|
+
{
|
|
39
|
+
tag: ArrayCheckTag.Min,
|
|
40
|
+
value: bound
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @brief Require an inclusive maximum array length.
|
|
47
|
+
* @param value Non-negative integer upper bound.
|
|
48
|
+
* @returns Fresh ArrayGuard with an appended maximum length check.
|
|
49
|
+
*/
|
|
50
|
+
max(value) {
|
|
51
|
+
const schema = readArrayMethodSchema(this, "array max receiver");
|
|
52
|
+
const bound = checkArrayLengthBound(value, "max");
|
|
53
|
+
return new ArrayGuard({
|
|
54
|
+
tag: SchemaTag.Array,
|
|
55
|
+
item: schema.item,
|
|
56
|
+
checks: [
|
|
57
|
+
...schema.checks,
|
|
58
|
+
{
|
|
59
|
+
tag: ArrayCheckTag.Max,
|
|
60
|
+
value: bound
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @brief Require one exact array length.
|
|
67
|
+
* @param value Non-negative integer exact length.
|
|
68
|
+
* @returns Fresh ArrayGuard with matching minimum and maximum length checks.
|
|
69
|
+
* @details Exact length is represented as two ordinary bounds so every
|
|
70
|
+
* backend can reuse the same comparison and diagnostic paths.
|
|
71
|
+
*/
|
|
72
|
+
length(value) {
|
|
73
|
+
const bound = checkArrayLengthBound(value, "exact");
|
|
74
|
+
return this.min(bound).max(bound);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @brief Require at least one array element.
|
|
78
|
+
* @returns Fresh ArrayGuard with a minimum length of one.
|
|
79
|
+
*/
|
|
80
|
+
nonempty() {
|
|
81
|
+
return this.min(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
setArrayGuardFactory((schema) => new ArrayGuard(schema));
|
package/dist/guard/base.d.ts
CHANGED
|
@@ -4,10 +4,24 @@
|
|
|
4
4
|
* @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
|
|
5
5
|
* existing guard instance.
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
7
|
+
import { SchemaTag } from "../kind/index.js";
|
|
8
|
+
import { type CheckResult } from "../issue/index.js";
|
|
8
9
|
import type { Graph } from "../ir/index.js";
|
|
9
10
|
import type { Schema } from "../schema/index.js";
|
|
11
|
+
import type { ArrayGuard } from "./array.js";
|
|
10
12
|
import type { Brand, Guard, Infer, Presence, PresenceSymbol, RuntimeValue, TypeSymbol } from "./types.js";
|
|
13
|
+
type ArraySchemaRecord = Extract<Schema, {
|
|
14
|
+
readonly tag: typeof SchemaTag.Array;
|
|
15
|
+
}>;
|
|
16
|
+
type ArrayGuardFactory = <TItem>(schema: ArraySchemaRecord) => ArrayGuard<TItem>;
|
|
17
|
+
/**
|
|
18
|
+
* @brief Register the concrete array guard factory.
|
|
19
|
+
* @param factory Constructor wrapper supplied by the array guard module.
|
|
20
|
+
* @details BaseGuard cannot import ArrayGuard directly without creating an
|
|
21
|
+
* initialization cycle. The guard barrel loads ArrayGuard, which installs this
|
|
22
|
+
* factory before public code can call fluent `array()`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function setArrayGuardFactory(factory: ArrayGuardFactory): void;
|
|
11
25
|
/**
|
|
12
26
|
* @brief Schema-backed guard base.
|
|
13
27
|
* @details Methods accept an unknown receiver on purpose. Public JavaScript can
|
|
@@ -43,6 +57,14 @@ export declare class BaseGuard<TValue, TPresence extends Presence = "required">
|
|
|
43
57
|
* @returns Result carrying the value on success or frozen issues on failure.
|
|
44
58
|
*/
|
|
45
59
|
check(this: unknown, value: unknown): CheckResult<RuntimeValue<TValue, TPresence>>;
|
|
60
|
+
/**
|
|
61
|
+
* @brief Validate a value and keep only the first diagnostic.
|
|
62
|
+
* @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
|
|
63
|
+
* existing guard instance.
|
|
64
|
+
* @param value Candidate runtime value.
|
|
65
|
+
* @returns Result carrying the value on success or one frozen issue on failure.
|
|
66
|
+
*/
|
|
67
|
+
checkFirst(this: unknown, value: unknown): CheckResult<RuntimeValue<TValue, TPresence>>;
|
|
46
68
|
/**
|
|
47
69
|
* @brief Validate a value and throw TypeSeaAssertionError on failure.
|
|
48
70
|
* @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
|
|
@@ -85,7 +107,7 @@ export declare class BaseGuard<TValue, TPresence extends Presence = "required">
|
|
|
85
107
|
* existing guard instance.
|
|
86
108
|
* @returns Fresh array guard.
|
|
87
109
|
*/
|
|
88
|
-
array():
|
|
110
|
+
array(): ArrayGuard<RuntimeValue<TValue, TPresence>>;
|
|
89
111
|
/**
|
|
90
112
|
* @brief Attach a compile-time brand without changing runtime validation.
|
|
91
113
|
* @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
|
|
@@ -118,5 +140,13 @@ export declare class BaseGuard<TValue, TPresence extends Presence = "required">
|
|
|
118
140
|
* @returns Fresh intersection guard requiring both schemas to pass.
|
|
119
141
|
*/
|
|
120
142
|
intersect<TOther extends Guard<unknown, Presence>>(other: TOther): BaseGuard<RuntimeValue<TValue, TPresence> & Infer<TOther>>;
|
|
143
|
+
/**
|
|
144
|
+
* @brief Require one own data property after this guard succeeds.
|
|
145
|
+
* @param key Own string property key to inspect.
|
|
146
|
+
* @param value Guard applied to the property value.
|
|
147
|
+
* @returns Fresh guard that preserves the base domain and property proof.
|
|
148
|
+
*/
|
|
149
|
+
property<const TKey extends string, TGuard extends Guard<unknown, Presence>>(key: TKey, value: TGuard): BaseGuard<RuntimeValue<TValue, TPresence> & Readonly<Record<TKey, Infer<TGuard>>>>;
|
|
121
150
|
}
|
|
151
|
+
export {};
|
|
122
152
|
//# sourceMappingURL=base.d.ts.map
|
package/dist/guard/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/guard/base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/guard/base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAoB,KAAK,WAAW,EAAc,MAAM,mBAAmB,CAAC;AACnF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AASjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACR,KAAK,EACL,KAAK,EACL,KAAK,EACL,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,UAAU,EACb,MAAM,YAAY,CAAC;AAEpB,KAAK,iBAAiB,GAAG,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,KAAK,CAAA;CAAE,CAAC,CAAC;AACnF,KAAK,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,iBAAiB,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;AAIjF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAErE;AAED;;;;;;GAMG;AACH,qBAAa,SAAS,CAClB,MAAM,EACN,SAAS,SAAS,QAAQ,GAAG,UAAU,CACzC,YAAW,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC;IACjC,SAAwB,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7C,SAAwB,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC;IACpD,SAAwB,MAAM,EAAE,MAAM,CAAC;IAEvC;;;;;;OAMG;gBACgB,MAAM,EAAE,MAAM;IAYjC;;;;;;OAMG;IACI,EAAE,CACL,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,GACf,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC;IAQ3C;;;;;;OAMG;IACI,KAAK,CACR,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,GACf,WAAW,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAO/C;;;;;;OAMG;IACI,UAAU,CACb,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,GACf,WAAW,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAW/C;;;;;;OAMG;IACI,MAAM,CACT,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,GACf,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC;IAUnD;;;;;OAKG;IACI,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,KAAK;IAIlC;;;;;OAKG;IACI,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAOhD;;;;;OAKG;IACI,aAAa,IAAI,SAAS,CAAC,MAAM,GAAG,SAAS,EAAE,SAAS,CAAC;IAOhE;;;;;OAKG;IACI,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC;IAOtD;;;;;OAKG;IACI,KAAK,IAAI,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAY3D;;;;;OAKG;IACI,KAAK,CAAC,MAAM,SAAS,MAAM,KAAK,SAAS,CAC5C,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,EACrB,SAAS,CACZ;IAQD;;;;;;;OAOG;IACI,MAAM,CACT,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,OAAO,EAC9D,IAAI,EAAE,MAAM,GACb,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;IAe/B;;;;;;OAMG;IACI,EAAE,CAAC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAC7C,KAAK,EAAE,MAAM,GACd,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAY7D;;;;;;OAMG;IACI,SAAS,CAAC,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EACpD,KAAK,EAAE,MAAM,GACd,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAQ7D;;;;;OAKG;IACI,QAAQ,CACX,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,MAAM,SAAS,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAEvC,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,MAAM,GACd,SAAS,CACR,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAC1E;CAaJ"}
|
package/dist/guard/base.js
CHANGED
|
@@ -7,10 +7,23 @@
|
|
|
7
7
|
import { SchemaTag } from "../kind/index.js";
|
|
8
8
|
import { checkSchema, isSchema } from "../evaluate/index.js";
|
|
9
9
|
import { makeValidationPlan } from "../plan/index.js";
|
|
10
|
+
import { freezeIssueArray } from "../issue/index.js";
|
|
11
|
+
import { err } from "../result/index.js";
|
|
10
12
|
import { TypeSeaAssertionError } from "./error.js";
|
|
11
13
|
import { checkRefinementInput, readConstructorSchema, readGuardSchema } from "./read.js";
|
|
12
14
|
import { defineReadonlyProperty, isStrictTrue } from "./props.js";
|
|
13
15
|
import { registerConstructedGuard } from "./registry.js";
|
|
16
|
+
let arrayGuardFactory;
|
|
17
|
+
/**
|
|
18
|
+
* @brief Register the concrete array guard factory.
|
|
19
|
+
* @param factory Constructor wrapper supplied by the array guard module.
|
|
20
|
+
* @details BaseGuard cannot import ArrayGuard directly without creating an
|
|
21
|
+
* initialization cycle. The guard barrel loads ArrayGuard, which installs this
|
|
22
|
+
* factory before public code can call fluent `array()`.
|
|
23
|
+
*/
|
|
24
|
+
export function setArrayGuardFactory(factory) {
|
|
25
|
+
arrayGuardFactory = factory;
|
|
26
|
+
}
|
|
14
27
|
/**
|
|
15
28
|
* @brief Schema-backed guard base.
|
|
16
29
|
* @details Methods accept an unknown receiver on purpose. Public JavaScript can
|
|
@@ -61,6 +74,20 @@ export class BaseGuard {
|
|
|
61
74
|
check(value) {
|
|
62
75
|
return checkSchema(readGuardSchema(this, "guard receiver"), value);
|
|
63
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* @brief Validate a value and keep only the first diagnostic.
|
|
79
|
+
* @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
|
|
80
|
+
* existing guard instance.
|
|
81
|
+
* @param value Candidate runtime value.
|
|
82
|
+
* @returns Result carrying the value on success or one frozen issue on failure.
|
|
83
|
+
*/
|
|
84
|
+
checkFirst(value) {
|
|
85
|
+
const result = checkSchema(readGuardSchema(this, "guard receiver"), value);
|
|
86
|
+
if (result.ok) {
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
return err(freezeIssueArray(readFirstIssue(result.error)));
|
|
90
|
+
}
|
|
64
91
|
/**
|
|
65
92
|
* @brief Validate a value and throw TypeSeaAssertionError on failure.
|
|
66
93
|
* @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
|
|
@@ -126,10 +153,15 @@ export class BaseGuard {
|
|
|
126
153
|
* @returns Fresh array guard.
|
|
127
154
|
*/
|
|
128
155
|
array() {
|
|
129
|
-
|
|
156
|
+
const schema = {
|
|
130
157
|
tag: SchemaTag.Array,
|
|
131
|
-
item: readGuardSchema(this, "array item")
|
|
132
|
-
|
|
158
|
+
item: readGuardSchema(this, "array item"),
|
|
159
|
+
checks: []
|
|
160
|
+
};
|
|
161
|
+
if (arrayGuardFactory === undefined) {
|
|
162
|
+
throw new TypeError("ArrayGuard factory is not initialized");
|
|
163
|
+
}
|
|
164
|
+
return arrayGuardFactory(schema);
|
|
133
165
|
}
|
|
134
166
|
/**
|
|
135
167
|
* @brief Attach a compile-time brand without changing runtime validation.
|
|
@@ -195,4 +227,43 @@ export class BaseGuard {
|
|
|
195
227
|
right: readGuardSchema(other, "intersection right")
|
|
196
228
|
});
|
|
197
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* @brief Require one own data property after this guard succeeds.
|
|
232
|
+
* @param key Own string property key to inspect.
|
|
233
|
+
* @param value Guard applied to the property value.
|
|
234
|
+
* @returns Fresh guard that preserves the base domain and property proof.
|
|
235
|
+
*/
|
|
236
|
+
property(key, value) {
|
|
237
|
+
if (typeof key !== "string") {
|
|
238
|
+
throw new TypeError("property key must be a string");
|
|
239
|
+
}
|
|
240
|
+
return new BaseGuard({
|
|
241
|
+
tag: SchemaTag.Property,
|
|
242
|
+
base: readGuardSchema(this, "property base"),
|
|
243
|
+
key,
|
|
244
|
+
value: readGuardSchema(value, "property value")
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* @brief Copy the first issue into a single-slot diagnostic vector.
|
|
250
|
+
* @details The full checker owns the original frozen issue vector. checkFirst
|
|
251
|
+
* publishes a narrower vector so callers cannot observe or retain extra issues.
|
|
252
|
+
* @param issues Issue vector returned by the full checker.
|
|
253
|
+
* @returns Mutable vector containing zero or one copied issue.
|
|
254
|
+
*/
|
|
255
|
+
function readFirstIssue(issues) {
|
|
256
|
+
const first = issues[0];
|
|
257
|
+
if (first === undefined) {
|
|
258
|
+
return [];
|
|
259
|
+
}
|
|
260
|
+
return [
|
|
261
|
+
{
|
|
262
|
+
path: first.path.slice(),
|
|
263
|
+
code: first.code,
|
|
264
|
+
expected: first.expected,
|
|
265
|
+
actual: first.actual,
|
|
266
|
+
message: first.message
|
|
267
|
+
}
|
|
268
|
+
];
|
|
198
269
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file date.ts
|
|
3
|
+
* @brief Date guard implementation.
|
|
4
|
+
* @details Date helpers store normalized epoch-millisecond bounds so runtime
|
|
5
|
+
* validation never has to read caller-owned Date objects again.
|
|
6
|
+
*/
|
|
7
|
+
import type { DateSchema } from "../schema/index.js";
|
|
8
|
+
import { BaseGuard } from "./base.js";
|
|
9
|
+
import type { Presence } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* @brief Persistent builder for valid Date predicates.
|
|
12
|
+
* @details Bound methods allocate fresh schema records and keep the source guard
|
|
13
|
+
* immutable, matching the scalar guard discipline used by number and string.
|
|
14
|
+
*/
|
|
15
|
+
export declare class DateGuard<TPresence extends Presence = "required"> extends BaseGuard<Date, TPresence> {
|
|
16
|
+
/**
|
|
17
|
+
* @brief Construct a frozen Date guard.
|
|
18
|
+
* @param schema Date schema backing this guard.
|
|
19
|
+
*/
|
|
20
|
+
constructor(schema: DateSchema);
|
|
21
|
+
/**
|
|
22
|
+
* @brief Add an inclusive lower Date bound.
|
|
23
|
+
* @param value Valid Date object used as the lower bound.
|
|
24
|
+
* @returns Fresh DateGuard with an appended min check.
|
|
25
|
+
*/
|
|
26
|
+
min(value: Date): DateGuard<TPresence>;
|
|
27
|
+
/**
|
|
28
|
+
* @brief Add an inclusive upper Date bound.
|
|
29
|
+
* @param value Valid Date object used as the upper bound.
|
|
30
|
+
* @returns Fresh DateGuard with an appended max check.
|
|
31
|
+
*/
|
|
32
|
+
max(value: Date): DateGuard<TPresence>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=date.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/guard/date.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAMtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,SAAS,CAClB,SAAS,SAAS,QAAQ,GAAG,UAAU,CACzC,SAAQ,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC;IAEhC;;;OAGG;gBACgB,MAAM,EAAE,UAAU;IAKrC;;;;OAIG;IACI,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC;IAc7C;;;;OAIG;IACI,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC;CAahD"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file date.ts
|
|
3
|
+
* @brief Date guard implementation.
|
|
4
|
+
* @details Date helpers store normalized epoch-millisecond bounds so runtime
|
|
5
|
+
* validation never has to read caller-owned Date objects again.
|
|
6
|
+
*/
|
|
7
|
+
import { DateCheckTag, SchemaTag } from "../kind/index.js";
|
|
8
|
+
import { BaseGuard } from "./base.js";
|
|
9
|
+
import { checkDateBound, readDateConstructorSchema, readDateMethodSchema } from "./read.js";
|
|
10
|
+
/**
|
|
11
|
+
* @brief Persistent builder for valid Date predicates.
|
|
12
|
+
* @details Bound methods allocate fresh schema records and keep the source guard
|
|
13
|
+
* immutable, matching the scalar guard discipline used by number and string.
|
|
14
|
+
*/
|
|
15
|
+
export class DateGuard extends BaseGuard {
|
|
16
|
+
/**
|
|
17
|
+
* @brief Construct a frozen Date guard.
|
|
18
|
+
* @param schema Date schema backing this guard.
|
|
19
|
+
*/
|
|
20
|
+
constructor(schema) {
|
|
21
|
+
super(readDateConstructorSchema(schema));
|
|
22
|
+
Object.freeze(this);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* @brief Add an inclusive lower Date bound.
|
|
26
|
+
* @param value Valid Date object used as the lower bound.
|
|
27
|
+
* @returns Fresh DateGuard with an appended min check.
|
|
28
|
+
*/
|
|
29
|
+
min(value) {
|
|
30
|
+
const schema = readDateMethodSchema(this, "date min receiver");
|
|
31
|
+
return new DateGuard({
|
|
32
|
+
tag: SchemaTag.Date,
|
|
33
|
+
checks: [
|
|
34
|
+
...schema.checks,
|
|
35
|
+
{
|
|
36
|
+
tag: DateCheckTag.Min,
|
|
37
|
+
value: checkDateBound(value, "min")
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @brief Add an inclusive upper Date bound.
|
|
44
|
+
* @param value Valid Date object used as the upper bound.
|
|
45
|
+
* @returns Fresh DateGuard with an appended max check.
|
|
46
|
+
*/
|
|
47
|
+
max(value) {
|
|
48
|
+
const schema = readDateMethodSchema(this, "date max receiver");
|
|
49
|
+
return new DateGuard({
|
|
50
|
+
tag: SchemaTag.Date,
|
|
51
|
+
checks: [
|
|
52
|
+
...schema.checks,
|
|
53
|
+
{
|
|
54
|
+
tag: DateCheckTag.Max,
|
|
55
|
+
value: checkDateBound(value, "max")
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
package/dist/guard/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* split by responsibility.
|
|
6
6
|
*/
|
|
7
7
|
export { BaseGuard } from "./base.js";
|
|
8
|
+
export { ArrayGuard } from "./array.js";
|
|
9
|
+
export { DateGuard } from "./date.js";
|
|
8
10
|
export { TypeSeaAssertionError } from "./error.js";
|
|
9
11
|
export { NumberGuard } from "./number.js";
|
|
10
12
|
export { StringGuard } from "./string.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guard/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EACR,KAAK,EACL,KAAK,EACL,aAAa,EACb,UAAU,EACV,KAAK,EACL,QAAQ,EACR,YAAY,EACf,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guard/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EACR,KAAK,EACL,KAAK,EACL,aAAa,EACb,UAAU,EACV,KAAK,EACL,QAAQ,EACR,YAAY,EACf,MAAM,YAAY,CAAC"}
|
package/dist/guard/index.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* split by responsibility.
|
|
6
6
|
*/
|
|
7
7
|
export { BaseGuard } from "./base.js";
|
|
8
|
+
export { ArrayGuard } from "./array.js";
|
|
9
|
+
export { DateGuard } from "./date.js";
|
|
8
10
|
export { TypeSeaAssertionError } from "./error.js";
|
|
9
11
|
export { NumberGuard } from "./number.js";
|
|
10
12
|
export { StringGuard } from "./string.js";
|
package/dist/guard/number.d.ts
CHANGED
|
@@ -35,6 +35,12 @@ export declare class NumberGuard<TPresence extends Presence = "required"> extend
|
|
|
35
35
|
* @returns Fresh NumberGuard with an appended gte check.
|
|
36
36
|
*/
|
|
37
37
|
gte(value: number): NumberGuard<TPresence>;
|
|
38
|
+
/**
|
|
39
|
+
* @brief Alias for an inclusive lower bound.
|
|
40
|
+
* @param value Finite lower bound.
|
|
41
|
+
* @returns Fresh NumberGuard with an appended gte check.
|
|
42
|
+
*/
|
|
43
|
+
min(value: number): NumberGuard<TPresence>;
|
|
38
44
|
/**
|
|
39
45
|
* @brief Add an inclusive upper bound.
|
|
40
46
|
* @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
|
|
@@ -43,5 +49,59 @@ export declare class NumberGuard<TPresence extends Presence = "required"> extend
|
|
|
43
49
|
* @returns Fresh NumberGuard with an appended lte check.
|
|
44
50
|
*/
|
|
45
51
|
lte(value: number): NumberGuard<TPresence>;
|
|
52
|
+
/**
|
|
53
|
+
* @brief Alias for an inclusive upper bound.
|
|
54
|
+
* @param value Finite upper bound.
|
|
55
|
+
* @returns Fresh NumberGuard with an appended lte check.
|
|
56
|
+
*/
|
|
57
|
+
max(value: number): NumberGuard<TPresence>;
|
|
58
|
+
/**
|
|
59
|
+
* @brief Add an exclusive lower bound.
|
|
60
|
+
* @param value Finite lower bound.
|
|
61
|
+
* @returns Fresh NumberGuard with an appended gt check.
|
|
62
|
+
*/
|
|
63
|
+
gt(value: number): NumberGuard<TPresence>;
|
|
64
|
+
/**
|
|
65
|
+
* @brief Add an exclusive upper bound.
|
|
66
|
+
* @param value Finite upper bound.
|
|
67
|
+
* @returns Fresh NumberGuard with an appended lt check.
|
|
68
|
+
*/
|
|
69
|
+
lt(value: number): NumberGuard<TPresence>;
|
|
70
|
+
/**
|
|
71
|
+
* @brief Require a number to be divisible by a positive finite divisor.
|
|
72
|
+
* @param value Positive finite divisor.
|
|
73
|
+
* @returns Fresh NumberGuard with an appended multipleOf check.
|
|
74
|
+
*/
|
|
75
|
+
multipleOf(value: number): NumberGuard<TPresence>;
|
|
76
|
+
/**
|
|
77
|
+
* @brief Require a number greater than zero.
|
|
78
|
+
* @returns Fresh NumberGuard with `gt(0)`.
|
|
79
|
+
*/
|
|
80
|
+
positive(): NumberGuard<TPresence>;
|
|
81
|
+
/**
|
|
82
|
+
* @brief Require a number greater than or equal to zero.
|
|
83
|
+
* @returns Fresh NumberGuard with `gte(0)`.
|
|
84
|
+
*/
|
|
85
|
+
nonnegative(): NumberGuard<TPresence>;
|
|
86
|
+
/**
|
|
87
|
+
* @brief Require a number less than zero.
|
|
88
|
+
* @returns Fresh NumberGuard with `lt(0)`.
|
|
89
|
+
*/
|
|
90
|
+
negative(): NumberGuard<TPresence>;
|
|
91
|
+
/**
|
|
92
|
+
* @brief Require a number less than or equal to zero.
|
|
93
|
+
* @returns Fresh NumberGuard with `lte(0)`.
|
|
94
|
+
*/
|
|
95
|
+
nonpositive(): NumberGuard<TPresence>;
|
|
96
|
+
/**
|
|
97
|
+
* @brief Keep the explicit Zod-compatible finite marker.
|
|
98
|
+
* @returns This guard because TypeSea numbers are finite by construction.
|
|
99
|
+
*/
|
|
100
|
+
finite(): this;
|
|
101
|
+
/**
|
|
102
|
+
* @brief Require a safe JavaScript integer.
|
|
103
|
+
* @returns Fresh NumberGuard constrained to Number.isSafeInteger domain.
|
|
104
|
+
*/
|
|
105
|
+
safe(): NumberGuard<TPresence>;
|
|
46
106
|
}
|
|
47
107
|
//# sourceMappingURL=number.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"number.d.ts","sourceRoot":"","sources":["../../src/guard/number.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAMtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,WAAW,CACpB,SAAS,SAAS,QAAQ,GAAG,UAAU,CACzC,SAAQ,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;IAElC;;;;;OAKG;gBACgB,MAAM,EAAE,YAAY;IAKvC;;;;;OAKG;IACI,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC;IAapC;;;;;;OAMG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAmBjD;;;;;;OAMG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"number.d.ts","sourceRoot":"","sources":["../../src/guard/number.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAMtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,WAAW,CACpB,SAAS,SAAS,QAAQ,GAAG,UAAU,CACzC,SAAQ,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;IAElC;;;;;OAKG;gBACgB,MAAM,EAAE,YAAY;IAKvC;;;;;OAKG;IACI,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC;IAapC;;;;;;OAMG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAmBjD;;;;OAIG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAIjD;;;;;;OAMG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAejD;;;;OAIG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAIjD;;;;OAIG;IACI,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAehD;;;;OAIG;IACI,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAehD;;;;OAIG;IACI,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAexD;;;OAGG;IACI,QAAQ,IAAI,WAAW,CAAC,SAAS,CAAC;IAIzC;;;OAGG;IACI,WAAW,IAAI,WAAW,CAAC,SAAS,CAAC;IAI5C;;;OAGG;IACI,QAAQ,IAAI,WAAW,CAAC,SAAS,CAAC;IAIzC;;;OAGG;IACI,WAAW,IAAI,WAAW,CAAC,SAAS,CAAC;IAI5C;;;OAGG;IACI,MAAM,IAAI,IAAI;IAIrB;;;OAGG;IACI,IAAI,IAAI,WAAW,CAAC,SAAS,CAAC;CAKxC"}
|
package/dist/guard/number.js
CHANGED
|
@@ -66,6 +66,14 @@ export class NumberGuard extends BaseGuard {
|
|
|
66
66
|
]
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* @brief Alias for an inclusive lower bound.
|
|
71
|
+
* @param value Finite lower bound.
|
|
72
|
+
* @returns Fresh NumberGuard with an appended gte check.
|
|
73
|
+
*/
|
|
74
|
+
min(value) {
|
|
75
|
+
return this.gte(value);
|
|
76
|
+
}
|
|
69
77
|
/**
|
|
70
78
|
* @brief Add an inclusive upper bound.
|
|
71
79
|
* @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
|
|
@@ -87,4 +95,125 @@ export class NumberGuard extends BaseGuard {
|
|
|
87
95
|
]
|
|
88
96
|
});
|
|
89
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* @brief Alias for an inclusive upper bound.
|
|
100
|
+
* @param value Finite upper bound.
|
|
101
|
+
* @returns Fresh NumberGuard with an appended lte check.
|
|
102
|
+
*/
|
|
103
|
+
max(value) {
|
|
104
|
+
return this.lte(value);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* @brief Add an exclusive lower bound.
|
|
108
|
+
* @param value Finite lower bound.
|
|
109
|
+
* @returns Fresh NumberGuard with an appended gt check.
|
|
110
|
+
*/
|
|
111
|
+
gt(value) {
|
|
112
|
+
const schema = readNumberMethodSchema(this, "number gt receiver");
|
|
113
|
+
const bound = checkFiniteNumberBound(value, "gt");
|
|
114
|
+
return new NumberGuard({
|
|
115
|
+
tag: SchemaTag.Number,
|
|
116
|
+
checks: [
|
|
117
|
+
...schema.checks,
|
|
118
|
+
{
|
|
119
|
+
tag: NumberCheckTag.Gt,
|
|
120
|
+
value: bound
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* @brief Add an exclusive upper bound.
|
|
127
|
+
* @param value Finite upper bound.
|
|
128
|
+
* @returns Fresh NumberGuard with an appended lt check.
|
|
129
|
+
*/
|
|
130
|
+
lt(value) {
|
|
131
|
+
const schema = readNumberMethodSchema(this, "number lt receiver");
|
|
132
|
+
const bound = checkFiniteNumberBound(value, "lt");
|
|
133
|
+
return new NumberGuard({
|
|
134
|
+
tag: SchemaTag.Number,
|
|
135
|
+
checks: [
|
|
136
|
+
...schema.checks,
|
|
137
|
+
{
|
|
138
|
+
tag: NumberCheckTag.Lt,
|
|
139
|
+
value: bound
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* @brief Require a number to be divisible by a positive finite divisor.
|
|
146
|
+
* @param value Positive finite divisor.
|
|
147
|
+
* @returns Fresh NumberGuard with an appended multipleOf check.
|
|
148
|
+
*/
|
|
149
|
+
multipleOf(value) {
|
|
150
|
+
const schema = readNumberMethodSchema(this, "number multipleOf receiver");
|
|
151
|
+
const divisor = checkPositiveFiniteNumber(value, "multipleOf");
|
|
152
|
+
return new NumberGuard({
|
|
153
|
+
tag: SchemaTag.Number,
|
|
154
|
+
checks: [
|
|
155
|
+
...schema.checks,
|
|
156
|
+
{
|
|
157
|
+
tag: NumberCheckTag.MultipleOf,
|
|
158
|
+
value: divisor
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* @brief Require a number greater than zero.
|
|
165
|
+
* @returns Fresh NumberGuard with `gt(0)`.
|
|
166
|
+
*/
|
|
167
|
+
positive() {
|
|
168
|
+
return this.gt(0);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* @brief Require a number greater than or equal to zero.
|
|
172
|
+
* @returns Fresh NumberGuard with `gte(0)`.
|
|
173
|
+
*/
|
|
174
|
+
nonnegative() {
|
|
175
|
+
return this.gte(0);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* @brief Require a number less than zero.
|
|
179
|
+
* @returns Fresh NumberGuard with `lt(0)`.
|
|
180
|
+
*/
|
|
181
|
+
negative() {
|
|
182
|
+
return this.lt(0);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* @brief Require a number less than or equal to zero.
|
|
186
|
+
* @returns Fresh NumberGuard with `lte(0)`.
|
|
187
|
+
*/
|
|
188
|
+
nonpositive() {
|
|
189
|
+
return this.lte(0);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* @brief Keep the explicit Zod-compatible finite marker.
|
|
193
|
+
* @returns This guard because TypeSea numbers are finite by construction.
|
|
194
|
+
*/
|
|
195
|
+
finite() {
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* @brief Require a safe JavaScript integer.
|
|
200
|
+
* @returns Fresh NumberGuard constrained to Number.isSafeInteger domain.
|
|
201
|
+
*/
|
|
202
|
+
safe() {
|
|
203
|
+
return this.int()
|
|
204
|
+
.gte(Number.MIN_SAFE_INTEGER)
|
|
205
|
+
.lte(Number.MAX_SAFE_INTEGER);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* @brief Validate a positive finite numeric divisor.
|
|
210
|
+
* @param value Candidate divisor.
|
|
211
|
+
* @param label Bound label used in RangeError messages.
|
|
212
|
+
* @returns Accepted divisor.
|
|
213
|
+
*/
|
|
214
|
+
function checkPositiveFiniteNumber(value, label) {
|
|
215
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
216
|
+
throw new RangeError(`${label} numeric divisor must be positive and finite`);
|
|
217
|
+
}
|
|
218
|
+
return value;
|
|
90
219
|
}
|