@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
|
@@ -1,796 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { integer } from './integer.js'
|
|
3
|
-
import { object } from './object.js'
|
|
4
|
-
import { string } from './string.js'
|
|
5
|
-
import { typedObject } from './typed-object.js'
|
|
6
|
-
import { typedRef } from './typed-ref.js'
|
|
7
|
-
|
|
8
|
-
describe('TypedRefSchema', () => {
|
|
9
|
-
describe('basic validation', () => {
|
|
10
|
-
it('validates through a typed object reference with explicit $type', () => {
|
|
11
|
-
const typedObjectSchema = typedObject(
|
|
12
|
-
'com.example.user',
|
|
13
|
-
'main',
|
|
14
|
-
object({
|
|
15
|
-
name: string(),
|
|
16
|
-
age: integer(),
|
|
17
|
-
}),
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
21
|
-
|
|
22
|
-
const result = schema.safeParse({
|
|
23
|
-
$type: 'com.example.user',
|
|
24
|
-
name: 'Alice',
|
|
25
|
-
age: 30,
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
expect(result.success).toBe(true)
|
|
29
|
-
if (result.success) {
|
|
30
|
-
expect(result.value.$type).toBe('com.example.user')
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('validates through a typed object with explicit $type', () => {
|
|
35
|
-
const typedObjectSchema = typedObject(
|
|
36
|
-
'com.example.user',
|
|
37
|
-
'main',
|
|
38
|
-
object({
|
|
39
|
-
name: string(),
|
|
40
|
-
age: integer(),
|
|
41
|
-
}),
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
45
|
-
|
|
46
|
-
const result = schema.safeParse({
|
|
47
|
-
$type: 'com.example.user',
|
|
48
|
-
name: 'Alice',
|
|
49
|
-
age: 30,
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
expect(result.success).toBe(true)
|
|
53
|
-
if (result.success) {
|
|
54
|
-
expect(result.value.$type).toBe('com.example.user')
|
|
55
|
-
}
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
it('rejects input with wrong $type', () => {
|
|
59
|
-
const typedObjectSchema = typedObject(
|
|
60
|
-
'com.example.user',
|
|
61
|
-
'main',
|
|
62
|
-
object({
|
|
63
|
-
name: string(),
|
|
64
|
-
}),
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
68
|
-
|
|
69
|
-
const result = schema.safeParse({
|
|
70
|
-
$type: 'com.example.wrong',
|
|
71
|
-
name: 'Alice',
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
expect(result.success).toBe(false)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('rejects invalid input through reference', () => {
|
|
78
|
-
const typedObjectSchema = typedObject(
|
|
79
|
-
'com.example.user',
|
|
80
|
-
'main',
|
|
81
|
-
object({
|
|
82
|
-
name: string(),
|
|
83
|
-
age: integer(),
|
|
84
|
-
}),
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
88
|
-
|
|
89
|
-
const result = schema.safeParse({
|
|
90
|
-
$type: 'com.example.user',
|
|
91
|
-
name: 'Alice',
|
|
92
|
-
age: 'thirty',
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
expect(result.success).toBe(false)
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it('rejects non-objects through reference', () => {
|
|
99
|
-
const typedObjectSchema = typedObject(
|
|
100
|
-
'com.example.value',
|
|
101
|
-
'main',
|
|
102
|
-
object({
|
|
103
|
-
value: string(),
|
|
104
|
-
}),
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
108
|
-
|
|
109
|
-
const result = schema.safeParse('not an object')
|
|
110
|
-
expect(result.success).toBe(false)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('rejects null through reference', () => {
|
|
114
|
-
const typedObjectSchema = typedObject(
|
|
115
|
-
'com.example.user',
|
|
116
|
-
'main',
|
|
117
|
-
object({
|
|
118
|
-
name: string(),
|
|
119
|
-
}),
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
123
|
-
|
|
124
|
-
const result = schema.safeParse(null)
|
|
125
|
-
expect(result.success).toBe(false)
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
it('rejects undefined through reference', () => {
|
|
129
|
-
const typedObjectSchema = typedObject(
|
|
130
|
-
'com.example.user',
|
|
131
|
-
'main',
|
|
132
|
-
object({
|
|
133
|
-
name: string(),
|
|
134
|
-
}),
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
138
|
-
|
|
139
|
-
const result = schema.safeParse(undefined)
|
|
140
|
-
expect(result.success).toBe(false)
|
|
141
|
-
})
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
describe('$type property', () => {
|
|
145
|
-
it('exposes the $type from the referenced schema', () => {
|
|
146
|
-
const typedObjectSchema = typedObject(
|
|
147
|
-
'com.example.post',
|
|
148
|
-
'main',
|
|
149
|
-
object({
|
|
150
|
-
text: string(),
|
|
151
|
-
}),
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
155
|
-
|
|
156
|
-
expect(schema.$type).toBe('com.example.post')
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
it('validates that output has correct $type', () => {
|
|
160
|
-
const typedObjectSchema = typedObject(
|
|
161
|
-
'com.example.like',
|
|
162
|
-
'main',
|
|
163
|
-
object({
|
|
164
|
-
subject: string(),
|
|
165
|
-
}),
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
169
|
-
|
|
170
|
-
const result = schema.safeParse({
|
|
171
|
-
$type: 'com.example.like',
|
|
172
|
-
subject: 'at://did:plc:abc/app.bsky.feed.post/123',
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
expect(result.success).toBe(true)
|
|
176
|
-
if (result.success) {
|
|
177
|
-
expect(result.value.$type).toBe('com.example.like')
|
|
178
|
-
}
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
it('ensures $type matches expected value', () => {
|
|
182
|
-
const typedObjectSchema = typedObject(
|
|
183
|
-
'com.example.follow',
|
|
184
|
-
'main',
|
|
185
|
-
object({
|
|
186
|
-
subject: string(),
|
|
187
|
-
}),
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
191
|
-
|
|
192
|
-
// Try to pass wrong $type
|
|
193
|
-
const result = schema.safeParse({
|
|
194
|
-
$type: 'com.example.block',
|
|
195
|
-
subject: 'did:plc:abc',
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
expect(result.success).toBe(false)
|
|
199
|
-
})
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
describe('lazy schema resolution', () => {
|
|
203
|
-
it('does not call getter until first validation', () => {
|
|
204
|
-
let getterCalled = false
|
|
205
|
-
|
|
206
|
-
const schema = typedRef(() => {
|
|
207
|
-
getterCalled = true
|
|
208
|
-
return typedObject(
|
|
209
|
-
'com.example.test',
|
|
210
|
-
'main',
|
|
211
|
-
object({
|
|
212
|
-
value: string(),
|
|
213
|
-
}),
|
|
214
|
-
)
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
expect(getterCalled).toBe(false)
|
|
218
|
-
|
|
219
|
-
schema.safeParse({ value: 'test' })
|
|
220
|
-
expect(getterCalled).toBe(true)
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
it('does not call getter until $type is accessed', () => {
|
|
224
|
-
let getterCalled = false
|
|
225
|
-
|
|
226
|
-
const schema = typedRef(() => {
|
|
227
|
-
getterCalled = true
|
|
228
|
-
return typedObject(
|
|
229
|
-
'com.example.test',
|
|
230
|
-
'main',
|
|
231
|
-
object({
|
|
232
|
-
value: string(),
|
|
233
|
-
}),
|
|
234
|
-
)
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
expect(getterCalled).toBe(false)
|
|
238
|
-
|
|
239
|
-
// Access $type should trigger getter
|
|
240
|
-
const type = schema.$type
|
|
241
|
-
expect(getterCalled).toBe(true)
|
|
242
|
-
expect(type).toBe('com.example.test')
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
it('throws error if getter is called recursively', () => {
|
|
246
|
-
// @ts-expect-error
|
|
247
|
-
const schema = typedRef(() => {
|
|
248
|
-
// This would cause infinite recursion if not protected
|
|
249
|
-
return schema.validator
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
expect(() => {
|
|
253
|
-
schema.safeParse({ value: 'test' })
|
|
254
|
-
}).toThrow()
|
|
255
|
-
})
|
|
256
|
-
})
|
|
257
|
-
|
|
258
|
-
describe('with constrained schemas', () => {
|
|
259
|
-
it('validates typed object with string constraints', () => {
|
|
260
|
-
const typedObjectSchema = typedObject(
|
|
261
|
-
'com.example.post',
|
|
262
|
-
'main',
|
|
263
|
-
object({
|
|
264
|
-
text: string({ minLength: 1, maxLength: 300 }),
|
|
265
|
-
}),
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
269
|
-
|
|
270
|
-
const result = schema.safeParse({
|
|
271
|
-
$type: 'com.example.post',
|
|
272
|
-
text: 'This is a valid post',
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
expect(result.success).toBe(true)
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
it('rejects typed object violating string constraints', () => {
|
|
279
|
-
const typedObjectSchema = typedObject(
|
|
280
|
-
'com.example.post',
|
|
281
|
-
'main',
|
|
282
|
-
object({
|
|
283
|
-
text: string({ minLength: 1, maxLength: 300 }),
|
|
284
|
-
}),
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
288
|
-
|
|
289
|
-
const result = schema.safeParse({
|
|
290
|
-
$type: 'com.example.post',
|
|
291
|
-
text: '',
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
expect(result.success).toBe(false)
|
|
295
|
-
})
|
|
296
|
-
|
|
297
|
-
it('validates typed object with integer constraints', () => {
|
|
298
|
-
const typedObjectSchema = typedObject(
|
|
299
|
-
'com.example.rating',
|
|
300
|
-
'main',
|
|
301
|
-
object({
|
|
302
|
-
score: integer({ minimum: 1, maximum: 5 }),
|
|
303
|
-
}),
|
|
304
|
-
)
|
|
305
|
-
|
|
306
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
307
|
-
|
|
308
|
-
const result = schema.safeParse({
|
|
309
|
-
$type: 'com.example.rating',
|
|
310
|
-
score: 4,
|
|
311
|
-
})
|
|
312
|
-
|
|
313
|
-
expect(result.success).toBe(true)
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
it('rejects typed object violating integer constraints', () => {
|
|
317
|
-
const typedObjectSchema = typedObject(
|
|
318
|
-
'com.example.rating',
|
|
319
|
-
'main',
|
|
320
|
-
object({
|
|
321
|
-
score: integer({ minimum: 1, maximum: 5 }),
|
|
322
|
-
}),
|
|
323
|
-
)
|
|
324
|
-
|
|
325
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
326
|
-
|
|
327
|
-
const result = schema.safeParse({
|
|
328
|
-
$type: 'com.example.rating',
|
|
329
|
-
score: 10,
|
|
330
|
-
})
|
|
331
|
-
|
|
332
|
-
expect(result.success).toBe(false)
|
|
333
|
-
})
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
describe('multiple validations', () => {
|
|
337
|
-
it('validates multiple inputs correctly', () => {
|
|
338
|
-
const typedObjectSchema = typedObject(
|
|
339
|
-
'com.example.user',
|
|
340
|
-
'main',
|
|
341
|
-
object({
|
|
342
|
-
name: string({ minLength: 2 }),
|
|
343
|
-
}),
|
|
344
|
-
)
|
|
345
|
-
|
|
346
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
347
|
-
|
|
348
|
-
const result1 = schema.safeParse({
|
|
349
|
-
$type: 'com.example.user',
|
|
350
|
-
name: 'Alice',
|
|
351
|
-
})
|
|
352
|
-
expect(result1.success).toBe(true)
|
|
353
|
-
|
|
354
|
-
const result2 = schema.safeParse({ $type: 'com.example.user', name: 'A' })
|
|
355
|
-
expect(result2.success).toBe(false)
|
|
356
|
-
|
|
357
|
-
const result3 = schema.safeParse({
|
|
358
|
-
$type: 'com.example.user',
|
|
359
|
-
name: 'Bob',
|
|
360
|
-
})
|
|
361
|
-
expect(result3.success).toBe(true)
|
|
362
|
-
|
|
363
|
-
const result4 = schema.safeParse({ $type: 'com.example.user', name: '' })
|
|
364
|
-
expect(result4.success).toBe(false)
|
|
365
|
-
})
|
|
366
|
-
|
|
367
|
-
it('handles different types of validation failures', () => {
|
|
368
|
-
const typedObjectSchema = typedObject(
|
|
369
|
-
'com.example.user',
|
|
370
|
-
'main',
|
|
371
|
-
object({
|
|
372
|
-
name: string({ minLength: 2 }),
|
|
373
|
-
age: integer({ minimum: 0, maximum: 150 }),
|
|
374
|
-
}),
|
|
375
|
-
)
|
|
376
|
-
|
|
377
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
378
|
-
|
|
379
|
-
const result1 = schema.safeParse({
|
|
380
|
-
$type: 'com.example.user',
|
|
381
|
-
name: 'A',
|
|
382
|
-
age: 25,
|
|
383
|
-
})
|
|
384
|
-
expect(result1.success).toBe(false)
|
|
385
|
-
|
|
386
|
-
const result2 = schema.safeParse({
|
|
387
|
-
$type: 'com.example.user',
|
|
388
|
-
name: 'Alice',
|
|
389
|
-
age: 200,
|
|
390
|
-
})
|
|
391
|
-
expect(result2.success).toBe(false)
|
|
392
|
-
|
|
393
|
-
const result3 = schema.safeParse({
|
|
394
|
-
$type: 'com.example.user',
|
|
395
|
-
name: 'Alice',
|
|
396
|
-
age: 25,
|
|
397
|
-
})
|
|
398
|
-
expect(result3.success).toBe(true)
|
|
399
|
-
|
|
400
|
-
const result4 = schema.safeParse({
|
|
401
|
-
$type: 'com.example.user',
|
|
402
|
-
name: 'Alice',
|
|
403
|
-
})
|
|
404
|
-
expect(result4.success).toBe(false)
|
|
405
|
-
})
|
|
406
|
-
|
|
407
|
-
it('validates same input multiple times consistently', () => {
|
|
408
|
-
const typedObjectSchema = typedObject(
|
|
409
|
-
'com.example.post',
|
|
410
|
-
'main',
|
|
411
|
-
object({
|
|
412
|
-
text: string(),
|
|
413
|
-
}),
|
|
414
|
-
)
|
|
415
|
-
|
|
416
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
417
|
-
|
|
418
|
-
const input = { $type: 'com.example.post', text: 'Hello world' }
|
|
419
|
-
|
|
420
|
-
const result1 = schema.safeParse(input)
|
|
421
|
-
const result2 = schema.safeParse(input)
|
|
422
|
-
const result3 = schema.safeParse(input)
|
|
423
|
-
|
|
424
|
-
expect(result1.success).toBe(true)
|
|
425
|
-
expect(result2.success).toBe(true)
|
|
426
|
-
expect(result3.success).toBe(true)
|
|
427
|
-
})
|
|
428
|
-
})
|
|
429
|
-
|
|
430
|
-
describe('edge cases', () => {
|
|
431
|
-
it('handles empty object validation', () => {
|
|
432
|
-
const typedObjectSchema = typedObject(
|
|
433
|
-
'com.example.empty',
|
|
434
|
-
'main',
|
|
435
|
-
object({}),
|
|
436
|
-
)
|
|
437
|
-
|
|
438
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
439
|
-
|
|
440
|
-
const result = schema.safeParse({ $type: 'com.example.empty' })
|
|
441
|
-
expect(result.success).toBe(true)
|
|
442
|
-
if (result.success) {
|
|
443
|
-
expect(result.value.$type).toBe('com.example.empty')
|
|
444
|
-
}
|
|
445
|
-
})
|
|
446
|
-
|
|
447
|
-
it('rejects arrays', () => {
|
|
448
|
-
const typedObjectSchema = typedObject(
|
|
449
|
-
'com.example.test',
|
|
450
|
-
'main',
|
|
451
|
-
object({
|
|
452
|
-
value: string(),
|
|
453
|
-
}),
|
|
454
|
-
)
|
|
455
|
-
|
|
456
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
457
|
-
|
|
458
|
-
const result = schema.safeParse([{ value: 'test' }])
|
|
459
|
-
expect(result.success).toBe(false)
|
|
460
|
-
})
|
|
461
|
-
|
|
462
|
-
it('rejects primitive values', () => {
|
|
463
|
-
const typedObjectSchema = typedObject(
|
|
464
|
-
'com.example.test',
|
|
465
|
-
'main',
|
|
466
|
-
object({
|
|
467
|
-
value: string(),
|
|
468
|
-
}),
|
|
469
|
-
)
|
|
470
|
-
|
|
471
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
472
|
-
|
|
473
|
-
const result1 = schema.safeParse('string')
|
|
474
|
-
expect(result1.success).toBe(false)
|
|
475
|
-
|
|
476
|
-
const result2 = schema.safeParse(123)
|
|
477
|
-
expect(result2.success).toBe(false)
|
|
478
|
-
|
|
479
|
-
const result3 = schema.safeParse(true)
|
|
480
|
-
expect(result3.success).toBe(false)
|
|
481
|
-
})
|
|
482
|
-
|
|
483
|
-
it('handles objects with extra properties', () => {
|
|
484
|
-
const typedObjectSchema = typedObject(
|
|
485
|
-
'com.example.user',
|
|
486
|
-
'main',
|
|
487
|
-
object({
|
|
488
|
-
name: string(),
|
|
489
|
-
}),
|
|
490
|
-
)
|
|
491
|
-
|
|
492
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
493
|
-
|
|
494
|
-
const result = schema.safeParse({
|
|
495
|
-
$type: 'com.example.user',
|
|
496
|
-
name: 'Alice',
|
|
497
|
-
extra: 'property',
|
|
498
|
-
another: 'value',
|
|
499
|
-
})
|
|
500
|
-
|
|
501
|
-
expect(result.success).toBe(true)
|
|
502
|
-
})
|
|
503
|
-
|
|
504
|
-
it('validates with zero values', () => {
|
|
505
|
-
const typedObjectSchema = typedObject(
|
|
506
|
-
'com.example.counter',
|
|
507
|
-
'main',
|
|
508
|
-
object({
|
|
509
|
-
count: integer(),
|
|
510
|
-
}),
|
|
511
|
-
)
|
|
512
|
-
|
|
513
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
514
|
-
|
|
515
|
-
const result = schema.safeParse({
|
|
516
|
-
$type: 'com.example.counter',
|
|
517
|
-
count: 0,
|
|
518
|
-
})
|
|
519
|
-
expect(result.success).toBe(true)
|
|
520
|
-
})
|
|
521
|
-
|
|
522
|
-
it('validates with empty strings', () => {
|
|
523
|
-
const typedObjectSchema = typedObject(
|
|
524
|
-
'com.example.text',
|
|
525
|
-
'main',
|
|
526
|
-
object({
|
|
527
|
-
content: string(),
|
|
528
|
-
}),
|
|
529
|
-
)
|
|
530
|
-
|
|
531
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
532
|
-
|
|
533
|
-
const result = schema.safeParse({
|
|
534
|
-
$type: 'com.example.text',
|
|
535
|
-
content: '',
|
|
536
|
-
})
|
|
537
|
-
expect(result.success).toBe(true)
|
|
538
|
-
})
|
|
539
|
-
|
|
540
|
-
it('rejects NaN in integer fields', () => {
|
|
541
|
-
const typedObjectSchema = typedObject(
|
|
542
|
-
'com.example.number',
|
|
543
|
-
'main',
|
|
544
|
-
object({
|
|
545
|
-
value: integer(),
|
|
546
|
-
}),
|
|
547
|
-
)
|
|
548
|
-
|
|
549
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
550
|
-
|
|
551
|
-
const result = schema.safeParse({
|
|
552
|
-
$type: 'com.example.number',
|
|
553
|
-
value: NaN,
|
|
554
|
-
})
|
|
555
|
-
expect(result.success).toBe(false)
|
|
556
|
-
})
|
|
557
|
-
|
|
558
|
-
it('rejects Infinity in integer fields', () => {
|
|
559
|
-
const typedObjectSchema = typedObject(
|
|
560
|
-
'com.example.number',
|
|
561
|
-
'main',
|
|
562
|
-
object({
|
|
563
|
-
value: integer(),
|
|
564
|
-
}),
|
|
565
|
-
)
|
|
566
|
-
|
|
567
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
568
|
-
|
|
569
|
-
const result = schema.safeParse({
|
|
570
|
-
$type: 'com.example.number',
|
|
571
|
-
value: Infinity,
|
|
572
|
-
})
|
|
573
|
-
expect(result.success).toBe(false)
|
|
574
|
-
})
|
|
575
|
-
})
|
|
576
|
-
|
|
577
|
-
describe('nested references', () => {
|
|
578
|
-
it('validates through nested TypedRefSchema', () => {
|
|
579
|
-
const typedObjectSchema = typedObject(
|
|
580
|
-
'com.example.user',
|
|
581
|
-
'main',
|
|
582
|
-
object({
|
|
583
|
-
name: string({ minLength: 2 }),
|
|
584
|
-
}),
|
|
585
|
-
)
|
|
586
|
-
|
|
587
|
-
const innerRef = typedRef(() => typedObjectSchema)
|
|
588
|
-
const outerRef = typedRef(() => innerRef.validator)
|
|
589
|
-
|
|
590
|
-
const result = outerRef.safeParse({
|
|
591
|
-
$type: 'com.example.user',
|
|
592
|
-
name: 'Alice',
|
|
593
|
-
})
|
|
594
|
-
expect(result.success).toBe(true)
|
|
595
|
-
if (result.success) {
|
|
596
|
-
expect(result.value.$type).toBe('com.example.user')
|
|
597
|
-
}
|
|
598
|
-
})
|
|
599
|
-
|
|
600
|
-
it('validates with objects containing TypedRef fields', () => {
|
|
601
|
-
const innerTyped = typedObject(
|
|
602
|
-
'com.example.profile',
|
|
603
|
-
'main',
|
|
604
|
-
object({
|
|
605
|
-
bio: string(),
|
|
606
|
-
}),
|
|
607
|
-
)
|
|
608
|
-
|
|
609
|
-
const outerTyped = typedObject(
|
|
610
|
-
'com.example.user',
|
|
611
|
-
'main',
|
|
612
|
-
object({
|
|
613
|
-
name: string(),
|
|
614
|
-
profile: typedRef(() => innerTyped),
|
|
615
|
-
}),
|
|
616
|
-
)
|
|
617
|
-
|
|
618
|
-
const schema = typedRef(() => outerTyped)
|
|
619
|
-
|
|
620
|
-
const result = schema.safeParse({
|
|
621
|
-
$type: 'com.example.user',
|
|
622
|
-
name: 'Alice',
|
|
623
|
-
profile: {
|
|
624
|
-
$type: 'com.example.profile',
|
|
625
|
-
bio: 'Software developer',
|
|
626
|
-
},
|
|
627
|
-
})
|
|
628
|
-
|
|
629
|
-
expect(result.success).toBe(true)
|
|
630
|
-
if (result.success) {
|
|
631
|
-
expect(result.value.$type).toBe('com.example.user')
|
|
632
|
-
expect(result.value.profile.$type).toBe('com.example.profile')
|
|
633
|
-
}
|
|
634
|
-
})
|
|
635
|
-
|
|
636
|
-
it('rejects nested objects with wrong $type', () => {
|
|
637
|
-
const innerTyped = typedObject(
|
|
638
|
-
'com.example.profile',
|
|
639
|
-
'main',
|
|
640
|
-
object({
|
|
641
|
-
bio: string(),
|
|
642
|
-
}),
|
|
643
|
-
)
|
|
644
|
-
|
|
645
|
-
const outerTyped = typedObject(
|
|
646
|
-
'com.example.user',
|
|
647
|
-
'main',
|
|
648
|
-
object({
|
|
649
|
-
name: string(),
|
|
650
|
-
profile: typedRef(() => innerTyped),
|
|
651
|
-
}),
|
|
652
|
-
)
|
|
653
|
-
|
|
654
|
-
const schema = typedRef(() => outerTyped)
|
|
655
|
-
|
|
656
|
-
const result = schema.safeParse({
|
|
657
|
-
$type: 'com.example.user',
|
|
658
|
-
name: 'Alice',
|
|
659
|
-
profile: {
|
|
660
|
-
$type: 'com.example.wrongtype',
|
|
661
|
-
bio: 'Software developer',
|
|
662
|
-
},
|
|
663
|
-
})
|
|
664
|
-
|
|
665
|
-
expect(result.success).toBe(false)
|
|
666
|
-
})
|
|
667
|
-
})
|
|
668
|
-
|
|
669
|
-
describe('schema property access', () => {
|
|
670
|
-
it('allows direct access to resolved schema', () => {
|
|
671
|
-
const typedObjectSchema = typedObject(
|
|
672
|
-
'com.example.test',
|
|
673
|
-
'main',
|
|
674
|
-
object({
|
|
675
|
-
value: string(),
|
|
676
|
-
}),
|
|
677
|
-
)
|
|
678
|
-
|
|
679
|
-
const refSchema = typedRef(() => typedObjectSchema)
|
|
680
|
-
|
|
681
|
-
const resolved = refSchema.validator
|
|
682
|
-
expect(resolved).toBe(typedObjectSchema)
|
|
683
|
-
expect(resolved.$type).toBe('com.example.test')
|
|
684
|
-
})
|
|
685
|
-
|
|
686
|
-
it('returns same instance on multiple schema property accesses', () => {
|
|
687
|
-
const typedObjectSchema = typedObject(
|
|
688
|
-
'com.example.test',
|
|
689
|
-
'main',
|
|
690
|
-
object({
|
|
691
|
-
value: string(),
|
|
692
|
-
}),
|
|
693
|
-
)
|
|
694
|
-
|
|
695
|
-
const refSchema = typedRef(() => typedObjectSchema)
|
|
696
|
-
|
|
697
|
-
const first = refSchema.validator
|
|
698
|
-
const second = refSchema.validator
|
|
699
|
-
const third = refSchema.validator
|
|
700
|
-
|
|
701
|
-
expect(first).toBe(second)
|
|
702
|
-
expect(second).toBe(third)
|
|
703
|
-
expect(first.$type).toBe('com.example.test')
|
|
704
|
-
})
|
|
705
|
-
})
|
|
706
|
-
|
|
707
|
-
describe('complex object structures', () => {
|
|
708
|
-
it('validates complex nested structure', () => {
|
|
709
|
-
const typedObjectSchema = typedObject(
|
|
710
|
-
'com.example.post',
|
|
711
|
-
'main',
|
|
712
|
-
object({
|
|
713
|
-
text: string({ minLength: 1, maxLength: 300 }),
|
|
714
|
-
createdAt: string({ format: 'datetime' }),
|
|
715
|
-
likeCount: integer({ minimum: 0 }),
|
|
716
|
-
}),
|
|
717
|
-
)
|
|
718
|
-
|
|
719
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
720
|
-
|
|
721
|
-
const result = schema.safeParse({
|
|
722
|
-
$type: 'com.example.post',
|
|
723
|
-
text: 'Hello world!',
|
|
724
|
-
createdAt: '2023-01-01T00:00:00Z',
|
|
725
|
-
likeCount: 42,
|
|
726
|
-
})
|
|
727
|
-
|
|
728
|
-
expect(result.success).toBe(true)
|
|
729
|
-
if (result.success) {
|
|
730
|
-
expect(result.value.$type).toBe('com.example.post')
|
|
731
|
-
expect(result.value.text).toBe('Hello world!')
|
|
732
|
-
expect(result.value.likeCount).toBe(42)
|
|
733
|
-
}
|
|
734
|
-
})
|
|
735
|
-
|
|
736
|
-
it('validates structure with multiple property types', () => {
|
|
737
|
-
const typedObjectSchema = typedObject(
|
|
738
|
-
'com.example.record',
|
|
739
|
-
'main',
|
|
740
|
-
object({
|
|
741
|
-
id: string({ format: 'nsid' }),
|
|
742
|
-
count: integer({ minimum: 0 }),
|
|
743
|
-
flag: string(),
|
|
744
|
-
}),
|
|
745
|
-
)
|
|
746
|
-
|
|
747
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
748
|
-
|
|
749
|
-
const result = schema.safeParse({
|
|
750
|
-
$type: 'com.example.record',
|
|
751
|
-
id: 'com.example.feed.post',
|
|
752
|
-
count: 100,
|
|
753
|
-
flag: 'active',
|
|
754
|
-
})
|
|
755
|
-
|
|
756
|
-
expect(result.success).toBe(true)
|
|
757
|
-
})
|
|
758
|
-
|
|
759
|
-
it('rejects structure with any invalid property', () => {
|
|
760
|
-
const typedObjectSchema = typedObject(
|
|
761
|
-
'com.example.record',
|
|
762
|
-
'main',
|
|
763
|
-
object({
|
|
764
|
-
name: string({ minLength: 1 }),
|
|
765
|
-
count: integer({ minimum: 0 }),
|
|
766
|
-
}),
|
|
767
|
-
)
|
|
768
|
-
|
|
769
|
-
const schema = typedRef(() => typedObjectSchema)
|
|
770
|
-
|
|
771
|
-
// Valid name, invalid count
|
|
772
|
-
const result1 = schema.safeParse({
|
|
773
|
-
$type: 'com.example.record',
|
|
774
|
-
name: 'test',
|
|
775
|
-
count: -5,
|
|
776
|
-
})
|
|
777
|
-
expect(result1.success).toBe(false)
|
|
778
|
-
|
|
779
|
-
// Invalid name, valid count
|
|
780
|
-
const result2 = schema.safeParse({
|
|
781
|
-
$type: 'com.example.record',
|
|
782
|
-
name: '',
|
|
783
|
-
count: 5,
|
|
784
|
-
})
|
|
785
|
-
expect(result2.success).toBe(false)
|
|
786
|
-
|
|
787
|
-
// Both invalid
|
|
788
|
-
const result3 = schema.safeParse({
|
|
789
|
-
$type: 'com.example.record',
|
|
790
|
-
name: '',
|
|
791
|
-
count: -5,
|
|
792
|
-
})
|
|
793
|
-
expect(result3.success).toBe(false)
|
|
794
|
-
})
|
|
795
|
-
})
|
|
796
|
-
})
|