@atproto/lex-document 0.0.3 → 0.0.5

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.
@@ -1,98 +1,75 @@
1
1
  import { l } from '@atproto/lex-schema'
2
2
 
3
+ // Re-usable shortcuts (avoid creating too many schemas)
4
+
5
+ const bool = l.boolean()
6
+ const int = l.integer()
7
+ const str = l.string()
8
+
9
+ const boopOpt = l.optional(bool)
10
+ const intOpt = l.optional(int)
11
+ const strOpt = l.optional(str)
12
+
13
+ const strArrOpt = l.optional(l.array(str))
14
+
3
15
  // https://atproto.com/specs/lexicon
4
16
 
5
17
  // "Concrete" Types
6
18
 
7
- export const lexiconBooleanSchema = l.object(
8
- {
9
- type: l.literal('boolean'),
10
- description: l.string(),
11
- default: l.boolean(),
12
- const: l.boolean(),
13
- },
14
- {
15
- required: ['type'],
16
- },
17
- )
19
+ export const lexiconBooleanSchema = l.object({
20
+ type: l.literal('boolean'),
21
+ default: boopOpt,
22
+ const: boopOpt,
23
+ description: strOpt,
24
+ })
18
25
  export type LexiconBoolean = l.Infer<typeof lexiconBooleanSchema>
19
26
 
20
- export const lexiconIntegerSchema = l.object(
21
- {
22
- type: l.literal('integer'),
23
- description: l.string(),
24
- default: l.integer(),
25
- minimum: l.integer(),
26
- maximum: l.integer(),
27
- enum: l.array(l.integer()),
28
- const: l.integer(),
29
- },
30
- {
31
- required: ['type'],
32
- },
33
- )
27
+ export const lexiconIntegerSchema = l.object({
28
+ type: l.literal('integer'),
29
+ default: intOpt,
30
+ minimum: intOpt,
31
+ maximum: intOpt,
32
+ enum: l.optional(l.array(l.integer())),
33
+ const: intOpt,
34
+ description: strOpt,
35
+ })
34
36
  export type LexiconInteger = l.Infer<typeof lexiconIntegerSchema>
35
37
 
36
- export type LexiconStringFormat = l.StringFormat
37
- export const lexiconStringFormatSchema = l.enum<LexiconStringFormat>(
38
- l.STRING_FORMATS,
39
- )
40
-
41
- export const lexiconStringSchema = l.object(
42
- {
43
- type: l.literal('string'),
44
- format: lexiconStringFormatSchema,
45
- description: l.string(),
46
- default: l.string(),
47
- minLength: l.integer(),
48
- maxLength: l.integer(),
49
- minGraphemes: l.integer(),
50
- maxGraphemes: l.integer(),
51
- enum: l.array(l.string()),
52
- const: l.string(),
53
- knownValues: l.array(l.string()),
54
- },
55
- {
56
- required: ['type'],
57
- },
58
- )
38
+ export const lexiconStringSchema = l.object({
39
+ type: l.literal('string'),
40
+ format: l.optional(l.enum<l.StringFormat>(l.STRING_FORMATS)),
41
+ default: strOpt,
42
+ minLength: intOpt,
43
+ maxLength: intOpt,
44
+ minGraphemes: intOpt,
45
+ maxGraphemes: intOpt,
46
+ enum: strArrOpt,
47
+ const: strOpt,
48
+ knownValues: strArrOpt,
49
+ description: strOpt,
50
+ })
59
51
  export type LexiconString = l.Infer<typeof lexiconStringSchema>
60
52
 
61
- export const lexiconBytesSchema = l.object(
62
- {
63
- type: l.literal('bytes'),
64
- description: l.string(),
65
- maxLength: l.integer(),
66
- minLength: l.integer(),
67
- },
68
- {
69
- required: ['type'],
70
- },
71
- )
53
+ export const lexiconBytesSchema = l.object({
54
+ type: l.literal('bytes'),
55
+ maxLength: intOpt,
56
+ minLength: intOpt,
57
+ description: strOpt,
58
+ })
72
59
  export type LexiconBytes = l.Infer<typeof lexiconBytesSchema>
