@atproto/lex-schema 0.0.14 → 0.0.15

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 (64) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/core/schema.d.ts +4 -3
  3. package/dist/core/schema.d.ts.map +1 -1
  4. package/dist/core/schema.js +6 -1
  5. package/dist/core/schema.js.map +1 -1
  6. package/dist/core/standard-schema.d.ts +14 -0
  7. package/dist/core/standard-schema.d.ts.map +1 -0
  8. package/dist/core/standard-schema.js +27 -0
  9. package/dist/core/standard-schema.js.map +1 -0
  10. package/dist/core/string-format.d.ts +4 -15
  11. package/dist/core/string-format.d.ts.map +1 -1
  12. package/dist/core/string-format.js +17 -14
  13. package/dist/core/string-format.js.map +1 -1
  14. package/dist/core/validation-error.d.ts +10 -2
  15. package/dist/core/validation-error.d.ts.map +1 -1
  16. package/dist/core/validation-error.js +10 -0
  17. package/dist/core/validation-error.js.map +1 -1
  18. package/dist/core/validation-issue.d.ts +15 -15
  19. package/dist/core/validation-issue.d.ts.map +1 -1
  20. package/dist/core/validation-issue.js +33 -29
  21. package/dist/core/validation-issue.js.map +1 -1
  22. package/dist/core/validator.d.ts +16 -13
  23. package/dist/core/validator.d.ts.map +1 -1
  24. package/dist/core/validator.js +3 -2
  25. package/dist/core/validator.js.map +1 -1
  26. package/dist/core.d.ts +0 -1
  27. package/dist/core.d.ts.map +1 -1
  28. package/dist/core.js +0 -1
  29. package/dist/core.js.map +1 -1
  30. package/dist/schema/custom.d.ts +1 -1
  31. package/dist/schema/custom.d.ts.map +1 -1
  32. package/dist/schema/custom.js.map +1 -1
  33. package/dist/schema/never.d.ts +1 -1
  34. package/dist/schema/nullable.d.ts +1 -1
  35. package/dist/schema/record.d.ts +1 -1
  36. package/dist/schema/ref.d.ts +1 -1
  37. package/dist/schema/ref.d.ts.map +1 -1
  38. package/dist/schema/ref.js.map +1 -1
  39. package/dist/schema/refine.d.ts +1 -1
  40. package/dist/schema/refine.d.ts.map +1 -1
  41. package/dist/schema/refine.js.map +1 -1
  42. package/dist/schema/typed-ref.d.ts +1 -1
  43. package/dist/schema/typed-union.d.ts +1 -1
  44. package/dist/schema/union.d.ts +2 -2
  45. package/dist/schema/union.d.ts.map +1 -1
  46. package/package.json +3 -2
  47. package/src/core/schema.ts +11 -10
  48. package/src/core/standard-schema.test.ts +124 -0
  49. package/src/core/standard-schema.ts +31 -0
  50. package/src/core/string-format.ts +14 -18
  51. package/src/core/validation-error.ts +16 -1
  52. package/src/core/validation-issue.ts +32 -32
  53. package/src/core/validator.ts +9 -5
  54. package/src/core.ts +0 -1
  55. package/src/schema/array.test.ts +2 -2
  56. package/src/schema/custom.ts +1 -7
  57. package/src/schema/params.test.ts +2 -2
  58. package/src/schema/ref.ts +1 -5
  59. package/src/schema/refine.ts +0 -1
  60. package/dist/core/property-key.d.ts +0 -2
  61. package/dist/core/property-key.d.ts.map +0 -1
  62. package/dist/core/property-key.js +0 -3
  63. package/dist/core/property-key.js.map +0 -1
  64. package/src/core/property-key.ts +0 -1
@@ -1,5 +1,4 @@
1
1
  import { ifCid, isLegacyBlobRef, isPlainObject } from '@atproto/lex-data'
2
- import { PropertyKey } from './property-key.js'
3
2
 
4
3
  /**
5
4
  * Abstract base class for all validation issues.
@@ -9,10 +8,13 @@ import { PropertyKey } from './property-key.js'
9
8
  * - The path to the invalid value in the data structure
10
9
  * - The actual input value that failed validation
11
10
  *
12
- * Subclasses add specific properties relevant to each issue type and
13
- * implement the {@link toString} method for human-readable error messages.
11
+ * Subclasses add specific properties relevant to each issue type and implement
12
+ * the {@link message} property for human-readable error messages (that don't
13
+ * contain the error path)
14
14
  */
