@atproto/lex-schema 0.1.5 → 0.1.6
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 +14 -0
- package/dist/core/$type.d.ts +2 -2
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js.map +1 -1
- package/dist/core/record-key.d.ts +1 -1
- package/dist/core/record-key.d.ts.map +1 -1
- package/dist/core/record-key.js.map +1 -1
- package/dist/core/schema.d.ts +3 -2
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +1 -1
- package/dist/core/schema.js.map +1 -1
- package/dist/core/standard-schema.d.ts +2 -2
- package/dist/core/standard-schema.d.ts.map +1 -1
- package/dist/core/standard-schema.js.map +1 -1
- package/dist/core/string-format.d.ts +2 -2
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/validation-error.d.ts +1 -1
- package/dist/core/validation-error.d.ts.map +1 -1
- package/dist/core/validation-error.js +1 -1
- package/dist/core/validation-error.js.map +1 -1
- package/dist/core/validator.d.ts +1 -1
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +1 -1
- package/dist/core/validator.js.map +1 -1
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +2 -2
- package/dist/helpers.js.map +1 -1
- package/dist/schema/array.d.ts +1 -1
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +1 -1
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +1 -1
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +2 -2
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.js +1 -1
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.js +1 -1
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +1 -1
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +3 -3
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.js +1 -1
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +1 -1
- package/dist/schema/dict.d.ts.map +1 -1
- package/dist/schema/dict.js +1 -1
- package/dist/schema/dict.js.map +1 -1
- package/dist/schema/discriminated-union.d.ts +1 -1
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +2 -1
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.js +1 -1
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.js +1 -1
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +1 -1
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +3 -1
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/lex-map.d.ts +1 -1
- package/dist/schema/lex-map.d.ts.map +1 -1
- package/dist/schema/lex-map.js +1 -1
- package/dist/schema/lex-map.js.map +1 -1
- package/dist/schema/lex-value.d.ts +1 -1
- package/dist/schema/lex-value.d.ts.map +1 -1
- package/dist/schema/lex-value.js +1 -1
- package/dist/schema/lex-value.js.map +1 -1
- package/dist/schema/literal.js +1 -1
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.js +1 -1
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.js +1 -1
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +1 -1
- package/dist/schema/nullable.d.ts.map +1 -1
- package/dist/schema/nullable.js +1 -1
- package/dist/schema/nullable.js.map +1 -1
- package/dist/schema/object.d.ts +2 -1
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +1 -1
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +2 -1
- package/dist/schema/optional.d.ts.map +1 -1
- package/dist/schema/optional.js +2 -1
- package/dist/schema/optional.js.map +1 -1
- package/dist/schema/params.d.ts +1 -1
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +1 -1
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +3 -2
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +2 -1
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +1 -1
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +1 -0
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +1 -1
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +1 -1
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +2 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +1 -1
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +2 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +2 -2
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +1 -1
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +1 -1
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +1 -1
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +2 -2
- package/dist/schema/refine.d.ts.map +1 -1
- package/dist/schema/refine.js +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/regexp.js +1 -1
- package/dist/schema/regexp.js.map +1 -1
- package/dist/schema/string.d.ts +2 -2
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +1 -1
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +3 -2
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js +2 -0
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +1 -1
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +1 -1
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +2 -2
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +1 -1
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +1 -1
- package/dist/schema/typed-ref.d.ts.map +1 -1
- package/dist/schema/typed-ref.js +1 -1
- package/dist/schema/typed-ref.js.map +1 -1
- package/dist/schema/typed-union.d.ts +1 -1
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +3 -1
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +1 -1
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +1 -1
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown.js +1 -1
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema/with-default.d.ts +1 -1
- package/dist/schema/with-default.d.ts.map +1 -1
- package/dist/schema/with-default.js +1 -1
- package/dist/schema/with-default.js.map +1 -1
- package/package.json +6 -10
- package/src/core/$type.test.ts +0 -24
- package/src/core/$type.ts +0 -199
- package/src/core/record-key.ts +0 -85
- package/src/core/result.ts +0 -15
- package/src/core/schema.ts +0 -412
- package/src/core/standard-schema.test.ts +0 -124
- package/src/core/standard-schema.ts +0 -31
- package/src/core/string-format.ts +0 -411
- package/src/core/types.ts +0 -120
- package/src/core/validation-error.ts +0 -134
- package/src/core/validation-issue.ts +0 -340
- package/src/core/validator.ts +0 -636
- package/src/core.ts +0 -9
- package/src/external.ts +0 -3
- package/src/helpers.test.ts +0 -694
- package/src/helpers.ts +0 -222
- package/src/index.ts +0 -3
- package/src/schema/array.test.ts +0 -251
- package/src/schema/array.ts +0 -126
- package/src/schema/blob.test.ts +0 -733
- package/src/schema/blob.ts +0 -150
- package/src/schema/boolean.test.ts +0 -118
- package/src/schema/boolean.ts +0 -46
- package/src/schema/bytes.test.ts +0 -227
- package/src/schema/bytes.ts +0 -81
- package/src/schema/cid.test.ts +0 -125
- package/src/schema/cid.ts +0 -69
- package/src/schema/custom.test.ts +0 -414
- package/src/schema/custom.ts +0 -106
- package/src/schema/dict.test.ts +0 -181
- package/src/schema/dict.ts +0 -122
- package/src/schema/discriminated-union.test.ts +0 -676
- package/src/schema/discriminated-union.ts +0 -196
- package/src/schema/enum.test.ts +0 -398
- package/src/schema/enum.ts +0 -77
- package/src/schema/integer.test.ts +0 -314
- package/src/schema/integer.ts +0 -86
- package/src/schema/intersection.test.ts +0 -33
- package/src/schema/intersection.ts +0 -113
- package/src/schema/lex-map.test.ts +0 -593
- package/src/schema/lex-map.ts +0 -63
- package/src/schema/lex-value.test.ts +0 -81
- package/src/schema/lex-value.ts +0 -86
- package/src/schema/literal.test.ts +0 -533
- package/src/schema/literal.ts +0 -70
- package/src/schema/never.test.ts +0 -175
- package/src/schema/never.ts +0 -56
- package/src/schema/null.test.ts +0 -80
- package/src/schema/null.ts +0 -49
- package/src/schema/nullable.test.ts +0 -470
- package/src/schema/nullable.ts +0 -74
- package/src/schema/object.test.ts +0 -69
- package/src/schema/object.ts +0 -136
- package/src/schema/optional.test.ts +0 -479
- package/src/schema/optional.ts +0 -92
- package/src/schema/params.test.ts +0 -1118
- package/src/schema/params.ts +0 -371
- package/src/schema/payload.test.ts +0 -340
- package/src/schema/payload.ts +0 -204
- package/src/schema/permission-set.test.ts +0 -613
- package/src/schema/permission-set.ts +0 -86
- package/src/schema/permission.test.ts +0 -537
- package/src/schema/permission.ts +0 -63
- package/src/schema/procedure.test.ts +0 -324
- package/src/schema/procedure.ts +0 -98
- package/src/schema/query.test.ts +0 -348
- package/src/schema/query.ts +0 -86
- package/src/schema/record.test.ts +0 -812
- package/src/schema/record.ts +0 -217
- package/src/schema/ref.test.ts +0 -349
- package/src/schema/ref.ts +0 -103
- package/src/schema/refine.test.ts +0 -579
- package/src/schema/refine.ts +0 -153
- package/src/schema/regexp.test.ts +0 -577
- package/src/schema/regexp.ts +0 -82
- package/src/schema/string.test.ts +0 -773
- package/src/schema/string.ts +0 -229
- package/src/schema/subscription.test.ts +0 -499
- package/src/schema/subscription.ts +0 -108
- package/src/schema/token.test.ts +0 -152
- package/src/schema/token.ts +0 -103
- package/src/schema/typed-object.test.ts +0 -745
- package/src/schema/typed-object.ts +0 -181
- package/src/schema/typed-ref.test.ts +0 -796
- package/src/schema/typed-ref.ts +0 -126
- package/src/schema/typed-union.test.ts +0 -355
- package/src/schema/typed-union.ts +0 -130
- package/src/schema/union.test.ts +0 -191
- package/src/schema/union.ts +0 -89
- package/src/schema/unknown.test.ts +0 -313
- package/src/schema/unknown.ts +0 -47
- package/src/schema/with-default.ts +0 -81
- package/src/schema.ts +0 -43
- package/src/util/array-agg.test.ts +0 -42
- package/src/util/array-agg.ts +0 -44
- package/src/util/assertion-util.ts +0 -1
- package/src/util/if-any.ts +0 -3
- package/src/util/lazy-property.ts +0 -14
- package/src/util/memoize.ts +0 -37
- package/tsconfig.build.json +0 -12
- package/tsconfig.json +0 -7
- package/tsconfig.tests.json +0 -8
package/src/schema/union.test.ts
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { boolean } from './boolean.js'
|
|
3
|
-
import { integer } from './integer.js'
|
|
4
|
-
import { object } from './object.js'
|
|
5
|
-
import { string } from './string.js'
|
|
6
|
-
import { union } from './union.js'
|
|
7
|
-
|
|
8
|
-
describe('UnionSchema', () => {
|
|
9
|
-
const stringOrNumber = union([string(), integer()])
|
|
10
|
-
|
|
11
|
-
it('validates string input', () => {
|
|
12
|
-
const result = stringOrNumber.safeParse('hello')
|
|
13
|
-
expect(result.success).toBe(true)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('validates number input', () => {
|
|
17
|
-
const result = stringOrNumber.safeParse(42)
|
|
18
|
-
expect(result.success).toBe(true)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('rejects boolean input', () => {
|
|
22
|
-
const result = stringOrNumber.safeParse(true)
|
|
23
|
-
expect(result.success).toBe(false)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('rejects null input', () => {
|
|
27
|
-
const result = stringOrNumber.safeParse(null)
|
|
28
|
-
expect(result.success).toBe(false)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('rejects undefined input', () => {
|
|
32
|
-
const result = stringOrNumber.safeParse(undefined)
|
|
33
|
-
expect(result.success).toBe(false)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('rejects object input when not in union', () => {
|
|
37
|
-
const result = stringOrNumber.safeParse({ key: 'value' })
|
|
38
|
-
expect(result.success).toBe(false)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('rejects array input when not in union', () => {
|
|
42
|
-
const result = stringOrNumber.safeParse([1, 2, 3])
|
|
43
|
-
expect(result.success).toBe(false)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
describe('with object types', () => {
|
|
47
|
-
const schema = union([
|
|
48
|
-
object({
|
|
49
|
-
type: string(),
|
|
50
|
-
name: string(),
|
|
51
|
-
}),
|
|
52
|
-
object({
|
|
53
|
-
type: string(),
|
|
54
|
-
age: integer(),
|
|
55
|
-
}),
|
|
56
|
-
])
|
|
57
|
-
|
|
58
|
-
it('validates first object variant', () => {
|
|
59
|
-
const result = schema.safeParse({
|
|
60
|
-
type: 'person',
|
|
61
|
-
name: 'Alice',
|
|
62
|
-
})
|
|
63
|
-
expect(result.success).toBe(true)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('validates second object variant', () => {
|
|
67
|
-
const result = schema.safeParse({
|
|
68
|
-
type: 'record',
|
|
69
|
-
age: 30,
|
|
70
|
-
})
|
|
71
|
-
expect(result.success).toBe(true)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
it('rejects object missing required properties', () => {
|
|
75
|
-
const result = schema.safeParse({
|
|
76
|
-
type: 'person',
|
|
77
|
-
})
|
|
78
|
-
expect(result.success).toBe(false)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('rejects object with invalid property types', () => {
|
|
82
|
-
const result = schema.safeParse({
|
|
83
|
-
type: 'record',
|
|
84
|
-
age: 'thirty',
|
|
85
|
-
})
|
|
86
|
-
expect(result.success).toBe(false)
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
describe('with three types', () => {
|
|
91
|
-
const schema = union([string(), integer(), boolean()])
|
|
92
|
-
|
|
93
|
-
it('validates string input', () => {
|
|
94
|
-
const result = schema.safeParse('text')
|
|
95
|
-
expect(result.success).toBe(true)
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it('validates number input', () => {
|
|
99
|
-
const result = schema.safeParse(123)
|
|
100
|
-
expect(result.success).toBe(true)
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('validates boolean input', () => {
|
|
104
|
-
const result = schema.safeParse(false)
|
|
105
|
-
expect(result.success).toBe(true)
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
it('rejects null input', () => {
|
|
109
|
-
const result = schema.safeParse(null)
|
|
110
|
-
expect(result.success).toBe(false)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('rejects array input', () => {
|
|
114
|
-
const result = schema.safeParse([])
|
|
115
|
-
expect(result.success).toBe(false)
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
describe('with constrained types', () => {
|
|
120
|
-
const schema = union([string({ minLength: 5 }), integer({ minimum: 100 })])
|
|
121
|
-
|
|
122
|
-
it('validates string meeting constraint', () => {
|
|
123
|
-
const result = schema.safeParse('hello')
|
|
124
|
-
expect(result.success).toBe(true)
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('validates number meeting constraint', () => {
|
|
128
|
-
const result = schema.safeParse(150)
|
|
129
|
-
expect(result.success).toBe(true)
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
it('rejects string not meeting constraint', () => {
|
|
133
|
-
const result = schema.safeParse('hi')
|
|
134
|
-
expect(result.success).toBe(false)
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('rejects number not meeting constraint', () => {
|
|
138
|
-
const result = schema.safeParse(50)
|
|
139
|
-
expect(result.success).toBe(false)
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('validates first matching type even if later types could match', () => {
|
|
143
|
-
const result = schema.safeParse('valid')
|
|
144
|
-
expect(result.success).toBe(true)
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
describe('edge cases', () => {
|
|
149
|
-
it('validates with single type in union', () => {
|
|
150
|
-
const schema = union([string()])
|
|
151
|
-
const result = schema.safeParse('test')
|
|
152
|
-
expect(result.success).toBe(true)
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
it('rejects when single type in union does not match', () => {
|
|
156
|
-
const schema = union([string()])
|
|
157
|
-
const result = schema.safeParse(123)
|
|
158
|
-
expect(result.success).toBe(false)
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
it('validates empty string', () => {
|
|
162
|
-
const result = stringOrNumber.safeParse('')
|
|
163
|
-
expect(result.success).toBe(true)
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it('validates zero', () => {
|
|
167
|
-
const result = stringOrNumber.safeParse(0)
|
|
168
|
-
expect(result.success).toBe(true)
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
it('validates negative numbers', () => {
|
|
172
|
-
const result = stringOrNumber.safeParse(-42)
|
|
173
|
-
expect(result.success).toBe(true)
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
it('rejects NaN', () => {
|
|
177
|
-
const result = stringOrNumber.safeParse(NaN)
|
|
178
|
-
expect(result.success).toBe(false)
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
it('rejects Infinity', () => {
|
|
182
|
-
const result = stringOrNumber.safeParse(Infinity)
|
|
183
|
-
expect(result.success).toBe(false)
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
it('rejects -Infinity', () => {
|
|
187
|
-
const result = stringOrNumber.safeParse(-Infinity)
|
|
188
|
-
expect(result.success).toBe(false)
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
})
|
package/src/schema/union.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
InferInput,
|
|
3
|
-
InferOutput,
|
|
4
|
-
Issue,
|
|
5
|
-
LexValidationError,
|
|
6
|
-
Schema,
|
|
7
|
-
ValidationContext,
|
|
8
|
-
Validator,
|
|
9
|
-
} from '../core.js'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Type representing a non-empty tuple of validators for union schemas.
|
|
13
|
-
*
|
|
14
|
-
* Requires at least one validator in the tuple.
|
|
15
|
-
*/
|
|
16
|
-
export type UnionSchemaValidators = readonly [Validator, ...Validator[]]
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Schema for validating values that match one of several possible schemas.
|
|
20
|
-
*
|
|
21
|
-
* Tries each validator in order until one succeeds. If all validators fail,
|
|
22
|
-
* returns a combined error from all attempts.
|
|
23
|
-
*
|
|
24
|
-
* @template TValidators - Tuple type of the validators in the union
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* const schema = new UnionSchema([l.string(), l.integer()])
|
|
29
|
-
* schema.validate('hello') // success
|
|
30
|
-
* schema.validate(42) // success
|
|
31
|
-
* schema.validate(true) // fails
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
export class UnionSchema<
|
|
35
|
-
const TValidators extends UnionSchemaValidators = any,
|
|
36
|
-
> extends Schema<
|
|
37
|
-
InferInput<TValidators[number]>,
|
|
38
|
-
InferOutput<TValidators[number]>
|
|
39
|
-
> {
|
|
40
|
-
readonly type = 'union' as const
|
|
41
|
-
|
|
42
|
-
constructor(protected readonly validators: TValidators) {
|
|
43
|
-
super()
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
47
|
-
const issues: Issue[] = []
|
|
48
|
-
|
|
49
|
-
for (const validator of this.validators) {
|
|
50
|
-
const result = ctx.validate(input, validator)
|
|
51
|
-
if (result.success) return result
|
|
52
|
-
|
|
53
|
-
issues.push(...result.issues)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return new LexValidationError(issues)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Creates a union schema that accepts values matching any of the provided schemas.
|
|
62
|
-
*
|
|
63
|
-
* Validators are tried in order. Use `discriminatedUnion()` for better
|
|
64
|
-
* performance when discriminating on a known property.
|
|
65
|
-
*
|
|
66
|
-
* @param validators - Non-empty array of validators to try
|
|
67
|
-
* @returns A new {@link UnionSchema} instance
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```ts
|
|
71
|
-
* // String or number
|
|
72
|
-
* const stringOrNumber = l.union([l.string(), l.integer()])
|
|
73
|
-
*
|
|
74
|
-
* // Nullable value
|
|
75
|
-
* const nullableString = l.union([l.string(), l.null()])
|
|
76
|
-
*
|
|
77
|
-
* // Multiple object types
|
|
78
|
-
* const mediaSchema = l.union([
|
|
79
|
-
* l.object({ type: l.literal('image'), url: l.string() }),
|
|
80
|
-
* l.object({ type: l.literal('video'), url: l.string(), duration: l.integer() }),
|
|
81
|
-
* ])
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
84
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
85
|
-
export function union<const TValidators extends UnionSchemaValidators>(
|
|
86
|
-
validators: TValidators,
|
|
87
|
-
) {
|
|
88
|
-
return new UnionSchema<TValidators>(validators)
|
|
89
|
-
}
|
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { unknown } from './unknown.js'
|
|
3
|
-
|
|
4
|
-
describe('UnknownSchema', () => {
|
|
5
|
-
describe('basic validation', () => {
|
|
6
|
-
const schema = unknown()
|
|
7
|
-
|
|
8
|
-
it('accepts strings', () => {
|
|
9
|
-
const result = schema.safeParse('hello')
|
|
10
|
-
expect(result.success).toBe(true)
|
|
11
|
-
if (result.success) {
|
|
12
|
-
expect(result.value).toBe('hello')
|
|
13
|
-
}
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('accepts numbers', () => {
|
|
17
|
-
const result = schema.safeParse(42)
|
|
18
|
-
expect(result.success).toBe(true)
|
|
19
|
-
if (result.success) {
|
|
20
|
-
expect(result.value).toBe(42)
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('accepts booleans', () => {
|
|
25
|
-
const result = schema.safeParse(true)
|
|
26
|
-
expect(result.success).toBe(true)
|
|
27
|
-
if (result.success) {
|
|
28
|
-
expect(result.value).toBe(true)
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('accepts null', () => {
|
|
33
|
-
const result = schema.safeParse(null)
|
|
34
|
-
expect(result.success).toBe(true)
|
|
35
|
-
if (result.success) {
|
|
36
|
-
expect(result.value).toBe(null)
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('accepts undefined', () => {
|
|
41
|
-
const result = schema.safeParse(undefined)
|
|
42
|
-
expect(result.success).toBe(true)
|
|
43
|
-
if (result.success) {
|
|
44
|
-
expect(result.value).toBe(undefined)
|
|
45
|
-
}
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('accepts plain objects', () => {
|
|
49
|
-
const obj = { key: 'value', nested: { prop: 123 } }
|
|
50
|
-
const result = schema.safeParse(obj)
|
|
51
|
-
expect(result.success).toBe(true)
|
|
52
|
-
if (result.success) {
|
|
53
|
-
expect(result.value).toEqual(obj)
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
it('accepts arrays', () => {
|
|
58
|
-
const arr = [1, 2, 3, 'four', { five: 5 }]
|
|
59
|
-
const result = schema.safeParse(arr)
|
|
60
|
-
expect(result.success).toBe(true)
|
|
61
|
-
if (result.success) {
|
|
62
|
-
expect(result.value).toEqual(arr)
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('accepts empty arrays', () => {
|
|
67
|
-
const result = schema.safeParse([])
|
|
68
|
-
expect(result.success).toBe(true)
|
|
69
|
-
if (result.success) {
|
|
70
|
-
expect(result.value).toEqual([])
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
it('accepts empty objects', () => {
|
|
75
|
-
const result = schema.safeParse({})
|
|
76
|
-
expect(result.success).toBe(true)
|
|
77
|
-
if (result.success) {
|
|
78
|
-
expect(result.value).toEqual({})
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
describe('edge cases', () => {
|
|
84
|
-
const schema = unknown()
|
|
85
|
-
|
|
86
|
-
it('accepts zero', () => {
|
|
87
|
-
const result = schema.safeParse(0)
|
|
88
|
-
expect(result.success).toBe(true)
|
|
89
|
-
if (result.success) {
|
|
90
|
-
expect(result.value).toBe(0)
|
|
91
|
-
}
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it('accepts empty string', () => {
|
|
95
|
-
const result = schema.safeParse('')
|
|
96
|
-
expect(result.success).toBe(true)
|
|
97
|
-
if (result.success) {
|
|
98
|
-
expect(result.value).toBe('')
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('accepts negative numbers', () => {
|
|
103
|
-
const result = schema.safeParse(-123)
|
|
104
|
-
expect(result.success).toBe(true)
|
|
105
|
-
if (result.success) {
|
|
106
|
-
expect(result.value).toBe(-123)
|
|
107
|
-
}
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('accepts floating point numbers', () => {
|
|
111
|
-
const result = schema.safeParse(3.14159)
|
|
112
|
-
expect(result.success).toBe(true)
|
|
113
|
-
if (result.success) {
|
|
114
|
-
expect(result.value).toBe(3.14159)
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it('accepts NaN', () => {
|
|
119
|
-
const result = schema.safeParse(NaN)
|
|
120
|
-
expect(result.success).toBe(true)
|
|
121
|
-
if (result.success) {
|
|
122
|
-
expect(result.value).toBeNaN()
|
|
123
|
-
}
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
it('accepts Infinity', () => {
|
|
127
|
-
const result = schema.safeParse(Infinity)
|
|
128
|
-
expect(result.success).toBe(true)
|
|
129
|
-
if (result.success) {
|
|
130
|
-
expect(result.value).toBe(Infinity)
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
it('accepts -Infinity', () => {
|
|
135
|
-
const result = schema.safeParse(-Infinity)
|
|
136
|
-
expect(result.success).toBe(true)
|
|
137
|
-
if (result.success) {
|
|
138
|
-
expect(result.value).toBe(-Infinity)
|
|
139
|
-
}
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('accepts BigInt', () => {
|
|
143
|
-
const bigIntValue = BigInt(9007199254740991)
|
|
144
|
-
const result = schema.safeParse(bigIntValue)
|
|
145
|
-
expect(result.success).toBe(true)
|
|
146
|
-
if (result.success) {
|
|
147
|
-
expect(result.value).toBe(bigIntValue)
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
it('accepts functions', () => {
|
|
152
|
-
const fn = () => 'test'
|
|
153
|
-
const result = schema.safeParse(fn)
|
|
154
|
-
expect(result.success).toBe(true)
|
|
155
|
-
if (result.success) {
|
|
156
|
-
expect(result.value).toBe(fn)
|
|
157
|
-
}
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
it('accepts Date objects', () => {
|
|
161
|
-
const date = new Date('2023-01-01')
|
|
162
|
-
const result = schema.safeParse(date)
|
|
163
|
-
expect(result.success).toBe(true)
|
|
164
|
-
if (result.success) {
|
|
165
|
-
expect(result.value).toBe(date)
|
|
166
|
-
}
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it('accepts RegExp objects', () => {
|
|
170
|
-
const regex = /test/gi
|
|
171
|
-
const result = schema.safeParse(regex)
|
|
172
|
-
expect(result.success).toBe(true)
|
|
173
|
-
if (result.success) {
|
|
174
|
-
expect(result.value).toBe(regex)
|
|
175
|
-
}
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
it('accepts Symbol', () => {
|
|
179
|
-
const sym = Symbol('test')
|
|
180
|
-
const result = schema.safeParse(sym)
|
|
181
|
-
expect(result.success).toBe(true)
|
|
182
|
-
if (result.success) {
|
|
183
|
-
expect(result.value).toBe(sym)
|
|
184
|
-
}
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
it('accepts Map objects', () => {
|
|
188
|
-
const map = new Map([['key', 'value']])
|
|
189
|
-
const result = schema.safeParse(map)
|
|
190
|
-
expect(result.success).toBe(true)
|
|
191
|
-
if (result.success) {
|
|
192
|
-
expect(result.value).toBe(map)
|
|
193
|
-
}
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
it('accepts Set objects', () => {
|
|
197
|
-
const set = new Set([1, 2, 3])
|
|
198
|
-
const result = schema.safeParse(set)
|
|
199
|
-
expect(result.success).toBe(true)
|
|
200
|
-
if (result.success) {
|
|
201
|
-
expect(result.value).toBe(set)
|
|
202
|
-
}
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
it('accepts WeakMap objects', () => {
|
|
206
|
-
const weakMap = new WeakMap()
|
|
207
|
-
const result = schema.safeParse(weakMap)
|
|
208
|
-
expect(result.success).toBe(true)
|
|
209
|
-
if (result.success) {
|
|
210
|
-
expect(result.value).toBe(weakMap)
|
|
211
|
-
}
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
it('accepts WeakSet objects', () => {
|
|
215
|
-
const weakSet = new WeakSet()
|
|
216
|
-
const result = schema.safeParse(weakSet)
|
|
217
|
-
expect(result.success).toBe(true)
|
|
218
|
-
if (result.success) {
|
|
219
|
-
expect(result.value).toBe(weakSet)
|
|
220
|
-
}
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
it('accepts class instances', () => {
|
|
224
|
-
class TestClass {
|
|
225
|
-
constructor(public value: string) {}
|
|
226
|
-
}
|
|
227
|
-
const instance = new TestClass('test')
|
|
228
|
-
const result = schema.safeParse(instance)
|
|
229
|
-
expect(result.success).toBe(true)
|
|
230
|
-
if (result.success) {
|
|
231
|
-
expect(result.value).toBe(instance)
|
|
232
|
-
}
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
it('accepts nested complex structures', () => {
|
|
236
|
-
const complex = {
|
|
237
|
-
array: [1, 'two', { three: 3 }],
|
|
238
|
-
nested: {
|
|
239
|
-
deep: {
|
|
240
|
-
value: [null, undefined, true],
|
|
241
|
-
},
|
|
242
|
-
},
|
|
243
|
-
fn: () => 'test',
|
|
244
|
-
date: new Date(),
|
|
245
|
-
}
|
|
246
|
-
const result = schema.safeParse(complex)
|
|
247
|
-
expect(result.success).toBe(true)
|
|
248
|
-
if (result.success) {
|
|
249
|
-
expect(result.value).toEqual(complex)
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
describe('special JavaScript values', () => {
|
|
255
|
-
const schema = unknown()
|
|
256
|
-
|
|
257
|
-
it('accepts objects with null prototype', () => {
|
|
258
|
-
const obj = Object.create(null)
|
|
259
|
-
obj.key = 'value'
|
|
260
|
-
const result = schema.safeParse(obj)
|
|
261
|
-
expect(result.success).toBe(true)
|
|
262
|
-
if (result.success) {
|
|
263
|
-
expect(result.value).toBe(obj)
|
|
264
|
-
}
|
|
265
|
-
})
|
|
266
|
-
|
|
267
|
-
it('accepts Proxy objects', () => {
|
|
268
|
-
const target = { value: 42 }
|
|
269
|
-
const proxy = new Proxy(target, {})
|
|
270
|
-
const result = schema.safeParse(proxy)
|
|
271
|
-
expect(result.success).toBe(true)
|
|
272
|
-
if (result.success) {
|
|
273
|
-
expect(result.value).toBe(proxy)
|
|
274
|
-
}
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
it('accepts typed arrays', () => {
|
|
278
|
-
const uint8Array = new Uint8Array([1, 2, 3])
|
|
279
|
-
const result = schema.safeParse(uint8Array)
|
|
280
|
-
expect(result.success).toBe(true)
|
|
281
|
-
if (result.success) {
|
|
282
|
-
expect(result.value).toBe(uint8Array)
|
|
283
|
-
}
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
it('accepts ArrayBuffer', () => {
|
|
287
|
-
const buffer = new ArrayBuffer(8)
|
|
288
|
-
const result = schema.safeParse(buffer)
|
|
289
|
-
expect(result.success).toBe(true)
|
|
290
|
-
if (result.success) {
|
|
291
|
-
expect(result.value).toBe(buffer)
|
|
292
|
-
}
|
|
293
|
-
})
|
|
294
|
-
|
|
295
|
-
it('accepts Promise objects', () => {
|
|
296
|
-
const promise = Promise.resolve(42)
|
|
297
|
-
const result = schema.safeParse(promise)
|
|
298
|
-
expect(result.success).toBe(true)
|
|
299
|
-
if (result.success) {
|
|
300
|
-
expect(result.value).toBe(promise)
|
|
301
|
-
}
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
it('accepts Error objects', () => {
|
|
305
|
-
const error = new Error('test error')
|
|
306
|
-
const result = schema.safeParse(error)
|
|
307
|
-
expect(result.success).toBe(true)
|
|
308
|
-
if (result.success) {
|
|
309
|
-
expect(result.value).toBe(error)
|
|
310
|
-
}
|
|
311
|
-
})
|
|
312
|
-
})
|
|
313
|
-
})
|
package/src/schema/unknown.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { Schema, ValidationContext } from '../core.js'
|
|
2
|
-
import { memoizedOptions } from '../util/memoize.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Schema that accepts any value without validation.
|
|
6
|
-
*
|
|
7
|
-
* Passes through any input unchanged. Use sparingly as it bypasses
|
|
8
|
-
* type safety. Useful for dynamic data or when the schema is not
|
|
9
|
-
* known at compile time.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* const schema = new UnknownSchema()
|
|
14
|
-
* schema.validate(anything) // always succeeds
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export class UnknownSchema extends Schema<unknown> {
|
|
18
|
-
readonly type = 'unknown' as const
|
|
19
|
-
|
|
20
|
-
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
21
|
-
return ctx.success(input)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Creates an unknown schema that accepts any value.
|
|
27
|
-
*
|
|
28
|
-
* The value passes through without any validation or transformation.
|
|
29
|
-
* Use this when you need to accept arbitrary data.
|
|
30
|
-
*
|
|
31
|
-
* @returns A new {@link UnknownSchema} instance
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```ts
|
|
35
|
-
* // Accept any value
|
|
36
|
-
* const anyDataSchema = l.unknown()
|
|
37
|
-
*
|
|
38
|
-
* // In an object with a dynamic field
|
|
39
|
-
* const flexibleSchema = l.object({
|
|
40
|
-
* type: l.string(),
|
|
41
|
-
* data: l.unknown(),
|
|
42
|
-
* })
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export const unknown = /*#__PURE__*/ memoizedOptions(function () {
|
|
46
|
-
return new UnknownSchema()
|
|
47
|
-
})
|