@atproto/lex-schema 0.0.9 → 0.0.11

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.
Files changed (280) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE.txt +1 -1
  3. package/dist/core/$type.d.ts +11 -0
  4. package/dist/core/$type.d.ts.map +1 -1
  5. package/dist/core/$type.js +4 -0
  6. package/dist/core/$type.js.map +1 -1
  7. package/dist/core/schema.d.ts +31 -24
  8. package/dist/core/schema.d.ts.map +1 -1
  9. package/dist/core/schema.js +38 -8
  10. package/dist/core/schema.js.map +1 -1
  11. package/dist/core/string-format.d.ts +35 -35
  12. package/dist/core/string-format.d.ts.map +1 -1
  13. package/dist/core/string-format.js +49 -91
  14. package/dist/core/string-format.js.map +1 -1
  15. package/dist/core/validation-error.d.ts +1 -1
  16. package/dist/core/validation-issue.js +1 -1
  17. package/dist/core/validation-issue.js.map +1 -1
  18. package/dist/core/validator.d.ts +53 -32
  19. package/dist/core/validator.d.ts.map +1 -1
  20. package/dist/core/validator.js +18 -22
  21. package/dist/core/validator.js.map +1 -1
  22. package/dist/external.d.ts +0 -85
  23. package/dist/external.d.ts.map +1 -1
  24. package/dist/external.js +0 -164
  25. package/dist/external.js.map +1 -1
  26. package/dist/helpers.d.ts +13 -5
  27. package/dist/helpers.d.ts.map +1 -1
  28. package/dist/helpers.js +4 -4
  29. package/dist/helpers.js.map +1 -1
  30. package/dist/schema/array.d.ts +9 -5
  31. package/dist/schema/array.d.ts.map +1 -1
  32. package/dist/schema/array.js +14 -5
  33. package/dist/schema/array.js.map +1 -1
  34. package/dist/schema/blob.d.ts +9 -7
  35. package/dist/schema/blob.d.ts.map +1 -1
  36. package/dist/schema/blob.js +9 -5
  37. package/dist/schema/blob.js.map +1 -1
  38. package/dist/schema/boolean.d.ts +3 -7
  39. package/dist/schema/boolean.d.ts.map +1 -1
  40. package/dist/schema/boolean.js +6 -7
  41. package/dist/schema/boolean.js.map +1 -1
  42. package/dist/schema/bytes.d.ts +3 -2
  43. package/dist/schema/bytes.d.ts.map +1 -1
  44. package/dist/schema/bytes.js +7 -3
  45. package/dist/schema/bytes.js.map +1 -1
  46. package/dist/schema/cid.d.ts +7 -7
  47. package/dist/schema/cid.d.ts.map +1 -1
  48. package/dist/schema/cid.js +5 -1
  49. package/dist/schema/cid.js.map +1 -1
  50. package/dist/schema/custom.d.ts +6 -5
  51. package/dist/schema/custom.d.ts.map +1 -1
  52. package/dist/schema/custom.js +10 -4
  53. package/dist/schema/custom.js.map +1 -1
  54. package/dist/schema/dict.d.ts +8 -8
  55. package/dist/schema/dict.d.ts.map +1 -1
  56. package/dist/schema/dict.js +11 -2
  57. package/dist/schema/dict.js.map +1 -1
  58. package/dist/schema/discriminated-union.d.ts +21 -14
  59. package/dist/schema/discriminated-union.d.ts.map +1 -1
  60. package/dist/schema/discriminated-union.js +7 -0
  61. package/dist/schema/discriminated-union.js.map +1 -1
  62. package/dist/schema/enum.d.ts +7 -9
  63. package/dist/schema/enum.d.ts.map +1 -1
  64. package/dist/schema/enum.js +8 -4
  65. package/dist/schema/enum.js.map +1 -1
  66. package/dist/schema/integer.d.ts +5 -5
  67. package/dist/schema/integer.d.ts.map +1 -1
  68. package/dist/schema/integer.js +9 -5
  69. package/dist/schema/integer.js.map +1 -1
  70. package/dist/schema/intersection.d.ts +4 -4
  71. package/dist/schema/intersection.d.ts.map +1 -1
  72. package/dist/schema/intersection.js +5 -0
  73. package/dist/schema/intersection.js.map +1 -1
  74. package/dist/schema/literal.d.ts +6 -9
  75. package/dist/schema/literal.d.ts.map +1 -1
  76. package/dist/schema/literal.js +7 -4
  77. package/dist/schema/literal.js.map +1 -1
  78. package/dist/schema/never.d.ts +3 -2
  79. package/dist/schema/never.d.ts.map +1 -1
  80. package/dist/schema/never.js +5 -1
  81. package/dist/schema/never.js.map +1 -1
  82. package/dist/schema/null.d.ts +4 -3
  83. package/dist/schema/null.d.ts.map +1 -1
  84. package/dist/schema/null.js +6 -4
  85. package/dist/schema/null.js.map +1 -1
  86. package/dist/schema/nullable.d.ts +6 -5
  87. package/dist/schema/nullable.d.ts.map +1 -1
  88. package/dist/schema/nullable.js +9 -5
  89. package/dist/schema/nullable.js.map +1 -1
  90. package/dist/schema/object.d.ts +10 -8
  91. package/dist/schema/object.d.ts.map +1 -1
  92. package/dist/schema/object.js +11 -3
  93. package/dist/schema/object.js.map +1 -1
  94. package/dist/schema/optional.d.ts +7 -5
  95. package/dist/schema/optional.d.ts.map +1 -1
  96. package/dist/schema/optional.js +14 -6
  97. package/dist/schema/optional.js.map +1 -1
  98. package/dist/schema/params.d.ts +26 -13
  99. package/dist/schema/params.d.ts.map +1 -1
  100. package/dist/schema/params.js +47 -25
  101. package/dist/schema/params.js.map +1 -1
  102. package/dist/schema/payload.d.ts +12 -9
  103. package/dist/schema/payload.d.ts.map +1 -1
  104. package/dist/schema/payload.js +11 -0
  105. package/dist/schema/payload.js.map +1 -1
  106. package/dist/schema/permission-set.d.ts +1 -0
  107. package/dist/schema/permission-set.d.ts.map +1 -1
  108. package/dist/schema/permission-set.js +5 -0
  109. package/dist/schema/permission-set.js.map +1 -1
  110. package/dist/schema/permission.d.ts +6 -5
  111. package/dist/schema/permission.d.ts.map +1 -1
  112. package/dist/schema/permission.js +5 -0
  113. package/dist/schema/permission.js.map +1 -1
  114. package/dist/schema/procedure.d.ts +2 -1
  115. package/dist/schema/procedure.d.ts.map +1 -1
  116. package/dist/schema/procedure.js +5 -0
  117. package/dist/schema/procedure.js.map +1 -1
  118. package/dist/schema/query.d.ts +2 -1
  119. package/dist/schema/query.d.ts.map +1 -1
  120. package/dist/schema/query.js +5 -0
  121. package/dist/schema/query.js.map +1 -1
  122. package/dist/schema/record.d.ts +48 -30
  123. package/dist/schema/record.d.ts.map +1 -1
  124. package/dist/schema/record.js +12 -9
  125. package/dist/schema/record.js.map +1 -1
  126. package/dist/schema/ref.d.ts +9 -6
  127. package/dist/schema/ref.d.ts.map +1 -1
  128. package/dist/schema/ref.js +9 -16
  129. package/dist/schema/ref.js.map +1 -1
  130. package/dist/schema/refine.d.ts +4 -4
  131. package/dist/schema/refine.d.ts.map +1 -1
  132. package/dist/schema/refine.js.map +1 -1
  133. package/dist/schema/regexp.d.ts +4 -3
  134. package/dist/schema/regexp.d.ts.map +1 -1
  135. package/dist/schema/regexp.js +5 -0
  136. package/dist/schema/regexp.js.map +1 -1
  137. package/dist/schema/string.d.ts +7 -8
  138. package/dist/schema/string.d.ts.map +1 -1
  139. package/dist/schema/string.js +13 -19
  140. package/dist/schema/string.js.map +1 -1
  141. package/dist/schema/subscription.d.ts +2 -1
  142. package/dist/schema/subscription.d.ts.map +1 -1
  143. package/dist/schema/subscription.js +5 -0
  144. package/dist/schema/subscription.js.map +1 -1
  145. package/dist/schema/token.d.ts +6 -5
  146. package/dist/schema/token.d.ts.map +1 -1
  147. package/dist/schema/token.js +5 -0
  148. package/dist/schema/token.js.map +1 -1
  149. package/dist/schema/typed-object.d.ts +43 -26
  150. package/dist/schema/typed-object.d.ts.map +1 -1
  151. package/dist/schema/typed-object.js +6 -3
  152. package/dist/schema/typed-object.js.map +1 -1
  153. package/dist/schema/typed-ref.d.ts +16 -25
  154. package/dist/schema/typed-ref.d.ts.map +1 -1
  155. package/dist/schema/typed-ref.js +7 -17
  156. package/dist/schema/typed-ref.js.map +1 -1
  157. package/dist/schema/typed-union.d.ts +9 -21
  158. package/dist/schema/typed-union.d.ts.map +1 -1
  159. package/dist/schema/typed-union.js +15 -11
  160. package/dist/schema/typed-union.js.map +1 -1
  161. package/dist/schema/union.d.ts +6 -6
  162. package/dist/schema/union.d.ts.map +1 -1
  163. package/dist/schema/union.js +7 -5
  164. package/dist/schema/union.js.map +1 -1
  165. package/dist/schema/unknown-object.d.ts +5 -4
  166. package/dist/schema/unknown-object.d.ts.map +1 -1
  167. package/dist/schema/unknown-object.js +5 -1
  168. package/dist/schema/unknown-object.js.map +1 -1
  169. package/dist/schema/unknown.d.ts +3 -2
  170. package/dist/schema/unknown.d.ts.map +1 -1
  171. package/dist/schema/unknown.js +5 -1
  172. package/dist/schema/unknown.js.map +1 -1
  173. package/dist/schema/with-default.d.ts +9 -0
  174. package/dist/schema/with-default.d.ts.map +1 -0
  175. package/dist/schema/with-default.js +27 -0
  176. package/dist/schema/with-default.js.map +1 -0
  177. package/dist/schema.d.ts +2 -2
  178. package/dist/schema.d.ts.map +1 -1
  179. package/dist/schema.js +2 -4
  180. package/dist/schema.js.map +1 -1
  181. package/dist/util/assertion-util.d.ts +0 -6
  182. package/dist/util/assertion-util.d.ts.map +1 -1
  183. package/dist/util/assertion-util.js +0 -28
  184. package/dist/util/assertion-util.js.map +1 -1
  185. package/dist/util/memoize.d.ts +2 -2
  186. package/dist/util/memoize.d.ts.map +1 -1
  187. package/dist/util/memoize.js +23 -39
  188. package/dist/util/memoize.js.map +1 -1
  189. package/package.json +3 -3
  190. package/src/core/$type.test.ts +20 -0
  191. package/src/core/$type.ts +30 -0
  192. package/src/core/schema.ts +86 -38
  193. package/src/core/string-format.ts +119 -158
  194. package/src/core/validation-issue.ts +1 -1
  195. package/src/core/validator.ts +93 -53
  196. package/src/external.ts +0 -404
  197. package/src/helpers.test.ts +22 -21
  198. package/src/helpers.ts +19 -14
  199. package/src/schema/array.test.ts +38 -40
  200. package/src/schema/array.ts +35 -13
  201. package/src/schema/blob.test.ts +21 -21
  202. package/src/schema/blob.ts +19 -17
  203. package/src/schema/boolean.test.ts +9 -8
  204. package/src/schema/boolean.ts +7 -13
  205. package/src/schema/bytes.test.ts +13 -13
  206. package/src/schema/bytes.ts +13 -8
  207. package/src/schema/cid.test.ts +3 -3
  208. package/src/schema/cid.ts +13 -12
  209. package/src/schema/custom.test.ts +26 -26
  210. package/src/schema/custom.ts +20 -13
  211. package/src/schema/dict.test.ts +21 -39
  212. package/src/schema/dict.ts +28 -19
  213. package/src/schema/discriminated-union.test.ts +128 -128
  214. package/src/schema/discriminated-union.ts +45 -26
  215. package/src/schema/enum.test.ts +17 -16
  216. package/src/schema/enum.ts +16 -16
  217. package/src/schema/integer.test.ts +22 -21
  218. package/src/schema/integer.ts +12 -9
  219. package/src/schema/intersection.test.ts +10 -10
  220. package/src/schema/intersection.ts +17 -14
  221. package/src/schema/literal.test.ts +35 -34
  222. package/src/schema/literal.ts +12 -15
  223. package/src/schema/never.test.ts +5 -5
  224. package/src/schema/never.ts +7 -2
  225. package/src/schema/null.test.ts +3 -3
  226. package/src/schema/null.ts +9 -9
  227. package/src/schema/nullable.test.ts +31 -42
  228. package/src/schema/nullable.ts +17 -9
  229. package/src/schema/object.test.ts +10 -12
  230. package/src/schema/object.ts +27 -18
  231. package/src/schema/optional.test.ts +21 -28
  232. package/src/schema/optional.ts +27 -10
  233. package/src/schema/params.test.ts +471 -47
  234. package/src/schema/params.ts +74 -38
  235. package/src/schema/payload.test.ts +150 -156
  236. package/src/schema/payload.ts +35 -19
  237. package/src/schema/permission-set.test.ts +206 -273
  238. package/src/schema/permission-set.ts +8 -0
  239. package/src/schema/permission.test.ts +177 -177
  240. package/src/schema/permission.ts +13 -5
  241. package/src/schema/procedure.test.ts +183 -242
  242. package/src/schema/procedure.ts +18 -5
  243. package/src/schema/query.test.ts +186 -200
  244. package/src/schema/query.ts +16 -4
  245. package/src/schema/record.test.ts +121 -101
  246. package/src/schema/record.ts +74 -40
  247. package/src/schema/ref.test.ts +101 -118
  248. package/src/schema/ref.ts +33 -28
  249. package/src/schema/refine.test.ts +28 -28
  250. package/src/schema/refine.ts +23 -20
  251. package/src/schema/regexp.test.ts +29 -33
  252. package/src/schema/regexp.ts +11 -7
  253. package/src/schema/string.test.ts +35 -35
  254. package/src/schema/string.ts +24 -33
  255. package/src/schema/subscription.test.ts +259 -387
  256. package/src/schema/subscription.ts +16 -4
  257. package/src/schema/token.test.ts +47 -324
  258. package/src/schema/token.ts +14 -7
  259. package/src/schema/typed-object.test.ts +98 -81
  260. package/src/schema/typed-object.ts +68 -33
  261. package/src/schema/typed-ref.test.ts +206 -234
  262. package/src/schema/typed-ref.ts +40 -42
  263. package/src/schema/typed-union.test.ts +40 -64
  264. package/src/schema/typed-union.ts +36 -58
  265. package/src/schema/union.test.ts +17 -27
  266. package/src/schema/union.ts +20 -16
  267. package/src/schema/unknown-object.test.ts +8 -8
  268. package/src/schema/unknown-object.ts +9 -7
  269. package/src/schema/unknown.test.ts +4 -4
  270. package/src/schema/unknown.ts +7 -5
  271. package/src/schema/with-default.ts +35 -0
  272. package/src/schema.ts +2 -6
  273. package/src/util/assertion-util.ts +0 -39
  274. package/src/util/memoize.ts +26 -46
  275. package/dist/schema/_parameters.d.ts +0 -17
  276. package/dist/schema/_parameters.d.ts.map +0 -1
  277. package/dist/schema/_parameters.js +0 -20
  278. package/dist/schema/_parameters.js.map +0 -1
  279. package/src/schema/_parameters.test.ts +0 -417
  280. package/src/schema/_parameters.ts +0 -26
