@atproto/lex-schema 0.0.2 → 0.0.3
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 +68 -0
- package/dist/core/$type.d.ts +6 -3
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js +1 -0
- package/dist/core/$type.js.map +1 -1
- package/dist/core/record-key.d.ts +3 -3
- package/dist/core/record-key.d.ts.map +1 -1
- package/dist/core/record-key.js +12 -6
- package/dist/core/record-key.js.map +1 -1
- package/dist/core/result.d.ts.map +1 -1
- package/dist/core/result.js +6 -0
- package/dist/core/result.js.map +1 -1
- package/dist/core/string-format.d.ts +30 -27
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js +56 -42
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/types.d.ts +9 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/external.d.ts +31 -28
- package/dist/external.d.ts.map +1 -1
- package/dist/external.js +33 -17
- package/dist/external.js.map +1 -1
- package/dist/schema/_parameters.d.ts +2 -2
- package/dist/schema/_parameters.d.ts.map +1 -1
- package/dist/schema/array.d.ts +5 -6
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +5 -6
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +2 -3
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +1 -2
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.d.ts +4 -5
- package/dist/schema/boolean.d.ts.map +1 -1
- package/dist/schema/boolean.js +2 -3
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.d.ts +3 -4
- package/dist/schema/bytes.d.ts.map +1 -1
- package/dist/schema/bytes.js +2 -3
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +13 -6
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +2 -4
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.d.ts +3 -4
- package/dist/schema/custom.d.ts.map +1 -1
- package/dist/schema/custom.js +4 -3
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +3 -3
- 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 +15 -24
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +40 -64
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.d.ts +8 -4
- package/dist/schema/enum.d.ts.map +1 -1
- package/dist/schema/enum.js +5 -3
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.d.ts +3 -4
- package/dist/schema/integer.d.ts.map +1 -1
- package/dist/schema/integer.js +3 -4
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +22 -14
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +12 -22
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/literal.d.ts +7 -3
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +5 -3
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.d.ts +2 -2
- package/dist/schema/never.d.ts.map +1 -1
- package/dist/schema/never.js +1 -1
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.d.ts +2 -3
- package/dist/schema/null.d.ts.map +1 -1
- package/dist/schema/null.js +1 -2
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +7 -0
- package/dist/schema/nullable.d.ts.map +1 -0
- package/dist/schema/nullable.js +19 -0
- package/dist/schema/nullable.js.map +1 -0
- package/dist/schema/object.d.ts +10 -44
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +10 -46
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +7 -0
- package/dist/schema/optional.d.ts.map +1 -0
- package/dist/schema/optional.js +25 -0
- package/dist/schema/optional.js.map +1 -0
- package/dist/schema/params.d.ts +14 -19
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +10 -24
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +4 -4
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +6 -6
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +1 -2
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +0 -1
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js +0 -1
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +8 -9
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +0 -1
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +7 -8
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +0 -1
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +34 -28
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +1 -2
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +2 -3
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +1 -2
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +18 -0
- package/dist/schema/refine.d.ts.map +1 -0
- package/dist/schema/refine.js +33 -0
- package/dist/schema/refine.js.map +1 -0
- package/dist/schema/regexp.d.ts +7 -0
- package/dist/schema/regexp.d.ts.map +1 -0
- package/dist/schema/regexp.js +22 -0
- package/dist/schema/regexp.js.map +1 -0
- package/dist/schema/string.d.ts +4 -8
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +6 -3
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +7 -6
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +2 -3
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +1 -2
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +29 -27
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +1 -2
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +2 -2
- 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 +3 -4
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +3 -10
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +2 -2
- 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-object.d.ts +2 -3
- package/dist/schema/unknown-object.d.ts.map +1 -1
- package/dist/schema/unknown-object.js +1 -2
- package/dist/schema/unknown-object.js.map +1 -1
- package/dist/schema/unknown.d.ts +2 -2
- package/dist/schema/unknown.d.ts.map +1 -1
- package/dist/schema/unknown.js +1 -1
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema.d.ts +4 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +6 -1
- package/dist/schema.js.map +1 -1
- package/dist/util/array-agg.d.ts.map +1 -1
- package/dist/util/array-agg.js +1 -0
- package/dist/util/array-agg.js.map +1 -1
- package/dist/util/lazy-property.d.ts +2 -0
- package/dist/util/lazy-property.d.ts.map +1 -0
- package/dist/util/lazy-property.js +14 -0
- package/dist/util/lazy-property.js.map +1 -0
- package/dist/validation/schema.d.ts +24 -0
- package/dist/validation/schema.d.ts.map +1 -0
- package/dist/validation/schema.js +57 -0
- package/dist/validation/schema.js.map +1 -0
- package/dist/validation/validation-error.d.ts +3 -3
- package/dist/validation/validation-error.d.ts.map +1 -1
- package/dist/validation/validation-error.js +32 -4
- package/dist/validation/validation-error.js.map +1 -1
- package/dist/validation/validation-issue.d.ts +32 -24
- package/dist/validation/validation-issue.d.ts.map +1 -1
- package/dist/validation/validation-issue.js +136 -92
- package/dist/validation/validation-issue.js.map +1 -1
- package/dist/validation/validator.d.ts +20 -50
- package/dist/validation/validator.d.ts.map +1 -1
- package/dist/validation/validator.js +40 -134
- package/dist/validation/validator.js.map +1 -1
- package/dist/validation.d.ts +1 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +1 -0
- package/dist/validation.js.map +1 -1
- package/package.json +8 -4
- package/src/core/$type.ts +7 -4
- package/src/core/record-key.ts +12 -5
- package/src/core/result.ts +6 -0
- package/src/core/string-format.ts +97 -61
- package/src/core/types.ts +12 -6
- package/src/external.ts +92 -70
- package/src/schema/_parameters.test.ts +416 -0
- package/src/schema/array.test.ts +237 -0
- package/src/schema/array.ts +17 -11
- package/src/schema/blob.test.ts +506 -0
- package/src/schema/blob.ts +3 -5
- package/src/schema/boolean.test.ts +116 -0
- package/src/schema/boolean.ts +5 -7
- package/src/schema/bytes.test.ts +226 -0
- package/src/schema/bytes.ts +4 -6
- package/src/schema/cid.test.ts +155 -0
- package/src/schema/cid.ts +14 -8
- package/src/schema/custom.test.ts +413 -0
- package/src/schema/custom.ts +10 -8
- package/src/schema/dict.test.ts +198 -0
- package/src/schema/dict.ts +6 -8
- package/src/schema/discriminated-union.test.ts +675 -0
- package/src/schema/discriminated-union.ts +68 -95
- package/src/schema/enum.test.ts +396 -0
- package/src/schema/enum.ts +12 -5
- package/src/schema/integer.test.ts +312 -0
- package/src/schema/integer.ts +5 -7
- package/src/schema/intersection.test.ts +32 -0
- package/src/schema/intersection.ts +37 -40
- package/src/schema/literal.test.ts +531 -0
- package/src/schema/literal.ts +12 -5
- package/src/schema/never.test.ts +174 -0
- package/src/schema/never.ts +3 -10
- package/src/schema/null.test.ts +79 -0
- package/src/schema/null.ts +3 -5
- package/src/schema/nullable.test.ts +480 -0
- package/src/schema/nullable.ts +23 -0
- package/src/schema/object.test.ts +47 -115
- package/src/schema/object.ts +19 -123
- package/src/schema/optional.test.ts +485 -0
- package/src/schema/optional.ts +31 -0
- package/src/schema/params.test.ts +582 -0
- package/src/schema/params.ts +37 -55
- package/src/schema/payload.test.ts +345 -0
- package/src/schema/payload.ts +5 -5
- package/src/schema/permission-set.test.ts +679 -0
- package/src/schema/permission-set.ts +6 -8
- package/src/schema/permission.test.ts +536 -0
- package/src/schema/permission.ts +0 -2
- package/src/schema/procedure.test.ts +443 -0
- package/src/schema/procedure.ts +11 -13
- package/src/schema/query.test.ts +408 -0
- package/src/schema/query.ts +9 -11
- package/src/schema/record.test.ts +694 -0
- package/src/schema/record.ts +38 -36
- package/src/schema/ref.test.ts +365 -0
- package/src/schema/ref.ts +8 -5
- package/src/schema/refine.test.ts +578 -0
- package/src/schema/refine.ts +85 -0
- package/src/schema/regexp.test.ts +580 -0
- package/src/schema/regexp.ts +22 -0
- package/src/schema/string.test.ts +612 -0
- package/src/schema/string.ts +11 -17
- package/src/schema/subscription.test.ts +689 -0
- package/src/schema/subscription.ts +13 -8
- package/src/schema/token.test.ts +428 -0
- package/src/schema/token.ts +3 -5
- package/src/schema/typed-object.test.ts +612 -0
- package/src/schema/typed-object.ts +23 -20
- package/src/schema/typed-ref.test.ts +823 -0
- package/src/schema/typed-ref.ts +10 -5
- package/src/schema/typed-union.test.ts +378 -0
- package/src/schema/typed-union.ts +6 -15
- package/src/schema/union.test.ts +200 -0
- package/src/schema/union.ts +5 -4
- package/src/schema/unknown-object.test.ts +592 -0
- package/src/schema/unknown-object.ts +3 -5
- package/src/schema/unknown.test.ts +312 -0
- package/src/schema/unknown.ts +3 -3
- package/src/schema.ts +7 -1
- package/src/util/array-agg.ts +1 -0
- package/src/util/lazy-property.ts +14 -0
- package/src/validation/schema.ts +92 -0
- package/src/validation/validation-error.ts +60 -9
- package/src/validation/validation-issue.ts +141 -144
- package/src/validation/validator.ts +67 -206
- package/src/validation.ts +1 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +7 -0
- package/tsconfig.tests.json +9 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { BytesSchema } from './bytes.js'
|
|
2
|
+
|
|
3
|
+
describe('BytesSchema', () => {
|
|
4
|
+
describe('basic validation', () => {
|
|
5
|
+
const schema = new BytesSchema({})
|
|
6
|
+
|
|
7
|
+
it('validates Uint8Array', () => {
|
|
8
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2, 3]))
|
|
9
|
+
expect(result.success).toBe(true)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('validates empty Uint8Array', () => {
|
|
13
|
+
const result = schema.safeParse(new Uint8Array([]))
|
|
14
|
+
expect(result.success).toBe(true)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('validates ArrayBuffer', () => {
|
|
18
|
+
const buffer = new ArrayBuffer(4)
|
|
19
|
+
const result = schema.safeParse(buffer)
|
|
20
|
+
expect(result.success).toBe(true)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('validates TypedArray views', () => {
|
|
24
|
+
const int8 = new Int8Array([1, 2, 3])
|
|
25
|
+
const result = schema.safeParse(int8)
|
|
26
|
+
expect(result.success).toBe(true)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('validates Uint16Array', () => {
|
|
30
|
+
const uint16 = new Uint16Array([1, 2, 3])
|
|
31
|
+
const result = schema.safeParse(uint16)
|
|
32
|
+
expect(result.success).toBe(true)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('validates DataView', () => {
|
|
36
|
+
const buffer = new ArrayBuffer(4)
|
|
37
|
+
const dataView = new DataView(buffer)
|
|
38
|
+
const result = schema.safeParse(dataView)
|
|
39
|
+
expect(result.success).toBe(true)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('rejects strings', () => {
|
|
43
|
+
const result = schema.safeParse('not bytes')
|
|
44
|
+
expect(result.success).toBe(false)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('rejects numbers', () => {
|
|
48
|
+
const result = schema.safeParse(123)
|
|
49
|
+
expect(result.success).toBe(false)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('rejects objects', () => {
|
|
53
|
+
const result = schema.safeParse({ data: [1, 2, 3] })
|
|
54
|
+
expect(result.success).toBe(false)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('rejects arrays', () => {
|
|
58
|
+
const result = schema.safeParse([1, 2, 3])
|
|
59
|
+
expect(result.success).toBe(false)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('rejects null', () => {
|
|
63
|
+
const result = schema.safeParse(null)
|
|
64
|
+
expect(result.success).toBe(false)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('rejects undefined', () => {
|
|
68
|
+
const result = schema.safeParse(undefined)
|
|
69
|
+
expect(result.success).toBe(false)
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe('minLength constraint', () => {
|
|
74
|
+
const schema = new BytesSchema({ minLength: 3 })
|
|
75
|
+
|
|
76
|
+
it('validates bytes at minimum length', () => {
|
|
77
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2]))
|
|
78
|
+
expect(result.success).toBe(true)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('validates bytes above minimum length', () => {
|
|
82
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2, 3, 4]))
|
|
83
|
+
expect(result.success).toBe(true)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('rejects bytes below minimum length', () => {
|
|
87
|
+
const result = schema.safeParse(new Uint8Array([0, 1]))
|
|
88
|
+
expect(result.success).toBe(false)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('rejects empty bytes when minLength is set', () => {
|
|
92
|
+
const result = schema.safeParse(new Uint8Array([]))
|
|
93
|
+
expect(result.success).toBe(false)
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('maxLength constraint', () => {
|
|
98
|
+
const schema = new BytesSchema({ maxLength: 5 })
|
|
99
|
+
|
|
100
|
+
it('validates bytes at maximum length', () => {
|
|
101
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2, 3, 4]))
|
|
102
|
+
expect(result.success).toBe(true)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('validates bytes below maximum length', () => {
|
|
106
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2]))
|
|
107
|
+
expect(result.success).toBe(true)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('validates empty bytes when only maxLength is set', () => {
|
|
111
|
+
const result = schema.safeParse(new Uint8Array([]))
|
|
112
|
+
expect(result.success).toBe(true)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('rejects bytes above maximum length', () => {
|
|
116
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2, 3, 4, 5]))
|
|
117
|
+
expect(result.success).toBe(false)
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
describe('minLength and maxLength constraints', () => {
|
|
122
|
+
const schema = new BytesSchema({ minLength: 2, maxLength: 5 })
|
|
123
|
+
|
|
124
|
+
it('validates bytes within range', () => {
|
|
125
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2]))
|
|
126
|
+
expect(result.success).toBe(true)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('validates bytes at minimum length', () => {
|
|
130
|
+
const result = schema.safeParse(new Uint8Array([0, 1]))
|
|
131
|
+
expect(result.success).toBe(true)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('validates bytes at maximum length', () => {
|
|
135
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2, 3, 4]))
|
|
136
|
+
expect(result.success).toBe(true)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('rejects bytes below minimum length', () => {
|
|
140
|
+
const result = schema.safeParse(new Uint8Array([0]))
|
|
141
|
+
expect(result.success).toBe(false)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('rejects bytes above maximum length', () => {
|
|
145
|
+
const result = schema.safeParse(new Uint8Array([0, 1, 2, 3, 4, 5]))
|
|
146
|
+
expect(result.success).toBe(false)
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
describe('edge cases', () => {
|
|
151
|
+
it('validates with minLength of 0', () => {
|
|
152
|
+
const schema = new BytesSchema({ minLength: 0 })
|
|
153
|
+
const result = schema.safeParse(new Uint8Array([]))
|
|
154
|
+
expect(result.success).toBe(true)
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('validates with maxLength of 0', () => {
|
|
158
|
+
const schema = new BytesSchema({ maxLength: 0 })
|
|
159
|
+
const result = schema.safeParse(new Uint8Array([]))
|
|
160
|
+
expect(result.success).toBe(true)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
it('rejects non-empty bytes with maxLength of 0', () => {
|
|
164
|
+
const schema = new BytesSchema({ maxLength: 0 })
|
|
165
|
+
const result = schema.safeParse(new Uint8Array([0]))
|
|
166
|
+
expect(result.success).toBe(false)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('validates bytes with all zeros', () => {
|
|
170
|
+
const schema = new BytesSchema({})
|
|
171
|
+
const result = schema.safeParse(new Uint8Array([0, 0, 0, 0]))
|
|
172
|
+
expect(result.success).toBe(true)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it('validates bytes with all 255s', () => {
|
|
176
|
+
const schema = new BytesSchema({})
|
|
177
|
+
const result = schema.safeParse(new Uint8Array([255, 255, 255, 255]))
|
|
178
|
+
expect(result.success).toBe(true)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
it('validates large byte arrays', () => {
|
|
182
|
+
const schema = new BytesSchema({})
|
|
183
|
+
const largeArray = new Uint8Array(10000)
|
|
184
|
+
const result = schema.safeParse(largeArray)
|
|
185
|
+
expect(result.success).toBe(true)
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
describe('TypedArray coercion', () => {
|
|
190
|
+
const schema = new BytesSchema({})
|
|
191
|
+
|
|
192
|
+
it('coerces Int8Array to Uint8Array', () => {
|
|
193
|
+
const int8 = new Int8Array([1, 2, 3])
|
|
194
|
+
const result = schema.safeParse(int8)
|
|
195
|
+
expect(result.success).toBe(true)
|
|
196
|
+
if (result.success) {
|
|
197
|
+
expect(result.value).toBeInstanceOf(Uint8Array)
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
it('coerces Uint16Array to Uint8Array', () => {
|
|
202
|
+
const uint16 = new Uint16Array([256, 512])
|
|
203
|
+
const result = schema.safeParse(uint16)
|
|
204
|
+
expect(result.success).toBe(true)
|
|
205
|
+
if (result.success) {
|
|
206
|
+
expect(result.value).toBeInstanceOf(Uint8Array)
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
it('coerces Float32Array to Uint8Array', () => {
|
|
211
|
+
const float32 = new Float32Array([1.5, 2.5])
|
|
212
|
+
const result = schema.safeParse(float32)
|
|
213
|
+
expect(result.success).toBe(true)
|
|
214
|
+
if (result.success) {
|
|
215
|
+
expect(result.value).toBeInstanceOf(Uint8Array)
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
it('validates coerced TypedArray with length constraints', () => {
|
|
220
|
+
const schema = new BytesSchema({ minLength: 2, maxLength: 10 })
|
|
221
|
+
const int16 = new Int16Array([1, 2, 3]) // 6 bytes
|
|
222
|
+
const result = schema.safeParse(int16)
|
|
223
|
+
expect(result.success).toBe(true)
|
|
224
|
+
})
|
|
225
|
+
})
|
|
226
|
+
})
|
package/src/schema/bytes.ts
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { asUint8Array } from '@atproto/lex-data'
|
|
2
|
-
import {
|
|
2
|
+
import { Schema, ValidationResult, ValidatorContext } from '../validation.js'
|
|
3
3
|
|
|
4
4
|
export type BytesSchemaOptions = {
|
|
5
5
|
minLength?: number
|
|
6
6
|
maxLength?: number
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export class BytesSchema extends
|
|
10
|
-
readonly
|
|
11
|
-
|
|
12
|
-
constructor(readonly options: BytesSchemaOptions) {
|
|
9
|
+
export class BytesSchema extends Schema<Uint8Array> {
|
|
10
|
+
constructor(readonly options: BytesSchemaOptions = {}) {
|
|
13
11
|
super()
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
validateInContext(
|
|
17
15
|
input: unknown,
|
|
18
16
|
ctx: ValidatorContext,
|
|
19
17
|
): ValidationResult<Uint8Array> {
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { parseCid } from '@atproto/lex-data'
|
|
2
|
+
import { CidSchema } from './cid.js'
|
|
3
|
+
|
|
4
|
+
describe('CidSchema', () => {
|
|
5
|
+
describe('default mode (non-strict)', () => {
|
|
6
|
+
const schema = new CidSchema()
|
|
7
|
+
|
|
8
|
+
it('validates CID v1 with DAG-CBOR codec and SHA-256', () => {
|
|
9
|
+
const cid = parseCid(
|
|
10
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
11
|
+
)
|
|
12
|
+
const result = schema.safeParse(cid)
|
|
13
|
+
expect(result.success).toBe(true)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('validates CID v1 with raw binary codec', () => {
|
|
17
|
+
const cid = parseCid(
|
|
18
|
+
'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4',
|
|
19
|
+
)
|
|
20
|
+
const result = schema.safeParse(cid)
|
|
21
|
+
expect(result.success).toBe(true)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('validates CID v0', () => {
|
|
25
|
+
const cid = parseCid('QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB')
|
|
26
|
+
const result = schema.safeParse(cid)
|
|
27
|
+
expect(result.success).toBe(true)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('validates multiple different CIDs', () => {
|
|
31
|
+
const cids = [
|
|
32
|
+
parseCid('bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'),
|
|
33
|
+
parseCid('bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q'),
|
|
34
|
+
parseCid('bafyreiaizynclnqiolq7byfpjjtgqzn4sfrsgn7z2hhf6bo4utdwkin7ke'),
|
|
35
|
+
parseCid('bafyreifd4w4tcr5tluxz7osjtnofffvtsmgdqcfrfi6evjde4pl27lrjpy'),
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
for (const cid of cids) {
|
|
39
|
+
const result = schema.safeParse(cid)
|
|
40
|
+
expect(result.success).toBe(true)
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('rejects non-CID objects', () => {
|
|
45
|
+
const result = schema.safeParse({ not: 'a cid' })
|
|
46
|
+
expect(result.success).toBe(false)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('rejects strings', () => {
|
|
50
|
+
const result = schema.safeParse(
|
|
51
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
52
|
+
)
|
|
53
|
+
expect(result.success).toBe(false)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('rejects numbers', () => {
|
|
57
|
+
const result = schema.safeParse(123)
|
|
58
|
+
expect(result.success).toBe(false)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('rejects null', () => {
|
|
62
|
+
const result = schema.safeParse(null)
|
|
63
|
+
expect(result.success).toBe(false)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('rejects undefined', () => {
|
|
67
|
+
const result = schema.safeParse(undefined)
|
|
68
|
+
expect(result.success).toBe(false)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('rejects arrays', () => {
|
|
72
|
+
const result = schema.safeParse([])
|
|
73
|
+
expect(result.success).toBe(false)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('rejects booleans', () => {
|
|
77
|
+
const result = schema.safeParse(true)
|
|
78
|
+
expect(result.success).toBe(false)
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
describe('strict mode', () => {
|
|
83
|
+
const schema = new CidSchema({ strict: true })
|
|
84
|
+
|
|
85
|
+
it('validates CID v1 with DAG-CBOR codec and SHA-256', () => {
|
|
86
|
+
const cid = parseCid(
|
|
87
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
88
|
+
)
|
|
89
|
+
const result = schema.safeParse(cid)
|
|
90
|
+
expect(result.success).toBe(true)
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it('validates CID v1 with raw binary codec and SHA-256', () => {
|
|
94
|
+
const cid = parseCid(
|
|
95
|
+
'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4',
|
|
96
|
+
)
|
|
97
|
+
const result = schema.safeParse(cid)
|
|
98
|
+
expect(result.success).toBe(true)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('rejects CID v0', () => {
|
|
102
|
+
const cid = parseCid('QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB')
|
|
103
|
+
const result = schema.safeParse(cid)
|
|
104
|
+
expect(result.success).toBe(false)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('rejects CID v1 with non-standard codec', () => {
|
|
108
|
+
// Using git-raw codec (0x78) instead of DAG-CBOR or raw binary
|
|
109
|
+
const cid = parseCid(
|
|
110
|
+
'bafybeigvgzoolc3drupxhlevdp2ugqcrbcsqfmcek2zxiw5wctk3xjpjwy',
|
|
111
|
+
)
|
|
112
|
+
const result = schema.safeParse(cid)
|
|
113
|
+
expect(result.success).toBe(false)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('rejects CID v1 with non-SHA-256 hash', () => {
|
|
117
|
+
// Using SHA-512 (0x13) instead of SHA-256
|
|
118
|
+
const cid = parseCid(
|
|
119
|
+
'bafybgqfcn3rz4mdzywp2jb6mjvpdq24rxjvbmdcmizrjdgx2ujjpvj4kxf4d62ywrzm6njk44cxhha4pj3bkvqz2esfgrm7mdkdcqcxjibf7c',
|
|
120
|
+
)
|
|
121
|
+
const result = schema.safeParse(cid)
|
|
122
|
+
expect(result.success).toBe(false)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('rejects non-CID objects', () => {
|
|
126
|
+
const result = schema.safeParse({ not: 'a cid' })
|
|
127
|
+
expect(result.success).toBe(false)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('rejects strings', () => {
|
|
131
|
+
const result = schema.safeParse(
|
|
132
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
133
|
+
)
|
|
134
|
+
expect(result.success).toBe(false)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('rejects null', () => {
|
|
138
|
+
const result = schema.safeParse(null)
|
|
139
|
+
expect(result.success).toBe(false)
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
describe('options', () => {
|
|
144
|
+
it('stores the provided options', () => {
|
|
145
|
+
const options = { strict: true }
|
|
146
|
+
const schema = new CidSchema(options)
|
|
147
|
+
expect(schema.options).toEqual(options)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
it('defaults to empty options', () => {
|
|
151
|
+
const schema = new CidSchema()
|
|
152
|
+
expect(schema.options).toEqual({})
|
|
153
|
+
})
|
|
154
|
+
})
|
|
155
|
+
})
|
package/src/schema/cid.ts
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Cid, isCid } from '@atproto/lex-data'
|
|
2
|
+
import { Schema, ValidationResult, ValidatorContext } from '../validation.js'
|
|
3
3
|
|
|
4
|
-
export {
|
|
4
|
+
export type { Cid }
|
|
5
5
|
|
|
6
6
|
export type CidSchemaOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* In strict mode, only CID with the following properties are accepted:
|
|
9
|
+
* - version: 1
|
|
10
|
+
* - codec: raw binary (0x55) or DAG-CBOR (0x71)
|
|
11
|
+
* - hash function: SHA-256 (0x12)
|
|
12
|
+
*
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
7
15
|
strict?: boolean
|
|
8
16
|
}
|
|
9
17
|
|
|
10
|
-
export class CidSchema extends
|
|
11
|
-
readonly lexiconType = 'cid-link' as const
|
|
12
|
-
|
|
18
|
+
export class CidSchema extends Schema<Cid> {
|
|
13
19
|
constructor(readonly options: CidSchemaOptions = {}) {
|
|
14
20
|
super()
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
validateInContext(
|
|
18
24
|
input: unknown,
|
|
19
25
|
ctx: ValidatorContext,
|
|
20
|
-
): ValidationResult<
|
|
26
|
+
): ValidationResult<Cid> {
|
|
21
27
|
if (!isCid(input, this.options)) {
|
|
22
28
|
return ctx.issueInvalidType(input, 'cid')
|
|
23
29
|
}
|