@atproto/lexicon 0.0.3 → 0.1.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.
@@ -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,32 @@ export default [
13
13
  'object',
14
14
  'array',
15
15
  'boolean',
16
- 'number',
16
+ 'float',
17
17
  'integer',
18
18
  'string',
19
- 'datetime',
19
+ 'bytes',
20
+ 'cidLink',
20
21
  ],
21
22
  properties: {
22
23
  object: { type: 'ref', ref: '#object' },
23
24
  array: { type: 'array', items: { type: 'string' } },
24
25
  boolean: { type: 'boolean' },
25
- number: { type: 'number' },
26
+ float: { type: 'float' },
26
27
  integer: { type: 'integer' },
27
28
  string: { type: 'string' },
28
- datetime: { type: 'datetime' },
29
+ bytes: { type: 'bytes' },
30
+ cidLink: { type: 'cid-link' },
29
31
  },
30
32
  },
31
33
  },
32
34
  object: {
33
35
  type: 'object',
34
- required: ['object', 'array', 'boolean', 'number', 'integer', 'string'],
36
+ required: ['object', 'array', 'boolean', 'float', 'integer', 'string'],
35
37
  properties: {
36
38
  object: { type: 'ref', ref: '#subobject' },
37
39
  array: { type: 'array', items: { type: 'string' } },
38
40
  boolean: { type: 'boolean' },
39
- number: { type: 'number' },
41
+ float: { type: 'float' },
40
42
  integer: { type: 'integer' },
41
43
  string: { type: 'string' },
42
44
  },
@@ -59,12 +61,14 @@ export default [
59
61
  description: 'A query',
60
62
  parameters: {
61
63
  type: 'params',
62
- required: ['boolean', 'number', 'integer'],
64
+ required: ['boolean', 'float', 'integer'],
63
65
  properties: {
64
66
  boolean: { type: 'boolean' },
65
- number: { type: 'number' },
67
+ float: { type: 'float' },
66
68
  integer: { type: 'integer' },
67
69
  string: { type: 'string' },
70
+ array: { type: 'array', items: { type: 'string' } },
71
+ def: { type: 'integer', default: 0 },
68
72
  },
69
73
  },
70
74
  output: {
@@ -83,12 +87,13 @@ export default [
83
87
  description: 'A procedure',
84
88
  parameters: {
85
89
  type: 'params',
86
- required: ['boolean', 'number', 'integer'],
90
+ required: ['boolean', 'float', 'integer'],
87
91
  properties: {
88
92
  boolean: { type: 'boolean' },
89
- number: { type: 'number' },
93
+ float: { type: 'float' },
90
94
  integer: { type: 'integer' },
91
95
  string: { type: 'string' },
96
+ array: { type: 'array', items: { type: 'string' } },
92
97
  },
93
98
  },
94
99
  input: {
@@ -114,7 +119,7 @@ export default [
114
119
  object: { type: 'ref', ref: 'com.example.kitchenSink#object' },
115
120
  array: { type: 'array', items: { type: 'string' } },
116
121
  boolean: { type: 'boolean' },
117
- number: { type: 'number' },
122
+ float: { type: 'float' },
118
123
  integer: { type: 'integer' },
119
124
  string: { type: 'string' },
120
125
  },
@@ -122,6 +127,35 @@ export default [
122
127
  },
123
128
  },
124
129
  },
130
+ {
131
+ lexicon: 1,
132
+ id: 'com.example.default',
133
+ defs: {
134
+ main: {
135
+ type: 'record',
136
+ record: {
137
+ type: 'object',
138
+ required: ['boolean'],
139
+ properties: {
140
+ boolean: { type: 'boolean', default: false },
141
+ float: { type: 'float', default: 0 },
142
+ integer: { type: 'integer', default: 0 },
143
+ string: { type: 'string', default: '' },
144
+ object: { type: 'ref', ref: '#object' },
145
+ },
146
+ },
147
+ },
148
+ object: {
149
+ type: 'object',
150
+ properties: {
151
+ boolean: { type: 'boolean', default: true },
152
+ float: { type: 'float', default: 1.5 },
153
+ integer: { type: 'integer', default: 1 },
154
+ string: { type: 'string', default: 'x' },
155
+ },
156
+ },
157
+ },
158
+ },
125
159
  {
126
160
  lexicon: 1,
127
161
  id: 'com.example.union',
@@ -186,7 +220,7 @@ export default [
186
220
  type: 'array',
187
221
  minLength: 2,
188
222
  maxLength: 4,
189
- items: { type: 'number' },
223
+ items: { type: 'float' },
190
224
  },
191
225
  },
192
226
  },
@@ -213,15 +247,15 @@ export default [
213
247
  },
214
248
  {
215
249
  lexicon: 1,
216
- id: 'com.example.numberRange',
250
+ id: 'com.example.floatRange',
217
251
  defs: {
218
252
  main: {
219
253
  type: 'record',
220
254
  record: {
221
255
  type: 'object',
222
256
  properties: {
223
- number: {
224
- type: 'number',
257
+ float: {
258
+ type: 'float',
225
259
  minimum: 2,
226
260
  maximum: 4,
227
261
  },
@@ -232,15 +266,15 @@ export default [
232
266
  },
233
267
  {
234
268
  lexicon: 1,
235
- id: 'com.example.numberEnum',
269
+ id: 'com.example.floatEnum',
236
270
  defs: {
237
271
  main: {
238
272
  type: 'record',
239
273
  record: {
240
274
  type: 'object',
241
275
  properties: {
242
- number: {
243
- type: 'number',
276
+ float: {
277
+ type: 'float',
244
278
  enum: [1, 1.5, 2],
245
279
  },
246
280
  },
@@ -250,15 +284,15 @@ export default [
250
284
  },
251
285
  {
252
286
  lexicon: 1,
253
- id: 'com.example.numberConst',
287
+ id: 'com.example.floatConst',
254
288
  defs: {
255
289
  main: {
256
290
  type: 'record',
257
291
  record: {
258
292
  type: 'object',
259
293
  properties: {
260
- number: {
261
- type: 'number',
294
+ float: {
295
+ type: 'float',
262
296
  const: 0,
263
297
  },
264
298
  },
@@ -340,6 +374,25 @@ export default [
340
374
  },
341
375
  },
342
376
  },
377
+ {
378
+ lexicon: 1,
379
+ id: 'com.example.stringLengthGrapheme',
380
+ defs: {
381
+ main: {
382
+ type: 'record',
383
+ record: {
384
+ type: 'object',
385
+ properties: {
386
+ string: {
387
+ type: 'string',
388
+ minGraphemes: 2,
389
+ maxGraphemes: 4,
390
+ },
391
+ },
392
+ },
393
+ },
394
+ },
395
+ },
343
396
  {
344
397
  lexicon: 1,
345
398
  id: 'com.example.stringEnum',
@@ -385,8 +438,130 @@ export default [
385
438
  record: {
386
439
  type: 'object',
387
440
  properties: {
388
- datetime: {
389
- type: 'datetime',
441
+ datetime: { type: 'string', format: 'datetime' },
442
+ },
443
+ },
444
+ },
445
+ },
446
+ },
447
+ {
448
+ lexicon: 1,
449
+ id: 'com.example.uri',
450
+ defs: {
451
+ main: {
452
+ type: 'record',
453
+ record: {
454
+ type: 'object',
455
+ properties: {
456
+ uri: { type: 'string', format: 'uri' },
457
+ },
458
+ },
459
+ },
460
+ },
461
+ },
462
+ {
463
+ lexicon: 1,
464
+ id: 'com.example.atUri',
465
+ defs: {
466
+ main: {
467
+ type: 'record',
468
+ record: {
469
+ type: 'object',
470
+ properties: {
471
+ atUri: { type: 'string', format: 'at-uri' },
472
+ },
473
+ },
474
+ },
475
+ },
476
+ },
477
+ {
478
+ lexicon: 1,
479
+ id: 'com.example.did',
480
+ defs: {
481
+ main: {
482
+ type: 'record',
483
+ record: {
484
+ type: 'object',
485
+ properties: {
486
+ did: { type: 'string', format: 'did' },
487
+ },
488
+ },
489
+ },
490
+ },
491
+ },
492
+ {
493
+ lexicon: 1,
494
+ id: 'com.example.handle',
495
+ defs: {
496
+ main: {
497
+ type: 'record',
498
+ record: {
499
+ type: 'object',
500
+ properties: {
501
+ handle: { type: 'string', format: 'handle' },
502
+ },
503
+ },
504
+ },
505
+ },
506
+ },
507
+ {
508
+ lexicon: 1,
509
+ id: 'com.example.atIdentifier',
510
+ defs: {
511
+ main: {
512
+ type: 'record',
513
+ record: {
514
+ type: 'object',
515
+ properties: {
516
+ atIdentifier: { type: 'string', format: 'at-identifier' },
517
+ },
518
+ },
519
+ },
520
+ },
521
+ },
522
+ {
523
+ lexicon: 1,
524
+ id: 'com.example.nsid',
525
+ defs: {
526
+ main: {
527
+ type: 'record',
528
+ record: {
529
+ type: 'object',
530
+ properties: {
531
+ nsid: { type: 'string', format: 'nsid' },
532
+ },
533
+ },
534
+ },
535
+ },
536
+ },
537
+ {
538
+ lexicon: 1,
539
+ id: 'com.example.cid',
540
+ defs: {
541
+ main: {
542
+ type: 'record',
543
+ record: {
544
+ type: 'object',
545
+ properties: {
546
+ cid: { type: 'string', format: 'cid' },
547
+ },
548
+ },
549
+ },
550
+ },
551
+ },
552
+ {
553
+ lexicon: 1,
554
+ id: 'com.example.byteLength',
555
+ defs: {
556
+ main: {
557
+ type: 'record',
558
+ record: {
559
+ type: 'object',
560
+ properties: {
561
+ bytes: {
562
+ type: 'bytes',
563
+ minLength: 2,
564
+ maxLength: 4,
390
565
  },
391
566
  },
392
567
  },