@@ -1,21 +1,21 @@
1
1
  import { describe, expect, it } from 'vitest'
2
- import { DiscriminatedUnionSchema } from './discriminated-union.js'
3
- import { EnumSchema } from './enum.js'
4
- import { IntegerSchema } from './integer.js'
5
- import { LiteralSchema } from './literal.js'
6
- import { ObjectSchema } from './object.js'
7
- import { StringSchema } from './string.js'
2
+ import { discriminatedUnion } from './discriminated-union.js'
3
+ import { enumSchema } from './enum.js'
4
+ import { integer } from './integer.js'
5
+ import { literal } from './literal.js'
6
+ import { object } from './object.js'
7
+ import { string } from './string.js'
8
8
 
9
9
  describe('DiscriminatedUnionSchema', () => {
10
10
  describe('with literal discriminators', () => {
11
- const schema = new DiscriminatedUnionSchema('type', [
12
- new ObjectSchema({
13
- type: new LiteralSchema('cat'),
14
- meow: new StringSchema({}),
11
+ const schema = discriminatedUnion('type', [
12
+ object({
13
+ type: literal('cat'),
14
+ meow: string(),
15
15
  }),
16
- new ObjectSchema({
17
- type: new LiteralSchema('dog'),
18
- bark: new StringSchema({}),
16
+ object({
17
+ type: literal('dog'),
18
+ bark: string(),
19
19
  }),
20
20
  ])
21
21
 
@@ -96,14 +96,14 @@ describe('DiscriminatedUnionSchema', () => {
96
96
  })
97
97
 
98
98
  describe('with enum discriminators', () => {
99
- const schema = new DiscriminatedUnionSchema('status', [
100
- new ObjectSchema({
101
- status: new EnumSchema(['pending', 'processing']),
102
- progress: new IntegerSchema({}),
99
+ const schema = discriminatedUnion('status', [
100
+ object({
101
+ status: enumSchema(['pending', 'processing']),
102
+ progress: integer(),
103
103
  }),
104
- new ObjectSchema({
105
- status: new EnumSchema(['complete', 'failed']),
106
- result: new StringSchema({}),
104
+ object({
105
+ status: enumSchema(['complete', 'failed']),
106
+ result: string(),
107
107
  }),
108
108
  ])
109
109
 
@@ -164,14 +164,14 @@ describe('DiscriminatedUnionSchema', () => {
164
164
  })
165
165
 
166
166
  describe('with mixed literal and enum discriminators', () => {
167
- const schema = new DiscriminatedUnionSchema('kind', [
168
- new ObjectSchema({
169
- kind: new LiteralSchema('simple'),
170
- value: new StringSchema({}),
167
+ const schema = discriminatedUnion('kind', [
168
+ object({
169
+ kind: literal('simple'),
170
+ value: string(),
171
171
  }),
172
- new ObjectSchema({
173
- kind: new EnumSchema(['complex', 'advanced']),
174
- value: new IntegerSchema({}),
172
+ object({
173
+ kind: enumSchema(['complex', 'advanced']),
174
+ value: integer(),
175
175
  }),
176
176
  ])
177
177
 
@@ -209,10 +209,10 @@ describe('DiscriminatedUnionSchema', () => {
209
209
  })
210
210
 
211
211
  describe('with single variant', () => {
212
- const schema = new DiscriminatedUnionSchema('type', [
213
- new ObjectSchema({
214
- type: new LiteralSchema('only'),
215
- value: new StringSchema({}),
212
+ const schema = discriminatedUnion('type', [
213
+ object({
214
+ type: literal('only'),
215
+ value: string(),
216
216
  }),
217
217
  ])
218
218
 
@@ -234,19 +234,19 @@ describe('DiscriminatedUnionSchema', () => {
234
234
  })
235
235
 
236
236
  describe('with three variants', () => {
237
- const schema = new DiscriminatedUnionSchema('shape', [
238
- new ObjectSchema({
239
- shape: new LiteralSchema('circle'),
240
- radius: new IntegerSchema({}),
237
+ const schema = discriminatedUnion('shape', [
238
+ object({
239
+ shape: literal('circle'),
240
+ radius: integer(),
241
241
  }),
242
- new ObjectSchema({
243
- shape: new LiteralSchema('square'),
244
- side: new IntegerSchema({}),
242
+ object({
243
+ shape: literal('square'),
244
+ side: integer(),
245
245
  }),
246
- new ObjectSchema({
247
- shape: new LiteralSchema('rectangle'),
248
- width: new IntegerSchema({}),
249
- height: new IntegerSchema({}),
246
+ object({
247
+ shape: literal('rectangle'),
248
+ width: integer(),
249
+ height: integer(),
250
250
  }),
251
251
  ])
252
252
 
@@ -285,14 +285,14 @@ describe('DiscriminatedUnionSchema', () => {
285
285
  })
286
286
 
287
287
  describe('with number discriminators', () => {
288
- const schema = new DiscriminatedUnionSchema('version', [
289
- new ObjectSchema({
290
- version: new LiteralSchema(1),
291
- oldFormat: new StringSchema({}),
288
+ const schema = discriminatedUnion('version', [
289
+ object({
290
+ version: literal(1),
291
+ oldFormat: string(),
292
292
  }),
293
- new ObjectSchema({
294
- version: new LiteralSchema(2),
295
- newFormat: new StringSchema({}),
293
+ object({
294
+ version: literal(2),
295
+ newFormat: string(),
296
296
  }),
297
297
  ])
298
298
 
@@ -330,14 +330,14 @@ describe('DiscriminatedUnionSchema', () => {
330
330
  })
331
331
 
332
332
  describe('with boolean discriminators', () => {
333
- const schema = new DiscriminatedUnionSchema('enabled', [
334
- new ObjectSchema({
335
- enabled: new LiteralSchema(true),
336
- config: new StringSchema({}),
333
+ const schema = discriminatedUnion('enabled', [
334
+ object({
335
+ enabled: literal(true),
336
+ config: string(),
337
337
  }),
338
- new ObjectSchema({
339
- enabled: new LiteralSchema(false),
340
- reason: new StringSchema({}),
338
+ object({
339
+ enabled: literal(false),
340
+ reason: string(),
341
341
  }),
342
342
  ])
343
343
 
@@ -367,14 +367,14 @@ describe('DiscriminatedUnionSchema', () => {
367
367
  })
368
368
 
369
369
  describe('with null discriminator', () => {
370
- const schema = new DiscriminatedUnionSchema('value', [
371
- new ObjectSchema({
372
- value: new LiteralSchema(null),
373
- empty: new StringSchema({}),
370
+ const schema = discriminatedUnion('value', [
371
+ object({
372
+ value: literal(null),
373
+ empty: string(),
374
374
  }),
375
- new ObjectSchema({
376
- value: new LiteralSchema('present'),
377
- data: new StringSchema({}),
375
+ object({
376
+ value: literal('present'),
377
+ data: string(),
378
378
  }),
379
379
  ])
380
380
 
@@ -406,14 +406,14 @@ describe('DiscriminatedUnionSchema', () => {
406
406
  describe('constructor validation', () => {
407
407
  it('throws on overlapping literal discriminator values', () => {
408
408
  expect(() => {
409
- new DiscriminatedUnionSchema('type', [
410
- new ObjectSchema({
411
- type: new LiteralSchema('duplicate'),
412
- a: new StringSchema({}),
409
+ discriminatedUnion('type', [
410
+ object({
411
+ type: literal('duplicate'),
412
+ a: string(),
413
413
  }),
414
- new ObjectSchema({
415
- type: new LiteralSchema('duplicate'),
416
- b: new StringSchema({}),
414
+ object({
415
+ type: literal('duplicate'),
416
+ b: string(),
417
417
  }),
418
418
  ])
419
419
  }).toThrow('Overlapping discriminator value: duplicate')
@@ -421,14 +421,14 @@ describe('DiscriminatedUnionSchema', () => {
421
421
 
422
422
  it('throws on overlapping enum discriminator values', () => {
423
423
  expect(() => {
424
- new DiscriminatedUnionSchema('status', [
425
- new ObjectSchema({
426
- status: new EnumSchema(['active', 'pending']),
427
- a: new StringSchema({}),
424
+ discriminatedUnion('status', [
425
+ object({
426
+ status: enumSchema(['active', 'pending']),
427
+ a: string(),
428
428
  }),
429
- new ObjectSchema({
430
- status: new EnumSchema(['pending', 'complete']),
431
- b: new StringSchema({}),
429
+ object({
430
+ status: enumSchema(['pending', 'complete']),
431
+ b: string(),
432
432
  }),
433
433
  ])
434
434
  }).toThrow('Overlapping discriminator value: pending')
@@ -436,14 +436,14 @@ describe('DiscriminatedUnionSchema', () => {
436
436
 
437
437
  it('throws on overlapping literal and enum discriminator values', () => {
438
438
  expect(() => {
439
- new DiscriminatedUnionSchema('kind', [
440
- new ObjectSchema({
441
- kind: new LiteralSchema('test'),
442
- a: new StringSchema({}),
439
+ discriminatedUnion('kind', [
440
+ object({
441
+ kind: literal('test'),
442
+ a: string(),
443
443
  }),
444
- new ObjectSchema({
445
- kind: new EnumSchema(['test', 'other']),
446
- b: new StringSchema({}),
444
+ object({
445
+ kind: enumSchema(['test', 'other']),
446
+ b: string(),
447
447
  }),
448
448
  ])
449
449
  }).toThrow('Overlapping discriminator value: test')
@@ -451,14 +451,14 @@ describe('DiscriminatedUnionSchema', () => {
451
451
  })
452
452
 
453
453
  describe('edge cases', () => {
454
- const schema = new DiscriminatedUnionSchema('type', [
455
- new ObjectSchema({
456
- type: new LiteralSchema('a'),
457
- value: new StringSchema({}),
454
+ const schema = discriminatedUnion('type', [
455
+ object({
456
+ type: literal('a'),
457
+ value: string(),
458
458
  }),
459
- new ObjectSchema({
460
- type: new LiteralSchema('b'),
461
- value: new IntegerSchema({}),
459
+ object({
460
+ type: literal('b'),
461
+ value: integer(),
462
462
  }),
463
463
  ])
464
464
 
@@ -490,10 +490,10 @@ describe('DiscriminatedUnionSchema', () => {
490
490
  })
491
491
 
492
492
  it('handles empty string discriminator', () => {
493
- const emptySchema = new DiscriminatedUnionSchema('key', [
494
- new ObjectSchema({
495
- key: new LiteralSchema(''),
496
- value: new StringSchema({}),
493
+ const emptySchema = discriminatedUnion('key', [
494
+ object({
495
+ key: literal(''),
496
+ value: string(),
497
497
  }),
498
498
  ])
499
499
 
@@ -505,10 +505,10 @@ describe('DiscriminatedUnionSchema', () => {
505
505
  })
506
506
 
507
507
  it('handles zero discriminator', () => {
508
- const zeroSchema = new DiscriminatedUnionSchema('count', [
509
- new ObjectSchema({
510
- count: new LiteralSchema(0),
511
- value: new StringSchema({}),
508
+ const zeroSchema = discriminatedUnion('count', [
509
+ object({
510
+ count: literal(0),
511
+ value: string(),
512
512
  }),
513
513
  ])
514
514
 
@@ -520,10 +520,10 @@ describe('DiscriminatedUnionSchema', () => {
520
520
  })
521
521
 
522
522
  it('handles false discriminator', () => {
523
- const falseSchema = new DiscriminatedUnionSchema('flag', [
524
- new ObjectSchema({
525
- flag: new LiteralSchema(false),
526
- value: new StringSchema({}),
523
+ const falseSchema = discriminatedUnion('flag', [
524
+ object({
525
+ flag: literal(false),
526
+ value: string(),
527
527
  }),
528
528
  ])
529
529
 
@@ -544,10 +544,10 @@ describe('DiscriminatedUnionSchema', () => {
544
544
  })
545
545
 
546
546
  it('handles discriminator with special characters', () => {
547
- const specialSchema = new DiscriminatedUnionSchema('$type', [
548
- new ObjectSchema({
549
- $type: new LiteralSchema('test'),
550
- value: new StringSchema({}),
547
+ const specialSchema = discriminatedUnion('$type', [
548
+ object({
549
+ $type: literal('test'),
550
+ value: string(),
551
551
  }),
552
552
  ])
553
553
 
@@ -576,16 +576,16 @@ describe('DiscriminatedUnionSchema', () => {
576
576
  })
577
577
 
578
578
  describe('complex nested structures', () => {
579
- const schema = new DiscriminatedUnionSchema('type', [
580
- new ObjectSchema({
581
- type: new LiteralSchema('user'),
582
- name: new StringSchema({}),
583
- age: new IntegerSchema({}),
579
+ const schema = discriminatedUnion('type', [
580
+ object({
581
+ type: literal('user'),
582
+ name: string(),
583
+ age: integer(),
584
584
  }),
585
- new ObjectSchema({
586
- type: new LiteralSchema('post'),
587
- title: new StringSchema({}),
588
- content: new StringSchema({}),
585
+ object({
586
+ type: literal('post'),
587
+ title: string(),
588
+ content: string(),
589
589
  }),
590
590
  ])
591
591
 
@@ -636,17 +636,17 @@ describe('DiscriminatedUnionSchema', () => {
636
636
 
637
637
  describe('discriminator key variations', () => {
638
638
  it('works with different discriminator key names', () => {
639
- const kindSchema = new DiscriminatedUnionSchema('kind', [
640
- new ObjectSchema({
641
- kind: new LiteralSchema('a'),
642
- value: new StringSchema({}),
639
+ const kindSchema = discriminatedUnion('kind', [
640
+ object({
641
+ kind: literal('a'),
642
+ value: string(),
643
643
  }),
644
644
  ])
645
645
 
646
- const tagSchema = new DiscriminatedUnionSchema('tag', [
647
- new ObjectSchema({
648
- tag: new LiteralSchema('a'),
649
- value: new StringSchema({}),
646
+ const tagSchema = discriminatedUnion('tag', [
647
+ object({
648
+ tag: literal('a'),
649
+ value: string(),
650
650
  }),
651
651
  ])
652
652
 
@@ -659,10 +659,10 @@ describe('DiscriminatedUnionSchema', () => {
659
659
  })
660
660
 
661
661
  it('rejects when discriminator key does not match schema', () => {
662
- const schema = new DiscriminatedUnionSchema('type', [
663
- new ObjectSchema({
664
- type: new LiteralSchema('a'),
665
- value: new StringSchema({}),
662
+ const schema = discriminatedUnion('type', [
663
+ object({
664
+ type: literal('a'),
665
+ value: string(),
666
666
  }),
667
667
  ])
668
668
 
@@ -1,32 +1,40 @@
1
1
  import { isPlainObject } from '@atproto/lex-data'
2
2
  import {
3
- Infer,
3
+ InferInput,
4
+ InferOutput,
4
5
  Schema,
6
+ ValidationContext,
5
7
  ValidationResult,
6
8
  Validator,
7
- ValidatorContext,
8
9
  } from '../core.js'
9
10
  import { EnumSchema } from './enum.js'
10
11
  import { LiteralSchema } from './literal.js'
11
12
  import { ObjectSchema } from './object.js'
12
13
 
13
- export type DiscriminatedUnionVariant<Discriminator extends string> =
14
- ObjectSchema<Record<Discriminator, EnumSchema | LiteralSchema>>
14
+ export type DiscriminatedUnionVariant<Discriminator extends string = string> =
15
+ ObjectSchema<Record<Discriminator, EnumSchema<any> | LiteralSchema<any>>>
15
16
 
16
- export type DiscriminatedUnionVariants<Discriminator extends string> =
17
+ export type DiscriminatedUnionVariants<TDiscriminator extends string> =
17
18
  readonly [
18
- DiscriminatedUnionVariant<Discriminator>,
19
- ...DiscriminatedUnionVariant<Discriminator>[],
19
+ DiscriminatedUnionVariant<TDiscriminator>,
20
+ ...DiscriminatedUnionVariant<TDiscriminator>[],
20
21
  ]
21
22
 
22
- export type DiscriminatedUnionSchemaOutput<
23
- Variants extends readonly Validator[],
24
- > = Variants extends readonly [
25
- infer V extends Validator,
26
- ...infer Rest extends readonly Validator[],
27
- ]
28
- ? Infer<V> | DiscriminatedUnionSchemaOutput<Rest>
29
- : never
23
+ type DiscriminatedUnionSchemaInput<TVariants extends readonly Validator[]> =
24
+ TVariants extends readonly [
25
+ infer TValidator extends Validator,
26
+ ...infer TRest extends readonly Validator[],
27
+ ]
28
+ ? InferInput<TValidator> | DiscriminatedUnionSchemaInput<TRest>
29
+ : never
30
+
31
+ type DiscriminatedUnionSchemaOutput<TVariants extends readonly Validator[]> =
32
+ TVariants extends readonly [
33
+ infer TValidator extends Validator,
34
+ ...infer TRest extends readonly Validator[],
35
+ ]
36
+ ? InferOutput<TValidator> | DiscriminatedUnionSchemaOutput<TRest>
37
+ : never
30
38
 
31
39
  /**
32
40
  * @note There is no discriminated union in Lexicon schemas. This is a custom
@@ -34,14 +42,17 @@ export type DiscriminatedUnionSchemaOutput<
34
42
  * lex library programmatically (i.e. not code generated from a lexicon schema).
35
43
  */
36
44
  export class DiscriminatedUnionSchema<
37
- const Discriminator extends string = any,
38
- const Variants extends DiscriminatedUnionVariants<Discriminator> = any,
39
- > extends Schema<DiscriminatedUnionSchemaOutput<Variants>> {
40
- readonly variantsMap: Map<unknown, DiscriminatedUnionVariant<Discriminator>>
45
+ const TDiscriminator extends string,
46
+ const TVariants extends DiscriminatedUnionVariants<TDiscriminator>,
47
+ > extends Schema<
48
+ DiscriminatedUnionSchemaInput<TVariants>,
49
+ DiscriminatedUnionSchemaOutput<TVariants>
50
+ > {
51
+ readonly variantsMap: Map<unknown, DiscriminatedUnionVariant<TDiscriminator>>
41
52
 
42
53
  constructor(
43
- readonly discriminator: Discriminator,
44
- variants: Variants,
54
+ readonly discriminator: TDiscriminator,
55
+ readonly variants: TVariants,
45
56
  ) {
46
57
  super()
47
58
 
@@ -51,10 +62,7 @@ export class DiscriminatedUnionSchema<
51
62
  this.variantsMap = buildVariantsMap(discriminator, variants)
52
63
  }
53
64
 
54
- validateInContext(
55
- input: unknown,
56
- ctx: ValidatorContext,
57
- ): ValidationResult<DiscriminatedUnionSchemaOutput<Variants>> {
65
+ validateInContext(input: unknown, ctx: ValidationContext) {
58
66
  if (!isPlainObject(input)) {
59
67
  return ctx.issueInvalidType(input, 'object')
60
68
  }
@@ -70,7 +78,7 @@ export class DiscriminatedUnionSchema<
70
78
  const variant = this.variantsMap.get(discriminatorValue)
71
79
  if (variant) {
72
80
  return ctx.validate(input, variant) as ValidationResult<
73
- DiscriminatedUnionSchemaOutput<Variants>
81
+ DiscriminatedUnionSchemaInput<TVariants>
74
82
  >
75
83
  }
76
84
 
@@ -115,3 +123,14 @@ function buildVariantsMap<Discriminator extends string>(
115
123
 
116
124
  return variantsMap
117
125
  }
126
+
127
+ /*@__NO_SIDE_EFFECTS__*/
128
+ export function discriminatedUnion<
129
+ const Discriminator extends string,
130
+ const Options extends DiscriminatedUnionVariants<Discriminator>,
131
+ >(discriminator: Discriminator, variants: Options) {
132
+ return new DiscriminatedUnionSchema<Discriminator, Options>(
133
+ discriminator,
134
+ variants,
135
+ )
136
+ }
@@ -1,9 +1,10 @@
1
1
  import { describe, expect, it } from 'vitest'
2
- import { EnumSchema } from './enum.js'
2
+ import { enumSchema } from './enum.js'
3
+ import { withDefault } from './with-default.js'
3
4
 
4
5
  describe('EnumSchema', () => {
5
6
  describe('with string values', () => {
6
- const schema = new EnumSchema(['male', 'female', 'other'])
7
+ const schema = enumSchema(['male', 'female', 'other'])
7
8
 
8
9
  it('validates matching string values', () => {
9
10
  const result = schema.safeParse('male')
@@ -58,7 +59,7 @@ describe('EnumSchema', () => {
58
59
  })
59
60
 
60
61
  describe('with number values', () => {
61
- const schema = new EnumSchema([1, 2, 3])
62
+ const schema = enumSchema([1, 2, 3])
62
63
 
63
64
  it('validates matching number values', () => {
64
65
  const result = schema.safeParse(1)
@@ -93,7 +94,7 @@ describe('EnumSchema', () => {
93
94
  })
94
95
 
95
96
  describe('with boolean values', () => {
96
- const schema = new EnumSchema([true, false])
97
+ const schema = enumSchema([true, false])
97
98
 
98
99
  it('validates true', () => {
99
100
  const result = schema.safeParse(true)
@@ -117,7 +118,7 @@ describe('EnumSchema', () => {
117
118
  })
118
119
 
119
120
  describe('with single boolean value', () => {
120
- const schema = new EnumSchema([true])
121
+ const schema = enumSchema([true])
121
122
 
122
123
  it('validates true', () => {
123
124
  const result = schema.safeParse(true)
@@ -131,7 +132,7 @@ describe('EnumSchema', () => {
131
132
  })
132
133
 
133
134
  describe('with null value', () => {
134
- const schema = new EnumSchema([null, 'value'])
135
+ const schema = enumSchema([null, 'value'])
135
136
 
136
137
  it('validates null', () => {
137
138
  const result = schema.safeParse(null)
@@ -150,7 +151,7 @@ describe('EnumSchema', () => {
150
151
  })
151
152
 
152
153
  describe('with mixed type values', () => {
153
- const schema = new EnumSchema(['string', 123, true, null])
154
+ const schema = enumSchema(['string', 123, true, null])
154
155
 
155
156
  it('validates string value', () => {
156
157
  const result = schema.safeParse('string')
@@ -181,7 +182,7 @@ describe('EnumSchema', () => {
181
182
  })
182
183
 
183
184
  describe('with default option', () => {
184
- const schema = new EnumSchema(['red', 'green', 'blue'], { default: 'red' })
185
+ const schema = withDefault(enumSchema(['red', 'green', 'blue']), 'red')
185
186
 
186
187
  it('validates matching values', () => {
187
188
  const result = schema.safeParse('green')
@@ -221,7 +222,7 @@ describe('EnumSchema', () => {
221
222
  })
222
223
 
223
224
  describe('with default option as number', () => {
224
- const schema = new EnumSchema([1, 2, 3], { default: 1 })
225
+ const schema = withDefault(enumSchema([1, 2, 3]), 1)
225
226
 
226
227
  it('uses default when input is undefined', () => {
227
228
  const result = schema.safeParse(undefined)
@@ -238,7 +239,7 @@ describe('EnumSchema', () => {
238
239
  })
239
240
 
240
241
  describe('with default option as boolean', () => {
241
- const schema = new EnumSchema([true, false], { default: false })
242
+ const schema = withDefault(enumSchema([true, false]), false)
242
243
 
243
244
  it('uses default when input is undefined', () => {
244
245
  const result = schema.safeParse(undefined)
@@ -258,7 +259,7 @@ describe('EnumSchema', () => {
258
259
  })
259
260
 
260
261
  describe('with default option as null', () => {
261
- const schema = new EnumSchema([null, 'value'], { default: null })
262
+ const schema = withDefault(enumSchema([null, 'value']), null)
262
263
 
263
264
  it('uses default when input is undefined', () => {
264
265
  const result = schema.safeParse(undefined)
@@ -278,7 +279,7 @@ describe('EnumSchema', () => {
278
279
  })
279
280
 
280
281
  describe('with single value', () => {
281
- const schema = new EnumSchema(['only'])
282
+ const schema = enumSchema(['only'])
282
283
 
283
284
  it('validates the single value', () => {
284
285
  const result = schema.safeParse('only')
@@ -294,7 +295,7 @@ describe('EnumSchema', () => {
294
295
  })
295
296
 
296
297
  describe('with empty string value', () => {
297
- const schema = new EnumSchema(['', 'value'])
298
+ const schema = enumSchema(['', 'value'])
298
299
 
299
300
  it('validates empty string', () => {
300
301
  const result = schema.safeParse('')
@@ -313,7 +314,7 @@ describe('EnumSchema', () => {
313
314
  })
314
315
 
315
316
  describe('with zero value', () => {
316
- const schema = new EnumSchema([0, 1, 2])
317
+ const schema = enumSchema([0, 1, 2])
317
318
 
318
319
  it('validates zero', () => {
319
320
  const result = schema.safeParse(0)
@@ -332,7 +333,7 @@ describe('EnumSchema', () => {
332
333
  })
333
334
 
334
335
  describe('case sensitivity', () => {
335
- const schema = new EnumSchema(['Value', 'VALUE', 'value'])
336
+ const schema = enumSchema(['Value', 'VALUE', 'value'])
336
337
 
337
338
  it('validates exact case matches', () => {
338
339
  expect(schema.safeParse('Value').success).toBe(true)
@@ -347,7 +348,7 @@ describe('EnumSchema', () => {
347
348
  })
348
349
 
349
350
  describe('with special string values', () => {
350
- const schema = new EnumSchema([
351
+ const schema = enumSchema([
351
352
  'with space',
352
353
  'with\ttab',
353
354
  'with\nnewline',