@atproto/lex-schema 0.0.9 → 0.0.10

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 (279) hide show
  1. package/CHANGELOG.md +34 -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-issue.js +1 -1
  16. package/dist/core/validation-issue.js.map +1 -1
  17. package/dist/core/validator.d.ts +53 -32
  18. package/dist/core/validator.d.ts.map +1 -1
  19. package/dist/core/validator.js +18 -22
  20. package/dist/core/validator.js.map +1 -1
  21. package/dist/external.d.ts +0 -85
  22. package/dist/external.d.ts.map +1 -1
  23. package/dist/external.js +0 -164
  24. package/dist/external.js.map +1 -1
  25. package/dist/helpers.d.ts +10 -5
  26. package/dist/helpers.d.ts.map +1 -1
  27. package/dist/helpers.js +3 -3
  28. package/dist/helpers.js.map +1 -1
  29. package/dist/schema/array.d.ts +9 -5
  30. package/dist/schema/array.d.ts.map +1 -1
  31. package/dist/schema/array.js +14 -5
  32. package/dist/schema/array.js.map +1 -1
  33. package/dist/schema/blob.d.ts +9 -7
  34. package/dist/schema/blob.d.ts.map +1 -1
  35. package/dist/schema/blob.js +9 -5
  36. package/dist/schema/blob.js.map +1 -1
  37. package/dist/schema/boolean.d.ts +3 -7
  38. package/dist/schema/boolean.d.ts.map +1 -1
  39. package/dist/schema/boolean.js +6 -7
  40. package/dist/schema/boolean.js.map +1 -1
  41. package/dist/schema/bytes.d.ts +3 -2
  42. package/dist/schema/bytes.d.ts.map +1 -1
  43. package/dist/schema/bytes.js +7 -3
  44. package/dist/schema/bytes.js.map +1 -1
  45. package/dist/schema/cid.d.ts +7 -7
  46. package/dist/schema/cid.d.ts.map +1 -1
  47. package/dist/schema/cid.js +5 -1
  48. package/dist/schema/cid.js.map +1 -1
  49. package/dist/schema/custom.d.ts +6 -5
  50. package/dist/schema/custom.d.ts.map +1 -1
  51. package/dist/schema/custom.js +10 -4
  52. package/dist/schema/custom.js.map +1 -1
  53. package/dist/schema/dict.d.ts +8 -8
  54. package/dist/schema/dict.d.ts.map +1 -1
  55. package/dist/schema/dict.js +11 -2
  56. package/dist/schema/dict.js.map +1 -1
  57. package/dist/schema/discriminated-union.d.ts +21 -14
  58. package/dist/schema/discriminated-union.d.ts.map +1 -1
  59. package/dist/schema/discriminated-union.js +7 -0
  60. package/dist/schema/discriminated-union.js.map +1 -1
  61. package/dist/schema/enum.d.ts +7 -9
  62. package/dist/schema/enum.d.ts.map +1 -1
  63. package/dist/schema/enum.js +8 -4
  64. package/dist/schema/enum.js.map +1 -1
  65. package/dist/schema/integer.d.ts +5 -5
  66. package/dist/schema/integer.d.ts.map +1 -1
  67. package/dist/schema/integer.js +9 -5
  68. package/dist/schema/integer.js.map +1 -1
  69. package/dist/schema/intersection.d.ts +4 -4
  70. package/dist/schema/intersection.d.ts.map +1 -1
  71. package/dist/schema/intersection.js +5 -0
  72. package/dist/schema/intersection.js.map +1 -1
  73. package/dist/schema/literal.d.ts +6 -9
  74. package/dist/schema/literal.d.ts.map +1 -1
  75. package/dist/schema/literal.js +7 -4
  76. package/dist/schema/literal.js.map +1 -1
  77. package/dist/schema/never.d.ts +3 -2
  78. package/dist/schema/never.d.ts.map +1 -1
  79. package/dist/schema/never.js +5 -1
  80. package/dist/schema/never.js.map +1 -1
  81. package/dist/schema/null.d.ts +4 -3
  82. package/dist/schema/null.d.ts.map +1 -1
  83. package/dist/schema/null.js +6 -4
  84. package/dist/schema/null.js.map +1 -1
  85. package/dist/schema/nullable.d.ts +6 -5
  86. package/dist/schema/nullable.d.ts.map +1 -1
  87. package/dist/schema/nullable.js +9 -5
  88. package/dist/schema/nullable.js.map +1 -1
  89. package/dist/schema/object.d.ts +10 -8
  90. package/dist/schema/object.d.ts.map +1 -1
  91. package/dist/schema/object.js +11 -3
  92. package/dist/schema/object.js.map +1 -1
  93. package/dist/schema/optional.d.ts +7 -5
  94. package/dist/schema/optional.d.ts.map +1 -1
  95. package/dist/schema/optional.js +14 -6
  96. package/dist/schema/optional.js.map +1 -1
  97. package/dist/schema/params.d.ts +24 -13
  98. package/dist/schema/params.d.ts.map +1 -1
  99. package/dist/schema/params.js +47 -25
  100. package/dist/schema/params.js.map +1 -1
  101. package/dist/schema/payload.d.ts +12 -9
  102. package/dist/schema/payload.d.ts.map +1 -1
  103. package/dist/schema/payload.js +11 -0
  104. package/dist/schema/payload.js.map +1 -1
  105. package/dist/schema/permission-set.d.ts +1 -0
  106. package/dist/schema/permission-set.d.ts.map +1 -1
  107. package/dist/schema/permission-set.js +5 -0
  108. package/dist/schema/permission-set.js.map +1 -1
  109. package/dist/schema/permission.d.ts +6 -5
  110. package/dist/schema/permission.d.ts.map +1 -1
  111. package/dist/schema/permission.js +5 -0
  112. package/dist/schema/permission.js.map +1 -1
  113. package/dist/schema/procedure.d.ts +2 -1
  114. package/dist/schema/procedure.d.ts.map +1 -1
  115. package/dist/schema/procedure.js +5 -0
  116. package/dist/schema/procedure.js.map +1 -1
  117. package/dist/schema/query.d.ts +2 -1
  118. package/dist/schema/query.d.ts.map +1 -1
  119. package/dist/schema/query.js +5 -0
  120. package/dist/schema/query.js.map +1 -1
  121. package/dist/schema/record.d.ts +48 -30
  122. package/dist/schema/record.d.ts.map +1 -1
  123. package/dist/schema/record.js +12 -9
  124. package/dist/schema/record.js.map +1 -1
  125. package/dist/schema/ref.d.ts +9 -6
  126. package/dist/schema/ref.d.ts.map +1 -1
  127. package/dist/schema/ref.js +9 -16
  128. package/dist/schema/ref.js.map +1 -1
  129. package/dist/schema/refine.d.ts +4 -4
  130. package/dist/schema/refine.d.ts.map +1 -1
  131. package/dist/schema/refine.js.map +1 -1
  132. package/dist/schema/regexp.d.ts +4 -3
  133. package/dist/schema/regexp.d.ts.map +1 -1
  134. package/dist/schema/regexp.js +5 -0
  135. package/dist/schema/regexp.js.map +1 -1
  136. package/dist/schema/string.d.ts +7 -8
  137. package/dist/schema/string.d.ts.map +1 -1
  138. package/dist/schema/string.js +13 -19
  139. package/dist/schema/string.js.map +1 -1
  140. package/dist/schema/subscription.d.ts +2 -1
  141. package/dist/schema/subscription.d.ts.map +1 -1
  142. package/dist/schema/subscription.js +5 -0
  143. package/dist/schema/subscription.js.map +1 -1
  144. package/dist/schema/token.d.ts +6 -5
  145. package/dist/schema/token.d.ts.map +1 -1
  146. package/dist/schema/token.js +5 -0
  147. package/dist/schema/token.js.map +1 -1
  148. package/dist/schema/typed-object.d.ts +43 -26
  149. package/dist/schema/typed-object.d.ts.map +1 -1
  150. package/dist/schema/typed-object.js +6 -3
  151. package/dist/schema/typed-object.js.map +1 -1
  152. package/dist/schema/typed-ref.d.ts +16 -25
  153. package/dist/schema/typed-ref.d.ts.map +1 -1
  154. package/dist/schema/typed-ref.js +7 -17
  155. package/dist/schema/typed-ref.js.map +1 -1
  156. package/dist/schema/typed-union.d.ts +9 -21
  157. package/dist/schema/typed-union.d.ts.map +1 -1
  158. package/dist/schema/typed-union.js +15 -11
  159. package/dist/schema/typed-union.js.map +1 -1
  160. package/dist/schema/union.d.ts +6 -6
  161. package/dist/schema/union.d.ts.map +1 -1
  162. package/dist/schema/union.js +7 -5
  163. package/dist/schema/union.js.map +1 -1
  164. package/dist/schema/unknown-object.d.ts +5 -4
  165. package/dist/schema/unknown-object.d.ts.map +1 -1
  166. package/dist/schema/unknown-object.js +5 -1
  167. package/dist/schema/unknown-object.js.map +1 -1
  168. package/dist/schema/unknown.d.ts +3 -2
  169. package/dist/schema/unknown.d.ts.map +1 -1
  170. package/dist/schema/unknown.js +5 -1
  171. package/dist/schema/unknown.js.map +1 -1
  172. package/dist/schema/with-default.d.ts +9 -0
  173. package/dist/schema/with-default.d.ts.map +1 -0
  174. package/dist/schema/with-default.js +27 -0
  175. package/dist/schema/with-default.js.map +1 -0
  176. package/dist/schema.d.ts +2 -2
  177. package/dist/schema.d.ts.map +1 -1
  178. package/dist/schema.js +2 -4
  179. package/dist/schema.js.map +1 -1
  180. package/dist/util/assertion-util.d.ts +0 -6
  181. package/dist/util/assertion-util.d.ts.map +1 -1
  182. package/dist/util/assertion-util.js +0 -28
  183. package/dist/util/assertion-util.js.map +1 -1
  184. package/dist/util/memoize.d.ts +2 -2
  185. package/dist/util/memoize.d.ts.map +1 -1
  186. package/dist/util/memoize.js +23 -39
  187. package/dist/util/memoize.js.map +1 -1
  188. package/package.json +3 -3
  189. package/src/core/$type.test.ts +20 -0
  190. package/src/core/$type.ts +30 -0
  191. package/src/core/schema.ts +86 -38
  192. package/src/core/string-format.ts +119 -158
  193. package/src/core/validation-issue.ts +1 -1
  194. package/src/core/validator.ts +93 -53
  195. package/src/external.ts +0 -404
  196. package/src/helpers.test.ts +22 -21
  197. package/src/helpers.ts +14 -14
  198. package/src/schema/array.test.ts +38 -40
  199. package/src/schema/array.ts +35 -13
  200. package/src/schema/blob.test.ts +21 -21
  201. package/src/schema/blob.ts +19 -17
  202. package/src/schema/boolean.test.ts +9 -8
  203. package/src/schema/boolean.ts +7 -13
  204. package/src/schema/bytes.test.ts +13 -13
  205. package/src/schema/bytes.ts +13 -8
  206. package/src/schema/cid.test.ts +3 -3
  207. package/src/schema/cid.ts +13 -12
  208. package/src/schema/custom.test.ts +26 -26
  209. package/src/schema/custom.ts +20 -13
  210. package/src/schema/dict.test.ts +21 -39
  211. package/src/schema/dict.ts +28 -19
  212. package/src/schema/discriminated-union.test.ts +128 -128
  213. package/src/schema/discriminated-union.ts +45 -26
  214. package/src/schema/enum.test.ts +17 -16
  215. package/src/schema/enum.ts +16 -16
  216. package/src/schema/integer.test.ts +22 -21
  217. package/src/schema/integer.ts +12 -9
  218. package/src/schema/intersection.test.ts +10 -10
  219. package/src/schema/intersection.ts +17 -14
  220. package/src/schema/literal.test.ts +35 -34
  221. package/src/schema/literal.ts +12 -15
  222. package/src/schema/never.test.ts +5 -5
  223. package/src/schema/never.ts +7 -2
  224. package/src/schema/null.test.ts +3 -3
  225. package/src/schema/null.ts +9 -9
  226. package/src/schema/nullable.test.ts +31 -42
  227. package/src/schema/nullable.ts +17 -9
  228. package/src/schema/object.test.ts +10 -12
  229. package/src/schema/object.ts +27 -18
  230. package/src/schema/optional.test.ts +21 -28
  231. package/src/schema/optional.ts +27 -10
  232. package/src/schema/params.test.ts +471 -47
  233. package/src/schema/params.ts +72 -38
  234. package/src/schema/payload.test.ts +150 -156
  235. package/src/schema/payload.ts +35 -19
  236. package/src/schema/permission-set.test.ts +206 -273
  237. package/src/schema/permission-set.ts +8 -0
  238. package/src/schema/permission.test.ts +177 -177
  239. package/src/schema/permission.ts +13 -5
  240. package/src/schema/procedure.test.ts +183 -242
  241. package/src/schema/procedure.ts +18 -5
  242. package/src/schema/query.test.ts +186 -200
  243. package/src/schema/query.ts +16 -4
  244. package/src/schema/record.test.ts +121 -101
  245. package/src/schema/record.ts +74 -40
  246. package/src/schema/ref.test.ts +101 -118
  247. package/src/schema/ref.ts +33 -28
  248. package/src/schema/refine.test.ts +28 -28
  249. package/src/schema/refine.ts +23 -20
  250. package/src/schema/regexp.test.ts +29 -33
  251. package/src/schema/regexp.ts +11 -7
  252. package/src/schema/string.test.ts +35 -35
  253. package/src/schema/string.ts +24 -33
  254. package/src/schema/subscription.test.ts +259 -387
  255. package/src/schema/subscription.ts +16 -4
  256. package/src/schema/token.test.ts +47 -324
  257. package/src/schema/token.ts +14 -7
  258. package/src/schema/typed-object.test.ts +98 -81
  259. package/src/schema/typed-object.ts +68 -33
  260. package/src/schema/typed-ref.test.ts +206 -234
  261. package/src/schema/typed-ref.ts +40 -42
  262. package/src/schema/typed-union.test.ts +40 -64
  263. package/src/schema/typed-union.ts +36 -58
  264. package/src/schema/union.test.ts +17 -27
  265. package/src/schema/union.ts +20 -16
  266. package/src/schema/unknown-object.test.ts +8 -8
  267. package/src/schema/unknown-object.ts +9 -7
  268. package/src/schema/unknown.test.ts +4 -4
  269. package/src/schema/unknown.ts +7 -5
  270. package/src/schema/with-default.ts +35 -0
  271. package/src/schema.ts +2 -6
  272. package/src/util/assertion-util.ts +0 -39
  273. package/src/util/memoize.ts +26 -46
  274. package/dist/schema/_parameters.d.ts +0 -17
  275. package/dist/schema/_parameters.d.ts.map +0 -1
  276. package/dist/schema/_parameters.js +0 -20
  277. package/dist/schema/_parameters.js.map +0 -1
  278. package/src/schema/_parameters.test.ts +0 -417
  279. package/src/schema/_parameters.ts +0 -26