15
15
  export abstract class Issue {
16
+ abstract readonly message: string
17
+
16
18
  constructor(
17
19
  readonly code: string,
18
20
  readonly path: readonly PropertyKey[],
@@ -22,7 +24,9 @@ export abstract class Issue {
22
24
  /**
23
25
  * Returns a human-readable description of the validation issue.
24
26
  */
25
- abstract toString(): string
27
+ toString() {
28
+ return `${this.message}${stringifyPath(this.path)}`
29
+ }
26
30
 
27
31
  /**
28
32
  * Converts the issue to a JSON-serializable object.
@@ -33,7 +37,7 @@ export abstract class Issue {
33
37
  return {
34
38
  code: this.code,
35
39
  path: this.path,
36
- message: this.toString(),
40
+ message: this.message,
37
41
  }
38
42
  }
39
43
  }
@@ -51,10 +55,6 @@ export class IssueCustom extends Issue {
51
55
  ) {
52
56
  super('custom', path, input)
53
57
  }
54
-
55
- toString() {
56
- return `${this.message}${stringifyPath(this.path)}`
57
- }
58
58
  }
59
59
 
60
60
  /**
@@ -67,20 +67,13 @@ export class IssueInvalidFormat extends Issue {
67
67
  path: readonly PropertyKey[],
68
68
  input: unknown,
69
69
  readonly format: string,
70
- readonly message?: string,
70
+ readonly detail?: string,
71
71
  ) {
72
72
  super('invalid_format', path, input)
73
73
  }
74
74
 
75
- toString() {
76
- return `Invalid ${this.formatDescription}${this.message ? ` (${this.message})` : ''}${stringifyPath(this.path)} (got ${stringifyValue(this.input)})`
77
- }
78
-
79
- toJSON() {
80
- return {
81
- ...super.toJSON(),
82
- format: this.format,
83
- }
75
+ override get message(): string {
76
+ return `Invalid ${this.formatDescription}${this.detail ? ` (${this.detail}, ` : ' ('}got ${stringifyValue(this.input)})`
84
77
  }
85
78
 
86
79
  /** Returns a human-readable description of the expected format. */
@@ -102,6 +95,13 @@ export class IssueInvalidFormat extends Issue {
102
95
  return this.format
103
96
  }
104
97
  }
98
+
99
+ toJSON() {
100
+ return {
101
+ ...super.toJSON(),
102
+ format: this.format,
103
+ }
104
+ }
105
105
  }
106
106
 
107
107
  /**
@@ -119,8 +119,8 @@ export class IssueInvalidType extends Issue {
119
119
  super('invalid_type', path, input)
120
120
  }
121
121
 
122
- toString() {
123
- return `Expected ${oneOf(this.expected.map(stringifyExpectedType))} value type${stringifyPath(this.path)} (got ${stringifyType(this.input)})`
122
+ override get message(): string {
123
+ return `Expected ${oneOf(this.expected.map(stringifyExpectedType))} value type (got ${stringifyType(this.input)})`
124
124
  }
125
125
 
126
126
  toJSON() {
@@ -146,8 +146,8 @@ export class IssueInvalidValue extends Issue {
146
146
  super('invalid_value', path, input)
147
147
  }
148
148
 
149
- toString() {
150
- return `Expected ${oneOf(this.values.map(stringifyValue))}${stringifyPath(this.path)} (got ${stringifyValue(this.input)})`
149
+ override get message(): string {
150
+ return `Expected ${oneOf(this.values.map(stringifyValue))} (got ${stringifyValue(this.input)})`
151
151
  }
152
152
 
153
153
  toJSON() {
@@ -170,8 +170,8 @@ export class IssueRequiredKey extends Issue {
170
170
  super('required_key', path, input)
171
171
  }
172
172
 
173
- toString() {
174
- return `Missing required key "${String(this.key)}"${stringifyPath(this.path)}`
173
+ override get message(): string {
174
+ return `Missing required key "${String(this.key)}"`
175
175
  }
176
176
 
177
177
  toJSON() {
@@ -214,8 +214,8 @@ export class IssueTooBig extends Issue {
214
214
  super('too_big', path, input)
215
215
  }
216
216
 
217
- toString() {
218
- return `${this.type} too big (maximum ${this.maximum})${stringifyPath(this.path)} (got ${this.actual})`
217
+ override get message(): string {
218
+ return `${this.type} too big (maximum ${this.maximum}, got ${this.actual})`
219
219
  }
220
220
 
221
221
  toJSON() {
@@ -241,8 +241,8 @@ export class IssueTooSmall extends Issue {
241
241
  super('too_small', path, input)
242
242
  }
243
243
 
244
- toString() {
245
- return `${this.type} too small (minimum ${this.minimum})${stringifyPath(this.path)} (got ${this.actual})`
244
+ override get message(): string {
245
+ return `${this.type} too small (minimum ${this.minimum}, got ${this.actual})`
246
246
  }
247
247
 
248
248
  toJSON() {
@@ -274,9 +274,9 @@ function buildJsonPath(path: readonly PropertyKey[]): string {
274
274
  }
275
275
 
276
276
  function toJsonPathSegment(segment: PropertyKey): string {
277
- if (typeof segment === 'number') {
278
- return `[${segment}]`
279
- } else if (/^[a-zA-Z_$][a-zA-Z0-9_]*$/.test(segment as string)) {
277
+ if (typeof segment === 'number' || typeof segment === 'symbol') {
278
+ return `[${String(segment)}]`
279
+ } else if (/^[a-zA-Z_$][a-zA-Z0-9_]*$/.test(segment)) {
280
280
  return `.${segment}`
281
281
  } else {
282
282
  return `[${JSON.stringify(segment)}]`
@@ -1,5 +1,5 @@
1
- import { PropertyKey } from './property-key.js'
2
- import { ResultFailure, ResultSuccess, failure, success } from './result.js'
1
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2
+ import { ResultFailure, ResultSuccess, success } from './result.js'
3
3
  import { LexValidationError } from './validation-error.js'
4
4
  import {
5
5
  Issue,
@@ -21,8 +21,12 @@ export type ValidationSuccess<Value = unknown> = ResultSuccess<Value>
21
21
 
22
22
  /**
23
23
  * Represents a failed validation result containing a {@link LexValidationError}.
24
+ *
25
+ * @extends ResultFailure<LexValidationError>
26
+ * @see {@link ResultFailure}
27
+ * @see {@link LexValidationError}
24
28
  */
25
- export type ValidationFailure = ResultFailure<LexValidationError>
29
+ export type ValidationFailure = LexValidationError
26
30
 
27
31
  /**
28
32
  * Discriminated union representing the outcome of a validation operation.
@@ -326,7 +330,7 @@ export class ValidationContext {
326
330
  if (this.issues.length > 0) {
327
331
  // Validator returned a success but issues were added via the context.
328
332
  // This means the overall validation failed.
329
- return failure(new LexValidationError(Array.from(this.issues)))
333
+ return new LexValidationError(Array.from(this.issues))
330
334
  }
331
335
 
332
336
  if (this.options.mode !== 'parse' && !Object.is(result.value, input)) {
@@ -426,7 +430,7 @@ export class ValidationContext {
426
430
  * @returns A failed validation result
427
431
  */
428
432
  failure(reason: LexValidationError): ValidationFailure {
429
- return failure(reason)
433
+ return reason
430
434
  }
431
435
 
432
436
  /**
package/src/core.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './core/$type.js'
2
- export * from './core/property-key.js'
3
2
  export * from './core/record-key.js'
4
3
  export * from './core/result.js'
5
4
  export * from './core/schema.js'
@@ -77,11 +77,11 @@ describe('ArraySchema', () => {
77
77
  it('rejects single values', () => {
78
78
  const schema = array(string())
79
79
  const result = schema.safeValidate(3)
80
- expect(result).toEqual({
80
+ expect(result).toMatchObject({
81
81
  success: false,
82
82
  reason: expect.objectContaining({
83
83
  message: expect.stringContaining(
84
- 'Expected array value type at $ (got integer)',
84
+ 'Expected array value type (got integer) at $',
85
85
  ),
86
86
  }),
87
87
  })
@@ -1,10 +1,4 @@
1
- import {
2
- Issue,
3
- IssueCustom,
4
- PropertyKey,
5
- Schema,
6
- ValidationContext,
7
- } from '../core.js'
1
+ import { Issue, IssueCustom, Schema, ValidationContext } from '../core.js'
8
2
 
9
3
  /**
10
4
  * Context object provided to custom assertion functions.
@@ -419,7 +419,7 @@ describe('ParamsSchema', () => {
419
419
  ['name', 'Alice'],
420
420
  ['bools', 'notabool'],
421
421
  ]),
422
- ).toThrow('Expected boolean value type at $.bools (got string)')
422
+ ).toThrow('Expected boolean value type (got string) at $.bools')
423
423
 
424
424
  expect(() =>
425
425
  schema.fromURLSearchParams(
@@ -431,7 +431,7 @@ describe('ParamsSchema', () => {
431
431
  path: ['foo', 'bar'],
432
432
  },
433
433
  ),
434
- ).toThrow('Expected boolean value type at $.foo.bar.bools (got string)')
434
+ ).toThrow('Expected boolean value type (got string) at $.foo.bar.bools')
435
435
  })
436
436
 
437
437
  it('ignores empty string values', () => {
package/src/schema/ref.ts CHANGED
@@ -32,11 +32,7 @@ export type RefSchemaGetter<out TValidator extends Validator> = () => TValidator
32
32
  * ```
33
33
  */
34
34
  export class RefSchema<const TValidator extends Validator>
35
- extends Schema<
36
- InferInput<TValidator>,
37
- InferOutput<TValidator>,
38
- TValidator['__lex']
39
- >
35
+ extends Schema<InferInput<TValidator>, InferOutput<TValidator>>
40
36
  implements WrappedValidator<TValidator>
41
37
  {
42
38
  readonly type = 'ref' as const
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  InferInput,
3
3
  IssueCustom,
4
- PropertyKey,
5
4
  ValidationContext,
6
5
  ValidationResult,
7
6
  Validator,
@@ -1,2 +0,0 @@
1
- export type PropertyKey = string | number;
2
- //# sourceMappingURL=property-key.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"property-key.d.ts","sourceRoot":"","sources":["../../src/core/property-key.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAA"}
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=property-key.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"property-key.js","sourceRoot":"","sources":["../../src/core/property-key.ts"],"names":[],"mappings":"","sourcesContent":["export type PropertyKey = string | number\n"]}
@@ -1 +0,0 @@
1
- export type PropertyKey = string | number