@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,346 +1,340 @@
1
1
  import { describe, expect, it } from 'vitest'
2
- import { IntegerSchema } from './integer.js'
3
- import { ObjectSchema } from './object.js'
4
- import { Payload } from './payload.js'
5
- import { StringSchema } from './string.js'
6
- import { UnknownSchema } from './unknown.js'
2
+ import { integer } from './integer.js'
3
+ import { object } from './object.js'
4
+ import { payload } from './payload.js'
5
+ import { string } from './string.js'
6
+ import { unknown } from './unknown.js'
7
7
 
8
8
  describe('Payload', () => {
9
9
  describe('basic construction', () => {
10
10
  it('creates payload with encoding and no schema', () => {
11
- const payload = new Payload('application/json', undefined)
12
- expect(payload.encoding).toBe('application/json')
13
- expect(payload.schema).toBeUndefined()
11
+ const def = payload('application/json', undefined)
12
+ expect(def.encoding).toBe('application/json')
13
+ expect(def.schema).toBeUndefined()
14
14
  })
15
15
 
16
16
  it('creates payload with encoding and schema', () => {
17
- const schema = new ObjectSchema({
18
- name: new StringSchema({}),
17
+ const schema = object({
18
+ name: string(),
19
19
  })
20
- const payload = new Payload('application/json', schema)
21
- expect(payload.encoding).toBe('application/json')
22
- expect(payload.schema).toBe(schema)
20
+ const def = payload('application/json', schema)
21
+ expect(def.encoding).toBe('application/json')
22
+ expect(def.schema).toBe(schema)
23
23
  })
24
24
 
25
25
  it('creates payload with undefined encoding and undefined schema', () => {
26
- const payload = new Payload(undefined, undefined)
27
- expect(payload.encoding).toBeUndefined()
28
- expect(payload.schema).toBeUndefined()
26
+ const def = payload(undefined, undefined)
27
+ expect(def.encoding).toBeUndefined()
28
+ expect(def.schema).toBeUndefined()
29
29
  })
30
30
 
31
31
  it('creates payload with text encoding', () => {
32
- const payload = new Payload('text/plain', undefined)
33
- expect(payload.encoding).toBe('text/plain')
34
- expect(payload.schema).toBeUndefined()
32
+ const def = payload('text/plain', undefined)
33
+ expect(def.encoding).toBe('text/plain')
34
+ expect(def.schema).toBeUndefined()
35
35
  })
36
36
 
37
37
  it('creates payload with text/html encoding', () => {
38
- const payload = new Payload('text/html', undefined)
39
- expect(payload.encoding).toBe('text/html')
40
- expect(payload.schema).toBeUndefined()
38
+ const def = payload('text/html', undefined)
39
+ expect(def.encoding).toBe('text/html')
40
+ expect(def.schema).toBeUndefined()
41
41
  })
42
42
 
43
43
  it('creates payload with application/octet-stream encoding', () => {
44
- const payload = new Payload('application/octet-stream', undefined)
45
- expect(payload.encoding).toBe('application/octet-stream')
46
- expect(payload.schema).toBeUndefined()
44
+ const def = payload('application/octet-stream', undefined)
45
+ expect(def.encoding).toBe('application/octet-stream')
46
+ expect(def.schema).toBeUndefined()
47
47
  })
48
48
 
49
49
  it('creates payload with image encoding', () => {
50
- const payload = new Payload('image/png', undefined)
51
- expect(payload.encoding).toBe('image/png')
52
- expect(payload.schema).toBeUndefined()
50
+ const def = payload('image/png', undefined)
51
+ expect(def.encoding).toBe('image/png')
52
+ expect(def.schema).toBeUndefined()
53
53
  })
54
54
  })
55
55
 
56
56
  describe('encoding types', () => {
57
57
  it('handles application/json encoding', () => {
58
- const payload = new Payload('application/json', undefined)
59
- expect(payload.encoding).toBe('application/json')
58
+ const def = payload('application/json', undefined)
59
+ expect(def.encoding).toBe('application/json')
60
60
  })
61
61
 
62
62
  it('handles text/* encodings', () => {
63
- const textPlain = new Payload('text/plain', undefined)
63
+ const textPlain = payload('text/plain', undefined)
64
64
  expect(textPlain.encoding).toBe('text/plain')
65
65
 
66
- const textHtml = new Payload('text/html', undefined)
66
+ const textHtml = payload('text/html', undefined)
67
67
  expect(textHtml.encoding).toBe('text/html')
68
68
 
69
- const textCss = new Payload('text/css', undefined)
69
+ const textCss = payload('text/css', undefined)
70
70
  expect(textCss.encoding).toBe('text/css')
71
71
  })
72
72
 
73
73
  it('handles binary encodings', () => {
74
- const octetStream = new Payload('application/octet-stream', undefined)
74
+ const octetStream = payload('application/octet-stream', undefined)
75
75
  expect(octetStream.encoding).toBe('application/octet-stream')
76
76
 
77
- const imagePng = new Payload('image/png', undefined)
77
+ const imagePng = payload('image/png', undefined)
78
78
  expect(imagePng.encoding).toBe('image/png')
79
79
 
80
- const imageJpeg = new Payload('image/jpeg', undefined)
80
+ const imageJpeg = payload('image/jpeg', undefined)
81
81
  expect(imageJpeg.encoding).toBe('image/jpeg')
82
82
  })
83
83
 
84
84
  it('handles custom mime types', () => {
85
- const payload = new Payload('application/vnd.custom+json', undefined)
86
- expect(payload.encoding).toBe('application/vnd.custom+json')
85
+ const def = payload('application/vnd.custom+json', undefined)
86
+ expect(def.encoding).toBe('application/vnd.custom+json')
87
87
  })
88
88
  })
89
89
 
90
90
  describe('with schemas', () => {
91
91
  it('creates payload with object schema', () => {
92
- const schema = new ObjectSchema({
93
- id: new IntegerSchema({}),
94
- name: new StringSchema({}),
92
+ const schema = object({
93
+ id: integer(),
94
+ name: string(),
95
95
  })
96
- const payload = new Payload('application/json', schema)
97
- expect(payload.encoding).toBe('application/json')
98
- expect(payload.schema).toBe(schema)
96
+ const def = payload('application/json', schema)
97
+ expect(def.encoding).toBe('application/json')
98
+ expect(def.schema).toBe(schema)
99
99
  })
100
100
 
101
101
  it('creates payload with string schema', () => {
102
- const schema = new StringSchema({})
103
- const payload = new Payload('application/json', schema)
104
- expect(payload.encoding).toBe('application/json')
105
- expect(payload.schema).toBe(schema)
102
+ const schema = string()
103
+ const def = payload('application/json', schema)
104
+ expect(def.encoding).toBe('application/json')
105
+ expect(def.schema).toBe(schema)
106
106
  })
107
107
 
108
108
  it('creates payload with integer schema', () => {
109
- const schema = new IntegerSchema({})
110
- const payload = new Payload('application/json', schema)
111
- expect(payload.encoding).toBe('application/json')
112
- expect(payload.schema).toBe(schema)
109
+ const schema = integer()
110
+ const def = payload('application/json', schema)
111
+ expect(def.encoding).toBe('application/json')
112
+ expect(def.schema).toBe(schema)
113
113
  })
114
114
 
115
115
  it('creates payload with unknown schema', () => {
116
- const schema = new UnknownSchema()
117
- const payload = new Payload('application/json', schema)
118
- expect(payload.encoding).toBe('application/json')
119
- expect(payload.schema).toBe(schema)
116
+ const schema = unknown()
117
+ const def = payload('application/json', schema)
118
+ expect(def.encoding).toBe('application/json')
119
+ expect(def.schema).toBe(schema)
120
120
  })
121
121
 
122
122
  it('creates payload with complex nested schema', () => {
123
- const schema = new ObjectSchema({
124
- user: new ObjectSchema({
125
- id: new IntegerSchema({}),
126
- name: new StringSchema({}),
127
- email: new StringSchema({ format: 'uri' }),
123
+ const schema = object({
124
+ user: object({
125
+ id: integer(),
126
+ name: string(),
127
+ email: string({ format: 'uri' }),
128
128
  }),
129
- metadata: new ObjectSchema({
130
- createdAt: new StringSchema({ format: 'datetime' }),
131
- updatedAt: new StringSchema({ format: 'datetime' }),
129
+ metadata: object({
130
+ createdAt: string({ format: 'datetime' }),
131
+ updatedAt: string({ format: 'datetime' }),
132
132
  }),
133
133
  })
134
- const payload = new Payload('application/json', schema)
135
- expect(payload.encoding).toBe('application/json')
136
- expect(payload.schema).toBe(schema)
134
+ const def = payload('application/json', schema)
135
+ expect(def.encoding).toBe('application/json')
136
+ expect(def.schema).toBe(schema)
137
137
  })
138
138
  })
139
139
 
140
140
  describe('validation constraints', () => {
141
141
  it('throws error when schema is defined but encoding is undefined', () => {
142
- const schema = new StringSchema({})
142
+ const schema = string()
143
143
  expect(() => {
144
144
  // @ts-expect-error
145
- new Payload(undefined, schema)
145
+ payload(undefined, schema)
146
146
  }).toThrow(TypeError)
147
147
  expect(() => {
148
148
  // @ts-expect-error
149
- new Payload(undefined, schema)
149
+ payload(undefined, schema)
150
150
  }).toThrow('schema cannot be defined when encoding is undefined')
151
151
  })
152
152
 
153
153
  it('throws error when object schema is defined but encoding is undefined', () => {
154
- const schema = new ObjectSchema({
155
- name: new StringSchema({}),
154
+ const schema = object({
155
+ name: string(),
156
156
  })
157
157
  expect(() => {
158
158
  // @ts-expect-error
159
- new Payload(undefined, schema)
159
+ payload(undefined, schema)
160
160
  }).toThrow(TypeError)
161
161
  expect(() => {
162
162
  // @ts-expect-error
163
- new Payload(undefined, schema)
163
+ payload(undefined, schema)
164
164
  }).toThrow('schema cannot be defined when encoding is undefined')
165
165
  })
166
166
 
167
167
  it('throws error when integer schema is defined but encoding is undefined', () => {
168
- const schema = new IntegerSchema({})
168
+ const schema = integer()
169
169
  expect(() => {
170
170
  // @ts-expect-error
171
- new Payload(undefined, schema)
171
+ payload(undefined, schema)
172
172
  }).toThrow(TypeError)
173
173
  })
174
174
 
175
175
  it('allows undefined encoding with undefined schema', () => {
176
176
  expect(() => {
177
- new Payload(undefined, undefined)
177
+ payload(undefined, undefined)
178
178
  }).not.toThrow()
179
179
  })
180
180
 
181
181
  it('allows defined encoding with undefined schema', () => {
182
182
  expect(() => {
183
- new Payload('application/json', undefined)
183
+ payload('application/json', undefined)
184
184
  }).not.toThrow()
185
185
  })
186
186
 
187
187
  it('allows defined encoding with defined schema', () => {
188
- const schema = new StringSchema({})
188
+ const schema = string()
189
189
  expect(() => {
190
- new Payload('application/json', schema)
190
+ payload('application/json', schema)
191
191
  }).not.toThrow()
192
192
  })
193
193
  })
194
194
 
195
195
  describe('property access', () => {
196
196
  it('has accessible encoding property', () => {
197
- const payload = new Payload('application/json', undefined)
198
- expect(payload.encoding).toBe('application/json')
197
+ const def = payload('application/json', undefined)
198
+ expect(def.encoding).toBe('application/json')
199
199
  })
200
200
 
201
201
  it('has accessible schema property', () => {
202
- const schema = new StringSchema({})
203
- const payload = new Payload('application/json', schema)
204
- expect(payload.schema).toBe(schema)
202
+ const schema = string()
203
+ const def = payload('application/json', schema)
204
+ expect(def.schema).toBe(schema)
205
205
  })
206
206
 
207
207
  it('encoding property is immutable in TypeScript', () => {
208
- const payload = new Payload('application/json', undefined)
208
+ const def = payload('application/json', undefined)
209
209
  // TypeScript enforces readonly at compile time
210
- expect(payload.encoding).toBe('application/json')
210
+ expect(def.encoding).toBe('application/json')
211
211
  })
212
212
 
213
213
  it('schema property is immutable in TypeScript', () => {
214
- const schema = new StringSchema({})
215
- const payload = new Payload('application/json', schema)
214
+ const schema = string()
215
+ const def = payload('application/json', schema)
216
216
  // TypeScript enforces readonly at compile time
217
- expect(payload.schema).toBe(schema)
217
+ expect(def.schema).toBe(schema)
218
218
  })
219
219
  })
220
220
 
221
221
  describe('usage scenarios', () => {
222
222
  it('creates payload for JSON API response', () => {
223
- const payload = new Payload(
223
+ const def = payload(
224
224
  'application/json',
225
- new ObjectSchema({
226
- success: new StringSchema({}),
227
- data: new UnknownSchema(),
225
+ object({
226
+ success: string(),
227
+ data: unknown(),
228
228
  }),
229
229
  )
230
- expect(payload.encoding).toBe('application/json')
231
- expect(payload.schema).toBeDefined()
230
+ expect(def.encoding).toBe('application/json')
231
+ expect(def.schema).toBeDefined()
232
232
  })
233
233
 
234
234
  it('creates payload for plain text response', () => {
235
- const payload = new Payload('text/plain', undefined)
236
- expect(payload.encoding).toBe('text/plain')
237
- expect(payload.schema).toBeUndefined()
235
+ const def = payload('text/plain', undefined)
236
+ expect(def.encoding).toBe('text/plain')
237
+ expect(def.schema).toBeUndefined()
238
238
  })
239
239
 
240
240
  it('creates payload for binary data', () => {
241
- const payload = new Payload('application/octet-stream', undefined)
242
- expect(payload.encoding).toBe('application/octet-stream')
243
- expect(payload.schema).toBeUndefined()
241
+ const def = payload('application/octet-stream', undefined)
242
+ expect(def.encoding).toBe('application/octet-stream')
243
+ expect(def.schema).toBeUndefined()
244
244
  })
245
245
 
246
246
  it('creates payload for image upload', () => {
247
- const payload = new Payload('image/jpeg', undefined)
248
- expect(payload.encoding).toBe('image/jpeg')
249
- expect(payload.schema).toBeUndefined()
247
+ const def = payload('image/jpeg', undefined)
248
+ expect(def.encoding).toBe('image/jpeg')
249
+ expect(def.schema).toBeUndefined()
250
250
  })
251
251
 
252
252
  it('creates payload for multipart form data', () => {
253
- const payload = new Payload('multipart/form-data', undefined)
254
- expect(payload.encoding).toBe('multipart/form-data')
255
- expect(payload.schema).toBeUndefined()
253
+ const def = payload('multipart/form-data', undefined)
254
+ expect(def.encoding).toBe('multipart/form-data')
255
+ expect(def.schema).toBeUndefined()
256
256
  })
257
257
 
258
258
  it('creates payload for URL encoded form', () => {
259
- const payload = new Payload(
260
- 'application/x-www-form-urlencoded',
261
- undefined,
262
- )
263
- expect(payload.encoding).toBe('application/x-www-form-urlencoded')
264
- expect(payload.schema).toBeUndefined()
259
+ const def = payload('application/x-www-form-urlencoded', undefined)
260
+ expect(def.encoding).toBe('application/x-www-form-urlencoded')
261
+ expect(def.schema).toBeUndefined()
265
262
  })
266
263
 
267
264
  it('creates empty payload (no encoding, no schema)', () => {
268
- const payload = new Payload(undefined, undefined)
269
- expect(payload.encoding).toBeUndefined()
270
- expect(payload.schema).toBeUndefined()
265
+ const def = payload(undefined, undefined)
266
+ expect(def.encoding).toBeUndefined()
267
+ expect(def.schema).toBeUndefined()
271
268
  })
272
269
  })
273
270
 
274
271
  describe('edge cases', () => {
275
272
  it('handles encoding with charset parameter', () => {
276
- const payload = new Payload('application/json; charset=utf-8', undefined)
277
- expect(payload.encoding).toBe('application/json; charset=utf-8')
273
+ const def = payload('application/json; charset=utf-8', undefined)
274
+ expect(def.encoding).toBe('application/json; charset=utf-8')
278
275
  })
279
276
 
280
277
  it('handles encoding with multiple parameters', () => {
281
- const payload = new Payload(
282
- 'multipart/form-data; boundary=something',
283
- undefined,
284
- )
285
- expect(payload.encoding).toBe('multipart/form-data; boundary=something')
278
+ const def = payload('multipart/form-data; boundary=something', undefined)
279
+ expect(def.encoding).toBe('multipart/form-data; boundary=something')
286
280
  })
287
281
 
288
282
  it('handles empty string encoding', () => {
289
- const payload = new Payload('', undefined)
290
- expect(payload.encoding).toBe('')
283
+ const def = payload('', undefined)
284
+ expect(def.encoding).toBe('')
291
285
  })
292
286
 
293
287
  it('creates multiple payloads with same schema reference', () => {
294
- const sharedSchema = new ObjectSchema({
295
- id: new IntegerSchema({}),
288
+ const sharedSchema = object({
289
+ id: integer(),
296
290
  })
297
- const payload1 = new Payload('application/json', sharedSchema)
298
- const payload2 = new Payload('application/json', sharedSchema)
291
+ const def1 = payload('application/json', sharedSchema)
292
+ const def2 = payload('application/json', sharedSchema)
299
293
 
300
- expect(payload1.schema).toBe(payload2.schema)
301
- expect(payload1.schema).toBe(sharedSchema)
294
+ expect(def1.schema).toBe(def2.schema)
295
+ expect(def1.schema).toBe(sharedSchema)
302
296
  })
303
297
 
304
298
  it('creates multiple payloads with different schemas', () => {
305
- const schema1 = new StringSchema({})
306
- const schema2 = new IntegerSchema({})
307
- const payload1 = new Payload('application/json', schema1)
308
- const payload2 = new Payload('application/json', schema2)
299
+ const schema1 = string()
300
+ const schema2 = integer()
301
+ const def1 = payload('application/json', schema1)
302
+ const def2 = payload('application/json', schema2)
309
303
 
310
- expect(payload1.schema).not.toBe(payload2.schema)
311
- expect(payload1.schema).toBe(schema1)
312
- expect(payload2.schema).toBe(schema2)
304
+ expect(def1.schema).not.toBe(def2.schema)
305
+ expect(def1.schema).toBe(schema1)
306
+ expect(def2.schema).toBe(schema2)
313
307
  })
314
308
  })
315
309
 
316
310
  describe('type inference scenarios', () => {
317
311
  it('works with application/json and object schema', () => {
318
- const schema = new ObjectSchema({
319
- message: new StringSchema({}),
312
+ const schema = object({
313
+ message: string(),
320
314
  })
321
- const payload = new Payload('application/json', schema)
322
- expect(payload.encoding).toBe('application/json')
323
- expect(payload.schema).toBe(schema)
315
+ const def = payload('application/json', schema)
316
+ expect(def.encoding).toBe('application/json')
317
+ expect(def.schema).toBe(schema)
324
318
  })
325
319
 
326
320
  it('works with text/* encodings expecting string bodies', () => {
327
- const payload1 = new Payload('text/plain', undefined)
328
- const payload2 = new Payload('text/html', undefined)
329
- const payload3 = new Payload('text/csv', undefined)
321
+ const def1 = payload('text/plain', undefined)
322
+ const def2 = payload('text/html', undefined)
323
+ const def3 = payload('text/csv', undefined)
330
324
 
331
- expect(payload1.encoding).toBe('text/plain')
332
- expect(payload2.encoding).toBe('text/html')
333
- expect(payload3.encoding).toBe('text/csv')
325
+ expect(def1.encoding).toBe('text/plain')
326
+ expect(def2.encoding).toBe('text/html')
327
+ expect(def3.encoding).toBe('text/csv')
334
328
  })
335
329
 
336
330
  it('works with binary encodings expecting Uint8Array bodies', () => {
337
- const payload1 = new Payload('image/png', undefined)
338
- const payload2 = new Payload('application/octet-stream', undefined)
339
- const payload3 = new Payload('video/mp4', undefined)
331
+ const def1 = payload('image/png', undefined)
332
+ const def2 = payload('application/octet-stream', undefined)
333
+ const def3 = payload('video/mp4', undefined)
340
334
 
341
- expect(payload1.encoding).toBe('image/png')
342
- expect(payload2.encoding).toBe('application/octet-stream')
343
- expect(payload3.encoding).toBe('video/mp4')
335
+ expect(def1.encoding).toBe('image/png')
336
+ expect(def2.encoding).toBe('application/octet-stream')
337
+ expect(def3.encoding).toBe('video/mp4')
344
338
  })
345
339
  })
346
340
  })
@@ -1,13 +1,14 @@
1
1
  import { LexValue } from '@atproto/lex-data'
2
2
  import { Infer, Schema } from '../core.js'
3
+ import { ObjectSchema, ObjectSchemaShape, object } from './object.js'
3
4
 
4
5
  export type InferPayload<
5
- P extends Payload,
6
- B,
7
- > = P['encoding'] extends infer E extends string
6
+ TPayload extends Payload,
7
+ TBody,
8
+ > = TPayload['encoding'] extends infer E extends string
8
9
  ? {
9
10
  encoding: SchemaEncodingToDataEncoding<E>
10
- body: InferPayloadBody<P, B>
11
+ body: InferPayloadBody<TPayload, TBody>
11
12
  }
12
13
  : void | undefined
13
14
 
@@ -17,33 +18,33 @@ export type SchemaEncodingToDataEncoding<E extends string> = E extends '*/*'
17
18
  ? `${T}/${string}`
18
19
  : E
19
20
 
20
- export type InferPayloadEncoding<P extends Payload> =
21
- P['encoding'] extends string
22
- ? SchemaEncodingToDataEncoding<P['encoding']>
21
+ export type InferPayloadEncoding<TPayload extends Payload> =
22
+ TPayload['encoding'] extends string
23
+ ? SchemaEncodingToDataEncoding<TPayload['encoding']>
23
24
  : undefined
24
25
 
25
26
  export type InferPayloadBody<
26
- P extends Payload,
27
- B,
28
- > = P['encoding'] extends undefined
27
+ TPayload extends Payload,
28
+ TBody,
29
+ > = TPayload['encoding'] extends undefined
29
30
  ? undefined // No encoding, no payload
30
- : P['schema'] extends Schema
31
- ? Infer<P['schema']>
32
- : P['encoding'] extends `application/json`
31
+ : TPayload['schema'] extends Schema
32
+ ? Infer<TPayload['schema']>
33
+ : TPayload['encoding'] extends `application/json`
33
34
  ? LexValue
34
- : B
35
+ : TBody
35
36
 
36
- export type PayloadSchema<E extends string | undefined> = E extends undefined
37
+ export type PayloadShape<E extends string | undefined> = E extends undefined
37
38
  ? undefined
38
39
  : Schema | undefined
39
40
 
40
41
  export class Payload<
41
- const Encoding extends string | undefined = string | undefined,
42
- const Schema extends PayloadSchema<Encoding> = PayloadSchema<Encoding>,
42
+ const TEncoding extends string | undefined = string | undefined,
43
+ const TPayload extends PayloadShape<TEncoding> = PayloadShape<TEncoding>,
43
44
  > {
44
45
  constructor(
45
- readonly encoding: Encoding,
46
- readonly schema: Schema,
46
+ readonly encoding: TEncoding,
47
+ readonly schema: TPayload,
47
48
  ) {
48
49
  if (encoding === undefined && schema !== undefined) {
49
50
  throw new TypeError('schema cannot be defined when encoding is undefined')
@@ -84,3 +85,18 @@ export class Payload<
84
85
  return encoding === mime
85
86
  }
86
87
  }
88
+
89
+ /*@__NO_SIDE_EFFECTS__*/
90
+ export function payload<
91
+ const E extends string | undefined = undefined,
92
+ const S extends PayloadShape<E> = undefined,
93
+ >(encoding: E = undefined as E, validator: S = undefined as S) {
94
+ return new Payload<E, S>(encoding, validator)
95
+ }
96
+
97
+ /*@__NO_SIDE_EFFECTS__*/
98
+ export function jsonPayload<const P extends ObjectSchemaShape>(
99
+ properties: P,
100
+ ): Payload<'application/json', ObjectSchema<P>> {
101
+ return payload('application/json', object(properties))
102
+ }