lib0 0.2.112 → 0.2.115-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 +1 -1
- package/broadcastchannel.js +1 -1
- package/buffer.d.ts +3 -3
- package/buffer.d.ts.map +1 -1
- package/buffer.js +1 -1
- package/coverage/tmp/coverage-27667-1761218530660-0.json +1 -0
- package/coverage/tmp/{coverage-20055-1752683207886-0.json → coverage-27668-1761218485882-0.json} +1 -1
- package/crypto/aes-gcm.d.ts +4 -4
- package/crypto/aes-gcm.d.ts.map +1 -1
- package/crypto/aes-gcm.js +6 -6
- package/crypto/common.d.ts +1 -1
- package/crypto/common.d.ts.map +1 -1
- package/crypto/common.js +1 -1
- package/crypto/ecdsa.d.ts +2 -2
- package/crypto/ecdsa.d.ts.map +1 -1
- package/crypto/ecdsa.js +4 -4
- package/crypto/rsa-oaep.d.ts +2 -2
- package/crypto/rsa-oaep.d.ts.map +1 -1
- package/crypto/rsa-oaep.js +3 -3
- package/decoding.d.ts +27 -14
- package/decoding.d.ts.map +1 -1
- package/decoding.js +12 -8
- package/delta/abstract-array.d.ts +166 -0
- package/delta/abstract-array.d.ts.map +1 -0
- package/delta/abstract-array.js +421 -0
- package/delta/abstract.d.ts +69 -0
- package/delta/abstract.d.ts.map +1 -0
- package/delta/abstract.js +102 -0
- package/delta/array.d.ts +23 -0
- package/delta/array.d.ts.map +1 -0
- package/delta/array.js +45 -0
- package/delta/array.test.d.ts +2 -0
- package/delta/array.test.d.ts.map +1 -0
- package/delta/binding.d.ts +105 -0
- package/delta/binding.d.ts.map +1 -0
- package/delta/binding.js +369 -0
- package/delta/binding.test.d.ts +5 -0
- package/delta/binding.test.d.ts.map +1 -0
- package/delta/d2.d.ts +705 -0
- package/delta/d2.d.ts.map +1 -0
- package/delta/d2.js +1309 -0
- package/delta/d2.test.d.ts +15 -0
- package/delta/d2.test.d.ts.map +1 -0
- package/delta/index.d.ts +14 -0
- package/delta/index.d.ts.map +1 -0
- package/delta/index.js +79 -0
- package/delta/map.d.ts +230 -0
- package/delta/map.d.ts.map +1 -0
- package/delta/map.js +304 -0
- package/delta/node.d.ts +119 -0
- package/delta/node.d.ts.map +1 -0
- package/delta/node.js +183 -0
- package/delta/node.test.d.ts +4 -0
- package/delta/node.test.d.ts.map +1 -0
- package/delta/ops.d.ts +466 -0
- package/delta/ops.d.ts.map +1 -0
- package/delta/ops.js +544 -0
- package/delta/readme.md +129 -0
- package/delta/text.d.ts +43 -0
- package/delta/text.d.ts.map +1 -0
- package/delta/text.js +54 -0
- package/delta/text.test.d.ts +6 -0
- package/delta/text.test.d.ts.map +1 -0
- package/delta/transformer.d.ts +164 -0
- package/delta/transformer.d.ts.map +1 -0
- package/delta/transformer.js +888 -0
- package/delta/transformer.test.d.ts +13 -0
- package/delta/transformer.test.d.ts.map +1 -0
- package/delta/value.d.ts +84 -0
- package/delta/value.d.ts.map +1 -0
- package/delta/value.js +168 -0
- package/dist/abstract-array.cjs +433 -0
- package/dist/abstract-array.cjs.map +1 -0
- package/dist/abstract.cjs +122 -0
- package/dist/abstract.cjs.map +1 -0
- package/dist/aes-gcm.cjs +12 -12
- package/dist/aes-gcm.cjs.map +1 -1
- package/dist/array.cjs +60 -17
- package/dist/array.cjs.map +1 -1
- package/dist/array2.cjs +26 -0
- package/dist/array2.cjs.map +1 -0
- package/dist/binding.cjs +398 -0
- package/dist/binding.cjs.map +1 -0
- package/dist/{broadcastchannel-2c4b0a1c.cjs → broadcastchannel-b4eaea6e.cjs} +4 -4
- package/dist/broadcastchannel-b4eaea6e.cjs.map +1 -0
- package/dist/broadcastchannel.cjs +12 -12
- package/dist/{buffer-a74f7330.cjs → buffer-adc4e6ea.cjs} +7 -7
- package/dist/buffer-adc4e6ea.cjs.map +1 -0
- package/dist/buffer.cjs +11 -11
- package/dist/buffer.d.ts +3 -3
- package/dist/buffer.d.ts.map +1 -1
- package/dist/cache.cjs +6 -6
- package/dist/common.cjs +1 -1
- package/dist/common.cjs.map +1 -1
- package/dist/component.cjs +14 -9
- package/dist/component.cjs.map +1 -1
- package/dist/crypto/aes-gcm.d.ts +4 -4
- package/dist/crypto/aes-gcm.d.ts.map +1 -1
- package/dist/crypto/common.d.ts +1 -1
- package/dist/crypto/common.d.ts.map +1 -1
- package/dist/crypto/ecdsa.d.ts +2 -2
- package/dist/crypto/ecdsa.d.ts.map +1 -1
- package/dist/crypto/rsa-oaep.d.ts +2 -2
- package/dist/crypto/rsa-oaep.d.ts.map +1 -1
- package/dist/d2.cjs +1347 -0
- package/dist/d2.cjs.map +1 -0
- package/dist/{decoding-2b136346.cjs → decoding-50b9ce38.cjs} +18 -14
- package/dist/decoding-50b9ce38.cjs.map +1 -0
- package/dist/decoding.cjs +6 -6
- package/dist/decoding.d.ts +27 -14
- package/dist/decoding.d.ts.map +1 -1
- package/dist/delta/abstract-array.d.ts +166 -0
- package/dist/delta/abstract-array.d.ts.map +1 -0
- package/dist/delta/abstract.d.ts +69 -0
- package/dist/delta/abstract.d.ts.map +1 -0
- package/dist/delta/array.d.ts +23 -0
- package/dist/delta/array.d.ts.map +1 -0
- package/dist/delta/array.test.d.ts +2 -0
- package/dist/delta/array.test.d.ts.map +1 -0
- package/dist/delta/binding.d.ts +105 -0
- package/dist/delta/binding.d.ts.map +1 -0
- package/dist/delta/binding.test.d.ts +5 -0
- package/dist/delta/binding.test.d.ts.map +1 -0
- package/dist/delta/d2.d.ts +705 -0
- package/dist/delta/d2.d.ts.map +1 -0
- package/dist/delta/d2.test.d.ts +15 -0
- package/dist/delta/d2.test.d.ts.map +1 -0
- package/dist/delta/index.d.ts +14 -0
- package/dist/delta/index.d.ts.map +1 -0
- package/dist/delta/map.d.ts +230 -0
- package/dist/delta/map.d.ts.map +1 -0
- package/dist/delta/node.d.ts +119 -0
- package/dist/delta/node.d.ts.map +1 -0
- package/dist/delta/node.test.d.ts +4 -0
- package/dist/delta/node.test.d.ts.map +1 -0
- package/dist/delta/ops.d.ts +466 -0
- package/dist/delta/ops.d.ts.map +1 -0
- package/dist/delta/text.d.ts +43 -0
- package/dist/delta/text.d.ts.map +1 -0
- package/dist/delta/text.test.d.ts +6 -0
- package/dist/delta/text.test.d.ts.map +1 -0
- package/dist/delta/transformer.d.ts +164 -0
- package/dist/delta/transformer.d.ts.map +1 -0
- package/dist/delta/transformer.test.d.ts +13 -0
- package/dist/delta/transformer.test.d.ts.map +1 -0
- package/dist/delta/value.d.ts +84 -0
- package/dist/delta/value.d.ts.map +1 -0
- package/dist/{diff-77c4cf8e.cjs → diff-f0776c15.cjs} +2 -2
- package/dist/{diff-77c4cf8e.cjs.map → diff-f0776c15.cjs.map} +1 -1
- package/dist/diff.cjs +3 -3
- package/dist/{dom-16daf1a0.cjs → dom-2b123630.cjs} +31 -2
- package/dist/dom-2b123630.cjs.map +1 -0
- package/dist/dom.cjs +17 -2
- package/dist/dom.cjs.map +1 -1
- package/dist/dom.d.ts +17 -0
- package/dist/dom.d.ts.map +1 -1
- package/dist/ecdsa.cjs +4 -4
- package/dist/ecdsa.cjs.map +1 -1
- package/dist/{encoding-1acb59c4.cjs → encoding-7f85922c.cjs} +5 -5
- package/dist/encoding-7f85922c.cjs.map +1 -0
- package/dist/encoding.cjs +4 -4
- package/dist/encoding.d.ts +6 -6
- package/dist/encoding.d.ts.map +1 -1
- package/dist/{environment-2de08e0e.cjs → environment-90227ead.cjs} +4 -4
- package/dist/{environment-2de08e0e.cjs.map → environment-90227ead.cjs.map} +1 -1
- package/dist/environment.cjs +5 -5
- package/dist/{error-8582d695.cjs → error-0c1f634f.cjs} +10 -2
- package/dist/error-0c1f634f.cjs.map +1 -0
- package/dist/error.cjs +2 -1
- package/dist/error.cjs.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/{eventloop-b299a889.cjs → eventloop-a0168106.cjs} +2 -2
- package/dist/{eventloop-b299a889.cjs.map → eventloop-a0168106.cjs.map} +1 -1
- package/dist/eventloop.cjs +3 -3
- package/dist/{function-09b8292c.cjs → function-e7d18feb.cjs} +2 -2
- package/dist/{function-09b8292c.cjs.map → function-e7d18feb.cjs.map} +1 -1
- package/dist/function.cjs +2 -2
- package/dist/index.cjs +23 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index2.cjs +71 -0
- package/dist/index2.cjs.map +1 -0
- package/dist/{indexeddb-0cbb4d6f.cjs → indexeddb-46d1e737.cjs} +3 -3
- package/dist/{indexeddb-0cbb4d6f.cjs.map → indexeddb-46d1e737.cjs.map} +1 -1
- package/dist/indexeddb.cjs +5 -5
- package/dist/indexeddbV2.cjs +2 -1
- package/dist/indexeddbV2.cjs.map +1 -1
- package/dist/jwt.cjs +12 -12
- package/dist/list.cjs +39 -12
- package/dist/list.cjs.map +1 -1
- package/dist/list.d.ts +13 -3
- package/dist/list.d.ts.map +1 -1
- package/dist/logging.cjs +11 -9
- package/dist/logging.cjs.map +1 -1
- package/dist/logging.common.cjs +7 -7
- package/dist/logging.node.cjs +7 -7
- package/dist/{map-0dabcc55.cjs → map-24d263c0.cjs} +7 -1
- package/dist/map-24d263c0.cjs.map +1 -0
- package/dist/map.cjs +314 -7
- package/dist/map.cjs.map +1 -1
- package/dist/map.d.ts +1 -0
- package/dist/map.d.ts.map +1 -1
- package/dist/map2.cjs +15 -0
- package/dist/map2.cjs.map +1 -0
- package/dist/{math-08e068f9.cjs → math-96d5e8c4.cjs} +4 -2
- package/dist/math-96d5e8c4.cjs.map +1 -0
- package/dist/math.cjs +1 -1
- package/dist/math.d.ts.map +1 -1
- package/dist/metric.cjs +1 -1
- package/dist/node.cjs +206 -0
- package/dist/node.cjs.map +1 -0
- package/dist/{number-466d8922.cjs → number-1fb57bba.cjs} +2 -2
- package/dist/{number-466d8922.cjs.map → number-1fb57bba.cjs.map} +1 -1
- package/dist/number.cjs +2 -2
- package/dist/{object-491858d1.cjs → object-18980796.cjs} +12 -2
- package/dist/object-18980796.cjs.map +1 -0
- package/dist/object.cjs +3 -1
- package/dist/object.cjs.map +1 -1
- package/dist/object.d.ts +3 -0
- package/dist/object.d.ts.map +1 -1
- package/dist/observable.cjs +1 -1
- package/dist/ops.cjs +575 -0
- package/dist/ops.cjs.map +1 -0
- package/dist/patience.cjs +2 -2
- package/dist/performance.node.cjs +4 -4
- package/dist/pledge.cjs +2 -1
- package/dist/pledge.cjs.map +1 -1
- package/dist/{prng-24dfe0bf.cjs → prng-004c76e8.cjs} +5 -5
- package/dist/{prng-24dfe0bf.cjs.map → prng-004c76e8.cjs.map} +1 -1
- package/dist/prng.cjs +12 -12
- package/dist/prng.d.ts +1 -1
- package/dist/prng.d.ts.map +1 -1
- package/dist/{promise-7d13a97c.cjs → promise-cda7b9bb.cjs} +2 -2
- package/dist/{promise-7d13a97c.cjs.map → promise-cda7b9bb.cjs.map} +1 -1
- package/dist/promise.cjs +3 -3
- package/dist/rabin-gf2-polynomial.cjs +11 -11
- package/dist/rabin-uncached.cjs +11 -11
- package/dist/rabin.cjs +11 -11
- package/dist/random.cjs +1 -1
- package/dist/rsa-oaep.cjs +3 -3
- package/dist/rsa-oaep.cjs.map +1 -1
- package/dist/schema.cjs +572 -167
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.ts +326 -122
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.test.d.ts +5 -0
- package/dist/schema.test.d.ts.map +1 -1
- package/dist/{sort-b8702761.cjs → sort-812cc211.cjs} +2 -2
- package/dist/{sort-b8702761.cjs.map → sort-812cc211.cjs.map} +1 -1
- package/dist/sort.cjs +2 -2
- package/dist/{statistics-c2316dca.cjs → statistics-65f6114b.cjs} +2 -2
- package/dist/{statistics-c2316dca.cjs.map → statistics-65f6114b.cjs.map} +1 -1
- package/dist/statistics.cjs +2 -2
- package/dist/{string-b2827a90.cjs → string-fddc5f8b.cjs} +3 -3
- package/dist/string-fddc5f8b.cjs.map +1 -0
- package/dist/string.cjs +1 -1
- package/dist/string.d.ts +3 -3
- package/dist/string.d.ts.map +1 -1
- package/dist/testing.cjs +16 -16
- package/dist/text.cjs +79 -0
- package/dist/text.cjs.map +1 -0
- package/dist/{time-bc2081b9.cjs → time-d8438852.cjs} +2 -2
- package/dist/{time-bc2081b9.cjs.map → time-d8438852.cjs.map} +1 -1
- package/dist/time.cjs +2 -2
- package/dist/traits.cjs +22 -0
- package/dist/traits.cjs.map +1 -1
- package/dist/traits.d.ts +1 -0
- package/dist/traits.d.ts.map +1 -1
- package/dist/traits.test.d.ts.map +1 -1
- package/dist/transformer.cjs +930 -0
- package/dist/transformer.cjs.map +1 -0
- package/dist/url.cjs +2 -1
- package/dist/url.cjs.map +1 -1
- package/dist/value.cjs +187 -0
- package/dist/value.cjs.map +1 -0
- package/dist/webcrypto.d.ts +1 -1
- package/dist/webcrypto.d.ts.map +1 -1
- package/dist/{websocket-40a601d4.cjs → websocket-b073d0fc.cjs} +3 -3
- package/dist/{websocket-40a601d4.cjs.map → websocket-b073d0fc.cjs.map} +1 -1
- package/dist/websocket.cjs +4 -4
- package/dom.d.ts +17 -0
- package/dom.d.ts.map +1 -1
- package/dom.js +21 -0
- package/encoding.d.ts +6 -6
- package/encoding.d.ts.map +1 -1
- package/encoding.js +1 -1
- package/error.d.ts +1 -0
- package/error.d.ts.map +1 -1
- package/error.js +6 -0
- package/list.d.ts +13 -3
- package/list.d.ts.map +1 -1
- package/list.js +36 -8
- package/map.d.ts +1 -0
- package/map.d.ts.map +1 -1
- package/map.js +6 -0
- package/math.d.ts.map +1 -1
- package/math.js +3 -1
- package/object.d.ts +3 -0
- package/object.d.ts.map +1 -1
- package/object.js +9 -1
- package/package.json +9 -3
- package/prng.d.ts +1 -1
- package/prng.d.ts.map +1 -1
- package/prng.js +1 -1
- package/schema.d.ts +326 -122
- package/schema.d.ts.map +1 -1
- package/schema.js +513 -141
- package/schema.test.d.ts +5 -0
- package/schema.test.d.ts.map +1 -1
- package/string.d.ts +3 -3
- package/string.d.ts.map +1 -1
- package/string.js +2 -2
- package/test.html +1 -0
- package/test.js +13 -1
- package/traits.d.ts +1 -0
- package/traits.d.ts.map +1 -1
- package/traits.js +21 -0
- package/traits.test.d.ts.map +1 -1
- package/webcrypto.d.ts +1 -1
- package/webcrypto.d.ts.map +1 -1
- package/coverage/tmp/coverage-20054-1752683240888-0.json +0 -1
- package/dist/broadcastchannel-2c4b0a1c.cjs.map +0 -1
- package/dist/buffer-a74f7330.cjs.map +0 -1
- package/dist/decoding-2b136346.cjs.map +0 -1
- package/dist/dom-16daf1a0.cjs.map +0 -1
- package/dist/encoding-1acb59c4.cjs.map +0 -1
- package/dist/error-8582d695.cjs.map +0 -1
- package/dist/map-0dabcc55.cjs.map +0 -1
- package/dist/math-08e068f9.cjs.map +0 -1
- package/dist/object-491858d1.cjs.map +0 -1
- package/dist/string-b2827a90.cjs.map +0 -1
package/schema.js
CHANGED
|
@@ -8,6 +8,9 @@ import * as obj from './object.js'
|
|
|
8
8
|
import * as arr from './array.js'
|
|
9
9
|
import * as error from './error.js'
|
|
10
10
|
import * as env from './environment.js'
|
|
11
|
+
import * as traits from './traits.js'
|
|
12
|
+
import * as fun from './function.js'
|
|
13
|
+
import * as string from './string.js'
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
16
|
* @typedef {string|number|bigint|boolean|null|undefined} LiteralType
|
|
@@ -19,17 +22,22 @@ import * as env from './environment.js'
|
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
24
|
* @template T
|
|
22
|
-
* @typedef {T extends
|
|
25
|
+
* @typedef {T extends Schema<infer X> ? X : T} Unwrap
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @template T
|
|
30
|
+
* @typedef {T extends Schema<infer X> ? X : T} TypeOf
|
|
23
31
|
*/
|
|
24
32
|
|
|
25
33
|
/**
|
|
26
34
|
* @template {readonly unknown[]} T
|
|
27
|
-
* @typedef {T extends readonly [
|
|
35
|
+
* @typedef {T extends readonly [Schema<infer First>, ...infer Rest] ? [First, ...UnwrapArray<Rest>] : [] } UnwrapArray
|
|
28
36
|
*/
|
|
29
37
|
|
|
30
38
|
/**
|
|
31
39
|
* @template T
|
|
32
|
-
* @typedef {T extends
|
|
40
|
+
* @typedef {T extends Schema<infer S> ? Schema<S> : never} CastToSchema
|
|
33
41
|
*/
|
|
34
42
|
|
|
35
43
|
/**
|
|
@@ -56,11 +64,98 @@ import * as env from './environment.js'
|
|
|
56
64
|
|
|
57
65
|
const schemaSymbol = Symbol('0schema')
|
|
58
66
|
|
|
67
|
+
class ValidationError {
|
|
68
|
+
constructor () {
|
|
69
|
+
/**
|
|
70
|
+
* Reverse errors
|
|
71
|
+
* @type {Array<{ path: string?, expected: string, has: string, message: string? }>}
|
|
72
|
+
*/
|
|
73
|
+
this._rerrs = []
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {string?} path
|
|
78
|
+
* @param {string} expected
|
|
79
|
+
* @param {string} has
|
|
80
|
+
* @param {string?} message
|
|
81
|
+
*/
|
|
82
|
+
extend (path, expected, has, message = null) {
|
|
83
|
+
this._rerrs.push({ path, expected, has, message })
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
toString () {
|
|
87
|
+
const s = []
|
|
88
|
+
for (let i = this._rerrs.length - 1; i > 0; i--) {
|
|
89
|
+
const r = this._rerrs[i]
|
|
90
|
+
s.push(string.repeat(' ', (this._rerrs.length - i) * 2) + `${r.path != null ? `[${r.path}] ` : ''}${r.has} doesn't match ${r.expected}. ${r.message}`)
|
|
91
|
+
}
|
|
92
|
+
return s.join('\n')
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @param {any} a
|
|
98
|
+
* @param {any} b
|
|
99
|
+
* @return {boolean}
|
|
100
|
+
*/
|
|
101
|
+
const shapeExtends = (a, b) => {
|
|
102
|
+
if (a === b) return true
|
|
103
|
+
if (a == null || b == null || a.constructor !== b.constructor) return false
|
|
104
|
+
if (a[traits.EqualityTraitSymbol]) return traits.equals(a, b) // last resort: check equality (do this before array and obj check which don't implement the equality trait)
|
|
105
|
+
if (arr.isArray(a)) {
|
|
106
|
+
return arr.every(a, aitem =>
|
|
107
|
+
arr.some(b, bitem => shapeExtends(aitem, bitem))
|
|
108
|
+
)
|
|
109
|
+
} else if (obj.isObject(a)) {
|
|
110
|
+
return obj.every(a, (aitem, akey) =>
|
|
111
|
+
shapeExtends(aitem, b[akey])
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
/* c8 ignore next */
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
|
|
59
118
|
/**
|
|
60
119
|
* @template T
|
|
120
|
+
* @implements {traits.EqualityTrait}
|
|
61
121
|
*/
|
|
62
|
-
export class
|
|
63
|
-
|
|
122
|
+
export class Schema {
|
|
123
|
+
// this.shape must not be defined on Schema. Otherwise typecheck on metatypes (e.g. $$object) won't work as expected anymore
|
|
124
|
+
/**
|
|
125
|
+
* If true, the more things are added to the shape the more objects this schema will accept (e.g.
|
|
126
|
+
* union). By default, the more objects are added, the the fewer objects this schema will accept.
|
|
127
|
+
* @protected
|
|
128
|
+
*/
|
|
129
|
+
static _dilutes = false
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @param {Schema<any>} other
|
|
133
|
+
*/
|
|
134
|
+
extends (other) {
|
|
135
|
+
let [a, b] = [/** @type {any} */(this).shape, /** @type {any} */ (other).shape]
|
|
136
|
+
if (/** @type {typeof Schema<any>} */ (this.constructor)._dilutes) [b, a] = [a, b]
|
|
137
|
+
return shapeExtends(a, b)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Overwrite this when necessary. By default, we only check the `shape` property which every shape
|
|
142
|
+
* should have.
|
|
143
|
+
* @param {Schema<any>} other
|
|
144
|
+
*/
|
|
145
|
+
equals (other) {
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
return this.constructor === other.constructor && fun.equalityDeep(this.shape, other.shape)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
[schemaSymbol] () { return true }
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {object} other
|
|
154
|
+
*/
|
|
155
|
+
[traits.EqualityTraitSymbol] (other) {
|
|
156
|
+
return this.equals(/** @type {any} */ (other))
|
|
157
|
+
}
|
|
158
|
+
|
|
64
159
|
/**
|
|
65
160
|
* Use `schema.validate(obj)` with a typed parameter that is already of typed to be an instance of
|
|
66
161
|
* Schema. Validate will check the structure of the parameter and return true iff the instance
|
|
@@ -78,25 +173,26 @@ export class $Schema {
|
|
|
78
173
|
* Similar to validate, but this method accepts untyped parameters.
|
|
79
174
|
*
|
|
80
175
|
* @param {any} _o
|
|
176
|
+
* @param {ValidationError} [_err]
|
|
81
177
|
* @return {_o is T}
|
|
82
178
|
*/
|
|
83
|
-
check (_o) {
|
|
179
|
+
check (_o, _err) {
|
|
84
180
|
error.methodUnimplemented()
|
|
85
181
|
}
|
|
86
182
|
/* c8 ignore stop */
|
|
87
183
|
|
|
88
184
|
/**
|
|
89
|
-
* @type {
|
|
185
|
+
* @type {Schema<T?>}
|
|
90
186
|
*/
|
|
91
187
|
get nullable () {
|
|
92
|
-
return union(this,
|
|
188
|
+
return $union(this, $null)
|
|
93
189
|
}
|
|
94
190
|
|
|
95
191
|
/**
|
|
96
|
-
* @type {$Optional
|
|
192
|
+
* @type {$Optional<Schema<T>>}
|
|
97
193
|
*/
|
|
98
194
|
get optional () {
|
|
99
|
-
return new $Optional(/** @type {
|
|
195
|
+
return new $Optional(/** @type {Schema<T>} */ (this))
|
|
100
196
|
}
|
|
101
197
|
|
|
102
198
|
/**
|
|
@@ -107,20 +203,27 @@ export class $Schema {
|
|
|
107
203
|
* **Do not rely on these error messages!**
|
|
108
204
|
* Performs an assertion check only if not in a production environment.
|
|
109
205
|
*
|
|
110
|
-
* @
|
|
111
|
-
* @
|
|
206
|
+
* @template OO
|
|
207
|
+
* @param {OO} o
|
|
208
|
+
* @return {Extract<OO, T> extends never ? T : (OO extends Array<never> ? T : Extract<OO,T>)}
|
|
112
209
|
*/
|
|
113
210
|
cast (o) {
|
|
114
211
|
assert(o, this)
|
|
115
|
-
return o
|
|
212
|
+
return /** @type {any} */ (o)
|
|
116
213
|
}
|
|
117
214
|
|
|
118
215
|
/**
|
|
216
|
+
* EXPECTO PATRONUM!! 🪄
|
|
217
|
+
* This function protects against type errors. Though it may not work in the real world.
|
|
218
|
+
*
|
|
219
|
+
* "After all this time?"
|
|
220
|
+
* "Always." - Snape, talking about type safety
|
|
221
|
+
*
|
|
119
222
|
* Ensures that a variable is a a specific type. Returns the value, or throws an exception if the assertion check failed.
|
|
120
223
|
* Use this if you know that the type is of a specific type and you just want to convince the type
|
|
121
224
|
* system.
|
|
122
225
|
*
|
|
123
|
-
* Can be useful when defining lambdas: `s.lambda(s.$number, s.$void).
|
|
226
|
+
* Can be useful when defining lambdas: `s.lambda(s.$number, s.$void).expect((n) => n + 1)`
|
|
124
227
|
*
|
|
125
228
|
* **Do not rely on these error messages!**
|
|
126
229
|
* Performs an assertion check if not in a production environment.
|
|
@@ -128,60 +231,115 @@ export class $Schema {
|
|
|
128
231
|
* @param {T} o
|
|
129
232
|
* @return {o extends T ? T : never}
|
|
130
233
|
*/
|
|
131
|
-
|
|
234
|
+
expect (o) {
|
|
132
235
|
assert(o, this)
|
|
133
236
|
return o
|
|
134
237
|
}
|
|
135
238
|
}
|
|
136
239
|
|
|
240
|
+
/**
|
|
241
|
+
* @template {(new (...args:any[]) => any) | ((...args:any[]) => any)} Constr
|
|
242
|
+
* @typedef {Constr extends ((...args:any[]) => infer T) ? T : (Constr extends (new (...args:any[]) => any) ? InstanceType<Constr> : never)} Instance
|
|
243
|
+
*/
|
|
244
|
+
|
|
137
245
|
/**
|
|
138
246
|
* @template {(new (...args:any[]) => any) | ((...args:any[]) => any)} C
|
|
139
|
-
* @extends {
|
|
247
|
+
* @extends {Schema<Instance<C>>}
|
|
140
248
|
*/
|
|
141
|
-
export class $ConstructedBy extends
|
|
249
|
+
export class $ConstructedBy extends Schema {
|
|
142
250
|
/**
|
|
143
251
|
* @param {C} c
|
|
252
|
+
* @param {((o:Instance<C>)=>boolean)|null} check
|
|
144
253
|
*/
|
|
145
|
-
constructor (c) {
|
|
254
|
+
constructor (c, check) {
|
|
146
255
|
super()
|
|
147
|
-
this.
|
|
256
|
+
this.shape = c
|
|
257
|
+
this._c = check
|
|
148
258
|
}
|
|
149
259
|
|
|
150
260
|
/**
|
|
151
261
|
* @param {any} o
|
|
262
|
+
* @param {ValidationError} [err]
|
|
152
263
|
* @return {o is C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType<C> : never)} o
|
|
153
264
|
*/
|
|
154
|
-
check (o) {
|
|
155
|
-
|
|
265
|
+
check (o, err = undefined) {
|
|
266
|
+
const c = o?.constructor === this.shape && (this._c == null || this._c(o))
|
|
267
|
+
/* c8 ignore next */
|
|
268
|
+
!c && err?.extend(null, this.shape.name, o?.constructor.name, o?.constructor !== this.shape ? 'Constructor match failed' : 'Check failed')
|
|
269
|
+
return c
|
|
156
270
|
}
|
|
157
271
|
}
|
|
158
272
|
|
|
159
273
|
/**
|
|
160
274
|
* @template {(new (...args:any[]) => any) | ((...args:any[]) => any)} C
|
|
161
275
|
* @param {C} c
|
|
276
|
+
* @param {((o:Instance<C>) => boolean)|null} check
|
|
162
277
|
* @return {CastToSchema<$ConstructedBy<C>>}
|
|
163
278
|
*/
|
|
164
|
-
export const constructedBy = c => new $ConstructedBy(c)
|
|
279
|
+
export const $constructedBy = (c, check = null) => new $ConstructedBy(c, check)
|
|
280
|
+
export const $$constructedBy = $constructedBy($ConstructedBy)
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Check custom properties on any object. You may want to overwrite the generated Schema<any>.
|
|
284
|
+
*
|
|
285
|
+
* @extends {Schema<any>}
|
|
286
|
+
*/
|
|
287
|
+
export class $Custom extends Schema {
|
|
288
|
+
/**
|
|
289
|
+
* @param {(o:any) => boolean} check
|
|
290
|
+
*/
|
|
291
|
+
constructor (check) {
|
|
292
|
+
super()
|
|
293
|
+
/**
|
|
294
|
+
* @type {(o:any) => boolean}
|
|
295
|
+
*/
|
|
296
|
+
this.shape = check
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* @param {any} o
|
|
301
|
+
* @param {ValidationError} err
|
|
302
|
+
* @return {o is any}
|
|
303
|
+
*/
|
|
304
|
+
check (o, err) {
|
|
305
|
+
const c = this.shape(o)
|
|
306
|
+
/* c8 ignore next */
|
|
307
|
+
!c && err?.extend(null, 'custom prop', o?.constructor.name, 'failed to check custom prop')
|
|
308
|
+
return c
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* @param {(o:any) => boolean} check
|
|
314
|
+
* @return {Schema<any>}
|
|
315
|
+
*/
|
|
316
|
+
export const $custom = check => new $Custom(check)
|
|
317
|
+
export const $$custom = $constructedBy($Custom)
|
|
165
318
|
|
|
166
319
|
/**
|
|
167
320
|
* @template {LiteralType} T
|
|
168
|
-
* @extends {
|
|
321
|
+
* @extends {Schema<T>}
|
|
169
322
|
*/
|
|
170
|
-
export class $Literal extends
|
|
323
|
+
export class $Literal extends Schema {
|
|
171
324
|
/**
|
|
172
325
|
* @param {Array<T>} literals
|
|
173
326
|
*/
|
|
174
327
|
constructor (literals) {
|
|
175
328
|
super()
|
|
176
|
-
this.
|
|
329
|
+
this.shape = literals
|
|
177
330
|
}
|
|
178
331
|
|
|
179
332
|
/**
|
|
333
|
+
*
|
|
180
334
|
* @param {any} o
|
|
335
|
+
* @param {ValidationError} [err]
|
|
181
336
|
* @return {o is T}
|
|
182
337
|
*/
|
|
183
|
-
check (o) {
|
|
184
|
-
|
|
338
|
+
check (o, err) {
|
|
339
|
+
const c = this.shape.some(a => a === o)
|
|
340
|
+
/* c8 ignore next */
|
|
341
|
+
!c && err?.extend(null, this.shape.join(' | '), o.toString())
|
|
342
|
+
return c
|
|
185
343
|
}
|
|
186
344
|
}
|
|
187
345
|
|
|
@@ -190,234 +348,405 @@ export class $Literal extends $Schema {
|
|
|
190
348
|
* @param {T} literals
|
|
191
349
|
* @return {CastToSchema<$Literal<T[number]>>}
|
|
192
350
|
*/
|
|
193
|
-
export const literal = (...literals) => new $Literal(literals)
|
|
351
|
+
export const $literal = (...literals) => new $Literal(literals)
|
|
352
|
+
export const $$literal = $constructedBy($Literal)
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* @template {Array<string|Schema<string|number>>} Ts
|
|
356
|
+
* @typedef {Ts extends [] ? `` : (Ts extends [infer T] ? (Unwrap<T> extends (string|number) ? Unwrap<T> : never) : (Ts extends [infer T1, ...infer Rest] ? `${Unwrap<T1> extends (string|number) ? Unwrap<T1> : never}${Rest extends Array<string|Schema<string|number>> ? CastStringTemplateArgsToTemplate<Rest> : never}` : never))} CastStringTemplateArgsToTemplate
|
|
357
|
+
*/
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @param {string} str
|
|
361
|
+
* @return {string}
|
|
362
|
+
*/
|
|
363
|
+
const _regexEscape = /** @type {any} */ (RegExp).escape || /** @type {(str:string) => string} */ (str =>
|
|
364
|
+
str.replace(/[().|&,$^[\]]/g, s => '\\' + s)
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* @param {string|Schema<any>} s
|
|
369
|
+
* @return {string[]}
|
|
370
|
+
*/
|
|
371
|
+
const _schemaStringTemplateToRegex = s => {
|
|
372
|
+
if ($string.check(s)) {
|
|
373
|
+
return [_regexEscape(s)]
|
|
374
|
+
}
|
|
375
|
+
if ($$literal.check(s)) {
|
|
376
|
+
return s.shape.map(v => v + '')
|
|
377
|
+
}
|
|
378
|
+
if ($$number.check(s)) {
|
|
379
|
+
return ['[+-]?\\d+.?\\d*']
|
|
380
|
+
}
|
|
381
|
+
if ($$string.check(s)) {
|
|
382
|
+
return ['.*']
|
|
383
|
+
}
|
|
384
|
+
if ($$union.check(s)) {
|
|
385
|
+
return s.shape.map(_schemaStringTemplateToRegex).flat(1)
|
|
386
|
+
}
|
|
387
|
+
/* c8 ignore next 2 */
|
|
388
|
+
// unexpected schema structure (only supports unions and string in literal types)
|
|
389
|
+
error.unexpectedCase()
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* @template {Array<string|Schema<string|number>>} T
|
|
394
|
+
* @extends {Schema<CastStringTemplateArgsToTemplate<T>>}
|
|
395
|
+
*/
|
|
396
|
+
export class $StringTemplate extends Schema {
|
|
397
|
+
/**
|
|
398
|
+
* @param {T} shape
|
|
399
|
+
*/
|
|
400
|
+
constructor (shape) {
|
|
401
|
+
super()
|
|
402
|
+
this.shape = shape
|
|
403
|
+
this._r = new RegExp('^' + shape.map(_schemaStringTemplateToRegex).map(opts => `(${opts.join('|')})`).join('') + '$')
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* @param {any} o
|
|
408
|
+
* @param {ValidationError} [err]
|
|
409
|
+
* @return {o is CastStringTemplateArgsToTemplate<T>}
|
|
410
|
+
*/
|
|
411
|
+
check (o, err) {
|
|
412
|
+
const c = this._r.exec(o) != null
|
|
413
|
+
/* c8 ignore next */
|
|
414
|
+
!c && err?.extend(null, this._r.toString(), o.toString(), 'String doesn\'t match string template.')
|
|
415
|
+
return c
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* @template {Array<string|Schema<string|number>>} T
|
|
421
|
+
* @param {T} literals
|
|
422
|
+
* @return {CastToSchema<$StringTemplate<T>>}
|
|
423
|
+
*/
|
|
424
|
+
export const $stringTemplate = (...literals) => new $StringTemplate(literals)
|
|
425
|
+
export const $$stringTemplate = $constructedBy($StringTemplate)
|
|
194
426
|
|
|
195
427
|
const isOptionalSymbol = Symbol('optional')
|
|
196
428
|
/**
|
|
197
|
-
* @template {
|
|
198
|
-
* @extends
|
|
429
|
+
* @template {Schema<any>} S
|
|
430
|
+
* @extends Schema<Unwrap<S>|undefined>
|
|
199
431
|
*/
|
|
200
|
-
class $Optional extends
|
|
432
|
+
class $Optional extends Schema {
|
|
201
433
|
/**
|
|
202
|
-
* @param {S}
|
|
434
|
+
* @param {S} shape
|
|
203
435
|
*/
|
|
204
|
-
constructor (
|
|
436
|
+
constructor (shape) {
|
|
205
437
|
super()
|
|
206
|
-
this.
|
|
438
|
+
this.shape = shape
|
|
207
439
|
}
|
|
208
440
|
|
|
209
441
|
/**
|
|
210
442
|
* @param {any} o
|
|
443
|
+
* @param {ValidationError} [err]
|
|
211
444
|
* @return {o is (Unwrap<S>|undefined)}
|
|
212
445
|
*/
|
|
213
|
-
check (o) {
|
|
214
|
-
|
|
446
|
+
check (o, err) {
|
|
447
|
+
const c = o === undefined || this.shape.check(o)
|
|
448
|
+
/* c8 ignore next */
|
|
449
|
+
!c && err?.extend(null, 'undefined (optional)', '()')
|
|
450
|
+
return c
|
|
215
451
|
}
|
|
216
452
|
|
|
217
453
|
get [isOptionalSymbol] () { return true }
|
|
218
454
|
}
|
|
455
|
+
export const $$optional = $constructedBy($Optional)
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* @extends Schema<never>
|
|
459
|
+
*/
|
|
460
|
+
class $Never extends Schema {
|
|
461
|
+
/**
|
|
462
|
+
* @param {any} _o
|
|
463
|
+
* @param {ValidationError} [err]
|
|
464
|
+
* @return {_o is never}
|
|
465
|
+
*/
|
|
466
|
+
check (_o, err) {
|
|
467
|
+
err?.extend(null, 'never', typeof _o)
|
|
468
|
+
return false
|
|
469
|
+
}
|
|
470
|
+
}
|
|
219
471
|
|
|
220
472
|
/**
|
|
221
|
-
* @
|
|
222
|
-
* @typedef {{ [Key in keyof S as S[Key] extends $Optional<$Schema<any>> ? Key : never]?: S[Key] extends $Optional<$Schema<infer Type>> ? Type : never } & { [Key in keyof S as S[Key] extends $Optional<$Schema<any>> ? never : Key]: S[Key] extends $Schema<infer Type> ? Type : never }} $ObjectToType
|
|
473
|
+
* @type {Schema<never>}
|
|
223
474
|
*/
|
|
475
|
+
export const $never = new $Never()
|
|
476
|
+
export const $$never = $constructedBy($Never)
|
|
224
477
|
|
|
225
478
|
/**
|
|
226
|
-
* @template {{[key:string|symbol|number]:
|
|
227
|
-
* @extends
|
|
479
|
+
* @template {{ [key: string|symbol|number]: Schema<any> }} S
|
|
480
|
+
* @typedef {{ [Key in keyof S as S[Key] extends $Optional<Schema<any>> ? Key : never]?: S[Key] extends $Optional<Schema<infer Type>> ? Type : never } & { [Key in keyof S as S[Key] extends $Optional<Schema<any>> ? never : Key]: S[Key] extends Schema<infer Type> ? Type : never }} $ObjectToType
|
|
228
481
|
*/
|
|
229
|
-
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* @template {{[key:string|symbol|number]: Schema<any>}} S
|
|
485
|
+
* @extends {Schema<$ObjectToType<S>>}
|
|
486
|
+
*/
|
|
487
|
+
export class $Object extends Schema {
|
|
230
488
|
/**
|
|
231
|
-
* @param {S}
|
|
489
|
+
* @param {S} shape
|
|
490
|
+
* @param {boolean} partial
|
|
232
491
|
*/
|
|
233
|
-
constructor (
|
|
492
|
+
constructor (shape, partial = false) {
|
|
234
493
|
super()
|
|
235
|
-
|
|
494
|
+
/**
|
|
495
|
+
* @type {S}
|
|
496
|
+
*/
|
|
497
|
+
this.shape = shape
|
|
498
|
+
this._isPartial = partial
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* @type {Schema<Partial<$ObjectToType<S>>>}
|
|
503
|
+
*/
|
|
504
|
+
get partial () {
|
|
505
|
+
return new $Object(this.shape, true)
|
|
236
506
|
}
|
|
237
507
|
|
|
238
508
|
/**
|
|
239
509
|
* @param {any} o
|
|
510
|
+
* @param {ValidationError} err
|
|
240
511
|
* @return {o is $ObjectToType<S>}
|
|
241
512
|
*/
|
|
242
|
-
check (o) {
|
|
243
|
-
|
|
513
|
+
check (o, err) {
|
|
514
|
+
if (o == null) {
|
|
515
|
+
/* c8 ignore next */
|
|
516
|
+
err?.extend(null, 'object', 'null')
|
|
517
|
+
return false
|
|
518
|
+
}
|
|
519
|
+
return obj.every(this.shape, (vv, vk) => {
|
|
520
|
+
const c = (this._isPartial && !obj.hasProperty(o, vk)) || vv.check(o[vk], err)
|
|
521
|
+
!c && err?.extend(vk.toString(), vv.toString(), typeof o[vk], 'Object property does not match')
|
|
522
|
+
return c
|
|
523
|
+
})
|
|
244
524
|
}
|
|
245
525
|
}
|
|
246
526
|
|
|
527
|
+
/**
|
|
528
|
+
* @template {{ [key:string|symbol|number]: Schema<any> }} S
|
|
529
|
+
* @typedef {Schema<{ [Key in keyof S as S[Key] extends $Optional<Schema<any>> ? Key : never]?: S[Key] extends $Optional<Schema<infer Type>> ? Type : never } & { [Key in keyof S as S[Key] extends $Optional<Schema<any>> ? never : Key]: S[Key] extends Schema<infer Type> ? Type : never }>} _ObjectDefToSchema
|
|
530
|
+
*/
|
|
531
|
+
|
|
247
532
|
// I used an explicit type annotation instead of $ObjectToType, so that the user doesn't see the
|
|
248
533
|
// weird type definitions when inspecting type definions.
|
|
249
534
|
/**
|
|
250
|
-
* @template {{ [key:string|symbol|number]:
|
|
535
|
+
* @template {{ [key:string|symbol|number]: Schema<any> }} S
|
|
251
536
|
* @param {S} def
|
|
252
|
-
* @return {
|
|
537
|
+
* @return {_ObjectDefToSchema<S> extends Schema<infer S> ? Schema<S> : never}
|
|
538
|
+
*/
|
|
539
|
+
export const $object = def => /** @type {any} */ (new $Object(def))
|
|
540
|
+
export const $$object = $constructedBy($Object)
|
|
541
|
+
/**
|
|
542
|
+
* @type {Schema<{[key:string]: any}>}
|
|
253
543
|
*/
|
|
254
|
-
export const
|
|
544
|
+
export const $objectAny = $custom(o => o != null && (o.constructor == null || o.constructor === Object))
|
|
255
545
|
|
|
256
546
|
/**
|
|
257
|
-
* @template {
|
|
258
|
-
* @template {
|
|
259
|
-
* @extends {
|
|
547
|
+
* @template {Schema<string|number|symbol>} Keys
|
|
548
|
+
* @template {Schema<any>} Values
|
|
549
|
+
* @extends {Schema<{ [key in Unwrap<Keys>]: Unwrap<Values> }>}
|
|
260
550
|
*/
|
|
261
|
-
export class $Record extends
|
|
551
|
+
export class $Record extends Schema {
|
|
262
552
|
/**
|
|
263
553
|
* @param {Keys} keys
|
|
264
554
|
* @param {Values} values
|
|
265
555
|
*/
|
|
266
556
|
constructor (keys, values) {
|
|
267
557
|
super()
|
|
268
|
-
this.
|
|
269
|
-
|
|
558
|
+
this.shape = {
|
|
559
|
+
keys, values
|
|
560
|
+
}
|
|
270
561
|
}
|
|
271
562
|
|
|
272
563
|
/**
|
|
273
564
|
* @param {any} o
|
|
274
|
-
* @
|
|
565
|
+
* @param {ValidationError} err
|
|
566
|
+
* @return {o is { [key in Unwrap<Keys>]: Unwrap<Values> }}
|
|
275
567
|
*/
|
|
276
|
-
check (o) {
|
|
277
|
-
return o != null && obj.every(o, (vv, vk) =>
|
|
568
|
+
check (o, err) {
|
|
569
|
+
return o != null && obj.every(o, (vv, vk) => {
|
|
570
|
+
const ck = this.shape.keys.check(vk, err)
|
|
571
|
+
/* c8 ignore next */
|
|
572
|
+
!ck && err?.extend(vk + '', 'Record', typeof o, ck ? 'Key doesn\'t match schema' : 'Value doesn\'t match value')
|
|
573
|
+
return ck && this.shape.values.check(vv, err)
|
|
574
|
+
})
|
|
278
575
|
}
|
|
279
576
|
}
|
|
280
577
|
|
|
281
578
|
/**
|
|
282
|
-
* @template {
|
|
283
|
-
* @template {
|
|
579
|
+
* @template {Schema<string|number|symbol>} Keys
|
|
580
|
+
* @template {Schema<any>} Values
|
|
284
581
|
* @param {Keys} keys
|
|
285
582
|
* @param {Values} values
|
|
286
583
|
* @return {CastToSchema<$Record<Keys,Values>>}
|
|
287
584
|
*/
|
|
288
|
-
export const record = (keys, values) => new $Record(keys, values)
|
|
585
|
+
export const $record = (keys, values) => new $Record(keys, values)
|
|
586
|
+
export const $$record = $constructedBy($Record)
|
|
289
587
|
|
|
290
588
|
/**
|
|
291
|
-
* @template {
|
|
292
|
-
* @extends {
|
|
589
|
+
* @template {Schema<any>[]} S
|
|
590
|
+
* @extends {Schema<{ [Key in keyof S]: S[Key] extends Schema<infer Type> ? Type : never }>}
|
|
293
591
|
*/
|
|
294
|
-
export class $Tuple extends
|
|
592
|
+
export class $Tuple extends Schema {
|
|
295
593
|
/**
|
|
296
|
-
* @param {S}
|
|
594
|
+
* @param {S} shape
|
|
297
595
|
*/
|
|
298
|
-
constructor (
|
|
596
|
+
constructor (shape) {
|
|
299
597
|
super()
|
|
300
|
-
this.
|
|
598
|
+
this.shape = shape
|
|
301
599
|
}
|
|
302
600
|
|
|
303
601
|
/**
|
|
304
602
|
* @param {any} o
|
|
305
|
-
* @
|
|
603
|
+
* @param {ValidationError} err
|
|
604
|
+
* @return {o is { [K in keyof S]: S[K] extends Schema<infer Type> ? Type : never }}
|
|
306
605
|
*/
|
|
307
|
-
check (o) {
|
|
308
|
-
return o != null && obj.every(this.
|
|
606
|
+
check (o, err) {
|
|
607
|
+
return o != null && obj.every(this.shape, (vv, vk) => {
|
|
608
|
+
const c = /** @type {Schema<any>} */ (vv).check(o[vk], err)
|
|
609
|
+
/* c8 ignore next */
|
|
610
|
+
!c && err?.extend(vk.toString(), 'Tuple', typeof vv)
|
|
611
|
+
return c
|
|
612
|
+
})
|
|
309
613
|
}
|
|
310
614
|
}
|
|
311
615
|
|
|
312
616
|
/**
|
|
313
|
-
* @template {Array
|
|
617
|
+
* @template {Array<Schema<any>>} T
|
|
314
618
|
* @param {T} def
|
|
315
619
|
* @return {CastToSchema<$Tuple<T>>}
|
|
316
620
|
*/
|
|
317
|
-
export const tuple = (...def) => new $Tuple(def)
|
|
621
|
+
export const $tuple = (...def) => new $Tuple(def)
|
|
622
|
+
export const $$tuple = $constructedBy($Tuple)
|
|
318
623
|
|
|
319
624
|
/**
|
|
320
|
-
* @template {
|
|
321
|
-
* @extends {
|
|
625
|
+
* @template {Schema<any>} S
|
|
626
|
+
* @extends {Schema<Array<S extends Schema<infer T> ? T : never>>}
|
|
322
627
|
*/
|
|
323
|
-
export class $Array extends
|
|
628
|
+
export class $Array extends Schema {
|
|
324
629
|
/**
|
|
325
630
|
* @param {Array<S>} v
|
|
326
631
|
*/
|
|
327
632
|
constructor (v) {
|
|
328
633
|
super()
|
|
329
634
|
/**
|
|
330
|
-
* @type {
|
|
635
|
+
* @type {Schema<S extends Schema<infer T> ? T : never>}
|
|
331
636
|
*/
|
|
332
|
-
this.
|
|
637
|
+
this.shape = v.length === 1 ? v[0] : new $Union(v)
|
|
333
638
|
}
|
|
334
639
|
|
|
335
640
|
/**
|
|
336
641
|
* @param {any} o
|
|
337
|
-
* @
|
|
642
|
+
* @param {ValidationError} [err]
|
|
643
|
+
* @return {o is Array<S extends Schema<infer T> ? T : never>} o
|
|
338
644
|
*/
|
|
339
|
-
check (o) {
|
|
340
|
-
|
|
645
|
+
check (o, err) {
|
|
646
|
+
const c = arr.isArray(o) && arr.every(o, oi => this.shape.check(oi))
|
|
647
|
+
/* c8 ignore next */
|
|
648
|
+
!c && err?.extend(null, 'Array', '')
|
|
649
|
+
return c
|
|
341
650
|
}
|
|
342
651
|
}
|
|
343
652
|
|
|
344
653
|
/**
|
|
345
|
-
* @template {Array
|
|
654
|
+
* @template {Array<Schema<any>>} T
|
|
346
655
|
* @param {T} def
|
|
347
|
-
* @return {
|
|
656
|
+
* @return {Schema<Array<T extends Array<Schema<infer S>> ? S : never>>}
|
|
657
|
+
*/
|
|
658
|
+
export const $array = (...def) => new $Array(def)
|
|
659
|
+
export const $$array = $constructedBy($Array)
|
|
660
|
+
/**
|
|
661
|
+
* @type {Schema<Array<any>>}
|
|
348
662
|
*/
|
|
349
|
-
export const
|
|
663
|
+
export const $arrayAny = $custom(o => arr.isArray(o))
|
|
350
664
|
|
|
351
665
|
/**
|
|
352
666
|
* @template T
|
|
353
|
-
* @extends {
|
|
667
|
+
* @extends {Schema<T>}
|
|
354
668
|
*/
|
|
355
|
-
export class $InstanceOf extends
|
|
669
|
+
export class $InstanceOf extends Schema {
|
|
356
670
|
/**
|
|
357
671
|
* @param {new (...args:any) => T} constructor
|
|
672
|
+
* @param {((o:T) => boolean)|null} check
|
|
358
673
|
*/
|
|
359
|
-
constructor (constructor) {
|
|
674
|
+
constructor (constructor, check) {
|
|
360
675
|
super()
|
|
361
|
-
this.
|
|
676
|
+
this.shape = constructor
|
|
677
|
+
this._c = check
|
|
362
678
|
}
|
|
363
679
|
|
|
364
680
|
/**
|
|
365
681
|
* @param {any} o
|
|
682
|
+
* @param {ValidationError} err
|
|
366
683
|
* @return {o is T}
|
|
367
684
|
*/
|
|
368
|
-
check (o) {
|
|
369
|
-
|
|
685
|
+
check (o, err) {
|
|
686
|
+
const c = o instanceof this.shape && (this._c == null || this._c(o))
|
|
687
|
+
/* c8 ignore next */
|
|
688
|
+
!c && err?.extend(null, this.shape.name, o?.constructor.name)
|
|
689
|
+
return c
|
|
370
690
|
}
|
|
371
691
|
}
|
|
372
692
|
|
|
373
693
|
/**
|
|
374
694
|
* @template T
|
|
375
695
|
* @param {new (...args:any) => T} c
|
|
376
|
-
* @
|
|
696
|
+
* @param {((o:T) => boolean)|null} check
|
|
697
|
+
* @return {Schema<T>}
|
|
377
698
|
*/
|
|
378
|
-
export const
|
|
699
|
+
export const $instanceOf = (c, check = null) => new $InstanceOf(c, check)
|
|
700
|
+
export const $$instanceOf = $constructedBy($InstanceOf)
|
|
701
|
+
|
|
702
|
+
export const $$schema = $instanceOf(Schema)
|
|
379
703
|
|
|
380
704
|
/**
|
|
381
|
-
* @template {
|
|
705
|
+
* @template {Schema<any>[]} Args
|
|
382
706
|
* @typedef {(...args:UnwrapArray<TuplePop<Args>>)=>Unwrap<TupleLast<Args>>} _LArgsToLambdaDef
|
|
383
707
|
*/
|
|
384
708
|
|
|
385
709
|
/**
|
|
386
|
-
* @template {Array
|
|
387
|
-
* @extends {
|
|
710
|
+
* @template {Array<Schema<any>>} Args
|
|
711
|
+
* @extends {Schema<_LArgsToLambdaDef<Args>>}
|
|
388
712
|
*/
|
|
389
|
-
export class $Lambda extends
|
|
713
|
+
export class $Lambda extends Schema {
|
|
390
714
|
/**
|
|
391
715
|
* @param {Args} args
|
|
392
716
|
*/
|
|
393
717
|
constructor (args) {
|
|
394
718
|
super()
|
|
395
719
|
this.len = args.length - 1
|
|
396
|
-
this.args = tuple(...args.slice(-1))
|
|
720
|
+
this.args = $tuple(...args.slice(-1))
|
|
397
721
|
this.res = args[this.len]
|
|
398
722
|
}
|
|
399
723
|
|
|
400
724
|
/**
|
|
401
725
|
* @param {any} f
|
|
726
|
+
* @param {ValidationError} err
|
|
402
727
|
* @return {f is _LArgsToLambdaDef<Args>}
|
|
403
728
|
*/
|
|
404
|
-
check (f) {
|
|
405
|
-
|
|
729
|
+
check (f, err) {
|
|
730
|
+
const c = f.constructor === Function && f.length <= this.len
|
|
731
|
+
/* c8 ignore next */
|
|
732
|
+
!c && err?.extend(null, 'function', typeof f)
|
|
733
|
+
return c
|
|
406
734
|
}
|
|
407
735
|
}
|
|
408
736
|
|
|
409
737
|
/**
|
|
410
|
-
* @template {
|
|
738
|
+
* @template {Schema<any>[]} Args
|
|
411
739
|
* @param {Args} args
|
|
412
|
-
* @return {
|
|
740
|
+
* @return {Schema<(...args:UnwrapArray<TuplePop<Args>>)=>Unwrap<TupleLast<Args>>>}
|
|
413
741
|
*/
|
|
414
|
-
export const lambda = (...args) => new $Lambda(args.length > 0 ? args : [
|
|
742
|
+
export const $lambda = (...args) => new $Lambda(args.length > 0 ? args : [$void])
|
|
743
|
+
export const $$lambda = $constructedBy($Lambda)
|
|
415
744
|
|
|
416
745
|
/**
|
|
417
|
-
* @template {Array
|
|
418
|
-
* @extends {
|
|
746
|
+
* @template {Array<Schema<any>>} T
|
|
747
|
+
* @extends {Schema<Intersect<UnwrapArray<T>>>}
|
|
419
748
|
*/
|
|
420
|
-
export class $Intersection extends
|
|
749
|
+
export class $Intersection extends Schema {
|
|
421
750
|
/**
|
|
422
751
|
* @param {T} v
|
|
423
752
|
*/
|
|
@@ -426,111 +755,154 @@ export class $Intersection extends $Schema {
|
|
|
426
755
|
/**
|
|
427
756
|
* @type {T}
|
|
428
757
|
*/
|
|
429
|
-
this.
|
|
758
|
+
this.shape = v
|
|
430
759
|
}
|
|
431
760
|
|
|
432
761
|
/**
|
|
433
762
|
* @param {any} o
|
|
763
|
+
* @param {ValidationError} [err]
|
|
434
764
|
* @return {o is Intersect<UnwrapArray<T>>}
|
|
435
765
|
*/
|
|
436
|
-
check (o) {
|
|
766
|
+
check (o, err) {
|
|
437
767
|
// @ts-ignore
|
|
438
|
-
|
|
768
|
+
const c = arr.every(this.shape, check => check.check(o, err))
|
|
769
|
+
/* c8 ignore next */
|
|
770
|
+
!c && err?.extend(null, 'Intersectinon', typeof o)
|
|
771
|
+
return c
|
|
439
772
|
}
|
|
440
773
|
}
|
|
441
774
|
|
|
442
775
|
/**
|
|
443
|
-
* @template {
|
|
776
|
+
* @template {Schema<any>[]} T
|
|
444
777
|
* @param {T} def
|
|
445
778
|
* @return {CastToSchema<$Intersection<T>>}
|
|
446
779
|
*/
|
|
447
|
-
export const intersect = (...def) => new $Intersection(def)
|
|
780
|
+
export const $intersect = (...def) => new $Intersection(def)
|
|
781
|
+
export const $$intersect = $constructedBy($Intersection, o => o.shape.length > 0) // Intersection with length=0 is considered "any"
|
|
448
782
|
|
|
449
783
|
/**
|
|
450
784
|
* @template S
|
|
451
|
-
* @extends {
|
|
785
|
+
* @extends {Schema<S>}
|
|
452
786
|
*/
|
|
453
|
-
export class $Union extends
|
|
787
|
+
export class $Union extends Schema {
|
|
788
|
+
static _dilutes = true
|
|
789
|
+
|
|
454
790
|
/**
|
|
455
|
-
* @param {Array
|
|
791
|
+
* @param {Array<Schema<S>>} v
|
|
456
792
|
*/
|
|
457
793
|
constructor (v) {
|
|
458
794
|
super()
|
|
459
|
-
this.
|
|
795
|
+
this.shape = v
|
|
460
796
|
}
|
|
461
797
|
|
|
462
798
|
/**
|
|
463
799
|
* @param {any} o
|
|
800
|
+
* @param {ValidationError} [err]
|
|
464
801
|
* @return {o is S}
|
|
465
802
|
*/
|
|
466
|
-
check (o) {
|
|
467
|
-
|
|
803
|
+
check (o, err) {
|
|
804
|
+
const c = arr.some(this.shape, (vv) => vv.check(o, err))
|
|
805
|
+
err?.extend(null, 'Union', typeof o)
|
|
806
|
+
return c
|
|
468
807
|
}
|
|
469
|
-
|
|
470
|
-
static schema = constructedBy($Union)
|
|
471
808
|
}
|
|
472
809
|
|
|
473
810
|
/**
|
|
474
|
-
* @template {Array
|
|
475
|
-
* @param {T}
|
|
476
|
-
* @return {CastToSchema<$Union<T extends [] ? never : (T extends Array
|
|
811
|
+
* @template {Array<Schema<any>>} T
|
|
812
|
+
* @param {T} schemas
|
|
813
|
+
* @return {CastToSchema<$Union<T extends [] ? never : (T extends Array<Schema<infer S>> ? S : never)>>}
|
|
477
814
|
*/
|
|
478
|
-
export const union = (...
|
|
815
|
+
export const $union = (...schemas) => $$union.check(schemas[0]) ? new $Union([...schemas[0].shape, ...schemas.slice(1)]) : (schemas.length === 1 ? schemas[0] : new $Union(schemas))
|
|
816
|
+
export const $$union = /** @type {Schema<$Union<any>>} */ ($constructedBy($Union))
|
|
479
817
|
|
|
818
|
+
const _t = () => true
|
|
480
819
|
/**
|
|
481
|
-
* @type {
|
|
820
|
+
* @type {Schema<any>}
|
|
482
821
|
*/
|
|
483
|
-
export const any =
|
|
822
|
+
export const $any = $custom(_t)
|
|
823
|
+
export const $$any = /** @type {Schema<Schema<any>>} */ ($constructedBy($Custom, o => o.shape === _t))
|
|
484
824
|
|
|
485
825
|
/**
|
|
486
|
-
* @type {
|
|
826
|
+
* @type {Schema<bigint>}
|
|
487
827
|
*/
|
|
488
|
-
export const bigint = constructedBy(BigInt)
|
|
828
|
+
export const $bigint = $constructedBy(BigInt)
|
|
829
|
+
export const $$bigint = /** @type {Schema<Schema<BigInt>>} */ ($constructedBy($ConstructedBy, o => o.shape === BigInt))
|
|
489
830
|
|
|
490
831
|
/**
|
|
491
|
-
* @type {
|
|
832
|
+
* @type {Schema<Symbol>}
|
|
492
833
|
*/
|
|
493
|
-
export const symbol = constructedBy(Symbol)
|
|
834
|
+
export const $symbol = $constructedBy(Symbol)
|
|
835
|
+
export const $$symbol = /** @type {Schema<Schema<Symbol>>} */ ($constructedBy($ConstructedBy, o => o.shape === Symbol))
|
|
494
836
|
|
|
495
837
|
/**
|
|
496
|
-
* @type {
|
|
838
|
+
* @type {Schema<number>}
|
|
497
839
|
*/
|
|
498
|
-
export const number = constructedBy(Number)
|
|
840
|
+
export const $number = $constructedBy(Number)
|
|
841
|
+
export const $$number = /** @type {Schema<Schema<number>>} */ ($constructedBy($ConstructedBy, o => o.shape === Number))
|
|
499
842
|
|
|
500
843
|
/**
|
|
501
|
-
* @type {
|
|
844
|
+
* @type {Schema<string>}
|
|
502
845
|
*/
|
|
503
|
-
export const string = constructedBy(String)
|
|
846
|
+
export const $string = $constructedBy(String)
|
|
847
|
+
export const $$string = /** @type {Schema<Schema<string>>} */ ($constructedBy($ConstructedBy, o => o.shape === String))
|
|
504
848
|
|
|
505
849
|
/**
|
|
506
|
-
* @type {
|
|
850
|
+
* @type {Schema<boolean>}
|
|
507
851
|
*/
|
|
508
|
-
const
|
|
852
|
+
export const $boolean = $constructedBy(Boolean)
|
|
853
|
+
export const $$boolean = /** @type {Schema<Schema<Boolean>>} */ ($constructedBy($ConstructedBy, o => o.shape === Boolean))
|
|
509
854
|
|
|
510
855
|
/**
|
|
511
|
-
* @type {
|
|
856
|
+
* @type {Schema<undefined>}
|
|
512
857
|
*/
|
|
513
|
-
const
|
|
858
|
+
export const $undefined = $literal(undefined)
|
|
859
|
+
export const $$undefined = /** @type {Schema<Schema<undefined>>} */ ($constructedBy($Literal, o => o.shape.length === 1 && o.shape[0] === undefined))
|
|
514
860
|
|
|
515
861
|
/**
|
|
516
|
-
* @type {
|
|
862
|
+
* @type {Schema<void>}
|
|
517
863
|
*/
|
|
518
|
-
const
|
|
864
|
+
export const $void = $literal(undefined)
|
|
865
|
+
export const $$void = /** @type {Schema<Schema<void>>} */ ($$undefined)
|
|
519
866
|
|
|
520
|
-
export
|
|
867
|
+
export const $null = $literal(null)
|
|
868
|
+
export const $$null = /** @type {Schema<Schema<null>>} */ ($constructedBy($Literal, o => o.shape.length === 1 && o.shape[0] === null))
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* @type {Schema<number|string|null|boolean>}
|
|
872
|
+
*/
|
|
873
|
+
export const $primitive = $union($number, $string, $null, $boolean)
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* @typedef {JSON[]} JSONArray
|
|
877
|
+
*/
|
|
878
|
+
/**
|
|
879
|
+
* @typedef {Unwrap<$primitive>|JSONArray|{ [key:string]:JSON }} JSON
|
|
880
|
+
*/
|
|
881
|
+
/**
|
|
882
|
+
* @type {Schema<null|number|string|boolean|JSON[]|{[key:string]:JSON}>}
|
|
883
|
+
*/
|
|
884
|
+
export const $json = (() => {
|
|
885
|
+
const $jsonArr = /** @type {$Array<$any>} */ ($array($any))
|
|
886
|
+
const $jsonRecord = /** @type {$Record<$string,$any>} */ ($record($string, $any))
|
|
887
|
+
const $json = $union($number, $string, $null, $boolean, $jsonArr, $jsonRecord)
|
|
888
|
+
$jsonArr.shape = $json
|
|
889
|
+
$jsonRecord.shape.values = $json
|
|
890
|
+
return $json
|
|
891
|
+
})()
|
|
521
892
|
|
|
522
893
|
/* c8 ignore start */
|
|
523
894
|
/**
|
|
524
895
|
* Assert that a variable is of this specific type.
|
|
525
896
|
* The assertion check is only performed in non-production environments.
|
|
526
897
|
*
|
|
527
|
-
* @type {<T>(o:any,schema
|
|
898
|
+
* @type {<T>(o:any,schema:Schema<T>) => asserts o is T}
|
|
528
899
|
*/
|
|
529
900
|
export const assert = env.production
|
|
530
901
|
? () => {}
|
|
531
902
|
: (o, schema) => {
|
|
532
|
-
|
|
533
|
-
|
|
903
|
+
const err = new ValidationError()
|
|
904
|
+
if (!schema.check(o, err)) {
|
|
905
|
+
throw error.create(`Expected value to be of type ${schema.constructor.name}.\n${err.toString()}`)
|
|
534
906
|
}
|
|
535
907
|
}
|
|
536
908
|
/* c8 ignore end */
|