@atproto/lex-schema 0.0.2 → 0.0.4

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 (289) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/dist/core/$type.d.ts +6 -3
  3. package/dist/core/$type.d.ts.map +1 -1
  4. package/dist/core/$type.js +1 -0
  5. package/dist/core/$type.js.map +1 -1
  6. package/dist/core/record-key.d.ts +3 -3
  7. package/dist/core/record-key.d.ts.map +1 -1
  8. package/dist/core/record-key.js +12 -6
  9. package/dist/core/record-key.js.map +1 -1
  10. package/dist/core/result.d.ts.map +1 -1
  11. package/dist/core/result.js +6 -0
  12. package/dist/core/result.js.map +1 -1
  13. package/dist/core/string-format.d.ts +30 -27
  14. package/dist/core/string-format.d.ts.map +1 -1
  15. package/dist/core/string-format.js +56 -42
  16. package/dist/core/string-format.js.map +1 -1
  17. package/dist/core/types.d.ts +9 -1
  18. package/dist/core/types.d.ts.map +1 -1
  19. package/dist/core/types.js.map +1 -1
  20. package/dist/external.d.ts +31 -28
  21. package/dist/external.d.ts.map +1 -1
  22. package/dist/external.js +33 -17
  23. package/dist/external.js.map +1 -1
  24. package/dist/schema/_parameters.d.ts +2 -2
  25. package/dist/schema/_parameters.d.ts.map +1 -1
  26. package/dist/schema/array.d.ts +5 -6
  27. package/dist/schema/array.d.ts.map +1 -1
  28. package/dist/schema/array.js +5 -6
  29. package/dist/schema/array.js.map +1 -1
  30. package/dist/schema/blob.d.ts +2 -3
  31. package/dist/schema/blob.d.ts.map +1 -1
  32. package/dist/schema/blob.js +1 -2
  33. package/dist/schema/blob.js.map +1 -1
  34. package/dist/schema/boolean.d.ts +4 -5
  35. package/dist/schema/boolean.d.ts.map +1 -1
  36. package/dist/schema/boolean.js +2 -3
  37. package/dist/schema/boolean.js.map +1 -1
  38. package/dist/schema/bytes.d.ts +3 -4
  39. package/dist/schema/bytes.d.ts.map +1 -1
  40. package/dist/schema/bytes.js +2 -3
  41. package/dist/schema/bytes.js.map +1 -1
  42. package/dist/schema/cid.d.ts +13 -6
  43. package/dist/schema/cid.d.ts.map +1 -1
  44. package/dist/schema/cid.js +2 -4
  45. package/dist/schema/cid.js.map +1 -1
  46. package/dist/schema/custom.d.ts +3 -4
  47. package/dist/schema/custom.d.ts.map +1 -1
  48. package/dist/schema/custom.js +4 -3
  49. package/dist/schema/custom.js.map +1 -1
  50. package/dist/schema/dict.d.ts +3 -3
  51. package/dist/schema/dict.d.ts.map +1 -1
  52. package/dist/schema/dict.js +1 -1
  53. package/dist/schema/dict.js.map +1 -1
  54. package/dist/schema/discriminated-union.d.ts +15 -24
  55. package/dist/schema/discriminated-union.d.ts.map +1 -1
  56. package/dist/schema/discriminated-union.js +40 -64
  57. package/dist/schema/discriminated-union.js.map +1 -1
  58. package/dist/schema/enum.d.ts +8 -4
  59. package/dist/schema/enum.d.ts.map +1 -1
  60. package/dist/schema/enum.js +5 -3
  61. package/dist/schema/enum.js.map +1 -1
  62. package/dist/schema/integer.d.ts +3 -4
  63. package/dist/schema/integer.d.ts.map +1 -1
  64. package/dist/schema/integer.js +3 -4
  65. package/dist/schema/integer.js.map +1 -1
  66. package/dist/schema/intersection.d.ts +22 -14
  67. package/dist/schema/intersection.d.ts.map +1 -1
  68. package/dist/schema/intersection.js +12 -22
  69. package/dist/schema/intersection.js.map +1 -1
  70. package/dist/schema/literal.d.ts +7 -3
  71. package/dist/schema/literal.d.ts.map +1 -1
  72. package/dist/schema/literal.js +5 -3
  73. package/dist/schema/literal.js.map +1 -1
  74. package/dist/schema/never.d.ts +2 -2
  75. package/dist/schema/never.d.ts.map +1 -1
  76. package/dist/schema/never.js +1 -1
  77. package/dist/schema/never.js.map +1 -1
  78. package/dist/schema/null.d.ts +2 -3
  79. package/dist/schema/null.d.ts.map +1 -1
  80. package/dist/schema/null.js +1 -2
  81. package/dist/schema/null.js.map +1 -1
  82. package/dist/schema/nullable.d.ts +7 -0
  83. package/dist/schema/nullable.d.ts.map +1 -0
  84. package/dist/schema/nullable.js +19 -0
  85. package/dist/schema/nullable.js.map +1 -0
  86. package/dist/schema/object.d.ts +10 -44
  87. package/dist/schema/object.d.ts.map +1 -1
  88. package/dist/schema/object.js +10 -46
  89. package/dist/schema/object.js.map +1 -1
  90. package/dist/schema/optional.d.ts +7 -0
  91. package/dist/schema/optional.d.ts.map +1 -0
  92. package/dist/schema/optional.js +25 -0
  93. package/dist/schema/optional.js.map +1 -0
  94. package/dist/schema/params.d.ts +14 -19
  95. package/dist/schema/params.d.ts.map +1 -1
  96. package/dist/schema/params.js +10 -24
  97. package/dist/schema/params.js.map +1 -1
  98. package/dist/schema/payload.d.ts +4 -4
  99. package/dist/schema/payload.d.ts.map +1 -1
  100. package/dist/schema/payload.js.map +1 -1
  101. package/dist/schema/permission-set.d.ts +6 -6
  102. package/dist/schema/permission-set.d.ts.map +1 -1
  103. package/dist/schema/permission-set.js +1 -2
  104. package/dist/schema/permission-set.js.map +1 -1
  105. package/dist/schema/permission.d.ts +0 -1
  106. package/dist/schema/permission.d.ts.map +1 -1
  107. package/dist/schema/permission.js +0 -1
  108. package/dist/schema/permission.js.map +1 -1
  109. package/dist/schema/procedure.d.ts +8 -9
  110. package/dist/schema/procedure.d.ts.map +1 -1
  111. package/dist/schema/procedure.js +0 -1
  112. package/dist/schema/procedure.js.map +1 -1
  113. package/dist/schema/query.d.ts +7 -8
  114. package/dist/schema/query.d.ts.map +1 -1
  115. package/dist/schema/query.js +0 -1
  116. package/dist/schema/query.js.map +1 -1
  117. package/dist/schema/record.d.ts +34 -28
  118. package/dist/schema/record.d.ts.map +1 -1
  119. package/dist/schema/record.js +1 -2
  120. package/dist/schema/record.js.map +1 -1
  121. package/dist/schema/ref.d.ts +2 -3
  122. package/dist/schema/ref.d.ts.map +1 -1
  123. package/dist/schema/ref.js +1 -2
  124. package/dist/schema/ref.js.map +1 -1
  125. package/dist/schema/refine.d.ts +18 -0
  126. package/dist/schema/refine.d.ts.map +1 -0
  127. package/dist/schema/refine.js +33 -0
  128. package/dist/schema/refine.js.map +1 -0
  129. package/dist/schema/regexp.d.ts +7 -0
  130. package/dist/schema/regexp.d.ts.map +1 -0
  131. package/dist/schema/regexp.js +22 -0
  132. package/dist/schema/regexp.js.map +1 -0
  133. package/dist/schema/string.d.ts +4 -8
  134. package/dist/schema/string.d.ts.map +1 -1
  135. package/dist/schema/string.js +6 -3
  136. package/dist/schema/string.js.map +1 -1
  137. package/dist/schema/subscription.d.ts +7 -6
  138. package/dist/schema/subscription.d.ts.map +1 -1
  139. package/dist/schema/subscription.js.map +1 -1
  140. package/dist/schema/token.d.ts +2 -3
  141. package/dist/schema/token.d.ts.map +1 -1
  142. package/dist/schema/token.js +1 -2
  143. package/dist/schema/token.js.map +1 -1
  144. package/dist/schema/typed-object.d.ts +29 -27
  145. package/dist/schema/typed-object.d.ts.map +1 -1
  146. package/dist/schema/typed-object.js +1 -2
  147. package/dist/schema/typed-object.js.map +1 -1
  148. package/dist/schema/typed-ref.d.ts +2 -2
  149. package/dist/schema/typed-ref.d.ts.map +1 -1
  150. package/dist/schema/typed-ref.js +1 -1
  151. package/dist/schema/typed-ref.js.map +1 -1
  152. package/dist/schema/typed-union.d.ts +3 -4
  153. package/dist/schema/typed-union.d.ts.map +1 -1
  154. package/dist/schema/typed-union.js +3 -10
  155. package/dist/schema/typed-union.js.map +1 -1
  156. package/dist/schema/union.d.ts +2 -2
  157. package/dist/schema/union.d.ts.map +1 -1
  158. package/dist/schema/union.js +1 -1
  159. package/dist/schema/union.js.map +1 -1
  160. package/dist/schema/unknown-object.d.ts +2 -3
  161. package/dist/schema/unknown-object.d.ts.map +1 -1
  162. package/dist/schema/unknown-object.js +1 -2
  163. package/dist/schema/unknown-object.js.map +1 -1
  164. package/dist/schema/unknown.d.ts +2 -2
  165. package/dist/schema/unknown.d.ts.map +1 -1
  166. package/dist/schema/unknown.js +1 -1
  167. package/dist/schema/unknown.js.map +1 -1
  168. package/dist/schema.d.ts +4 -0
  169. package/dist/schema.d.ts.map +1 -1
  170. package/dist/schema.js +6 -1
  171. package/dist/schema.js.map +1 -1
  172. package/dist/util/array-agg.d.ts.map +1 -1
  173. package/dist/util/array-agg.js +1 -0
  174. package/dist/util/array-agg.js.map +1 -1
  175. package/dist/util/lazy-property.d.ts +2 -0
  176. package/dist/util/lazy-property.d.ts.map +1 -0
  177. package/dist/util/lazy-property.js +14 -0
  178. package/dist/util/lazy-property.js.map +1 -0
  179. package/dist/validation/schema.d.ts +24 -0
  180. package/dist/validation/schema.d.ts.map +1 -0
  181. package/dist/validation/schema.js +57 -0
  182. package/dist/validation/schema.js.map +1 -0
  183. package/dist/validation/validation-error.d.ts +3 -3
  184. package/dist/validation/validation-error.d.ts.map +1 -1
  185. package/dist/validation/validation-error.js +32 -4
  186. package/dist/validation/validation-error.js.map +1 -1
  187. package/dist/validation/validation-issue.d.ts +32 -24
  188. package/dist/validation/validation-issue.d.ts.map +1 -1
  189. package/dist/validation/validation-issue.js +136 -92
  190. package/dist/validation/validation-issue.js.map +1 -1
  191. package/dist/validation/validator.d.ts +20 -50
  192. package/dist/validation/validator.d.ts.map +1 -1
  193. package/dist/validation/validator.js +40 -134
  194. package/dist/validation/validator.js.map +1 -1
  195. package/dist/validation.d.ts +1 -0
  196. package/dist/validation.d.ts.map +1 -1
  197. package/dist/validation.js +1 -0
  198. package/dist/validation.js.map +1 -1
  199. package/package.json +8 -4
  200. package/src/core/$type.ts +7 -4
  201. package/src/core/record-key.ts +12 -5
  202. package/src/core/result.ts +6 -0
  203. package/src/core/string-format.ts +97 -61
  204. package/src/core/types.ts +12 -6
  205. package/src/external.ts +92 -70
  206. package/src/schema/_parameters.test.ts +416 -0
  207. package/src/schema/array.test.ts +237 -0
  208. package/src/schema/array.ts +17 -11
  209. package/src/schema/blob.test.ts +506 -0
  210. package/src/schema/blob.ts +3 -5
  211. package/src/schema/boolean.test.ts +116 -0
  212. package/src/schema/boolean.ts +5 -7
  213. package/src/schema/bytes.test.ts +226 -0
  214. package/src/schema/bytes.ts +4 -6
  215. package/src/schema/cid.test.ts +155 -0
  216. package/src/schema/cid.ts +14 -8
  217. package/src/schema/custom.test.ts +413 -0
  218. package/src/schema/custom.ts +10 -8
  219. package/src/schema/dict.test.ts +198 -0
  220. package/src/schema/dict.ts +6 -8
  221. package/src/schema/discriminated-union.test.ts +675 -0
  222. package/src/schema/discriminated-union.ts +68 -95
  223. package/src/schema/enum.test.ts +396 -0
  224. package/src/schema/enum.ts +12 -5
  225. package/src/schema/integer.test.ts +312 -0
  226. package/src/schema/integer.ts +5 -7
  227. package/src/schema/intersection.test.ts +32 -0
  228. package/src/schema/intersection.ts +37 -40
  229. package/src/schema/literal.test.ts +531 -0
  230. package/src/schema/literal.ts +12 -5
  231. package/src/schema/never.test.ts +174 -0
  232. package/src/schema/never.ts +3 -10
  233. package/src/schema/null.test.ts +79 -0
  234. package/src/schema/null.ts +3 -5
  235. package/src/schema/nullable.test.ts +480 -0
  236. package/src/schema/nullable.ts +23 -0
  237. package/src/schema/object.test.ts +47 -115
  238. package/src/schema/object.ts +19 -123
  239. package/src/schema/optional.test.ts +485 -0
  240. package/src/schema/optional.ts +31 -0
  241. package/src/schema/params.test.ts +582 -0
  242. package/src/schema/params.ts +37 -55
  243. package/src/schema/payload.test.ts +345 -0
  244. package/src/schema/payload.ts +5 -5
  245. package/src/schema/permission-set.test.ts +679 -0
  246. package/src/schema/permission-set.ts +6 -8
  247. package/src/schema/permission.test.ts +536 -0
  248. package/src/schema/permission.ts +0 -2
  249. package/src/schema/procedure.test.ts +443 -0
  250. package/src/schema/procedure.ts +11 -13
  251. package/src/schema/query.test.ts +408 -0
  252. package/src/schema/query.ts +9 -11
  253. package/src/schema/record.test.ts +694 -0
  254. package/src/schema/record.ts +38 -36
  255. package/src/schema/ref.test.ts +365 -0
  256. package/src/schema/ref.ts +8 -5
  257. package/src/schema/refine.test.ts +578 -0
  258. package/src/schema/refine.ts +85 -0
  259. package/src/schema/regexp.test.ts +580 -0
  260. package/src/schema/regexp.ts +22 -0
  261. package/src/schema/string.test.ts +612 -0
  262. package/src/schema/string.ts +11 -17
  263. package/src/schema/subscription.test.ts +689 -0
  264. package/src/schema/subscription.ts +13 -8
  265. package/src/schema/token.test.ts +428 -0
  266. package/src/schema/token.ts +3 -5
  267. package/src/schema/typed-object.test.ts +612 -0
  268. package/src/schema/typed-object.ts +23 -20
  269. package/src/schema/typed-ref.test.ts +823 -0
  270. package/src/schema/typed-ref.ts +10 -5
  271. package/src/schema/typed-union.test.ts +378 -0
  272. package/src/schema/typed-union.ts +6 -15
  273. package/src/schema/union.test.ts +200 -0
  274. package/src/schema/union.ts +5 -4
  275. package/src/schema/unknown-object.test.ts +592 -0
  276. package/src/schema/unknown-object.ts +3 -5
  277. package/src/schema/unknown.test.ts +312 -0
  278. package/src/schema/unknown.ts +3 -3
  279. package/src/schema.ts +7 -1
  280. package/src/util/array-agg.ts +1 -0
  281. package/src/util/lazy-property.ts +14 -0
  282. package/src/validation/schema.ts +92 -0
  283. package/src/validation/validation-error.ts +60 -9
  284. package/src/validation/validation-issue.ts +141 -144
  285. package/src/validation/validator.ts +67 -206
  286. package/src/validation.ts +1 -0
  287. package/tsconfig.build.json +12 -0
  288. package/tsconfig.json +7 -0
  289. package/tsconfig.tests.json +9 -0
