@atproto/lexicon 0.0.4 → 0.2.0

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 (47) hide show
  1. package/dist/blob-refs.d.ts +67 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +12944 -680
  4. package/dist/index.js.map +4 -4
  5. package/dist/lexicons.d.ts +6 -4
  6. package/dist/serialize.d.ts +12 -0
  7. package/dist/src/index.d.ts +2 -0
  8. package/dist/src/lexicons.d.ts +15 -0
  9. package/dist/src/record/index.d.ts +4 -0
  10. package/dist/src/record/schema.d.ts +9 -0
  11. package/dist/src/record/schemas.d.ts +10 -0
  12. package/dist/src/record/util.d.ts +1 -0
  13. package/dist/src/record/validation.d.ts +24 -0
  14. package/dist/src/record/validator.d.ts +17 -0
  15. package/dist/src/types.d.ts +30268 -0
  16. package/dist/src/util.d.ts +6 -0
  17. package/dist/src/validation.d.ts +6 -0
  18. package/dist/src/validators/blob.d.ts +6 -0
  19. package/dist/src/validators/complex.d.ts +5 -0
  20. package/dist/src/validators/primitives.d.ts +9 -0
  21. package/dist/src/validators/xrpc.d.ts +3 -0
  22. package/dist/tsconfig.build.tsbuildinfo +1 -0
  23. package/dist/types.d.ts +14999 -23510
  24. package/dist/util.d.ts +6 -1
  25. package/dist/validation.d.ts +6 -5
  26. package/dist/validators/blob.d.ts +0 -3
  27. package/dist/validators/complex.d.ts +2 -2
  28. package/dist/validators/formats.d.ts +10 -0
  29. package/dist/validators/primitives.d.ts +2 -2
  30. package/dist/validators/xrpc.d.ts +1 -1
  31. package/package.json +13 -4
  32. package/src/blob-refs.ts +70 -0
  33. package/src/index.ts +2 -0
  34. package/src/lexicons.ts +36 -5
  35. package/src/serialize.ts +93 -0
  36. package/src/types.ts +306 -180
  37. package/src/util.ts +64 -5
  38. package/src/validation.ts +28 -4
  39. package/src/validators/blob.ts +5 -43
  40. package/src/validators/complex.ts +31 -32
  41. package/src/validators/formats.ts +121 -0
  42. package/src/validators/primitives.ts +114 -67
  43. package/src/validators/xrpc.ts +29 -29
  44. package/tests/_scaffolds/lexicons.ts +178 -51
  45. package/tests/general.test.ts +496 -177
  46. package/tsconfig.build.tsbuildinfo +1 -1
  47. package/tsconfig.json +3 -1
@@ -2,49 +2,49 @@ import { Lexicons } from '../lexicons'
2
2
  import { LexXrpcParameters, ValidationResult, ValidationError } from '../types'
3
3
 
4
4
  import * as PrimitiveValidators from './primitives'
5
+ import { array } from './complex'
5
6
 
