@atproto/lex-schema 0.1.1 → 0.1.2
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.
- package/CHANGELOG.md +6 -0
- package/dist/core/result.d.ts +1 -125
- package/dist/core/result.d.ts.map +1 -1
- package/dist/core/result.js +1 -128
- package/dist/core/result.js.map +1 -1
- package/dist/core/validation-error.d.ts +0 -18
- package/dist/core/validation-error.d.ts.map +1 -1
- package/dist/core/validation-error.js +0 -30
- package/dist/core/validation-error.js.map +1 -1
- package/dist/core/validator.d.ts +8 -15
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +3 -14
- package/dist/core/validator.js.map +1 -1
- package/dist/schema/array.d.ts +1 -1
- package/dist/schema/blob.d.ts +1 -1
- package/dist/schema/boolean.d.ts +1 -1
- package/dist/schema/bytes.d.ts +1 -1
- package/dist/schema/cid.d.ts +1 -1
- package/dist/schema/custom.d.ts +1 -1
- package/dist/schema/dict.d.ts +1 -1
- package/dist/schema/enum.d.ts +1 -1
- package/dist/schema/integer.d.ts +1 -1
- package/dist/schema/intersection.d.ts +1 -1
- package/dist/schema/lex-map.d.ts +1 -1
- package/dist/schema/lex-value.d.ts +1 -1
- package/dist/schema/literal.d.ts +1 -1
- package/dist/schema/null.d.ts +1 -1
- package/dist/schema/nullable.d.ts +1 -1
- package/dist/schema/object.d.ts +1 -1
- package/dist/schema/optional.d.ts +1 -1
- package/dist/schema/params.d.ts +2 -2
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/regexp.d.ts +1 -1
- package/dist/schema/string.d.ts +1 -1
- package/dist/schema/token.d.ts +2 -1
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +6 -1
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-union.d.ts +1 -1
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +3 -3
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown.d.ts +1 -1
- package/package.json +2 -2
- package/src/core/result.ts +8 -155
- package/src/core/validation-error.ts +1 -33
- package/src/core/validator.ts +10 -21
- package/src/schema/token.ts +9 -1
- package/src/schema/union.ts +4 -4
package/src/core/result.ts
CHANGED
|
@@ -1,162 +1,15 @@
|
|
|
1
|
-
export type ResultSuccess<V = any> = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
* @typeParam E - The type of the error reason
|
|
7
|
-
*/
|
|
8
|
-
export type ResultFailure<E = Error> = { success: false; reason: E }
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A discriminated union type representing either a success or failure outcome.
|
|
12
|
-
*
|
|
13
|
-
* Check the `success` property to determine the outcome and access the
|
|
14
|
-
* appropriate property (`value` for success, `reason` for failure).
|
|
15
|
-
*
|
|
16
|
-
* @typeParam V - The type of the success value
|
|
17
|
-
* @typeParam E - The type of the error reason
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* function parseJson(text: string): Result<unknown, SyntaxError> {
|
|
22
|
-
* try {
|
|
23
|
-
* return success(JSON.parse(text))
|
|
24
|
-
* } catch (e) {
|
|
25
|
-
* return failure(e as SyntaxError)
|
|
26
|
-
* }
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
export type Result<V = any, E = Error> = ResultSuccess<V> | ResultFailure<E>
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Creates a successful result wrapping the given value.
|
|
34
|
-
*
|
|
35
|
-
* @typeParam V - The type of the value
|
|
36
|
-
* @param value - The success value to wrap
|
|
37
|
-
* @returns {ResultSuccess} A success result containing the value
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```typescript
|
|
41
|
-
* const result = success(42)
|
|
42
|
-
* console.log(result.success) // true
|
|
43
|
-
* console.log(result.value) // 42
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
47
|
-
export function success<V>(value: V): ResultSuccess<V> {
|
|
48
|
-
return { success: true, value }
|
|
1
|
+
export type ResultSuccess<V = any> = {
|
|
2
|
+
success: true
|
|
3
|
+
value: V
|
|
4
|
+
reason?: undefined
|
|
49
5
|
}
|
|
50
6
|
|
|
51
7
|
/**
|
|
52
|
-
*
|
|
8
|
+
* Represents a failed result containing an error reason.
|
|
53
9
|
*
|
|
54
10
|
* @typeParam E - The type of the error reason
|
|
55
|
-
* @param reason - The error reason to wrap
|
|
56
|
-
* @returns {ResultFailure} A failure result containing the error
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```typescript
|
|
60
|
-
* const result = failure(new Error('Something went wrong'))
|
|
61
|
-
* console.log(result.success) // false
|
|
62
|
-
* console.log(result.reason.message) // "Something went wrong"
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
66
|
-
export function failure<E>(reason: E): ResultFailure<E> {
|
|
67
|
-
return { success: false, reason }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Extracts the error reason from a failure result.
|
|
72
|
-
*
|
|
73
|
-
* @typeParam T - The type of the error reason
|
|
74
|
-
* @param result - A failure result
|
|
75
|
-
* @returns {T} The error reason
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```typescript
|
|
79
|
-
* const result = failure(new Error('oops'))
|
|
80
|
-
* const error = failureReason(result)
|
|
81
|
-
* console.log(error.message) // "oops"
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
84
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
85
|
-
export function failureReason<T>(result: ResultFailure<T>): T {
|
|
86
|
-
return result.reason
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Extracts the value from a success result.
|
|
91
|
-
*
|
|
92
|
-
* @typeParam T - The type of the success value
|
|
93
|
-
* @param result - A success result
|
|
94
|
-
* @returns {T} The success value
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* ```typescript
|
|
98
|
-
* const result = success(42)
|
|
99
|
-
* const value = successValue(result)
|
|
100
|
-
* console.log(value) // 42
|
|
101
|
-
* ```
|
|
102
|
-
*/
|
|
103
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
104
|
-
export function successValue<T>(result: ResultSuccess<T>): T {
|
|
105
|
-
return result.value
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Catches any error and wraps it in a {@link ResultFailure<Error>}.
|
|
110
|
-
*
|
|
111
|
-
* @param err - The error to catch.
|
|
112
|
-
* @returns {ResultFailure} A failure result containing the error.
|
|
113
|
-
* @example
|
|
114
|
-
*
|
|
115
|
-
* ```ts
|
|
116
|
-
* declare function someFunction(): Promise<string>
|
|
117
|
-
*
|
|
118
|
-
* const result = await someFunction().then(success, catchall)
|
|
119
|
-
* if (result.success) {
|
|
120
|
-
* console.log(result.value) // string
|
|
121
|
-
* } else {
|
|
122
|
-
* console.error(result.reason instanceof Error) // true
|
|
123
|
-
* console.error(result.reason.message) // string
|
|
124
|
-
* }
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
128
|
-
export function catchall(err: unknown): ResultFailure<Error> {
|
|
129
|
-
if (err instanceof Error) return failure(err)
|
|
130
|
-
return failure(new Error('Unknown error', { cause: err }))
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Creates a catcher function for the given constructor that wraps caught errors
|
|
135
|
-
* in a {@link ResultFailure}.
|
|
136
|
-
*
|
|
137
|
-
* @example
|
|
138
|
-
*
|
|
139
|
-
* ```ts
|
|
140
|
-
* class FooError extends Error {}
|
|
141
|
-
* class BarError extends Error {}
|
|
142
|
-
*
|
|
143
|
-
* declare function someFunction(): Promise<string>
|
|
144
|
-
*
|
|
145
|
-
* const result = await someFunction()
|
|
146
|
-
* .then(success)
|
|
147
|
-
* .catch(createCatcher(FooError))
|
|
148
|
-
* .catch(createCatcher(BarError))
|
|
149
|
-
*
|
|
150
|
-
* if (result.success) {
|
|
151
|
-
* console.log(result.value) // string
|
|
152
|
-
* } else {
|
|
153
|
-
* console.error(result.reason) // FooError | BarError
|
|
154
|
-
* }
|
|
155
11
|
*/
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (err instanceof Ctor) return failure(err)
|
|
160
|
-
throw err
|
|
161
|
-
}
|
|
12
|
+
export type ResultFailure<E = Error> = {
|
|
13
|
+
success: false
|
|
14
|
+
reason: E
|
|
162
15
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LexError } from '@atproto/lex-data'
|
|
2
2
|
import { arrayAgg } from '../util/array-agg.js'
|
|
3
|
-
import { ResultFailure
|
|
3
|
+
import { ResultFailure } from './result.js'
|
|
4
4
|
import {
|
|
5
5
|
Issue,
|
|
6
6
|
IssueInvalidType,
|
|
@@ -82,38 +82,6 @@ export class LexValidationError
|
|
|
82
82
|
issues: this.issues.map((issue) => issue.toJSON()),
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Creates a validation error by combining multiple validation failures.
|
|
88
|
-
*
|
|
89
|
-
* This is useful when validating against multiple possible schemas (e.g., unions)
|
|
90
|
-
* and all branches fail. The resulting error contains issues from all failures.
|
|
91
|
-
*
|
|
92
|
-
* @param failures - The validation failures to combine
|
|
93
|
-
* @returns A single validation error containing all issues from the failures
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* ```typescript
|
|
97
|
-
* const failures = schemas.map(s => s.safeValidate(data)).filter(r => !r.success)
|
|
98
|
-
* if (failures.length === schemas.length) {
|
|
99
|
-
* throw LexValidationError.fromFailures(failures)
|
|
100
|
-
* }
|
|
101
|
-
* ```
|
|
102
|
-
*/
|
|
103
|
-
static fromFailures(
|
|
104
|
-
failures: readonly ResultFailure<LexValidationError>[],
|
|
105
|
-
): LexValidationError {
|
|
106
|
-
if (failures.length === 1) return failureReason(failures[0])
|
|
107
|
-
const issues = failures.flatMap(extractFailureIssues)
|
|
108
|
-
return new LexValidationError(issues, {
|
|
109
|
-
// Keep the original errors as the cause chain
|
|
110
|
-
cause: failures.map(failureReason),
|
|
111
|
-
})
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function extractFailureIssues(result: ResultFailure<LexValidationError>) {
|
|
116
|
-
return result.reason.issues
|
|
117
85
|
}
|
|
118
86
|
|
|
119
87
|
function aggregateIssues(issues: Issue[]): Issue[] {
|
package/src/core/validator.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { ResultFailure, ResultSuccess, success } from './result.js'
|
|
1
|
+
import type * as Result from './result.js'
|
|
3
2
|
import { LexValidationError } from './validation-error.js'
|
|
4
3
|
import {
|
|
5
4
|
Issue,
|
|
@@ -15,16 +14,16 @@ import {
|
|
|
15
14
|
/**
|
|
16
15
|
* Represents a successful validation result.
|
|
17
16
|
*
|
|
18
|
-
* @typeParam
|
|
17
|
+
* @typeParam TValue - The type of the validated value
|
|
18
|
+
* @extends Result.ResultSuccess<TValue>
|
|
19
19
|
*/
|
|
20
|
-
export type ValidationSuccess<
|
|
20
|
+
export type ValidationSuccess<TValue = unknown> = Result.ResultSuccess<TValue>
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Represents a failed validation result containing a {@link LexValidationError}.
|
|
24
24
|
*
|
|
25
|
-
* @extends ResultFailure<LexValidationError>
|
|
26
|
-
* @see {@link ResultFailure}
|
|
27
25
|
* @see {@link LexValidationError}
|
|
26
|
+
* @extends Result.ResultFailure<LexValidationError>
|
|
28
27
|
*/
|
|
29
28
|
export type ValidationFailure = LexValidationError
|
|
30
29
|
|
|
@@ -429,24 +428,14 @@ export class ValidationContext {
|
|
|
429
428
|
}
|
|
430
429
|
|
|
431
430
|
/**
|
|
432
|
-
*
|
|
431
|
+
* Helper method to create a successful validation result.
|
|
433
432
|
*
|
|
434
433
|
* @typeParam V - The value type
|
|
435
434
|
* @param value - The validated value
|
|
436
435
|
* @returns A successful validation result
|
|
437
436
|
*/
|
|
438
|
-
success<V>(value: V):
|
|
439
|
-
return success
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* Creates a failed validation result with the given error.
|
|
444
|
-
*
|
|
445
|
-
* @param reason - The validation error
|
|
446
|
-
* @returns A failed validation result
|
|
447
|
-
*/
|
|
448
|
-
failure(reason: LexValidationError): ValidationFailure {
|
|
449
|
-
return reason
|
|
437
|
+
success<V>(value: V): ValidationSuccess<V> {
|
|
438
|
+
return { success: true, value }
|
|
450
439
|
}
|
|
451
440
|
|
|
452
441
|
/**
|
|
@@ -457,8 +446,8 @@ export class ValidationContext {
|
|
|
457
446
|
* @param issue - The validation issue that caused the failure
|
|
458
447
|
* @returns A failed validation result
|
|
459
448
|
*/
|
|
460
|
-
issue(issue: Issue) {
|
|
461
|
-
return
|
|
449
|
+
issue(issue: Issue): ValidationFailure {
|
|
450
|
+
return new LexValidationError([...this.issues, issue])
|
|
462
451
|
}
|
|
463
452
|
|
|
464
453
|
/**
|
package/src/schema/token.ts
CHANGED
|
@@ -24,6 +24,10 @@ export class TokenSchema<
|
|
|
24
24
|
super()
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
get $token(): TValue {
|
|
28
|
+
return this.value
|
|
29
|
+
}
|
|
30
|
+
|
|
27
31
|
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
28
32
|
if (input === this.value) {
|
|
29
33
|
return ctx.success(this.value)
|
|
@@ -31,7 +35,11 @@ export class TokenSchema<
|
|
|
31
35
|
|
|
32
36
|
// @NOTE: allow using the token instance itself (but convert to the actual
|
|
33
37
|
// token value)
|
|
34
|
-
if (
|
|
38
|
+
if (
|
|
39
|
+
ctx.options.mode === 'parse' &&
|
|
40
|
+
input instanceof TokenSchema &&
|
|
41
|
+
input.value === this.value
|
|
42
|
+
) {
|
|
35
43
|
return ctx.success(this.value)
|
|
36
44
|
}
|
|
37
45
|
|
package/src/schema/union.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
InferInput,
|
|
3
3
|
InferOutput,
|
|
4
|
+
Issue,
|
|
4
5
|
LexValidationError,
|
|
5
6
|
Schema,
|
|
6
7
|
ValidationContext,
|
|
7
|
-
ValidationFailure,
|
|
8
8
|
Validator,
|
|
9
9
|
} from '../core.js'
|
|
10
10
|
|
|
@@ -44,16 +44,16 @@ export class UnionSchema<
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
47
|
-
const
|
|
47
|
+
const issues: Issue[] = []
|
|
48
48
|
|
|
49
49
|
for (const validator of this.validators) {
|
|
50
50
|
const result = ctx.validate(input, validator)
|
|
51
51
|
if (result.success) return result
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
issues.push(...result.issues)
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
return
|
|
56
|
+
return new LexValidationError(issues)
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|