@@ -0,0 +1,443 @@
1
+ import { ObjectSchema } from './object.js'
2
+ import { ParamsSchema } from './params.js'
3
+ import { Payload } from './payload.js'
4
+ import {
5
+ InferProcedureInputBody,
6
+ InferProcedureOutputBody,
7
+ InferProcedureParameters,
8
+ Procedure,
9
+ } from './procedure.js'
10
+ import { StringSchema } from './string.js'
11
+
12
+ describe('Procedure', () => {
13
+ describe('basic construction', () => {
14
+ it('creates a procedure with all parameters', () => {
15
+ const nsid = 'com.example.createPost'
16
+ const parameters = new ParamsSchema({})
17
+ const input = new Payload('application/json', undefined)
18
+ const output = new Payload('application/json', undefined)
19
+ const errors = ['InvalidRequest', 'Unauthorized'] as const
20
+
21
+ const procedure = new Procedure(nsid, parameters, input, output, errors)
22
+
23
+ expect(procedure.nsid).toBe(nsid)
24
+ expect(procedure.parameters).toBe(parameters)
25
+ expect(procedure.input).toBe(input)
26
+ expect(procedure.output).toBe(output)
27
+ expect(procedure.errors).toBe(errors)
28
+ })
29
+
30
+ it('creates a procedure without errors', () => {
31
+ const nsid = 'com.example.doSomething'
32
+ const parameters = new ParamsSchema({})
33
+ const input = new Payload('application/json', undefined)
34
+ const output = new Payload('application/json', undefined)
35
+
36
+ const procedure = new Procedure(
37
+ nsid,
38
+ parameters,
39
+ input,
40
+ output,
41
+ undefined,
42
+ )
43
+
44
+ expect(procedure.nsid).toBe(nsid)
45
+ expect(procedure.parameters).toBe(parameters)
46
+ expect(procedure.input).toBe(input)
47
+ expect(procedure.output).toBe(output)
48
+ expect(procedure.errors).toBeUndefined()
49
+ })
50
+
51
+ it('creates a procedure with empty errors array', () => {
52
+ const nsid = 'com.example.action'
53
+ const parameters = new ParamsSchema({})
54
+ const input = new Payload('application/json', undefined)
55
+ const output = new Payload('application/json', undefined)
56
+ const errors = [] as const
57
+
58
+ const procedure = new Procedure(nsid, parameters, input, output, errors)
59
+
60
+ expect(procedure.errors).toEqual([])
61
+ })
62
+ })
63
+
64
+ describe('with parameters schema', () => {
65
+ it('creates a procedure with query parameters', () => {
66
+ const nsid = 'com.example.listPosts'
67
+ const parameters = new ParamsSchema({
68
+ limit: new StringSchema({}),
69
+ cursor: new StringSchema({}),
70
+ })
71
+ const input = new Payload(undefined, undefined)
72
+ const output = new Payload('application/json', undefined)
73
+
74
+ const procedure = new Procedure(
75
+ nsid,
76
+ parameters,
77
+ input,
78
+ output,
79
+ undefined,
80
+ )
81
+
82
+ expect(procedure.parameters).toBe(parameters)
83
+ expect(procedure.parameters.validators).toHaveProperty('limit')
84
+ expect(procedure.parameters.validators).toHaveProperty('cursor')
85
+ })
86
+
87
+ it('creates a procedure with empty parameters', () => {
88
+ const nsid = 'com.example.action'
89
+ const parameters = new ParamsSchema({})
90
+ const input = new Payload('application/json', undefined)
91
+ const output = new Payload('application/json', undefined)
92
+
93
+ const procedure = new Procedure(
94
+ nsid,
95
+ parameters,
96
+ input,
97
+ output,
98
+ undefined,
99
+ )
100
+
101
+ expect(procedure.parameters).toBe(parameters)
102
+ expect(Object.keys(procedure.parameters.validators)).toHaveLength(0)
103
+ })
104
+ })
105
+
106
+ describe('with input payload', () => {
107
+ it('creates a procedure with JSON input', () => {
108
+ const nsid = 'com.example.createPost'
109
+ const parameters = new ParamsSchema({})
110
+ const inputSchema = new ObjectSchema({
111
+ text: new StringSchema({}),
112
+ })
113
+ const input = new Payload('application/json', inputSchema)
114
+ const output = new Payload('application/json', undefined)
115
+
116
+ const procedure = new Procedure(
117
+ nsid,
118
+ parameters,
119
+ input,
120
+ output,
121
+ undefined,
122
+ )
123
+
124
+ expect(procedure.input.encoding).toBe('application/json')
125
+ expect(procedure.input.schema).toBe(inputSchema)
126
+ })
127
+
128
+ it('creates a procedure with text input', () => {
129
+ const nsid = 'com.example.uploadText'
130
+ const parameters = new ParamsSchema({})
131
+ const input = new Payload('text/plain', undefined)
132
+ const output = new Payload('application/json', undefined)
133
+
134
+ const procedure = new Procedure(
135
+ nsid,
136
+ parameters,
137
+ input,
138
+ output,
139
+ undefined,
140
+ )
141
+
142
+ expect(procedure.input.encoding).toBe('text/plain')
143
+ expect(procedure.input.schema).toBeUndefined()
144
+ })
145
+
146
+ it('creates a procedure with binary input', () => {
147
+ const nsid = 'com.example.uploadBlob'
148
+ const parameters = new ParamsSchema({})
149
+ const input = new Payload('application/octet-stream', undefined)
150
+ const output = new Payload('application/json', undefined)
151
+
152
+ const procedure = new Procedure(
153
+ nsid,
154
+ parameters,
155
+ input,
156
+ output,
157
+ undefined,
158
+ )
159
+
160
+ expect(procedure.input.encoding).toBe('application/octet-stream')
161
+ })
162
+
163
+ it('creates a procedure with no input', () => {
164
+ const nsid = 'com.example.action'
165
+ const parameters = new ParamsSchema({})
166
+ const input = new Payload(undefined, undefined)
167
+ const output = new Payload('application/json', undefined)
168
+
169
+ const procedure = new Procedure(
170
+ nsid,
171
+ parameters,
172
+ input,
173
+ output,
174
+ undefined,
175
+ )
176
+
177
+ expect(procedure.input.encoding).toBeUndefined()
178
+ expect(procedure.input.schema).toBeUndefined()
179
+ })
180
+ })
181
+
182
+ describe('with output payload', () => {
183
+ it('creates a procedure with JSON output', () => {
184
+ const nsid = 'com.example.getPost'
185
+ const parameters = new ParamsSchema({})
186
+ const input = new Payload(undefined, undefined)
187
+ const outputSchema = new ObjectSchema({
188
+ uri: new StringSchema({}),
189
+ cid: new StringSchema({}),
190
+ })
191
+ const output = new Payload('application/json', outputSchema)
192
+
193
+ const procedure = new Procedure(
194
+ nsid,
195
+ parameters,
196
+ input,
197
+ output,
198
+ undefined,
199
+ )
200
+
201
+ expect(procedure.output.encoding).toBe('application/json')
202
+ expect(procedure.output.schema).toBe(outputSchema)
203
+ })
204
+
205
+ it('creates a procedure with text output', () => {
206
+ const nsid = 'com.example.export'
207
+ const parameters = new ParamsSchema({})
208
+ const input = new Payload(undefined, undefined)
209
+ const output = new Payload('text/plain', undefined)
210
+
211
+ const procedure = new Procedure(
212
+ nsid,
213
+ parameters,
214
+ input,
215
+ output,
216
+ undefined,
217
+ )
218
+
219
+ expect(procedure.output.encoding).toBe('text/plain')
220
+ })
221
+
222
+ it('creates a procedure with binary output', () => {
223
+ const nsid = 'com.example.download'
224
+ const parameters = new ParamsSchema({})
225
+ const input = new Payload(undefined, undefined)
226
+ const output = new Payload('application/octet-stream', undefined)
227
+
228
+ const procedure = new Procedure(
229
+ nsid,
230
+ parameters,
231
+ input,
232
+ output,
233
+ undefined,
234
+ )
235
+
236
+ expect(procedure.output.encoding).toBe('application/octet-stream')
237
+ })
238
+
239
+ it('creates a procedure with no output', () => {
240
+ const nsid = 'com.example.deletePost'
241
+ const parameters = new ParamsSchema({})
242
+ const input = new Payload('application/json', undefined)
243
+ const output = new Payload(undefined, undefined)
244
+
245
+ const procedure = new Procedure(
246
+ nsid,
247
+ parameters,
248
+ input,
249
+ output,
250
+ undefined,
251
+ )
252
+
253
+ expect(procedure.output.encoding).toBeUndefined()
254
+ expect(procedure.output.schema).toBeUndefined()
255
+ })
256
+ })
257
+
258
+ describe('with error definitions', () => {
259
+ it('creates a procedure with single error', () => {
260
+ const nsid = 'com.example.action'
261
+ const parameters = new ParamsSchema({})
262
+ const input = new Payload('application/json', undefined)
263
+ const output = new Payload('application/json', undefined)
264
+ const errors = ['InvalidRequest'] as const
265
+
266
+ const procedure = new Procedure(nsid, parameters, input, output, errors)
267
+
268
+ expect(procedure.errors).toEqual(['InvalidRequest'])
269
+ })
270
+
271
+ it('creates a procedure with multiple errors', () => {
272
+ const nsid = 'com.example.createPost'
273
+ const parameters = new ParamsSchema({})
274
+ const input = new Payload('application/json', undefined)
275
+ const output = new Payload('application/json', undefined)
276
+ const errors = [
277
+ 'InvalidRequest',
278
+ 'Unauthorized',
279
+ 'RateLimitExceeded',
280
+ ] as const
281
+
282
+ const procedure = new Procedure(nsid, parameters, input, output, errors)
283
+
284
+ expect(procedure.errors).toHaveLength(3)
285
+ expect(procedure.errors).toContain('InvalidRequest')
286
+ expect(procedure.errors).toContain('Unauthorized')
287
+ expect(procedure.errors).toContain('RateLimitExceeded')
288
+ })
289
+ })
290
+
291
+ describe('type inference helpers', () => {
292
+ it('infers procedure parameters type', () => {
293
+ const parameters = new ParamsSchema({
294
+ limit: new StringSchema({}),
295
+ })
296
+ const procedure = new Procedure(
297
+ 'com.example.list',
298
+ parameters,
299
+ new Payload(undefined, undefined),
300
+ new Payload(undefined, undefined),
301
+ undefined,
302
+ )
303
+
304
+ type Params = InferProcedureParameters<typeof procedure>
305
+ // Type test - this will fail at compile time if inference is wrong
306
+ const params: Params = { limit: 'test' }
307
+ expect(params).toBeDefined()
308
+ })
309
+
310
+ it('infers procedure input body type', () => {
311
+ const inputSchema = new ObjectSchema({
312
+ text: new StringSchema({}),
313
+ })
314
+ const procedure = new Procedure(
315
+ 'com.example.create',
316
+ new ParamsSchema({}),
317
+ new Payload('application/json', inputSchema),
318
+ new Payload(undefined, undefined),
319
+ undefined,
320
+ )
321
+
322
+ type InputBody = InferProcedureInputBody<typeof procedure>
323
+ // Type test - this will fail at compile time if inference is wrong
324
+ const input: InputBody = { text: 'hello' }
325
+ expect(input).toBeDefined()
326
+ })
327
+
328
+ it('infers procedure output body type', () => {
329
+ const outputSchema = new ObjectSchema({
330
+ uri: new StringSchema({}),
331
+ })
332
+ const procedure = new Procedure(
333
+ 'com.example.get',
334
+ new ParamsSchema({}),
335
+ new Payload(undefined, undefined),
336
+ new Payload('application/json', outputSchema),
337
+ undefined,
338
+ )
339
+
340
+ type OutputBody = InferProcedureOutputBody<typeof procedure>
341
+ // Type test - this will fail at compile time if inference is wrong
342
+ const output: OutputBody = { uri: 'at://did:plc:abc/post/123' }
343
+ expect(output).toBeDefined()
344
+ })
345
+ })
346
+
347
+ describe('property access', () => {
348
+ it('provides access to all properties', () => {
349
+ const nsid = 'com.example.test'
350
+ const parameters = new ParamsSchema({})
351
+ const input = new Payload('application/json', undefined)
352
+ const output = new Payload('application/json', undefined)
353
+ const errors = ['Error1', 'Error2'] as const
354
+
355
+ const procedure = new Procedure(nsid, parameters, input, output, errors)
356
+
357
+ // Verify all properties are accessible
358
+ expect(procedure.nsid).toBe(nsid)
359
+ expect(procedure.parameters).toBe(parameters)
360
+ expect(procedure.input).toBe(input)
361
+ expect(procedure.output).toBe(output)
362
+ expect(procedure.errors).toBe(errors)
363
+ })
364
+
365
+ it('maintains reference equality for complex properties', () => {
366
+ const parameters = new ParamsSchema({ test: new StringSchema({}) })
367
+ const inputSchema = new ObjectSchema({ field: new StringSchema({}) })
368
+ const outputSchema = new ObjectSchema({ result: new StringSchema({}) })
369
+ const input = new Payload('application/json', inputSchema)
370
+ const output = new Payload('application/json', outputSchema)
371
+
372
+ const procedure = new Procedure(
373
+ 'com.example.test',
374
+ parameters,
375
+ input,
376
+ output,
377
+ undefined,
378
+ )
379
+
380
+ // Verify references are maintained
381
+ expect(procedure.parameters).toBe(parameters)
382
+ expect(procedure.input).toBe(input)
383
+ expect(procedure.output).toBe(output)
384
+ expect(procedure.input.schema).toBe(inputSchema)
385
+ expect(procedure.output.schema).toBe(outputSchema)
386
+ })
387
+ })
388
+
389
+ describe('complex scenarios', () => {
390
+ it('creates a fully-featured procedure', () => {
391
+ const nsid = 'com.example.chat.sendMessage'
392
+ const parameters = new ParamsSchema({
393
+ conversationId: new StringSchema({}),
394
+ })
395
+ const inputSchema = new ObjectSchema({
396
+ text: new StringSchema({}),
397
+ mentions: new StringSchema({}),
398
+ })
399
+ const outputSchema = new ObjectSchema({
400
+ messageId: new StringSchema({}),
401
+ timestamp: new StringSchema({}),
402
+ })
403
+ const input = new Payload('application/json', inputSchema)
404
+ const output = new Payload('application/json', outputSchema)
405
+ const errors = [
406
+ 'ConversationNotFound',
407
+ 'MessageTooLong',
408
+ 'RateLimitExceeded',
409
+ ] as const
410
+
411
+ const procedure = new Procedure(nsid, parameters, input, output, errors)
412
+
413
+ expect(procedure.nsid).toBe(nsid)
414
+ expect(procedure.parameters.validators).toHaveProperty('conversationId')
415
+ expect(procedure.input.encoding).toBe('application/json')
416
+ expect(procedure.input.schema).toBe(inputSchema)
417
+ expect(procedure.output.encoding).toBe('application/json')
418
+ expect(procedure.output.schema).toBe(outputSchema)
419
+ expect(procedure.errors).toEqual(errors)
420
+ })
421
+
422
+ it('creates a minimal procedure', () => {
423
+ const nsid = 'com.example.ping'
424
+ const parameters = new ParamsSchema({})
425
+ const input = new Payload(undefined, undefined)
426
+ const output = new Payload(undefined, undefined)
427
+
428
+ const procedure = new Procedure(
429
+ nsid,
430
+ parameters,
431
+ input,
432
+ output,
433
+ undefined,
434
+ )
435
+
436
+ expect(procedure.nsid).toBe(nsid)
437
+ expect(Object.keys(procedure.parameters.validators)).toHaveLength(0)
438
+ expect(procedure.input.encoding).toBeUndefined()
439
+ expect(procedure.output.encoding).toBeUndefined()
440
+ expect(procedure.errors).toBeUndefined()
441
+ })
442
+ })
443
+ })
@@ -1,4 +1,4 @@
1
- import { Nsid } from '../core.js'
1
+ import { NsidString } from '../core.js'
2
2
  import { Infer } from '../validation.js'
3
3
  import { ParamsSchema } from './params.js'
4
4
  import { InferPayloadBody, Payload } from './payload.js'
@@ -17,19 +17,17 @@ export type InferProcedureOutputBody<Q extends Procedure> =
17
17
  : never
18
18
 
19
19
  export class Procedure<
20
- N extends Nsid = any,
21
- P extends ParamsSchema = any,
22
- I extends Payload = any,
23
- O extends Payload = any,
24
- E extends undefined | readonly string[] = any,
20
+ TNsid extends NsidString = any,
21
+ TParameters extends ParamsSchema = any,
22
+ TInputPayload extends Payload = any,
23
+ TOutputPayload extends Payload = any,
24
+ TErrors extends undefined | readonly string[] = any,
25
25
  > {
26
- readonly lexiconType = 'procedure' as const
27
-
28
26
  constructor(
29
- readonly nsid: N,
30
- readonly parameters: P,
31
- readonly input: I,
32
- readonly output: O,
33
- readonly errors: E,
27
+ readonly nsid: TNsid,
28
+ readonly parameters: TParameters,
29
+ readonly input: TInputPayload,
30
+ readonly output: TOutputPayload,
31
+ readonly errors: TErrors,
34
32
  ) {}
35
33
  }