6
7
  export function params(
7
8
  lexicons: Lexicons,
8
9
  path: string,
9
10
  def: LexXrpcParameters,
10
- value: unknown,
11
+ val: unknown,
11
12
  ): ValidationResult {
12
- def = def as LexXrpcParameters
13
-
14
13
  // type
15
- if (!value || typeof value !== 'object') {
16
- // in this case, we just fall back to an object
17
- value = {}
18
- }
14
+ const value = val && typeof val === 'object' ? val : {}
15
+
16
+ const requiredProps = new Set(def.required ?? [])
19
17
 
20
- // required
21
- if (Array.isArray(def.required)) {
22
- for (const key of def.required) {
23
- if (!(key in (value as Record<string, unknown>))) {
18
+ // properties
19
+ let resultValue = value
20
+ if (typeof def.properties === 'object') {
21
+ for (const key in def.properties) {
22
+ const propDef = def.properties[key]
23
+ const validated =
24
+ propDef.type === 'array'
25
+ ? array(lexicons, key, propDef, value[key])
26
+ : PrimitiveValidators.validate(lexicons, key, propDef, value[key])
27
+ const propValue = validated.success ? validated.value : value[key]
28
+ const propIsUndefined = typeof propValue === 'undefined'
29
+ // Return error for bad validation, giving required rule precedence
30
+ if (propIsUndefined && requiredProps.has(key)) {
24
31
  return {
25
32
  success: false,
26
33
  error: new ValidationError(`${path} must have the property "${key}"`),
27
34
  }
35
+ } else if (!propIsUndefined && !validated.success) {
36
+ return validated
37
+ }
38
+ // Adjust value based on e.g. applied defaults, cloning shallowly if there was a changed value
39
+ if (propValue !== value[key]) {
40
+ if (resultValue === value) {
41
+ // Lazy shallow clone
42
+ resultValue = { ...value }
43
+ }
44
+ resultValue[key] = propValue
28
45
  }
29
46
  }
30
47
  }
31
48
 
32
- // properties
33
- for (const key in def.properties) {
34
- if (typeof (value as Record<string, unknown>)[key] === 'undefined') {
35
- continue // skip- if required, will have already failed
36
- }
37
- const paramDef = def.properties[key]
38
- const res = PrimitiveValidators.validate(
39
- lexicons,
40
- key,
41
- paramDef,
42
- (value as Record<string, unknown>)[key],
43
- )
44
- if (!res.success) {
45
- return res
46
- }
47
- }
48
-
49
- return { success: true }
49
+ return { success: true, value: resultValue }
50
50
  }
@@ -13,30 +13,29 @@ export default [
13
13
  'object',
14
14
  'array',
15
15
  'boolean',
16
- 'number',
17
16
  'integer',
18
17
  'string',
19
- 'datetime',
18
+ 'bytes',
19
+ 'cidLink',
20
20
  ],
21
21
  properties: {
22
22
  object: { type: 'ref', ref: '#object' },
23
23
  array: { type: 'array', items: { type: 'string' } },
24
24
  boolean: { type: 'boolean' },
25
- number: { type: 'number' },
26
25
  integer: { type: 'integer' },
27
26
  string: { type: 'string' },
28
- datetime: { type: 'datetime' },
27
+ bytes: { type: 'bytes' },
28
+ cidLink: { type: 'cid-link' },
29
29
  },
30
30
  },
31
31
  },
32
32
  object: {
33
33
  type: 'object',
34
- required: ['object', 'array', 'boolean', 'number', 'integer', 'string'],
34
+ required: ['object', 'array', 'boolean', 'integer', 'string'],
35
35
  properties: {
36
36
  object: { type: 'ref', ref: '#subobject' },
37
37
  array: { type: 'array', items: { type: 'string' } },
38
38
  boolean: { type: 'boolean' },
39
- number: { type: 'number' },
40
39
  integer: { type: 'integer' },
41
40
  string: { type: 'string' },
42
41
  },
@@ -59,12 +58,13 @@ export default [
59
58
  description: 'A query',
60
59
  parameters: {
61
60
  type: 'params',
62
- required: ['boolean', 'number', 'integer'],
61
+ required: ['boolean', 'integer'],
63
62
  properties: {
64
63
  boolean: { type: 'boolean' },
65
- number: { type: 'number' },
66
64
  integer: { type: 'integer' },
67
65
  string: { type: 'string' },
66
+ array: { type: 'array', items: { type: 'string' } },
67
+ def: { type: 'integer', default: 0 },
68
68
  },
69
69
  },
70
70
  output: {
@@ -83,12 +83,12 @@ export default [
83
83
  description: 'A procedure',
84
84
  parameters: {
85
85
  type: 'params',
86
- required: ['boolean', 'number', 'integer'],
86
+ required: ['boolean', 'integer'],
87
87
  properties: {
88
88
  boolean: { type: 'boolean' },
89
- number: { type: 'number' },
90
89
  integer: { type: 'integer' },
91
90
  string: { type: 'string' },
91
+ array: { type: 'array', items: { type: 'string' } },
92
92
  },
93
93
  },
94
94
  input: {
@@ -114,7 +114,6 @@ export default [
114
114
  object: { type: 'ref', ref: 'com.example.kitchenSink#object' },
115
115
  array: { type: 'array', items: { type: 'string' } },
116
116
  boolean: { type: 'boolean' },
117
- number: { type: 'number' },
118
117
  integer: { type: 'integer' },
119
118
  string: { type: 'string' },
120
119
  },
@@ -122,6 +121,33 @@ export default [
122
121
  },
123
122
  },
124
123
  },
124
+ {
125
+ lexicon: 1,
126
+ id: 'com.example.default',
127
+ defs: {
128
+ main: {
129
+ type: 'record',
130
+ record: {
131
+ type: 'object',
132
+ required: ['boolean'],
133
+ properties: {
134
+ boolean: { type: 'boolean', default: false },
135
+ integer: { type: 'integer', default: 0 },
136
+ string: { type: 'string', default: '' },
137
+ object: { type: 'ref', ref: '#object' },
138
+ },
139
+ },
140
+ },
141
+ object: {
142
+ type: 'object',
143
+ properties: {
144
+ boolean: { type: 'boolean', default: true },
145
+ integer: { type: 'integer', default: 1 },
146
+ string: { type: 'string', default: 'x' },
147
+ },
148
+ },
149
+ },
150
+ },
125
151
  {
126
152
  lexicon: 1,
127
153
  id: 'com.example.union',
@@ -186,7 +212,7 @@ export default [
186
212
  type: 'array',
187
213
  minLength: 2,
188
214
  maxLength: 4,
189
- items: { type: 'number' },
215
+ items: { type: 'integer' },
190
216
  },
191
217
  },
192
218
  },
@@ -213,15 +239,15 @@ export default [
213
239
  },
214
240
  {
215
241
  lexicon: 1,
216
- id: 'com.example.numberRange',
242
+ id: 'com.example.integerRange',
217
243
  defs: {
218
244
  main: {
219
245
  type: 'record',
220
246
  record: {
221
247
  type: 'object',
222
248
  properties: {
223
- number: {
224
- type: 'number',
249
+ integer: {
250
+ type: 'integer',
225
251
  minimum: 2,
226
252
  maximum: 4,
227
253
  },
@@ -232,16 +258,16 @@ export default [
232
258
  },
233
259
  {
234
260
  lexicon: 1,
235
- id: 'com.example.numberEnum',
261
+ id: 'com.example.integerEnum',
236
262
  defs: {
237
263
  main: {
238
264
  type: 'record',
239
265
  record: {
240
266
  type: 'object',
241
267
  properties: {
242
- number: {
243
- type: 'number',
244
- enum: [1, 1.5, 2],
268
+ integer: {
269
+ type: 'integer',
270
+ enum: [1, 2],
245
271
  },
246
272
  },
247
273
  },
@@ -250,15 +276,15 @@ export default [
250
276
  },
251
277
  {
252
278
  lexicon: 1,
253
- id: 'com.example.numberConst',
279
+ id: 'com.example.integerConst',
254
280
  defs: {
255
281
  main: {
256
282
  type: 'record',
257
283
  record: {
258
284
  type: 'object',
259
285
  properties: {
260
- number: {
261
- type: 'number',
286
+ integer: {
287
+ type: 'integer',
262
288
  const: 0,
263
289
  },
264
290
  },
@@ -268,17 +294,17 @@ export default [
268
294
  },
269
295
  {
270
296
  lexicon: 1,
271
- id: 'com.example.integerRange',
297
+ id: 'com.example.stringLength',
272
298
  defs: {
273
299
  main: {
274
300
  type: 'record',
275
301
  record: {
276
302
  type: 'object',
277
303
  properties: {
278
- integer: {
279
- type: 'integer',
280
- minimum: 2,
281
- maximum: 4,
304
+ string: {
305
+ type: 'string',
306
+ minLength: 2,
307
+ maxLength: 4,
282
308
  },
283
309
  },
284
310
  },
@@ -287,16 +313,17 @@ export default [
287
313
  },
288
314
  {
289
315
  lexicon: 1,
290
- id: 'com.example.integerEnum',
316
+ id: 'com.example.stringLengthGrapheme',
291
317
  defs: {
292
318
  main: {
293
319
  type: 'record',
294
320
  record: {
295
321
  type: 'object',
296
322
  properties: {
297
- integer: {
298
- type: 'integer',
299
- enum: [1, 2],
323
+ string: {
324
+ type: 'string',
325
+ minGraphemes: 2,
326
+ maxGraphemes: 4,
300
327
  },
301
328
  },
302
329
  },
@@ -305,16 +332,16 @@ export default [
305
332
  },
306
333
  {
307
334
  lexicon: 1,
308
- id: 'com.example.integerConst',
335
+ id: 'com.example.stringEnum',
309
336
  defs: {
310
337
  main: {
311
338
  type: 'record',
312
339
  record: {
313
340
  type: 'object',
314
341
  properties: {
315
- integer: {
316
- type: 'integer',
317
- const: 0,
342
+ string: {
343
+ type: 'string',
344
+ enum: ['a', 'b'],
318
345
  },
319
346
  },
320
347
  },
@@ -323,7 +350,7 @@ export default [
323
350
  },
324
351
  {
325
352
  lexicon: 1,
326
- id: 'com.example.stringLength',
353
+ id: 'com.example.stringConst',
327
354
  defs: {
328
355
  main: {
329
356
  type: 'record',
@@ -332,8 +359,7 @@ export default [
332
359
  properties: {
333
360
  string: {
334
361
  type: 'string',
335
- minLength: 2,
336
- maxLength: 4,
362
+ const: 'a',
337
363
  },
338
364
  },
339
365
  },
@@ -342,17 +368,14 @@ export default [
342
368
  },
343
369
  {
344
370
  lexicon: 1,
345
- id: 'com.example.stringEnum',
371
+ id: 'com.example.datetime',
346
372
  defs: {
347
373
  main: {
348
374
  type: 'record',
349
375
  record: {
350
376
  type: 'object',
351
377
  properties: {
352
- string: {
353
- type: 'string',
354
- enum: ['a', 'b'],
355
- },
378
+ datetime: { type: 'string', format: 'datetime' },
356
379
  },
357
380
  },
358
381
  },
@@ -360,17 +383,14 @@ export default [
360
383
  },
361
384
  {
362
385
  lexicon: 1,
363
- id: 'com.example.stringConst',
386
+ id: 'com.example.uri',
364
387
  defs: {
365
388
  main: {
366
389
  type: 'record',
367
390
  record: {
368
391
  type: 'object',
369
392
  properties: {
370
- string: {
371
- type: 'string',
372
- const: 'a',
373
- },
393
+ uri: { type: 'string', format: 'uri' },
374
394
  },
375
395
  },
376
396
  },
@@ -378,15 +398,122 @@ export default [
378
398
  },
379
399
  {
380
400
  lexicon: 1,
381
- id: 'com.example.datetime',
401
+ id: 'com.example.atUri',
382
402
  defs: {
383
403
  main: {
384
404
  type: 'record',
385
405
  record: {
386
406
  type: 'object',
387
407
  properties: {
388
- datetime: {
389
- type: 'datetime',
408
+ atUri: { type: 'string', format: 'at-uri' },
409
+ },
410
+ },
411
+ },
412
+ },
413
+ },
414
+ {
415
+ lexicon: 1,
416
+ id: 'com.example.did',
417
+ defs: {
418
+ main: {
419
+ type: 'record',
420
+ record: {
421
+ type: 'object',
422
+ properties: {
423
+ did: { type: 'string', format: 'did' },
424
+ },
425
+ },
426
+ },
427
+ },
428
+ },
429
+ {
430
+ lexicon: 1,
431
+ id: 'com.example.handle',
432
+ defs: {
433
+ main: {
434
+ type: 'record',
435
+ record: {
436
+ type: 'object',
437
+ properties: {
438
+ handle: { type: 'string', format: 'handle' },
439
+ },
440
+ },
441
+ },
442
+ },
443
+ },
444
+ {
445
+ lexicon: 1,
446
+ id: 'com.example.atIdentifier',
447
+ defs: {
448
+ main: {
449
+ type: 'record',
450
+ record: {
451
+ type: 'object',
452
+ properties: {
453
+ atIdentifier: { type: 'string', format: 'at-identifier' },
454
+ },
455
+ },
456
+ },
457
+ },
458
+ },
459
+ {
460
+ lexicon: 1,
461
+ id: 'com.example.nsid',
462
+ defs: {
463
+ main: {
464
+ type: 'record',
465
+ record: {
466
+ type: 'object',
467
+ properties: {
468
+ nsid: { type: 'string', format: 'nsid' },
469
+ },
470
+ },
471
+ },
472
+ },
473
+ },
474
+ {
475
+ lexicon: 1,
476
+ id: 'com.example.cid',
477
+ defs: {
478
+ main: {
479
+ type: 'record',
480
+ record: {
481
+ type: 'object',
482
+ properties: {
483
+ cid: { type: 'string', format: 'cid' },
484
+ },
485
+ },
486
+ },
487
+ },
488
+ },
489
+ {
490
+ lexicon: 1,
491
+ id: 'com.example.language',
492
+ defs: {
493
+ main: {
494
+ type: 'record',
495
+ record: {
496
+ type: 'object',
497
+ properties: {
498
+ language: { type: 'string', format: 'language' },
499
+ },
500
+ },
501
+ },
502
+ },
503
+ },
504
+ {
505
+ lexicon: 1,
506
+ id: 'com.example.byteLength',
507
+ defs: {
508
+ main: {
509
+ type: 'record',
510
+ record: {
511
+ type: 'object',
512
+ properties: {
513
+ bytes: {
514
+ type: 'bytes',
515
+ minLength: 2,
516
+ maxLength: 4,
390
517
  },
391
518
  },
392
519
  },