@atproto/lex-schema 0.0.11 → 0.0.13
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 +54 -0
- package/dist/core/$type.d.ts +149 -0
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js +44 -0
- package/dist/core/$type.js.map +1 -1
- package/dist/core/record-key.d.ts +44 -0
- package/dist/core/record-key.d.ts.map +1 -1
- package/dist/core/record-key.js +30 -0
- package/dist/core/record-key.js.map +1 -1
- package/dist/core/result.d.ts +85 -4
- package/dist/core/result.d.ts.map +1 -1
- package/dist/core/result.js +60 -4
- package/dist/core/result.js.map +1 -1
- package/dist/core/schema.d.ts +232 -5
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +197 -4
- package/dist/core/schema.js.map +1 -1
- package/dist/core/string-format.d.ts +244 -11
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js +150 -0
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/types.d.ts +90 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/validation-error.d.ts +60 -0
- package/dist/core/validation-error.d.ts.map +1 -1
- package/dist/core/validation-error.js +60 -0
- package/dist/core/validation-error.js.map +1 -1
- package/dist/core/validation-issue.d.ts +61 -0
- package/dist/core/validation-issue.d.ts.map +1 -1
- package/dist/core/validation-issue.js +54 -1
- package/dist/core/validation-issue.js.map +1 -1
- package/dist/core/validator.d.ts +356 -11
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +203 -4
- package/dist/core/validator.js.map +1 -1
- package/dist/helpers.d.ts +12 -28
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js.map +1 -1
- package/dist/schema/array.d.ts +46 -0
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +16 -1
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +50 -2
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +44 -2
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.d.ts +29 -0
- package/dist/schema/boolean.d.ts.map +1 -1
- package/dist/schema/boolean.js +30 -1
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.d.ts +39 -0
- package/dist/schema/bytes.d.ts.map +1 -1
- package/dist/schema/bytes.js +34 -1
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +39 -0
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +35 -1
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.d.ts +67 -1
- package/dist/schema/custom.d.ts.map +1 -1
- package/dist/schema/custom.js +55 -0
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +45 -0
- package/dist/schema/dict.d.ts.map +1 -1
- package/dist/schema/dict.js +46 -1
- package/dist/schema/dict.js.map +1 -1
- package/dist/schema/discriminated-union.d.ts +59 -0
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +47 -1
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.d.ts +49 -0
- package/dist/schema/enum.d.ts.map +1 -1
- package/dist/schema/enum.js +49 -0
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.d.ts +43 -0
- package/dist/schema/integer.d.ts.map +1 -1
- package/dist/schema/integer.js +38 -1
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +55 -0
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +50 -0
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/lex-map.d.ts +37 -0
- package/dist/schema/lex-map.d.ts.map +1 -0
- package/dist/schema/lex-map.js +60 -0
- package/dist/schema/lex-map.js.map +1 -0
- package/dist/schema/lex-value.d.ts +35 -0
- package/dist/schema/lex-value.d.ts.map +1 -0
- package/dist/schema/lex-value.js +87 -0
- package/dist/schema/lex-value.js.map +1 -0
- package/dist/schema/literal.d.ts +45 -0
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +45 -0
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.d.ts +43 -0
- package/dist/schema/never.d.ts.map +1 -1
- package/dist/schema/never.js +44 -1
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.d.ts +30 -0
- package/dist/schema/null.d.ts.map +1 -1
- package/dist/schema/null.js +31 -1
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +42 -0
- package/dist/schema/nullable.d.ts.map +1 -1
- package/dist/schema/nullable.js +42 -0
- package/dist/schema/nullable.js.map +1 -1
- package/dist/schema/object.d.ts +57 -0
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +53 -1
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +43 -0
- package/dist/schema/optional.d.ts.map +1 -1
- package/dist/schema/optional.js +43 -0
- package/dist/schema/optional.js.map +1 -1
- package/dist/schema/params.d.ts +96 -12
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +155 -21
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +111 -15
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +73 -3
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +58 -0
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +50 -0
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +42 -0
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js +39 -0
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +64 -0
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +64 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +55 -0
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +55 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +76 -25
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +21 -0
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +51 -0
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +18 -0
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +58 -9
- package/dist/schema/refine.d.ts.map +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/regexp.d.ts +45 -0
- package/dist/schema/regexp.d.ts.map +1 -1
- package/dist/schema/regexp.js +46 -1
- package/dist/schema/regexp.js.map +1 -1
- package/dist/schema/string.d.ts +72 -6
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +56 -8
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +72 -2
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js +59 -0
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +48 -0
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +49 -1
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +73 -23
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +20 -1
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +54 -0
- package/dist/schema/typed-ref.d.ts.map +1 -1
- package/dist/schema/typed-ref.js +16 -0
- package/dist/schema/typed-ref.js.map +1 -1
- package/dist/schema/typed-union.d.ts +51 -1
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +52 -2
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +46 -0
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +41 -0
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown.d.ts +34 -0
- package/dist/schema/unknown.d.ts.map +1 -1
- package/dist/schema/unknown.js +34 -0
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema/with-default.d.ts +45 -0
- package/dist/schema/with-default.d.ts.map +1 -1
- package/dist/schema/with-default.js +45 -0
- package/dist/schema/with-default.js.map +1 -1
- package/dist/schema.d.ts +2 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -1
- package/dist/schema.js.map +1 -1
- package/dist/util/if-any.d.ts +2 -0
- package/dist/util/if-any.d.ts.map +1 -0
- package/dist/util/if-any.js +3 -0
- package/dist/util/if-any.js.map +1 -0
- package/package.json +3 -3
- package/src/core/$type.ts +150 -18
- package/src/core/record-key.ts +44 -0
- package/src/core/result.ts +86 -4
- package/src/core/schema.ts +244 -9
- package/src/core/string-format.ts +259 -13
- package/src/core/types.ts +91 -3
- package/src/core/validation-error.ts +60 -0
- package/src/core/validation-issue.ts +68 -2
- package/src/core/validator.ts +373 -12
- package/src/helpers.test.ts +110 -29
- package/src/helpers.ts +54 -25
- package/src/schema/array.test.ts +94 -79
- package/src/schema/array.ts +48 -1
- package/src/schema/blob.ts +50 -1
- package/src/schema/boolean.ts +31 -1
- package/src/schema/bytes.ts +41 -1
- package/src/schema/cid.ts +41 -1
- package/src/schema/custom.ts +68 -1
- package/src/schema/dict.ts +47 -1
- package/src/schema/discriminated-union.ts +61 -1
- package/src/schema/enum.ts +50 -0
- package/src/schema/integer.ts +45 -1
- package/src/schema/intersection.ts +56 -0
- package/src/schema/{unknown-object.test.ts → lex-map.test.ts} +9 -9
- package/src/schema/lex-map.ts +63 -0
- package/src/schema/lex-value.test.ts +81 -0
- package/src/schema/lex-value.ts +86 -0
- package/src/schema/literal.ts +46 -0
- package/src/schema/never.ts +45 -1
- package/src/schema/null.ts +32 -1
- package/src/schema/nullable.ts +43 -0
- package/src/schema/object.ts +59 -1
- package/src/schema/optional.ts +44 -0
- package/src/schema/params.test.ts +133 -38
- package/src/schema/params.ts +237 -37
- package/src/schema/payload.test.ts +3 -3
- package/src/schema/payload.ts +145 -42
- package/src/schema/permission-set.ts +58 -0
- package/src/schema/permission.ts +42 -0
- package/src/schema/procedure.ts +64 -0
- package/src/schema/query.ts +55 -0
- package/src/schema/record.ts +82 -16
- package/src/schema/ref.ts +52 -0
- package/src/schema/refine.ts +58 -9
- package/src/schema/regexp.ts +47 -1
- package/src/schema/string.test.ts +99 -2
- package/src/schema/string.ts +108 -15
- package/src/schema/subscription.ts +72 -2
- package/src/schema/token.ts +50 -1
- package/src/schema/typed-object.ts +81 -16
- package/src/schema/typed-ref.ts +55 -0
- package/src/schema/typed-union.ts +58 -3
- package/src/schema/union.ts +47 -0
- package/src/schema/unknown.ts +35 -0
- package/src/schema/with-default.ts +46 -0
- package/src/schema.ts +2 -1
- package/src/util/if-any.ts +3 -0
- package/dist/schema/unknown-object.d.ts +0 -8
- package/dist/schema/unknown-object.d.ts.map +0 -1
- package/dist/schema/unknown-object.js +0 -19
- package/dist/schema/unknown-object.js.map +0 -1
- package/src/schema/unknown-object.ts +0 -19
package/src/schema/array.test.ts
CHANGED
|
@@ -5,103 +5,118 @@ import { object } from './object.js'
|
|
|
5
5
|
import { string } from './string.js'
|
|
6
6
|
|
|
7
7
|
describe('ArraySchema', () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
describe('validation', () => {
|
|
9
|
+
it('validates arrays with string items', () => {
|
|
10
|
+
const schema = array(string())
|
|
11
|
+
const result = schema.safeValidate(['hello', 'world'])
|
|
12
|
+
expect(result).toMatchObject({ success: true })
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('validates arrays with integer items', () => {
|
|
16
|
+
const schema = array(integer())
|
|
17
|
+
const result = schema.safeValidate([1, 2, 3])
|
|
18
|
+
expect(result).toMatchObject({ success: true })
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('validates arrays with object items', () => {
|
|
22
|
+
const schema = array(
|
|
23
|
+
object({
|
|
24
|
+
name: string(),
|
|
25
|
+
age: integer(),
|
|
26
|
+
}),
|
|
27
|
+
)
|
|
28
|
+
const result = schema.safeValidate([
|
|
29
|
+
{ name: 'Alice', age: 30 },
|
|
30
|
+
{ name: 'Bob', age: 25 },
|
|
31
|
+
])
|
|
32
|
+
expect(result).toMatchObject({ success: true })
|
|
33
|
+
})
|
|
19
34
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}),
|
|
26
|
-
)
|
|
27
|
-
const result = schema.safeParse([
|
|
28
|
-
{ name: 'Alice', age: 30 },
|
|
29
|
-
{ name: 'Bob', age: 25 },
|
|
30
|
-
])
|
|
31
|
-
expect(result.success).toBe(true)
|
|
32
|
-
})
|
|
35
|
+
it('validates empty arrays', () => {
|
|
36
|
+
const schema = array(string())
|
|
37
|
+
const result = schema.safeValidate([])
|
|
38
|
+
expect(result).toMatchObject({ success: true })
|
|
39
|
+
})
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
it('rejects non-array values', () => {
|
|
42
|
+
const schema = array(string())
|
|
43
|
+
const result = schema.safeValidate('not an array')
|
|
44
|
+
expect(result).toMatchObject({ success: false })
|
|
45
|
+
})
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
it('rejects null values', () => {
|
|
48
|
+
const schema = array(string())
|
|
49
|
+
const result = schema.safeValidate(null)
|
|
50
|
+
expect(result).toMatchObject({ success: false })
|
|
51
|
+
})
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
it('rejects undefined values', () => {
|
|
54
|
+
const schema = array(string())
|
|
55
|
+
const result = schema.safeValidate(undefined)
|
|
56
|
+
expect(result).toMatchObject({ success: false })
|
|
57
|
+
})
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
it('rejects objects that look like arrays', () => {
|
|
60
|
+
const schema = array(string())
|
|
61
|
+
const result = schema.safeValidate({ 0: 'a', 1: 'b', length: 2 })
|
|
62
|
+
expect(result).toMatchObject({ success: false })
|
|
63
|
+
})
|
|
57
64
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
it('rejects arrays with invalid items', () => {
|
|
66
|
+
const schema = array(integer())
|
|
67
|
+
const result = schema.safeValidate([1, 2, 'three'])
|
|
68
|
+
expect(result).toMatchObject({ success: false })
|
|
69
|
+
})
|
|
63
70
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
it('rejects arrays with some invalid items', () => {
|
|
72
|
+
const schema = array(string())
|
|
73
|
+
const result = schema.safeValidate(['valid', null, 'also valid'])
|
|
74
|
+
expect(result).toMatchObject({ success: false })
|
|
75
|
+
})
|
|
69
76
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
it('rejects single values', () => {
|
|
78
|
+
const schema = array(string())
|
|
79
|
+
const result = schema.safeValidate(3)
|
|
80
|
+
expect(result).toEqual({
|
|
81
|
+
success: false,
|
|
82
|
+
reason: expect.objectContaining({
|
|
83
|
+
message: expect.stringContaining(
|
|
84
|
+
'Expected array value type at $ (got integer)',
|
|
85
|
+
),
|
|
86
|
+
}),
|
|
87
|
+
})
|
|
88
|
+
})
|
|
74
89
|
})
|
|
75
90
|
|
|
76
91
|
describe('minLength constraint', () => {
|
|
77
92
|
it('validates arrays meeting minLength', () => {
|
|
78
93
|
const schema = array(string(), { minLength: 2 })
|
|
79
94
|
const result = schema.safeParse(['a', 'b'])
|
|
80
|
-
expect(result
|
|
95
|
+
expect(result).toMatchObject({ success: true })
|
|
81
96
|
})
|
|
82
97
|
|
|
83
98
|
it('validates arrays exceeding minLength', () => {
|
|
84
99
|
const schema = array(string(), { minLength: 2 })
|
|
85
100
|
const result = schema.safeParse(['a', 'b', 'c'])
|
|
86
|
-
expect(result
|
|
101
|
+
expect(result).toMatchObject({ success: true })
|
|
87
102
|
})
|
|
88
103
|
|
|
89
104
|
it('rejects arrays below minLength', () => {
|
|
90
105
|
const schema = array(string(), { minLength: 3 })
|
|
91
106
|
const result = schema.safeParse(['a', 'b'])
|
|
92
|
-
expect(result
|
|
107
|
+
expect(result).toMatchObject({ success: false })
|
|
93
108
|
})
|
|
94
109
|
|
|
95
110
|
it('rejects empty arrays when minLength is set', () => {
|
|
96
111
|
const schema = array(string(), { minLength: 1 })
|
|
97
112
|
const result = schema.safeParse([])
|
|
98
|
-
expect(result
|
|
113
|
+
expect(result).toMatchObject({ success: false })
|
|
99
114
|
})
|
|
100
115
|
|
|
101
116
|
it('validates empty arrays when minLength is 0', () => {
|
|
102
117
|
const schema = array(string(), { minLength: 0 })
|
|
103
118
|
const result = schema.safeParse([])
|
|
104
|
-
expect(result
|
|
119
|
+
expect(result).toMatchObject({ success: true })
|
|
105
120
|
})
|
|
106
121
|
})
|
|
107
122
|
|
|
@@ -109,37 +124,37 @@ describe('ArraySchema', () => {
|
|
|
109
124
|
it('validates arrays meeting maxLength', () => {
|
|
110
125
|
const schema = array(string(), { maxLength: 3 })
|
|
111
126
|
const result = schema.safeParse(['a', 'b', 'c'])
|
|
112
|
-
expect(result
|
|
127
|
+
expect(result).toMatchObject({ success: true })
|
|
113
128
|
})
|
|
114
129
|
|
|
115
130
|
it('validates arrays below maxLength', () => {
|
|
116
131
|
const schema = array(string(), { maxLength: 3 })
|
|
117
132
|
const result = schema.safeParse(['a', 'b'])
|
|
118
|
-
expect(result
|
|
133
|
+
expect(result).toMatchObject({ success: true })
|
|
119
134
|
})
|
|
120
135
|
|
|
121
136
|
it('rejects arrays exceeding maxLength', () => {
|
|
122
137
|
const schema = array(string(), { maxLength: 2 })
|
|
123
138
|
const result = schema.safeParse(['a', 'b', 'c'])
|
|
124
|
-
expect(result
|
|
139
|
+
expect(result).toMatchObject({ success: false })
|
|
125
140
|
})
|
|
126
141
|
|
|
127
142
|
it('validates empty arrays with maxLength', () => {
|
|
128
143
|
const schema = array(string(), { maxLength: 5 })
|
|
129
144
|
const result = schema.safeParse([])
|
|
130
|
-
expect(result
|
|
145
|
+
expect(result).toMatchObject({ success: true })
|
|
131
146
|
})
|
|
132
147
|
|
|
133
148
|
it('rejects empty arrays when maxLength is 0', () => {
|
|
134
149
|
const schema = array(string(), { maxLength: 0 })
|
|
135
150
|
const result = schema.safeParse(['a'])
|
|
136
|
-
expect(result
|
|
151
|
+
expect(result).toMatchObject({ success: false })
|
|
137
152
|
})
|
|
138
153
|
|
|
139
154
|
it('validates empty arrays when maxLength is 0', () => {
|
|
140
155
|
const schema = array(string(), { maxLength: 0 })
|
|
141
156
|
const result = schema.safeParse([])
|
|
142
|
-
expect(result
|
|
157
|
+
expect(result).toMatchObject({ success: true })
|
|
143
158
|
})
|
|
144
159
|
})
|
|
145
160
|
|
|
@@ -150,7 +165,7 @@ describe('ArraySchema', () => {
|
|
|
150
165
|
maxLength: 4,
|
|
151
166
|
})
|
|
152
167
|
const result = schema.safeParse(['a', 'b', 'c'])
|
|
153
|
-
expect(result
|
|
168
|
+
expect(result).toMatchObject({ success: true })
|
|
154
169
|
})
|
|
155
170
|
|
|
156
171
|
it('validates arrays at min boundary', () => {
|
|
@@ -159,7 +174,7 @@ describe('ArraySchema', () => {
|
|
|
159
174
|
maxLength: 4,
|
|
160
175
|
})
|
|
161
176
|
const result = schema.safeParse(['a', 'b'])
|
|
162
|
-
expect(result
|
|
177
|
+
expect(result).toMatchObject({ success: true })
|
|
163
178
|
})
|
|
164
179
|
|
|
165
180
|
it('validates arrays at max boundary', () => {
|
|
@@ -168,7 +183,7 @@ describe('ArraySchema', () => {
|
|
|
168
183
|
maxLength: 4,
|
|
169
184
|
})
|
|
170
185
|
const result = schema.safeParse(['a', 'b', 'c', 'd'])
|
|
171
|
-
expect(result
|
|
186
|
+
expect(result).toMatchObject({ success: true })
|
|
172
187
|
})
|
|
173
188
|
|
|
174
189
|
it('rejects arrays below minLength', () => {
|
|
@@ -177,7 +192,7 @@ describe('ArraySchema', () => {
|
|
|
177
192
|
maxLength: 4,
|
|
178
193
|
})
|
|
179
194
|
const result = schema.safeParse(['a'])
|
|
180
|
-
expect(result
|
|
195
|
+
expect(result).toMatchObject({ success: false })
|
|
181
196
|
})
|
|
182
197
|
|
|
183
198
|
it('rejects arrays above maxLength', () => {
|
|
@@ -186,7 +201,7 @@ describe('ArraySchema', () => {
|
|
|
186
201
|
maxLength: 4,
|
|
187
202
|
})
|
|
188
203
|
const result = schema.safeParse(['a', 'b', 'c', 'd', 'e'])
|
|
189
|
-
expect(result
|
|
204
|
+
expect(result).toMatchObject({ success: false })
|
|
190
205
|
})
|
|
191
206
|
|
|
192
207
|
it('validates single-length range', () => {
|
|
@@ -195,7 +210,7 @@ describe('ArraySchema', () => {
|
|
|
195
210
|
maxLength: 3,
|
|
196
211
|
})
|
|
197
212
|
const result = schema.safeParse(['a', 'b', 'c'])
|
|
198
|
-
expect(result
|
|
213
|
+
expect(result).toMatchObject({ success: true })
|
|
199
214
|
})
|
|
200
215
|
|
|
201
216
|
it('rejects arrays not matching exact length', () => {
|
|
@@ -204,7 +219,7 @@ describe('ArraySchema', () => {
|
|
|
204
219
|
maxLength: 3,
|
|
205
220
|
})
|
|
206
221
|
const result = schema.safeParse(['a', 'b'])
|
|
207
|
-
expect(result
|
|
222
|
+
expect(result).toMatchObject({ success: false })
|
|
208
223
|
})
|
|
209
224
|
})
|
|
210
225
|
|
|
@@ -215,7 +230,7 @@ describe('ArraySchema', () => {
|
|
|
215
230
|
['a', 'b'],
|
|
216
231
|
['c', 'd'],
|
|
217
232
|
])
|
|
218
|
-
expect(result
|
|
233
|
+
expect(result).toMatchObject({ success: true })
|
|
219
234
|
})
|
|
220
235
|
|
|
221
236
|
it('rejects invalid nested arrays', () => {
|
|
@@ -224,13 +239,13 @@ describe('ArraySchema', () => {
|
|
|
224
239
|
[1, 2],
|
|
225
240
|
[3, 'four'],
|
|
226
241
|
])
|
|
227
|
-
expect(result
|
|
242
|
+
expect(result).toMatchObject({ success: false })
|
|
228
243
|
})
|
|
229
244
|
|
|
230
245
|
it('validates deeply nested arrays', () => {
|
|
231
246
|
const schema = array(array(array(integer())))
|
|
232
247
|
const result = schema.safeParse([[[1, 2], [3]], [[4, 5, 6]]])
|
|
233
|
-
expect(result
|
|
248
|
+
expect(result).toMatchObject({ success: true })
|
|
234
249
|
})
|
|
235
250
|
})
|
|
236
251
|
})
|
package/src/schema/array.ts
CHANGED
|
@@ -7,15 +7,37 @@ import {
|
|
|
7
7
|
} from '../core.js'
|
|
8
8
|
import { memoizedTransformer } from '../util/memoize.js'
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Configuration options for array schema validation.
|
|
12
|
+
*
|
|
13
|
+
* @property minLength - Minimum number of items in the array
|
|
14
|
+
* @property maxLength - Maximum number of items in the array
|
|
15
|
+
*/
|
|
10
16
|
export type ArraySchemaOptions = {
|
|
11
17
|
minLength?: number
|
|
12
18
|
maxLength?: number
|
|
13
19
|
}
|
|
14
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Schema for validating arrays where all items match a given schema.
|
|
23
|
+
*
|
|
24
|
+
* Validates that the input is an array, checks length constraints, and
|
|
25
|
+
* validates each item against the provided item schema.
|
|
26
|
+
*
|
|
27
|
+
* @template TItem - The validator type for array items
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const schema = new ArraySchema(l.string(), { maxLength: 10 })
|
|
32
|
+
* const result = schema.validate(['a', 'b', 'c'])
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
15
35
|
export class ArraySchema<const TItem extends Validator> extends Schema<
|
|
16
36
|
Array<InferInput<TItem>>,
|
|
17
37
|
Array<InferOutput<TItem>>
|
|
18
38
|
> {
|
|
39
|
+
readonly type = 'array' as const
|
|
40
|
+
|
|
19
41
|
constructor(
|
|
20
42
|
readonly validator: TItem,
|
|
21
43
|
readonly options: ArraySchemaOptions = {},
|
|
@@ -25,7 +47,7 @@ export class ArraySchema<const TItem extends Validator> extends Schema<
|
|
|
25
47
|
|
|
26
48
|
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
27
49
|
if (!Array.isArray(input)) {
|
|
28
|
-
return ctx.
|
|
50
|
+
return ctx.issueUnexpectedType(input, 'array')
|
|
29
51
|
}
|
|
30
52
|
|
|
31
53
|
const { minLength, maxLength } = this.options
|
|
@@ -60,6 +82,31 @@ export class ArraySchema<const TItem extends Validator> extends Schema<
|
|
|
60
82
|
}
|
|
61
83
|
}
|
|
62
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Creates an array schema that validates each item against the provided schema.
|
|
87
|
+
*
|
|
88
|
+
* @param items - Schema to validate each array item against
|
|
89
|
+
* @param options - Optional length constraints
|
|
90
|
+
* @returns A new {@link ArraySchema} instance
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* // Array of strings
|
|
95
|
+
* const tagsSchema = l.array(l.string())
|
|
96
|
+
*
|
|
97
|
+
* // Array with length constraints
|
|
98
|
+
* const limitedSchema = l.array(l.integer(), { maxLength: 100 })
|
|
99
|
+
*
|
|
100
|
+
* // Array of objects
|
|
101
|
+
* const usersSchema = l.array(l.object({
|
|
102
|
+
* name: l.string(),
|
|
103
|
+
* age: l.integer(),
|
|
104
|
+
* }))
|
|
105
|
+
*
|
|
106
|
+
* // Non-empty array
|
|
107
|
+
* const nonEmptySchema = l.array(l.string(), { minLength: 1 })
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
63
110
|
/*@__NO_SIDE_EFFECTS__*/
|
|
64
111
|
function arraySchema<const TValidator extends Validator>(
|
|
65
112
|
items: TValidator,
|
package/src/schema/blob.ts
CHANGED
|
@@ -8,6 +8,13 @@ import {
|
|
|
8
8
|
import { Schema, ValidationContext } from '../core.js'
|
|
9
9
|
import { memoizedOptions } from '../util/memoize.js'
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Configuration options for blob schema validation.
|
|
13
|
+
*
|
|
14
|
+
* @property allowLegacy - Whether to allow legacy blob references format
|
|
15
|
+
* @property accept - List of accepted MIME types (supports wildcards like 'image/*' or '*\/*')
|
|
16
|
+
* @property maxSize - Maximum blob size in bytes
|
|
17
|
+
*/
|
|
11
18
|
export type BlobSchemaOptions = BlobRefCheckOptions & {
|
|
12
19
|
/**
|
|
13
20
|
* Whether to allow legacy blob references format
|
|
@@ -25,12 +32,30 @@ export type BlobSchemaOptions = BlobRefCheckOptions & {
|
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
export type { BlobRef, LegacyBlobRef }
|
|
35
|
+
export { isBlobRef, isLegacyBlobRef }
|
|
28
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Schema for validating blob references in AT Protocol.
|
|
39
|
+
*
|
|
40
|
+
* Validates BlobRef objects which contain a CID reference to binary data,
|
|
41
|
+
* along with metadata like MIME type and size. Can optionally accept
|
|
42
|
+
* legacy blob reference format.
|
|
43
|
+
*
|
|
44
|
+
* @template TOptions - The configuration options type
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const schema = new BlobSchema({ accept: ['image/*'], maxSize: 1000000 })
|
|
49
|
+
* const result = schema.validate(blobRef)
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
29
52
|
export class BlobSchema<
|
|
30
53
|
const TOptions extends BlobSchemaOptions = NonNullable<unknown>,
|
|
31
54
|
> extends Schema<
|
|
32
55
|
TOptions extends { allowLegacy: true } ? BlobRef | LegacyBlobRef : BlobRef
|
|
33
56
|
> {
|
|
57
|
+
readonly type = 'blob' as const
|
|
58
|
+
|
|
34
59
|
constructor(readonly options?: TOptions) {
|
|
35
60
|
super()
|
|
36
61
|
}
|
|
@@ -46,7 +71,7 @@ export class BlobSchema<
|
|
|
46
71
|
: null
|
|
47
72
|
|
|
48
73
|
if (!blob) {
|
|
49
|
-
return ctx.
|
|
74
|
+
return ctx.issueUnexpectedType(input, 'blob')
|
|
50
75
|
}
|
|
51
76
|
|
|
52
77
|
const accept = this.options?.accept
|
|
@@ -80,6 +105,30 @@ function matchesMime(mime: string, accepted: string[]): boolean {
|
|
|
80
105
|
return false
|
|
81
106
|
}
|
|
82
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Creates a blob schema for validating blob references with optional constraints.
|
|
110
|
+
*
|
|
111
|
+
* Blob references are used in AT Protocol to reference binary data stored
|
|
112
|
+
* separately from records. They contain a CID, MIME type, and size information.
|
|
113
|
+
*
|
|
114
|
+
* @param options - Optional configuration for MIME type filtering and size limits
|
|
115
|
+
* @returns A new {@link BlobSchema} instance
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* // Basic blob reference
|
|
120
|
+
* const fileSchema = l.blob()
|
|
121
|
+
*
|
|
122
|
+
* // Image files only
|
|
123
|
+
* const imageSchema = l.blob({ accept: ['image/png', 'image/jpeg', 'image/gif'] })
|
|
124
|
+
*
|
|
125
|
+
* // Any image type with size limit
|
|
126
|
+
* const avatarSchema = l.blob({ accept: ['image/*'], maxSize: 1000000 })
|
|
127
|
+
*
|
|
128
|
+
* // Allow legacy format
|
|
129
|
+
* const legacySchema = l.blob({ allowLegacy: true })
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
83
132
|
export const blob = /*#__PURE__*/ memoizedOptions(function <
|
|
84
133
|
O extends BlobSchemaOptions = { allowLegacy?: false },
|
|
85
134
|
>(options?: O) {
|
package/src/schema/boolean.ts
CHANGED
|
@@ -1,16 +1,46 @@
|
|
|
1
1
|
import { Schema, ValidationContext } from '../core.js'
|
|
2
2
|
import { memoizedOptions } from '../util/memoize.js'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Schema for validating boolean values.
|
|
6
|
+
*
|
|
7
|
+
* Only accepts JavaScript `true` or `false` values. Does not perform
|
|
8
|
+
* any coercion from strings or numbers.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const schema = new BooleanSchema()
|
|
13
|
+
* schema.validate(true) // success
|
|
14
|
+
* schema.validate(false) // success
|
|
15
|
+
* schema.validate('true') // fails - no string coercion
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
4
18
|
export class BooleanSchema extends Schema<boolean> {
|
|
19
|
+
readonly type = 'boolean' as const
|
|
20
|
+
|
|
5
21
|
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
6
22
|
if (typeof input === 'boolean') {
|
|
7
23
|
return ctx.success(input)
|
|
8
24
|
}
|
|
9
25
|
|
|
10
|
-
return ctx.
|
|
26
|
+
return ctx.issueUnexpectedType(input, 'boolean')
|
|
11
27
|
}
|
|
12
28
|
}
|
|
13
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Creates a boolean schema that validates true/false values.
|
|
32
|
+
*
|
|
33
|
+
* @returns A new {@link BooleanSchema} instance
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const enabledSchema = l.boolean()
|
|
38
|
+
*
|
|
39
|
+
* enabledSchema.parse(true) // true
|
|
40
|
+
* enabledSchema.parse(false) // false
|
|
41
|
+
* enabledSchema.parse('true') // throws - strings not accepted
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
14
44
|
export const boolean = /*#__PURE__*/ memoizedOptions(function () {
|
|
15
45
|
return new BooleanSchema()
|
|
16
46
|
})
|
package/src/schema/bytes.ts
CHANGED
|
@@ -2,12 +2,32 @@ import { asUint8Array, ifUint8Array } from '@atproto/lex-data'
|
|
|
2
2
|
import { Schema, ValidationContext } from '../core.js'
|
|
3
3
|
import { memoizedOptions } from '../util/memoize.js'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Configuration options for bytes schema validation.
|
|
7
|
+
*
|
|
8
|
+
* @property minLength - Minimum length in bytes
|
|
9
|
+
* @property maxLength - Maximum length in bytes
|
|
10
|
+
*/
|
|
5
11
|
export type BytesSchemaOptions = {
|
|
6
12
|
minLength?: number
|
|
7
13
|
maxLength?: number
|
|
8
14
|
}
|
|
9
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Schema for validating binary data as Uint8Array with optional length constraints.
|
|
18
|
+
*
|
|
19
|
+
* In "parse" mode, coerces various binary formats (Buffer, ArrayBuffer, etc.)
|
|
20
|
+
* into Uint8Array. In "validate" mode, only accepts Uint8Array directly.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const schema = new BytesSchema({ maxLength: 1024 })
|
|
25
|
+
* const result = schema.validate(new Uint8Array([1, 2, 3]))
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
10
28
|
export class BytesSchema extends Schema<Uint8Array> {
|
|
29
|
+
readonly type = 'bytes' as const
|
|
30
|
+
|
|
11
31
|
constructor(readonly options: BytesSchemaOptions = {}) {
|
|
12
32
|
super()
|
|
13
33
|
}
|
|
@@ -17,7 +37,7 @@ export class BytesSchema extends Schema<Uint8Array> {
|
|
|
17
37
|
const bytes =
|
|
18
38
|
ctx.options.mode === 'parse' ? asUint8Array(input) : ifUint8Array(input)
|
|
19
39
|
if (!bytes) {
|
|
20
|
-
return ctx.
|
|
40
|
+
return ctx.issueUnexpectedType(input, 'bytes')
|
|
21
41
|
}
|
|
22
42
|
|
|
23
43
|
const { minLength } = this.options
|
|
@@ -34,6 +54,26 @@ export class BytesSchema extends Schema<Uint8Array> {
|
|
|
34
54
|
}
|
|
35
55
|
}
|
|
36
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Creates a bytes schema for validating binary data with optional length constraints.
|
|
59
|
+
*
|
|
60
|
+
* Validates Uint8Array values and can coerce other binary formats in parse mode.
|
|
61
|
+
*
|
|
62
|
+
* @param options - Optional configuration for minimum and maximum byte length
|
|
63
|
+
* @returns A new {@link BytesSchema} instance
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* // Basic bytes schema
|
|
68
|
+
* const dataSchema = l.bytes()
|
|
69
|
+
*
|
|
70
|
+
* // With size constraints
|
|
71
|
+
* const avatarSchema = l.bytes({ maxLength: 1000000 }) // 1MB max
|
|
72
|
+
*
|
|
73
|
+
* // With minimum size
|
|
74
|
+
* const hashSchema = l.bytes({ minLength: 32, maxLength: 32 }) // Exactly 32 bytes
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
37
77
|
export const bytes = /*#__PURE__*/ memoizedOptions(function (
|
|
38
78
|
options?: BytesSchemaOptions,
|
|
39
79
|
) {
|
package/src/schema/cid.ts
CHANGED
|
@@ -4,24 +4,64 @@ import { memoizedOptions } from '../util/memoize.js'
|
|
|
4
4
|
|
|
5
5
|
export type { Cid }
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Configuration options for CID schema validation.
|
|
9
|
+
*
|
|
10
|
+
* @see CheckCidOptions from @atproto/lex-data for available options
|
|
11
|
+
*/
|
|
7
12
|
export type CidSchemaOptions = CheckCidOptions
|
|
8
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Schema for validating Content Identifiers (CIDs).
|
|
16
|
+
*
|
|
17
|
+
* CIDs are self-describing content-addressed identifiers used in AT Protocol
|
|
18
|
+
* to reference data by its cryptographic hash. This schema validates that
|
|
19
|
+
* the input is a valid CID object.
|
|
20
|
+
*
|
|
21
|
+
* @template TOptions - The configuration options type
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const schema = new CidSchema()
|
|
26
|
+
* const result = schema.validate(someCid)
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
9
29
|
export class CidSchema<
|
|
10
30
|
const TOptions extends CidSchemaOptions = { flavor: undefined },
|
|
11
31
|
> extends Schema<InferCheckedCid<TOptions>> {
|
|
32
|
+
readonly type = 'cid' as const
|
|
33
|
+
|
|
12
34
|
constructor(readonly options?: TOptions) {
|
|
13
35
|
super()
|
|
14
36
|
}
|
|
15
37
|
|
|
16
38
|
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
17
39
|
if (!isCid(input, this.options)) {
|
|
18
|
-
return ctx.
|
|
40
|
+
return ctx.issueUnexpectedType(input, 'cid')
|
|
19
41
|
}
|
|
20
42
|
|
|
21
43
|
return ctx.success(input)
|
|
22
44
|
}
|
|
23
45
|
}
|
|
24
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Creates a CID schema for validating Content Identifiers.
|
|
49
|
+
*
|
|
50
|
+
* CIDs are used throughout AT Protocol to reference content by its hash.
|
|
51
|
+
* This is commonly used for referencing blobs, commits, and other data.
|
|
52
|
+
*
|
|
53
|
+
* @param options - Optional configuration for CID validation
|
|
54
|
+
* @returns A new {@link CidSchema} instance
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* // Basic CID validation
|
|
59
|
+
* const cidSchema = l.cid()
|
|
60
|
+
*
|
|
61
|
+
* // Validate a CID from a blob reference
|
|
62
|
+
* const result = cidSchema.validate(blobRef.ref)
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
25
65
|
export const cid = /*#__PURE__*/ memoizedOptions(function <
|
|
26
66
|
O extends CidSchemaOptions = NonNullable<unknown>,
|
|
27
67
|
>(options?: O) {
|