@@ -81,7 +81,7 @@ describe('InferMethodInput', () => {
81
81
  test('with payload schema', () => {
82
82
  const procedure = l.procedure(
83
83
  'com.example.create',
84
- l.params({}),
84
+ l.params(),
85
85
  l.payload('application/json', l.object({ text: l.string() })),
86
86
  l.payload(undefined, undefined),
87
87
  undefined,
@@ -103,7 +103,7 @@ describe('InferMethodInput', () => {
103
103
  test('without payload schema', () => {
104
104
  const procedure = l.procedure(
105
105
  'com.example.create',
106
- l.params({}),
106
+ l.params(),
107
107
  l.payload('*/*', undefined),
108
108
  l.payload(undefined, undefined),
109
109
  undefined,
@@ -127,7 +127,7 @@ describe('InferMethodInputBody', () => {
127
127
  test('with payload schema', () => {
128
128
  const procedure = l.procedure(
129
129
  'com.example.create',
130
- l.params({}),
130
+ l.params(),
131
131
  l.payload('application/json', l.object({ text: l.string() })),
132
132
  l.payload(undefined, undefined),
133
133
  undefined,
@@ -145,7 +145,7 @@ describe('InferMethodInputBody', () => {
145
145
  test('without payload schema', () => {
146
146
  const procedure = l.procedure(
147
147
  'com.example.upload',
148
- l.params({}),
148
+ l.params(),
149
149
  l.payload('*/*', undefined),
150
150
  l.payload(undefined, undefined),
151
151
  undefined,
@@ -167,7 +167,7 @@ describe('InferMethodInputEncoding', () => {
167
167
  test('with payload schema', () => {
168
168
  const procedure = l.procedure(
169
169
  'com.example.create',
170
- l.params({}),
170
+ l.params(),
171
171
  l.payload('application/json', l.object({ text: l.string() })),
172
172
  l.payload(undefined, undefined),
173
173
  undefined,
@@ -185,7 +185,7 @@ describe('InferMethodInputEncoding', () => {
185
185
  test('without payload schema', () => {
186
186
  const procedure = l.procedure(
187
187
  'com.example.upload',
188
- l.params({}),
188
+ l.params(),
189
189
  l.payload('*/*', undefined),
190
190
  l.payload(undefined, undefined),
191
191
  undefined,
@@ -206,7 +206,7 @@ describe('InferMethodOutput', () => {
206
206
  test('with payload schema', () => {
207
207
  const query = l.query(
208
208
  'com.example.query',
209
- l.params({}),
209
+ l.params(),
210
210
  l.payload('application/json', l.object({ items: l.array(l.string()) })),
211
211
  )
212
212
 
@@ -222,7 +222,7 @@ describe('InferMethodOutput', () => {
222
222
  test('without payload schema', () => {
223
223
  const query = l.query(
224
224
  'com.example.query',
225
- l.params({}),
225
+ l.params(),
226
226
  l.payload('*/*', undefined),
227
227
  )
228
228
 
@@ -240,7 +240,7 @@ describe('InferMethodOutput', () => {
240
240
  test('with payload schema', () => {
241
241
  const procedure = l.procedure(
242
242
  'com.example.create',
243
- l.params({}),
243
+ l.params(),
244
244
  l.payload(undefined, undefined),
245
245
  l.payload(
246
246
  'application/json',
@@ -266,7 +266,7 @@ describe('InferMethodOutput', () => {
266
266
  test('without payload schema', () => {
267
267
  const procedure = l.procedure(
268
268
  'com.example.export',
269
- l.params({}),
269
+ l.params(),
270
270
  l.payload(undefined, undefined),
271
271
  l.payload('*/*', undefined),
272
272
  undefined,
@@ -294,7 +294,7 @@ describe('InferMethodOutputBody', () => {
294
294
  test('with payload schema', () => {
295
295
  const query = l.query(
296
296
  'com.example.query',
297
- l.params({}),
297
+ l.params(),
298
298
  l.payload(
299
299
  'application/json',
300
300
  l.object({
@@ -319,7 +319,7 @@ describe('InferMethodOutputBody', () => {
319
319
  test('without payload schema', () => {
320
320
  const query = l.query(
321
321
  'com.example.query',
322
- l.params({}),
322
+ l.params(),
323
323
  l.payload('*/*', undefined),
324
324
  )
325
325
 
@@ -337,7 +337,7 @@ describe('InferMethodOutputBody', () => {
337
337
  test('with payload schema', () => {
338
338
  const procedure = l.procedure(
339
339
  'com.example.get',
340
- l.params({}),
340
+ l.params(),
341
341
  l.payload(undefined, undefined),
342
342
  l.payload(
343
343
  'application/json',
@@ -358,7 +358,7 @@ describe('InferMethodOutputBody', () => {
358
358
  test('without payload schema', () => {
359
359
  const procedure = l.procedure(
360
360
  'com.example.export',
361
- l.params({}),
361
+ l.params(),
362
362
  l.payload(undefined, undefined),
363
363
  l.payload('*/*', undefined),
364
364
  undefined,
@@ -380,7 +380,7 @@ describe('InferMethodOutputEncoding', () => {
380
380
  test('with payload schema', () => {
381
381
  const query = l.query(
382
382
  'com.example.query',
383
- l.params({}),
383
+ l.params(),
384
384
  l.payload('application/json', l.object({ data: l.string() })),
385
385
  )
386
386
 
@@ -396,7 +396,7 @@ describe('InferMethodOutputEncoding', () => {
396
396
  test('without payload schema', () => {
397
397
  const query = l.query(
398
398
  'com.example.query',
399
- l.params({}),
399
+ l.params(),
400
400
  l.payload('*/*', undefined),
401
401
  )
402
402
 
@@ -413,7 +413,7 @@ describe('InferMethodOutputEncoding', () => {
413
413
  test('with payload schema', () => {
414
414
  const procedure = l.procedure(
415
415
  'com.example.create',
416
- l.params({}),
416
+ l.params(),
417
417
  l.payload(undefined, undefined),
418
418
  l.payload('application/json', l.object({ id: l.string() })),
419
419
  undefined,
@@ -431,7 +431,7 @@ describe('InferMethodOutputEncoding', () => {
431
431
  test('without payload schema', () => {
432
432
  const procedure = l.procedure(
433
433
  'com.example.export',
434
- l.params({}),
434
+ l.params(),
435
435
  l.payload(undefined, undefined),
436
436
  l.payload('*/*', undefined),
437
437
  undefined,
@@ -452,7 +452,7 @@ describe('InferMethodMessage', () => {
452
452
  test('with message schema', () => {
453
453
  const subscription = l.subscription(
454
454
  'com.example.subscribe',
455
- l.params({}),
455
+ l.params(),
456
456
  l.object({
457
457
  seq: l.integer(),
458
458
  event: l.string(),
@@ -473,13 +473,14 @@ describe('InferMethodMessage', () => {
473
473
  test('without message schema', () => {
474
474
  const subscription = l.subscription(
475
475
  'com.example.subscribe',
476
- l.params({}),
476
+ l.params(),
477
477
  l.unknown(),
478
478
  )
479
479
 
480
480
  type Message = l.InferMethodMessage<typeof subscription>
481
481
 
482
- expectType<Message>(undefined as unknown)
482
+ // @ts-expect-error "unknown" is turned into LexValue
483
+ expectType<Message>(undefined)
483
484
  expectType<Message>({ any: 'value' })
484
485
  expectType<Message>(123)
485
486
  })
package/src/helpers.ts CHANGED
@@ -1,16 +1,16 @@
1
- import { LexErrorData } from '@atproto/lex-data'
2
- import { Infer, Restricted, Schema } from './core.js'
1
+ import { LexErrorData, LexValue } from '@atproto/lex-data'
2
+ import { InferOutput, Restricted, Schema } from './core.js'
3
3
  import {
4
4
  InferPayload,
5
5
  InferPayloadBody,
6
6
  InferPayloadEncoding,
7
- ObjectSchema,
8
- OptionalSchema,
9
7
  Payload,
10
8
  Procedure,
11
9
  Query,
12
- StringSchema,
13
10
  Subscription,
11
+ object,
12
+ optional,
13
+ string,
14
14
  } from './schema.js'
15
15
 
16
16
  export type Main<T> = T | { main: T }
@@ -29,10 +29,8 @@ export function getMain<T extends object>(ns: Main<T>): T {
29
29
  */
30
30
  type BinaryData = Restricted<'Binary data'>
31
31
 
32
- export type InferMethodParams<
33
- //
34
- M extends Procedure | Query | Subscription,
35
- > = Infer<M['parameters']>
32
+ export type InferMethodParams<M extends Procedure | Query | Subscription> =
33
+ InferOutput<M['parameters']>
36
34
 
37
35
  export type InferMethodInput<
38
36
  M extends Procedure | Query | Subscription,
@@ -67,9 +65,11 @@ export type InferMethodOutputEncoding<
67
65
  export type InferMethodMessage<
68
66
  //
69
67
  M extends Procedure | Query | Subscription,
70
- > = M extends { message: Schema } ? Infer<M['message']> : undefined
68
+ > = M extends { message: Schema }
69
+ ? LexValue & InferOutput<M['message']>
70
+ : undefined
71
71
 
72
- export const lexErrorData: Schema<LexErrorData> = new ObjectSchema({
73
- error: new StringSchema({ minLength: 1 }),
74
- message: new OptionalSchema(new StringSchema({})),
75
- })
72
+ export const lexErrorData = object({
73
+ error: string({ minLength: 1 }),
74
+ message: optional(string()),
75
+ }) satisfies Schema<LexErrorData>
@@ -1,27 +1,27 @@
1
1
  import { describe, expect, it } from 'vitest'
2
- import { ArraySchema } from './array.js'
3
- import { IntegerSchema } from './integer.js'
4
- import { ObjectSchema } from './object.js'
5
- import { StringSchema } from './string.js'
2
+ import { array } from './array.js'
3
+ import { integer } from './integer.js'
4
+ import { object } from './object.js'
5
+ import { string } from './string.js'
6
6
 
7
7
  describe('ArraySchema', () => {
8
8
  it('validates arrays with string items', () => {
9
- const schema = new ArraySchema(new StringSchema({}))
9
+ const schema = array(string())
10
10
  const result = schema.safeParse(['hello', 'world'])
11
11
  expect(result.success).toBe(true)
12
12
  })
13
13
 
14
14
  it('validates arrays with integer items', () => {
15
- const schema = new ArraySchema(new IntegerSchema({}))
15
+ const schema = array(integer())
16
16
  const result = schema.safeParse([1, 2, 3])
17
17
  expect(result.success).toBe(true)
18
18
  })
19
19
 
20
20
  it('validates arrays with object items', () => {
21
- const schema = new ArraySchema(
22
- new ObjectSchema({
23
- name: new StringSchema({}),
24
- age: new IntegerSchema({}),
21
+ const schema = array(
22
+ object({
23
+ name: string(),
24
+ age: integer(),
25
25
  }),
26
26
  )
27
27
  const result = schema.safeParse([
@@ -32,74 +32,74 @@ describe('ArraySchema', () => {
32
32
  })
33
33
 
34
34
  it('validates empty arrays', () => {
35
- const schema = new ArraySchema(new StringSchema({}))
35
+ const schema = array(string())
36
36
  const result = schema.safeParse([])
37
37
  expect(result.success).toBe(true)
38
38
  })
39
39
 
40
40
  it('rejects non-array values', () => {
41
- const schema = new ArraySchema(new StringSchema({}))
41
+ const schema = array(string())
42
42
  const result = schema.safeParse('not an array')
43
43
  expect(result.success).toBe(false)
44
44
  })
45
45
 
46
46
  it('rejects null values', () => {
47
- const schema = new ArraySchema(new StringSchema({}))
47
+ const schema = array(string())
48
48
  const result = schema.safeParse(null)
49
49
  expect(result.success).toBe(false)
50
50
  })
51
51
 
52
52
  it('rejects undefined values', () => {
53
- const schema = new ArraySchema(new StringSchema({}))
53
+ const schema = array(string())
54
54
  const result = schema.safeParse(undefined)
55
55
  expect(result.success).toBe(false)
56
56
  })
57
57
 
58
58
  it('rejects objects that look like arrays', () => {
59
- const schema = new ArraySchema(new StringSchema({}))
59
+ const schema = array(string())
60
60
  const result = schema.safeParse({ 0: 'a', 1: 'b', length: 2 })
61
61
  expect(result.success).toBe(false)
62
62
  })
63
63
 
64
64
  it('rejects arrays with invalid items', () => {
65
- const schema = new ArraySchema(new IntegerSchema({}))
65
+ const schema = array(integer())
66
66
  const result = schema.safeParse([1, 2, 'three'])
67
67
  expect(result.success).toBe(false)
68
68
  })
69
69
 
70
70
  it('rejects arrays with some invalid items', () => {
71
- const schema = new ArraySchema(new StringSchema({}))
71
+ const schema = array(string())
72
72
  const result = schema.safeParse(['valid', null, 'also valid'])
73
73
  expect(result.success).toBe(false)
74
74
  })
75
75
 
76
76
  describe('minLength constraint', () => {
77
77
  it('validates arrays meeting minLength', () => {
78
- const schema = new ArraySchema(new StringSchema({}), { minLength: 2 })
78
+ const schema = array(string(), { minLength: 2 })
79
79
  const result = schema.safeParse(['a', 'b'])
80
80
  expect(result.success).toBe(true)
81
81
  })
82
82
 
83
83
  it('validates arrays exceeding minLength', () => {
84
- const schema = new ArraySchema(new StringSchema({}), { minLength: 2 })
84
+ const schema = array(string(), { minLength: 2 })
85
85
  const result = schema.safeParse(['a', 'b', 'c'])
86
86
  expect(result.success).toBe(true)
87
87
  })
88
88
 
89
89
  it('rejects arrays below minLength', () => {
90
- const schema = new ArraySchema(new StringSchema({}), { minLength: 3 })
90
+ const schema = array(string(), { minLength: 3 })
91
91
  const result = schema.safeParse(['a', 'b'])
92
92
  expect(result.success).toBe(false)
93
93
  })
94
94
 
95
95
  it('rejects empty arrays when minLength is set', () => {
96
- const schema = new ArraySchema(new StringSchema({}), { minLength: 1 })
96
+ const schema = array(string(), { minLength: 1 })
97
97
  const result = schema.safeParse([])
98
98
  expect(result.success).toBe(false)
99
99
  })
100
100
 
101
101
  it('validates empty arrays when minLength is 0', () => {
102
- const schema = new ArraySchema(new StringSchema({}), { minLength: 0 })
102
+ const schema = array(string(), { minLength: 0 })
103
103
  const result = schema.safeParse([])
104
104
  expect(result.success).toBe(true)
105
105
  })
@@ -107,37 +107,37 @@ describe('ArraySchema', () => {
107
107
 
108
108
  describe('maxLength constraint', () => {
109
109
  it('validates arrays meeting maxLength', () => {
110
- const schema = new ArraySchema(new StringSchema({}), { maxLength: 3 })
110
+ const schema = array(string(), { maxLength: 3 })
111
111
  const result = schema.safeParse(['a', 'b', 'c'])
112
112
  expect(result.success).toBe(true)
113
113
  })
114
114
 
115
115
  it('validates arrays below maxLength', () => {
116
- const schema = new ArraySchema(new StringSchema({}), { maxLength: 3 })
116
+ const schema = array(string(), { maxLength: 3 })
117
117
  const result = schema.safeParse(['a', 'b'])
118
118
  expect(result.success).toBe(true)
119
119
  })
120
120
 
121
121
  it('rejects arrays exceeding maxLength', () => {
122
- const schema = new ArraySchema(new StringSchema({}), { maxLength: 2 })
122
+ const schema = array(string(), { maxLength: 2 })
123
123
  const result = schema.safeParse(['a', 'b', 'c'])
124
124
  expect(result.success).toBe(false)
125
125
  })
126
126
 
127
127
  it('validates empty arrays with maxLength', () => {
128
- const schema = new ArraySchema(new StringSchema({}), { maxLength: 5 })
128
+ const schema = array(string(), { maxLength: 5 })
129
129
  const result = schema.safeParse([])
130
130
  expect(result.success).toBe(true)
131
131
  })
132
132
 
133
133
  it('rejects empty arrays when maxLength is 0', () => {
134
- const schema = new ArraySchema(new StringSchema({}), { maxLength: 0 })
134
+ const schema = array(string(), { maxLength: 0 })
135
135
  const result = schema.safeParse(['a'])
136
136
  expect(result.success).toBe(false)
137
137
  })
138
138
 
139
139
  it('validates empty arrays when maxLength is 0', () => {
140
- const schema = new ArraySchema(new StringSchema({}), { maxLength: 0 })
140
+ const schema = array(string(), { maxLength: 0 })
141
141
  const result = schema.safeParse([])
142
142
  expect(result.success).toBe(true)
143
143
  })
@@ -145,7 +145,7 @@ describe('ArraySchema', () => {
145
145
 
146
146
  describe('minLength and maxLength together', () => {
147
147
  it('validates arrays within range', () => {
148
- const schema = new ArraySchema(new StringSchema({}), {
148
+ const schema = array(string(), {
149
149
  minLength: 2,
150
150
  maxLength: 4,
151
151
  })
@@ -154,7 +154,7 @@ describe('ArraySchema', () => {
154
154
  })
155
155
 
156
156
  it('validates arrays at min boundary', () => {
157
- const schema = new ArraySchema(new StringSchema({}), {
157
+ const schema = array(string(), {
158
158
  minLength: 2,
159
159
  maxLength: 4,
160
160
  })
@@ -163,7 +163,7 @@ describe('ArraySchema', () => {
163
163
  })
164
164
 
165
165
  it('validates arrays at max boundary', () => {
166
- const schema = new ArraySchema(new StringSchema({}), {
166
+ const schema = array(string(), {
167
167
  minLength: 2,
168
168
  maxLength: 4,
169
169
  })
@@ -172,7 +172,7 @@ describe('ArraySchema', () => {
172
172
  })
173
173
 
174
174
  it('rejects arrays below minLength', () => {
175
- const schema = new ArraySchema(new StringSchema({}), {
175
+ const schema = array(string(), {
176
176
  minLength: 2,
177
177
  maxLength: 4,
178
178
  })
@@ -181,7 +181,7 @@ describe('ArraySchema', () => {
181
181
  })
182
182
 
183
183
  it('rejects arrays above maxLength', () => {
184
- const schema = new ArraySchema(new StringSchema({}), {
184
+ const schema = array(string(), {
185
185
  minLength: 2,
186
186
  maxLength: 4,
187
187
  })
@@ -190,7 +190,7 @@ describe('ArraySchema', () => {
190
190
  })
191
191
 
192
192
  it('validates single-length range', () => {
193
- const schema = new ArraySchema(new StringSchema({}), {
193
+ const schema = array(string(), {
194
194
  minLength: 3,
195
195
  maxLength: 3,
196
196
  })
@@ -199,7 +199,7 @@ describe('ArraySchema', () => {
199
199
  })
200
200
 
201
201
  it('rejects arrays not matching exact length', () => {
202
- const schema = new ArraySchema(new StringSchema({}), {
202
+ const schema = array(string(), {
203
203
  minLength: 3,
204
204
  maxLength: 3,
205
205
  })
@@ -210,7 +210,7 @@ describe('ArraySchema', () => {
210
210
 
211
211
  describe('nested arrays', () => {
212
212
  it('validates arrays of arrays', () => {
213
- const schema = new ArraySchema(new ArraySchema(new StringSchema({})))
213
+ const schema = array(array(string()))
214
214
  const result = schema.safeParse([
215
215
  ['a', 'b'],
216
216
  ['c', 'd'],
@@ -219,7 +219,7 @@ describe('ArraySchema', () => {
219
219
  })
220
220
 
221
221
  it('rejects invalid nested arrays', () => {
222
- const schema = new ArraySchema(new ArraySchema(new IntegerSchema({})))
222
+ const schema = array(array(integer()))
223
223
  const result = schema.safeParse([
224
224
  [1, 2],
225
225
  [3, 'four'],
@@ -228,9 +228,7 @@ describe('ArraySchema', () => {
228
228
  })
229
229
 
230
230
  it('validates deeply nested arrays', () => {
231
- const schema = new ArraySchema(
232
- new ArraySchema(new ArraySchema(new IntegerSchema({}))),
233
- )
231
+ const schema = array(array(array(integer())))
234
232
  const result = schema.safeParse([[[1, 2], [3]], [[4, 5, 6]]])
235
233
  expect(result.success).toBe(true)
236
234
  })
@@ -1,30 +1,29 @@
1
1
  import {
2
- Infer,
2
+ InferInput,
3
+ InferOutput,
3
4
  Schema,
4
- ValidationResult,
5
+ ValidationContext,
5
6
  Validator,
6
- ValidatorContext,
7
7
  } from '../core.js'
8
+ import { memoizedTransformer } from '../util/memoize.js'
8
9
 
9
10
  export type ArraySchemaOptions = {
10
11
  minLength?: number
11
12
  maxLength?: number
12
13
  }
13
14
 
14
- export class ArraySchema<const T extends Validator> extends Schema<
15
- Array<Infer<T>>
15
+ export class ArraySchema<const TItem extends Validator> extends Schema<
16
+ Array<InferInput<TItem>>,
17
+ Array<InferOutput<TItem>>
16
18
  > {
17
19
  constructor(
18
- readonly itemsSchema: T,
20
+ readonly validator: TItem,
19
21
  readonly options: ArraySchemaOptions = {},
20
22
  ) {
21
23
  super()
22
24
  }
23
25
 
24
- validateInContext(
25
- input: unknown,
26
- ctx: ValidatorContext,
27
- ): ValidationResult<Array<Infer<T>>> {
26
+ validateInContext(input: unknown, ctx: ValidationContext) {
28
27
  if (!Array.isArray(input)) {
29
28
  return ctx.issueInvalidType(input, 'array')
30
29
  }
@@ -39,19 +38,42 @@ export class ArraySchema<const T extends Validator> extends Schema<
39
38
  return ctx.issueTooBig(input, 'array', maxLength, input.length)
40
39
  }
41
40
 
42
- let copy: undefined | Array<Infer<T>>
41
+ let copy: undefined | unknown[]
43
42
 
44
43
  for (let i = 0; i < input.length; i++) {
45
- const result = ctx.validateChild(input, i, this.itemsSchema)
44
+ const result = ctx.validateChild(input, i, this.validator)
46
45
  if (!result.success) return result
47
46
 
48
47
  if (result.value !== input[i]) {
48
+ if (ctx.options.mode === 'validate') {
49
+ // In "validate" mode, we can't modify the input, so we issue an error
50
+ return ctx.issueInvalidPropertyValue(input, i, [result.value])
51
+ }
52
+
49
53
  // Copy on write (but only if we did not already make a copy)
50
54
  copy ??= Array.from(input)
51
55
  copy[i] = result.value
52
56
  }
53
57
  }
54
58
 
55
- return ctx.success(copy ?? input) as ValidationResult<Array<Infer<T>>>
59
+ return ctx.success(copy ?? input)
56
60
  }
57
61
  }
62
+
63
+ /*@__NO_SIDE_EFFECTS__*/
64
+ function arraySchema<const TValidator extends Validator>(
65
+ items: TValidator,
66
+ options?: ArraySchemaOptions,
67
+ ): ArraySchema<TValidator>
68
+ function arraySchema<
69
+ const TValue,
70
+ const TValidator extends Validator<TValue> = Validator<TValue>,
71
+ >(items: TValidator, options?: ArraySchemaOptions): ArraySchema<TValidator>
72
+ function arraySchema<const TValidator extends Validator>(
73
+ items: TValidator,
74
+ options?: ArraySchemaOptions,
75
+ ) {
76
+ return new ArraySchema<TValidator>(items, options)
77
+ }
78
+
79
+ export const array = /*#__PURE__*/ memoizedTransformer(arraySchema)