73
60
 
74
- export const lexiconCidLinkSchema = l.object(
75
- {
76
- type: l.literal('cid-link'),
77
- description: l.string(),
78
- },
79
- {
80
- required: ['type'],
81
- },
82
- )
61
+ export const lexiconCidLinkSchema = l.object({
62
+ type: l.literal('cid-link'),
63
+ description: strOpt,
64
+ })
83
65
  export type LexiconCid = l.Infer<typeof lexiconCidLinkSchema>
84
66
 
85
- export const lexiconBlobSchema = l.object(
86
- {
87
- type: l.literal('blob'),
88
- description: l.string(),
89
- accept: l.array(l.string()),
90
- maxSize: l.integer(),
91
- },
92
- {
93
- required: ['type'],
94
- },
95
- )
67
+ export const lexiconBlobSchema = l.object({
68
+ type: l.literal('blob'),
69
+ accept: strArrOpt,
70
+ maxSize: intOpt,
71
+ description: strOpt,
72
+ })
96
73
  export type LexiconBlob = l.Infer<typeof lexiconBlobSchema>
97
74
 
98
75
  const CONCRETE_TYPES = [
@@ -108,51 +85,31 @@ const CONCRETE_TYPES = [
108
85
 
109
86
  // Meta types
110
87
 
111
- export const lexiconUnknownSchema = l.object(
112
- {
113
- type: l.literal('unknown'),
114
- description: l.string(),
115
- },
116
- {
117
- required: ['type'],
118
- },
119
- )
88
+ export const lexiconUnknownSchema = l.object({
89
+ type: l.literal('unknown'),
90
+ description: strOpt,
91
+ })
120
92
  export type LexiconUnknown = l.Infer<typeof lexiconUnknownSchema>
121
93
 
122
- export const lexiconTokenSchema = l.object(
123
- {
124
- type: l.literal('token'),
125
- description: l.string(),
126
- },
127
- {
128
- required: ['type'],
129
- },
130
- )
94
+ export const lexiconTokenSchema = l.object({
95
+ type: l.literal('token'),
96
+ description: strOpt,
97
+ })
131
98
  export type LexiconToken = l.Infer<typeof lexiconTokenSchema>
132
99
 
133
- export const lexiconRefSchema = l.object(
134
- {
135
- type: l.literal('ref'),
136
- description: l.string(),
137
- ref: l.string(),
138
- },
139
- {
140
- required: ['type', 'ref'],
141
- },
142
- )
100
+ export const lexiconRefSchema = l.object({
101
+ type: l.literal('ref'),
102
+ ref: str,
103
+ description: strOpt,
104
+ })
143
105
  export type LexiconRef = l.Infer<typeof lexiconRefSchema>
144
106
 
145
- export const lexiconRefUnionSchema = l.object(
146
- {
147
- type: l.literal('union'),
148
- description: l.string(),
149
- refs: l.array(l.string()),
150
- closed: l.boolean(),
151
- },
152
- {
153
- required: ['type', 'refs'],
154
- },
155
- )
107
+ export const lexiconRefUnionSchema = l.object({
108
+ type: l.literal('union'),
109
+ refs: l.array(str),
110
+ closed: boopOpt,
111
+ description: strOpt,
112
+ })
156
113
  export type LexiconRefUnion = l.Infer<typeof lexiconRefUnionSchema>
157
114
 
158
115
  // Complex Types
@@ -167,171 +124,138 @@ const ARRAY_ITEMS_SCHEMAS = [
167
124
 
168
125
  export type LexiconArrayItems = l.Infer<(typeof ARRAY_ITEMS_SCHEMAS)[number]>
169
126
 
170
- export const lexiconArraySchema = l.object(
171
- {
172
- type: l.literal('array'),
173
- description: l.string(),
174
- items: l.discriminatedUnion('type', ARRAY_ITEMS_SCHEMAS),
175
- minLength: l.integer(),
176
- maxLength: l.integer(),
177
- },
178
- {
179
- required: ['type', 'items'],
180
- },
181
- )
127
+ export const lexiconArraySchema = l.object({
128
+ type: l.literal('array'),
129
+ items: l.discriminatedUnion('type', ARRAY_ITEMS_SCHEMAS),
130
+ minLength: intOpt,
131
+ maxLength: intOpt,
132
+ description: strOpt,
133
+ })
182
134
  export type LexiconArray = l.Infer<typeof lexiconArraySchema>
183
135
 
184
- export const lexiconObjectSchema = l.object(
185
- {
136
+ const requirePropertiesRefinement: l.RefinementCheck<{
137
+ required?: string[]
138
+ properties: Record<string, unknown>
139
+ }> = {
140
+ check: (v) => !v.required || v.required.every((k) => k in v.properties),
141
+ message: 'All required parameters must be defined in properties',
142
+ path: 'required',
143
+ }
144
+
145
+ export const lexiconObjectSchema = l.refine(
146
+ l.object({
186
147
  type: l.literal('object'),
187
- description: l.string(),
188
- required: l.array(l.string()),
189
- nullable: l.array(l.string()),
190
148
  properties: l.dict(
191
- l.string(),
149
+ str,
192
150
  l.discriminatedUnion('type', [
193
151
  ...ARRAY_ITEMS_SCHEMAS,
194
152
  lexiconArraySchema,
195
153
  ]),
196
154
  ),
197
- },
198
- {
199
- required: ['type', 'properties'],
200
- },
155
+ required: strArrOpt,
156
+ nullable: strArrOpt,
157
+ description: strOpt,
158
+ }),
159
+ requirePropertiesRefinement,
201
160
  )
202
161
  export type LexiconObject = l.Infer<typeof lexiconObjectSchema>
203
162
 
204
163
  // Records
205
164
 
206
- export const lexiconRecordSchema = l.object(
207
- {
208
- type: l.literal('record'),
209
- description: l.string(),
210
- key: l.string(),
211
- record: lexiconObjectSchema,
212
- },
213
- { required: ['type', 'record'] },
165
+ export const lexiconRecordKeySchema = l.custom(
166
+ l.isLexiconRecordKey,
167
+ 'Invalid record key definition (must be "any", "nsid", "tid", or "literal:<string>")',
214
168
  )
169
+
170
+ export type LexiconRecordKey = l.LexiconRecordKey
171
+
172
+ export const lexiconRecordSchema = l.object({
173
+ type: l.literal('record'),
174
+ record: lexiconObjectSchema,
175
+ description: strOpt,
176
+ key: lexiconRecordKeySchema,
177
+ })
215
178
  export type LexiconRecord = l.Infer<typeof lexiconRecordSchema>
216
179
 
217
180
  // XRPC Methods
218
181
 
219
- export const lexiconParameters = l.object(
220
- {
182
+ export const lexiconParameters = l.refine(
183
+ l.object({
221
184
  type: l.literal('params'),
222
- description: l.string(),
223
- required: l.array(l.string()),
224
185
  properties: l.dict(
225
- l.string(),
186
+ str,
226
187
  l.discriminatedUnion('type', [
227
188
  lexiconBooleanSchema,
228
189
  lexiconIntegerSchema,
229
190
  lexiconStringSchema,
230
- l.object(
231
- {
232
- type: l.literal('array'),
233
- description: l.string(),
234
- items: l.discriminatedUnion('type', [
235
- lexiconBooleanSchema,
236
- lexiconIntegerSchema,
237
- lexiconStringSchema,
238
- ]),
239
- minLength: l.integer(),
240
- maxLength: l.integer(),
241
- },
242
- {
243
- required: ['type', 'items'],
244
- },
245
- ),
191
+ l.object({
192
+ type: l.literal('array'),
193
+ items: l.discriminatedUnion('type', [
194
+ lexiconBooleanSchema,
195
+ lexiconIntegerSchema,
196
+ lexiconStringSchema,
197
+ ]),
198
+ minLength: intOpt,
199
+ maxLength: intOpt,
200
+ description: strOpt,
201
+ }),
246
202
  ]),
247
203
  ),
248
- },
249
- {
250
- required: ['type', 'properties'],
251
- },
204
+ required: strArrOpt,
205
+ description: strOpt,
206
+ }),
207
+ requirePropertiesRefinement,
252
208
  )
253
209
  export type LexiconParameters = l.Infer<typeof lexiconParameters>
254
210
 
255
- export const lexiconPayload = l.object(
256
- {
257
- description: l.string(),
258
- encoding: l.string(),
259
- schema: l.discriminatedUnion('type', [
211
+ export const lexiconPayload = l.object({
212
+ encoding: str,
213
+ schema: l.optional(
214
+ l.discriminatedUnion('type', [
260
215
  lexiconRefSchema,
261
216
  lexiconRefUnionSchema,
262
217
  lexiconObjectSchema,
263
218
  ]),
264
- },
265
- {
266
- required: ['encoding'],
267
- },
268
- )
219
+ ),
220
+ description: strOpt,
221
+ })
269
222
  export type LexiconPayload = l.Infer<typeof lexiconPayload>
270
223
 
271
- export const lexiconSubscriptionMessage = l.object({
272
- description: l.string(),
273
- schema: l.discriminatedUnion('type', [
274
- lexiconRefSchema,
275
- lexiconRefUnionSchema,
276
- lexiconObjectSchema,
277
- ]),
224
+ export const lexiconError = l.object({
225
+ name: l.string({ minLength: 1 }),
226
+ description: strOpt,
278
227
  })
279
- export type LexiconSubscriptionMessage = l.Infer<
280
- typeof lexiconSubscriptionMessage
281
- >
282
-
283
- export const lexiconError = l.object(
284
- {
285
- name: l.string({ minLength: 1 }),
286
- description: l.string(),
287
- },
288
- {
289
- required: ['name'],
290
- },
291
- )
292
228
  export type LexiconError = l.Infer<typeof lexiconError>
293
229
 
294
- export const lexiconQuerySchema = l.object(
295
- {
296
- type: l.literal('query'),
297
- description: l.string(),
298
- parameters: lexiconParameters,
299
- output: lexiconPayload,
300
- errors: l.array(lexiconError),
301
- },
302
- {
303
- required: ['type'],
304
- },
305
- )
230
+ export const lexiconQuerySchema = l.object({
231
+ type: l.literal('query'),
232
+ parameters: l.optional(lexiconParameters),
233
+ output: l.optional(lexiconPayload),
234
+ errors: l.optional(l.array(lexiconError)),
235
+ description: strOpt,
236
+ })
306
237
  export type LexiconQuery = l.Infer<typeof lexiconQuerySchema>
307
238
 
308
- export const lexiconProcedureSchema = l.object(
309
- {
310
- type: l.literal('procedure'),
311
- description: l.string(),
312
- parameters: lexiconParameters,
313
- input: lexiconPayload,
314
- output: lexiconPayload,
315
- errors: l.array(lexiconError),
316
- },
317
- {
318
- required: ['type'],
319
- },
320
- )
239
+ export const lexiconProcedureSchema = l.object({
240
+ type: l.literal('procedure'),
241
+ parameters: l.optional(lexiconParameters),
242
+ input: l.optional(lexiconPayload),
243
+ output: l.optional(lexiconPayload),
244
+ errors: l.optional(l.array(lexiconError)),
245
+ description: strOpt,
246
+ })
321
247
  export type LexiconProcedure = l.Infer<typeof lexiconProcedureSchema>
322
248
 
323
- export const lexiconSubscriptionSchema = l.object(
324
- {
325
- type: l.literal('subscription'),
326
- description: l.string(),
327
- parameters: lexiconParameters,
328
- message: lexiconSubscriptionMessage,
329
- errors: l.array(lexiconError),
330
- },
331
- {
332
- required: ['type'],
333
- },
334
- )
249
+ export const lexiconSubscriptionSchema = l.object({
250
+ type: l.literal('subscription'),
251
+ description: strOpt,
252
+ parameters: l.optional(lexiconParameters),
253
+ message: l.object({
254
+ description: strOpt,
255
+ schema: lexiconRefUnionSchema,
256
+ }),
257
+ errors: l.optional(l.array(lexiconError)),
258
+ })
335
259
 
336
260
  export type LexiconSubscription = l.Infer<typeof lexiconSubscriptionSchema>
337
261
 
@@ -341,37 +265,29 @@ const lexiconLanguageSchema = l.string({ format: 'language' })
341
265
 
342
266
  export type LexiconLanguage = l.Infer<typeof lexiconLanguageSchema>
343
267
 
344
- const lexiconLanguageDict = l.dict(lexiconLanguageSchema, l.string())
268
+ const lexiconLanguageDict = l.dict(lexiconLanguageSchema, str)
345
269
 
346
270
  export type LexiconLanguageDict = l.Infer<typeof lexiconLanguageDict>
347
271
 
348
- const lexiconPermissionSchema = l.object(
349
- {
272
+ const lexiconPermissionSchema = l.intersection(
273
+ l.object({
350
274
  type: l.literal('permission'),
351
275
  resource: l.string({ minLength: 1 }),
352
- },
353
- {
354
- required: ['type', 'resource'],
355
- unknownProperties: l.paramsSchema,
356
- },
276
+ }),
277
+ l.paramsSchema,
357
278
  )
358
279
 
359
280
  export type LexiconPermission = l.Infer<typeof lexiconPermissionSchema>
360
281
 
361
- const lexiconPermissionSetSchema = l.object(
362
- {
363
- type: l.literal('permission-set'),
364
- description: l.string(),
365
- title: l.string(),
366
- 'title:lang': lexiconLanguageDict,
367
- detail: l.string(),
368
- 'detail:lang': lexiconLanguageDict,
369
- permissions: l.array(lexiconPermissionSchema),
370
- },
371
- {
372
- required: ['type', 'permissions'],
373
- },
374
- )
282
+ const lexiconPermissionSetSchema = l.object({
283
+ type: l.literal('permission-set'),
284
+ permissions: l.array(lexiconPermissionSchema),
285
+ title: strOpt,
286
+ 'title:lang': l.optional(lexiconLanguageDict),
287
+ detail: strOpt,
288
+ 'detail:lang': l.optional(lexiconLanguageDict),
289
+ description: strOpt,
290
+ })
375
291
 
376
292
  export type LexiconPermissionSet = l.Infer<typeof lexiconPermissionSetSchema>
377
293
 
@@ -404,24 +320,19 @@ export type MainLexiconDefinition = l.Infer<
404
320
  export const lexiconIdentifierSchema = l.string({ format: 'nsid' })
405
321
  export type LexiconIdentifier = l.Infer<typeof lexiconIdentifierSchema>
406
322
 
407
- export const lexiconDocumentSchema = l.object(
408
- {
409
- lexicon: l.literal(1),
410
- id: lexiconIdentifierSchema,
411
- revision: l.integer(),
412
- description: l.string(),
413
- defs: l.object(
414
- { main: l.discriminatedUnion('type', MAIN_LEXICON_SCHEMAS) },
415
- {
416
- unknownProperties: l.dict(
417
- l.string({ minLength: 1 }),
418
- l.discriminatedUnion('type', NAMED_LEXICON_SCHEMAS),
419
- ),
420
- },
323
+ export const lexiconDocumentSchema = l.object({
324
+ lexicon: l.literal(1),
325
+ id: lexiconIdentifierSchema,
326
+ revision: intOpt,
327
+ description: strOpt,
328
+ defs: l.intersection(
329
+ l.object({
330
+ main: l.optional(l.discriminatedUnion('type', MAIN_LEXICON_SCHEMAS)),
331
+ }),
332
+ l.dict(
333
+ l.string({ minLength: 1 }),
334
+ l.discriminatedUnion('type', NAMED_LEXICON_SCHEMAS),
421
335
  ),
422
- },
423
- {
424
- required: ['lexicon', 'id', 'defs'],
425
- },
426
- )
336
+ ),
337
+ })
427
338
  export type LexiconDocument = l.Infer<typeof lexiconDocumentSchema>