@atproto/lex-schema 0.0.10 → 0.0.12
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 +26 -0
- package/dist/core/$type.d.ts +149 -0
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js +44 -0
- package/dist/core/$type.js.map +1 -1
- package/dist/core/record-key.d.ts +44 -0
- package/dist/core/record-key.d.ts.map +1 -1
- package/dist/core/record-key.js +30 -0
- package/dist/core/record-key.js.map +1 -1
- package/dist/core/result.d.ts +85 -4
- package/dist/core/result.d.ts.map +1 -1
- package/dist/core/result.js +60 -4
- package/dist/core/result.js.map +1 -1
- package/dist/core/schema.d.ts +229 -2
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +197 -4
- package/dist/core/schema.js.map +1 -1
- package/dist/core/string-format.d.ts +244 -11
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js +150 -0
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/types.d.ts +90 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/validation-error.d.ts +61 -1
- package/dist/core/validation-error.d.ts.map +1 -1
- package/dist/core/validation-error.js +60 -0
- package/dist/core/validation-error.js.map +1 -1
- package/dist/core/validation-issue.d.ts +61 -0
- package/dist/core/validation-issue.d.ts.map +1 -1
- package/dist/core/validation-issue.js +51 -0
- package/dist/core/validation-issue.js.map +1 -1
- package/dist/core/validator.d.ts +347 -10
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +184 -3
- package/dist/core/validator.js.map +1 -1
- package/dist/helpers.d.ts +13 -25
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +2 -2
- package/dist/helpers.js.map +1 -1
- package/dist/schema/array.d.ts +45 -0
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +14 -0
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +46 -0
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +39 -0
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.d.ts +28 -0
- package/dist/schema/boolean.d.ts.map +1 -1
- package/dist/schema/boolean.js +28 -0
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.d.ts +38 -0
- package/dist/schema/bytes.d.ts.map +1 -1
- package/dist/schema/bytes.js +32 -0
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +38 -0
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +33 -0
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.d.ts +66 -1
- package/dist/schema/custom.d.ts.map +1 -1
- package/dist/schema/custom.js +54 -0
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +44 -0
- package/dist/schema/dict.d.ts.map +1 -1
- package/dist/schema/dict.js +44 -0
- package/dist/schema/dict.js.map +1 -1
- package/dist/schema/discriminated-union.d.ts +58 -0
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +45 -0
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.d.ts +48 -0
- package/dist/schema/enum.d.ts.map +1 -1
- package/dist/schema/enum.js +48 -0
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.d.ts +42 -0
- package/dist/schema/integer.d.ts.map +1 -1
- package/dist/schema/integer.js +36 -0
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +54 -0
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +49 -0
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/literal.d.ts +44 -0
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +44 -0
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.d.ts +42 -0
- package/dist/schema/never.d.ts.map +1 -1
- package/dist/schema/never.js +42 -0
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.d.ts +29 -0
- package/dist/schema/null.d.ts.map +1 -1
- package/dist/schema/null.js +29 -0
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +41 -0
- package/dist/schema/nullable.d.ts.map +1 -1
- package/dist/schema/nullable.js +41 -0
- package/dist/schema/nullable.js.map +1 -1
- package/dist/schema/object.d.ts +56 -0
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +51 -0
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +42 -0
- package/dist/schema/optional.d.ts.map +1 -1
- package/dist/schema/optional.js +42 -0
- package/dist/schema/optional.js.map +1 -1
- package/dist/schema/params.d.ts +89 -7
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +84 -10
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +111 -15
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +70 -0
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +58 -0
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +50 -0
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +42 -0
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js +39 -0
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +64 -0
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +64 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +55 -0
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +55 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +63 -8
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +20 -0
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +50 -0
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +17 -0
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +58 -9
- package/dist/schema/refine.d.ts.map +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/regexp.d.ts +44 -0
- package/dist/schema/regexp.d.ts.map +1 -1
- package/dist/schema/regexp.js +44 -0
- package/dist/schema/regexp.js.map +1 -1
- package/dist/schema/string.d.ts +50 -0
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +41 -0
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +72 -2
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js +59 -0
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +47 -0
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +47 -0
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +62 -8
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +18 -0
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +53 -0
- package/dist/schema/typed-ref.d.ts.map +1 -1
- package/dist/schema/typed-ref.js +15 -0
- package/dist/schema/typed-ref.js.map +1 -1
- package/dist/schema/typed-union.d.ts +50 -1
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +50 -1
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +45 -0
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +40 -0
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown-object.d.ts +34 -0
- package/dist/schema/unknown-object.d.ts.map +1 -1
- package/dist/schema/unknown-object.js +31 -0
- package/dist/schema/unknown-object.js.map +1 -1
- package/dist/schema/unknown.d.ts +33 -0
- package/dist/schema/unknown.d.ts.map +1 -1
- package/dist/schema/unknown.js +33 -0
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema/with-default.d.ts +44 -0
- package/dist/schema/with-default.d.ts.map +1 -1
- package/dist/schema/with-default.js +44 -0
- package/dist/schema/with-default.js.map +1 -1
- package/package.json +4 -4
- package/src/core/$type.ts +150 -18
- package/src/core/record-key.ts +44 -0
- package/src/core/result.ts +86 -4
- package/src/core/schema.ts +236 -7
- package/src/core/string-format.ts +259 -13
- package/src/core/types.ts +91 -3
- package/src/core/validation-error.ts +60 -0
- package/src/core/validation-issue.ts +65 -0
- package/src/core/validator.ts +351 -10
- package/src/helpers.test.ts +110 -29
- package/src/helpers.ts +14 -14
- package/src/schema/array.test.ts +94 -79
- package/src/schema/array.ts +45 -0
- package/src/schema/blob.ts +46 -0
- package/src/schema/boolean.ts +28 -0
- package/src/schema/bytes.ts +38 -0
- package/src/schema/cid.ts +38 -0
- package/src/schema/custom.ts +66 -1
- package/src/schema/dict.ts +44 -0
- package/src/schema/discriminated-union.ts +58 -0
- package/src/schema/enum.ts +48 -0
- package/src/schema/integer.ts +42 -0
- package/src/schema/intersection.ts +54 -0
- package/src/schema/literal.ts +44 -0
- package/src/schema/never.ts +42 -0
- package/src/schema/null.ts +29 -0
- package/src/schema/nullable.ts +41 -0
- package/src/schema/object.ts +56 -0
- package/src/schema/optional.ts +42 -0
- package/src/schema/params.test.ts +58 -2
- package/src/schema/params.ts +124 -16
- package/src/schema/payload.test.ts +3 -3
- package/src/schema/payload.ts +142 -38
- package/src/schema/permission-set.ts +58 -0
- package/src/schema/permission.ts +42 -0
- package/src/schema/procedure.ts +64 -0
- package/src/schema/query.ts +55 -0
- package/src/schema/record.ts +63 -8
- package/src/schema/ref.ts +50 -0
- package/src/schema/refine.ts +58 -9
- package/src/schema/regexp.ts +44 -0
- package/src/schema/string.ts +50 -0
- package/src/schema/subscription.ts +72 -2
- package/src/schema/token.ts +47 -0
- package/src/schema/typed-object.ts +62 -8
- package/src/schema/typed-ref.ts +53 -0
- package/src/schema/typed-union.ts +55 -2
- package/src/schema/union.ts +45 -0
- package/src/schema/unknown-object.ts +34 -0
- package/src/schema/unknown.ts +33 -0
- package/src/schema/with-default.ts +44 -0
package/src/schema/refine.ts
CHANGED
|
@@ -8,18 +8,40 @@ import {
|
|
|
8
8
|
} from '../core.js'
|
|
9
9
|
import { CustomAssertionContext } from './custom.js'
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for a refinement check that validates a condition.
|
|
13
|
+
*
|
|
14
|
+
* @template T - The type being validated
|
|
15
|
+
* @property check - Function that returns true if the value passes the check
|
|
16
|
+
* @property message - Error message when the check fails
|
|
17
|
+
* @property path - Optional path to associate with the error
|
|
18
|
+
*/
|
|
11
19
|
export type RefinementCheck<T> = {
|
|
12
20
|
check: (value: T, ctx: CustomAssertionContext) => boolean
|
|
13
21
|
message: string
|
|
14
22
|
path?: PropertyKey | readonly PropertyKey[]
|
|
15
23
|
}
|
|
16
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Configuration for a refinement assertion that narrows the type.
|
|
27
|
+
*
|
|
28
|
+
* @template T - The input type being validated
|
|
29
|
+
* @template Out - The narrowed output type
|
|
30
|
+
* @property check - Type guard function that narrows the type
|
|
31
|
+
* @property message - Error message when the assertion fails
|
|
32
|
+
* @property path - Optional path to associate with the error
|
|
33
|
+
*/
|
|
17
34
|
export type RefinementAssertion<T, Out extends T> = {
|
|
18
35
|
check: (this: null, value: T, ctx: CustomAssertionContext) => value is Out
|
|
19
36
|
message: string
|
|
20
37
|
path?: PropertyKey | readonly PropertyKey[]
|
|
21
38
|
}
|
|
22
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Infers the input type from a refinement configuration.
|
|
42
|
+
*
|
|
43
|
+
* @template R - The refinement type
|
|
44
|
+
*/
|
|
23
45
|
export type InferRefinement<R> =
|
|
24
46
|
R extends RefinementCheck<infer T>
|
|
25
47
|
? T
|
|
@@ -27,25 +49,52 @@ export type InferRefinement<R> =
|
|
|
27
49
|
? T
|
|
28
50
|
: never
|
|
29
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Union type of refinement check or assertion.
|
|
54
|
+
*
|
|
55
|
+
* @template T - The input type being validated
|
|
56
|
+
* @template Out - The output type (same as T for checks, narrowed for assertions)
|
|
57
|
+
*/
|
|
30
58
|
export type Refinement<T = any, Out extends T = T> =
|
|
31
59
|
| RefinementCheck<T>
|
|
32
60
|
| RefinementAssertion<T, Out>
|
|
33
61
|
|
|
34
62
|
/**
|
|
35
|
-
*
|
|
63
|
+
* Creates a refined schema by adding additional validation constraints.
|
|
36
64
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* @returns A new schema that includes the refinement.
|
|
40
|
-
* @example
|
|
65
|
+
* Wraps an existing schema with an additional check function. The base schema
|
|
66
|
+
* is validated first, then the refinement check is applied to the result.
|
|
41
67
|
*
|
|
68
|
+
* @param schema - The base schema to refine
|
|
69
|
+
* @param refinement - The refinement check or assertion to apply
|
|
70
|
+
* @returns A new schema that includes the refinement
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
42
73
|
* ```ts
|
|
43
|
-
*
|
|
74
|
+
* // Simple check refinement
|
|
75
|
+
* const positiveInt = l.refine(l.integer(), {
|
|
44
76
|
* check: (value) => value > 0,
|
|
45
|
-
* message: 'Value must be
|
|
77
|
+
* message: 'Value must be positive',
|
|
46
78
|
* })
|
|
47
|
-
*
|
|
48
|
-
* //
|
|
79
|
+
*
|
|
80
|
+
* positiveInt.parse(5) // 5
|
|
81
|
+
* positiveInt.parse(-1) // throws
|
|
82
|
+
*
|
|
83
|
+
* // Type-narrowing assertion
|
|
84
|
+
* const nonEmptyString = l.refine(l.string(), {
|
|
85
|
+
* check: (value): value is string & { length: number } => value.length > 0,
|
|
86
|
+
* message: 'String must not be empty',
|
|
87
|
+
* })
|
|
88
|
+
*
|
|
89
|
+
* // With custom path for nested errors
|
|
90
|
+
* const validDateRange = l.refine(
|
|
91
|
+
* l.object({ start: l.string(), end: l.string() }),
|
|
92
|
+
* {
|
|
93
|
+
* check: (v) => new Date(v.start) < new Date(v.end),
|
|
94
|
+
* message: 'Start date must be before end date',
|
|
95
|
+
* path: ['end'],
|
|
96
|
+
* }
|
|
97
|
+
* )
|
|
49
98
|
* ```
|
|
50
99
|
*/
|
|
51
100
|
export function refine<
|
package/src/schema/regexp.ts
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { Schema, ValidationContext } from '../core.js'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Schema for validating strings against a regular expression pattern.
|
|
5
|
+
*
|
|
6
|
+
* Validates that the input is a string and matches the provided pattern.
|
|
7
|
+
* The pattern is tested using RegExp.test().
|
|
8
|
+
*
|
|
9
|
+
* @template TValue - The string type (can be narrowed with branded types)
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const schema = new RegexpSchema(/^[a-z]+$/)
|
|
14
|
+
* schema.validate('hello') // success
|
|
15
|
+
* schema.validate('Hello') // fails - uppercase not allowed
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
3
18
|
export class RegexpSchema<
|
|
4
19
|
TValue extends string = string,
|
|
5
20
|
> extends Schema<TValue> {
|
|
@@ -20,6 +35,35 @@ export class RegexpSchema<
|
|
|
20
35
|
}
|
|
21
36
|
}
|
|
22
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Creates a regexp schema that validates strings against a pattern.
|
|
40
|
+
*
|
|
41
|
+
* Useful for custom string formats not covered by the built-in format
|
|
42
|
+
* validators.
|
|
43
|
+
*
|
|
44
|
+
* @param pattern - Regular expression pattern to match against
|
|
45
|
+
* @returns A new {@link RegexpSchema} instance
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* // Simple pattern
|
|
50
|
+
* const slugSchema = l.regexp(/^[a-z0-9-]+$/)
|
|
51
|
+
*
|
|
52
|
+
* // With anchors for exact match
|
|
53
|
+
* const uuidSchema = l.regexp(
|
|
54
|
+
* /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
|
|
55
|
+
* )
|
|
56
|
+
*
|
|
57
|
+
* // Semantic versioning
|
|
58
|
+
* const semverSchema = l.regexp(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/)
|
|
59
|
+
*
|
|
60
|
+
* // Use in object
|
|
61
|
+
* const configSchema = l.object({
|
|
62
|
+
* name: l.regexp(/^[a-z][a-z0-9-]*$/), // kebab-case identifier
|
|
63
|
+
* version: semverSchema,
|
|
64
|
+
* })
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
23
67
|
/*@__NO_SIDE_EFFECTS__*/
|
|
24
68
|
export function regexp<TInput extends string = string>(pattern: RegExp) {
|
|
25
69
|
return new RegexpSchema<TInput>(pattern)
|
package/src/schema/string.ts
CHANGED
|
@@ -9,6 +9,15 @@ import {
|
|
|
9
9
|
import { memoizedOptions } from '../util/memoize.js'
|
|
10
10
|
import { TokenSchema } from './token.js'
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Configuration options for string schema validation.
|
|
14
|
+
*
|
|
15
|
+
* @property format - Expected string format (e.g., 'datetime', 'uri', 'at-uri', 'did', 'handle', 'nsid', 'cid', 'tid', 'record-key', 'at-identifier', 'language')
|
|
16
|
+
* @property minLength - Minimum length in UTF-8 bytes
|
|
17
|
+
* @property maxLength - Maximum length in UTF-8 bytes
|
|
18
|
+
* @property minGraphemes - Minimum number of grapheme clusters
|
|
19
|
+
* @property maxGraphemes - Maximum number of grapheme clusters
|
|
20
|
+
*/
|
|
12
21
|
export type StringSchemaOptions = {
|
|
13
22
|
format?: StringFormat
|
|
14
23
|
minLength?: number
|
|
@@ -17,6 +26,20 @@ export type StringSchemaOptions = {
|
|
|
17
26
|
maxGraphemes?: number
|
|
18
27
|
}
|
|
19
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Schema for validating string values with optional format and length constraints.
|
|
31
|
+
*
|
|
32
|
+
* Supports various string formats defined in the Lexicon specification, as well as
|
|
33
|
+
* length constraints measured in UTF-8 bytes or grapheme clusters.
|
|
34
|
+
*
|
|
35
|
+
* @template TOptions - The configuration options type
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const schema = new StringSchema({ format: 'datetime', maxLength: 64 })
|
|
40
|
+
* const result = schema.validate('2024-01-15T10:30:00Z')
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
20
43
|
export class StringSchema<
|
|
21
44
|
const TOptions extends StringSchemaOptions = StringSchemaOptions,
|
|
22
45
|
> extends Schema<
|
|
@@ -123,6 +146,33 @@ export function coerceToString(input: unknown): string | null {
|
|
|
123
146
|
}
|
|
124
147
|
}
|
|
125
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Creates a string schema with optional format and length constraints.
|
|
151
|
+
*
|
|
152
|
+
* Strings can be validated against various formats (datetime, uri, did, handle, etc.)
|
|
153
|
+
* and constrained by length in UTF-8 bytes or grapheme clusters.
|
|
154
|
+
*
|
|
155
|
+
* @param options - Optional configuration for format and length constraints
|
|
156
|
+
* @returns A new {@link StringSchema} instance
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* // Basic string
|
|
161
|
+
* const nameSchema = l.string()
|
|
162
|
+
*
|
|
163
|
+
* // With format validation
|
|
164
|
+
* const dateSchema = l.string({ format: 'datetime' })
|
|
165
|
+
*
|
|
166
|
+
* // With length constraints (UTF-8 bytes)
|
|
167
|
+
* const bioSchema = l.string({ maxLength: 256 })
|
|
168
|
+
*
|
|
169
|
+
* // With grapheme constraints (user-perceived characters)
|
|
170
|
+
* const displayNameSchema = l.string({ maxGraphemes: 64 })
|
|
171
|
+
*
|
|
172
|
+
* // Combining constraints
|
|
173
|
+
* const handleSchema = l.string({ format: 'handle', minLength: 3, maxLength: 253 })
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
126
176
|
export const string = /*#__PURE__*/ memoizedOptions(function <
|
|
127
177
|
const O extends StringSchemaOptions = NonNullable<unknown>,
|
|
128
178
|
>(options?: StringSchemaOptions & O) {
|
|
@@ -1,18 +1,51 @@
|
|
|
1
|
+
import { LexValue } from '@atproto/lex-data'
|
|
1
2
|
import { Infer, NsidString, Schema } from '../core.js'
|
|
2
3
|
import { ParamsSchema } from './params.js'
|
|
3
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Infers the parameters type from a Subscription definition.
|
|
7
|
+
*
|
|
8
|
+
* @template S - The Subscription type
|
|
9
|
+
*/
|
|
4
10
|
export type InferSubscriptionParameters<S extends Subscription> = Infer<
|
|
5
11
|
S['parameters']
|
|
6
12
|
>
|
|
7
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Infers the message type from a Subscription definition.
|
|
16
|
+
*
|
|
17
|
+
* @template S - The Subscription type
|
|
18
|
+
*/
|
|
8
19
|
export type InferSubscriptionMessage<S extends Subscription> = Infer<
|
|
9
20
|
S['message']
|
|
10
21
|
>
|
|
11
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Represents a Lexicon subscription (WebSocket) endpoint definition.
|
|
25
|
+
*
|
|
26
|
+
* Subscriptions are real-time event streams delivered over WebSocket.
|
|
27
|
+
* They have parameters for initializing the connection and a message
|
|
28
|
+
* schema for validating incoming events.
|
|
29
|
+
*
|
|
30
|
+
* @template TNsid - The NSID identifying this subscription
|
|
31
|
+
* @template TParameters - The connection parameters schema type
|
|
32
|
+
* @template TMessage - The message schema type
|
|
33
|
+
* @template TErrors - Array of error type strings, or undefined
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const firehose = new Subscription(
|
|
38
|
+
* 'com.atproto.sync.subscribeRepos',
|
|
39
|
+
* l.params({ cursor: l.optional(l.integer()) }),
|
|
40
|
+
* repoEventSchema,
|
|
41
|
+
* ['FutureCursor']
|
|
42
|
+
* )
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
12
45
|
export class Subscription<
|
|
13
46
|
const TNsid extends NsidString = NsidString,
|
|
14
47
|
const TParameters extends ParamsSchema = ParamsSchema,
|
|
15
|
-
const TMessage extends Schema = Schema
|
|
48
|
+
const TMessage extends Schema<LexValue> = Schema<LexValue>,
|
|
16
49
|
const TErrors extends undefined | readonly string[] =
|
|
17
50
|
| undefined
|
|
18
51
|
| readonly string[],
|
|
@@ -27,11 +60,48 @@ export class Subscription<
|
|
|
27
60
|
) {}
|
|
28
61
|
}
|
|
29
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Creates a subscription definition for a Lexicon WebSocket endpoint.
|
|
65
|
+
*
|
|
66
|
+
* Subscriptions enable real-time event streaming. The connection is
|
|
67
|
+
* initialized with parameters, and the server sends messages matching
|
|
68
|
+
* the message schema.
|
|
69
|
+
*
|
|
70
|
+
* @param nsid - The NSID identifying this subscription endpoint
|
|
71
|
+
* @param parameters - Schema for connection parameters
|
|
72
|
+
* @param message - Schema for validating incoming messages
|
|
73
|
+
* @param errors - Optional array of error type strings
|
|
74
|
+
* @returns A new {@link Subscription} instance
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* // Repository event stream
|
|
79
|
+
* const subscribeRepos = l.subscription(
|
|
80
|
+
* 'com.atproto.sync.subscribeRepos',
|
|
81
|
+
* l.params({
|
|
82
|
+
* cursor: l.optional(l.integer()),
|
|
83
|
+
* }),
|
|
84
|
+
* l.typedUnion([
|
|
85
|
+
* l.typedRef(() => commitEventSchema),
|
|
86
|
+
* l.typedRef(() => handleEventSchema),
|
|
87
|
+
* l.typedRef(() => identityEventSchema),
|
|
88
|
+
* ], false),
|
|
89
|
+
* ['FutureCursor', 'ConsumerTooSlow'],
|
|
90
|
+
* )
|
|
91
|
+
*
|
|
92
|
+
* // Label stream
|
|
93
|
+
* const subscribeLabels = l.subscription(
|
|
94
|
+
* 'com.atproto.label.subscribeLabels',
|
|
95
|
+
* l.params({ cursor: l.optional(l.integer()) }),
|
|
96
|
+
* labelEventSchema,
|
|
97
|
+
* )
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
30
100
|
/*@__NO_SIDE_EFFECTS__*/
|
|
31
101
|
export function subscription<
|
|
32
102
|
const N extends NsidString,
|
|
33
103
|
const P extends ParamsSchema,
|
|
34
|
-
const M extends Schema
|
|
104
|
+
const M extends Schema<LexValue>,
|
|
35
105
|
const E extends undefined | readonly string[] = undefined,
|
|
36
106
|
>(nsid: N, parameters: P, message: M, errors: E = undefined as E) {
|
|
37
107
|
return new Subscription<N, P, M, E>(nsid, parameters, message, errors)
|
package/src/schema/token.ts
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { $type, NsidString, Schema, ValidationContext } from '../core.js'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Schema for Lexicon token values.
|
|
5
|
+
*
|
|
6
|
+
* Tokens are named constants in Lexicon, identified by their NSID and hash.
|
|
7
|
+
* They validate to their string value (e.g., 'app.bsky.feed.defs#requestLess').
|
|
8
|
+
* TokenSchema instances can also be used as values themselves.
|
|
9
|
+
*
|
|
10
|
+
* @template TValue - The token string literal type
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const schema = new TokenSchema('app.bsky.feed.defs#requestLess')
|
|
15
|
+
* schema.validate('app.bsky.feed.defs#requestLess') // success
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
3
18
|
export class TokenSchema<
|
|
4
19
|
const TValue extends string = string,
|
|
5
20
|
> extends Schema<TValue> {
|
|
@@ -37,6 +52,38 @@ export class TokenSchema<
|
|
|
37
52
|
}
|
|
38
53
|
}
|
|
39
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Creates a token schema for Lexicon named constants.
|
|
57
|
+
*
|
|
58
|
+
* Tokens are used in Lexicon as named constants or enum-like values.
|
|
59
|
+
* The token instance can be used both as a schema validator and as
|
|
60
|
+
* the token value itself (it serializes to its string value).
|
|
61
|
+
*
|
|
62
|
+
* @param nsid - The NSID part of the token
|
|
63
|
+
* @param hash - The hash part of the token (defaults to 'main')
|
|
64
|
+
* @returns A new {@link TokenSchema} instance
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* // Define tokens
|
|
69
|
+
* const requestLess = l.token('app.bsky.feed.defs', 'requestLess')
|
|
70
|
+
* const requestMore = l.token('app.bsky.feed.defs', 'requestMore')
|
|
71
|
+
*
|
|
72
|
+
* // Use as a value
|
|
73
|
+
* console.log(requestLess.toString()) // 'app.bsky.feed.defs#requestLess'
|
|
74
|
+
*
|
|
75
|
+
* // Use in union for validation
|
|
76
|
+
* const feedbackSchema = l.union([requestLess, requestMore])
|
|
77
|
+
*
|
|
78
|
+
* // Validate
|
|
79
|
+
* feedbackSchema.parse('app.bsky.feed.defs#requestLess') // success
|
|
80
|
+
*
|
|
81
|
+
* // Token instances can be used as values in other schemas
|
|
82
|
+
* const feedbackRequest = l.object({
|
|
83
|
+
* feedback: requestLess, // Accepts the token value
|
|
84
|
+
* })
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
40
87
|
/*@__NO_SIDE_EFFECTS__*/
|
|
41
88
|
export function token<
|
|
42
89
|
const N extends NsidString,
|
|
@@ -15,6 +15,24 @@ import {
|
|
|
15
15
|
Validator,
|
|
16
16
|
} from '../core.js'
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Schema for typed objects in Lexicon unions.
|
|
20
|
+
*
|
|
21
|
+
* Typed objects have a `$type` field that identifies which variant they are
|
|
22
|
+
* in a union. The `$type` can be omitted in input (it's implicit), but if
|
|
23
|
+
* present, it must match the expected value.
|
|
24
|
+
*
|
|
25
|
+
* @template TType - The $type string literal type
|
|
26
|
+
* @template TShape - The validator type for the object's shape
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const schema = new TypedObjectSchema(
|
|
31
|
+
* 'app.bsky.embed.images#view',
|
|
32
|
+
* l.object({ images: l.array(imageSchema) })
|
|
33
|
+
* )
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
18
36
|
export class TypedObjectSchema<
|
|
19
37
|
const TType extends $Type = $Type,
|
|
20
38
|
const TShape extends Validator<{ [k: string]: unknown }> = any,
|
|
@@ -72,15 +90,51 @@ export class TypedObjectSchema<
|
|
|
72
90
|
}
|
|
73
91
|
|
|
74
92
|
/**
|
|
93
|
+
* Creates a typed object schema for use in Lexicon unions.
|
|
94
|
+
*
|
|
95
|
+
* Typed objects are identified by their `$type` field, which combines an NSID
|
|
96
|
+
* and a hash (e.g., 'app.bsky.embed.images#view'). Used for union variants.
|
|
97
|
+
*
|
|
75
98
|
* This function offers two overloads:
|
|
76
|
-
* - One that
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
99
|
+
* - One that infers the type from arguments (no circular reference support)
|
|
100
|
+
* - One with explicit interface for codegen with circular references
|
|
101
|
+
*
|
|
102
|
+
* @param nsid - The NSID part of the type (e.g., 'app.bsky.embed.images')
|
|
103
|
+
* @param hash - The hash part of the type (e.g., 'view'), defaults to 'main'
|
|
104
|
+
* @param validator - Schema for validating the object properties
|
|
105
|
+
* @returns A new {@link TypedObjectSchema} instance
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* // Image embed view
|
|
110
|
+
* const imageViewSchema = l.typedObject(
|
|
111
|
+
* 'app.bsky.embed.images',
|
|
112
|
+
* 'view',
|
|
113
|
+
* l.object({
|
|
114
|
+
* images: l.array(l.object({
|
|
115
|
+
* thumb: l.string(),
|
|
116
|
+
* fullsize: l.string(),
|
|
117
|
+
* alt: l.string(),
|
|
118
|
+
* })),
|
|
119
|
+
* })
|
|
120
|
+
* )
|
|
121
|
+
*
|
|
122
|
+
* // Main type (hash defaults to 'main')
|
|
123
|
+
* const postViewSchema = l.typedObject(
|
|
124
|
+
* 'app.bsky.feed.defs',
|
|
125
|
+
* 'postView',
|
|
126
|
+
* l.object({ uri: l.string(), cid: l.string(), author: authorSchema })
|
|
127
|
+
* )
|
|
128
|
+
*
|
|
129
|
+
* // Use $isTypeOf to narrow union types
|
|
130
|
+
* if (imageViewSchema.$isTypeOf(embed)) {
|
|
131
|
+
* // embed is narrowed to image view type
|
|
132
|
+
* }
|
|
133
|
+
*
|
|
134
|
+
* // Use $build to construct typed objects
|
|
135
|
+
* const view = imageViewSchema.$build({ images: [...] })
|
|
136
|
+
* // view.$type === 'app.bsky.embed.images#view'
|
|
137
|
+
* ```
|
|
84
138
|
*/
|
|
85
139
|
export function typedObject<
|
|
86
140
|
const N extends NsidString,
|
package/src/schema/typed-ref.ts
CHANGED
|
@@ -7,6 +7,14 @@ import {
|
|
|
7
7
|
Validator,
|
|
8
8
|
} from '../core.js'
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Interface for validators that have a $type property.
|
|
12
|
+
*
|
|
13
|
+
* Used by typed objects and records to identify their type in unions.
|
|
14
|
+
*
|
|
15
|
+
* @template TInput - The input type (with optional $type)
|
|
16
|
+
* @template TOutput - The output type (with non-optional $type)
|
|
17
|
+
*/
|
|
10
18
|
export interface TypedObjectValidator<
|
|
11
19
|
TInput extends { $type?: string } = { $type?: string },
|
|
12
20
|
TOutput extends TInput = TInput,
|
|
@@ -14,9 +22,29 @@ export interface TypedObjectValidator<
|
|
|
14
22
|
$type: NonNullable<TOutput['$type']>
|
|
15
23
|
}
|
|
16
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Function type that returns a typed object validator, used for lazy resolution.
|
|
27
|
+
*
|
|
28
|
+
* @template TValidator - The typed object validator type
|
|
29
|
+
*/
|
|
17
30
|
export type TypedRefGetter<out TValidator extends TypedObjectValidator> =
|
|
18
31
|
() => TValidator
|
|
19
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Schema for referencing typed objects with lazy resolution.
|
|
35
|
+
*
|
|
36
|
+
* Used in typed unions to reference typed object schemas. Requires the
|
|
37
|
+
* `$type` field to be present and match the referenced schema's type.
|
|
38
|
+
* The referenced schema is resolved lazily to support circular references.
|
|
39
|
+
*
|
|
40
|
+
* @template TValidator - The referenced typed object validator type
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const ref = new TypedRefSchema(() => imageViewSchema)
|
|
45
|
+
* // ref.$type === 'app.bsky.embed.images#view'
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
20
48
|
export class TypedRefSchema<
|
|
21
49
|
const TValidator extends TypedObjectValidator = TypedObjectValidator,
|
|
22
50
|
> extends Schema<
|
|
@@ -54,6 +82,31 @@ export class TypedRefSchema<
|
|
|
54
82
|
}
|
|
55
83
|
}
|
|
56
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Creates a reference to a typed object schema for use in typed unions.
|
|
87
|
+
*
|
|
88
|
+
* Unlike regular `ref()`, this requires the referenced schema to have a
|
|
89
|
+
* `$type` property, and validates that the input's `$type` matches.
|
|
90
|
+
*
|
|
91
|
+
* @param get - Function that returns the typed object validator
|
|
92
|
+
* @returns A new {@link TypedRefSchema} instance
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* // Reference to image embed view
|
|
97
|
+
* const imageRef = l.typedRef(() => imageViewSchema)
|
|
98
|
+
*
|
|
99
|
+
* // Use in a typed union
|
|
100
|
+
* const embedUnion = l.typedUnion([
|
|
101
|
+
* l.typedRef(() => imageViewSchema),
|
|
102
|
+
* l.typedRef(() => videoViewSchema),
|
|
103
|
+
* l.typedRef(() => externalViewSchema),
|
|
104
|
+
* ], true) // closed union
|
|
105
|
+
*
|
|
106
|
+
* // The $type is accessible on the ref
|
|
107
|
+
* console.log(imageRef.$type) // 'app.bsky.embed.images#view'
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
57
110
|
/*@__NO_SIDE_EFFECTS__*/
|
|
58
111
|
export function typedRef<const TValidator extends TypedObjectValidator>(
|
|
59
112
|
get: TypedRefGetter<TValidator>,
|
|
@@ -7,10 +7,32 @@ import {
|
|
|
7
7
|
ValidationContext,
|
|
8
8
|
} from '../core.js'
|
|
9
9
|
import { lazyProperty } from '../util/lazy-property.js'
|
|
10
|
+
import { TypedObjectSchema } from './typed-object.js'
|
|
10
11
|
import { TypedRefSchema } from './typed-ref.js'
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Schema for Lexicon typed unions (unions discriminated by $type).
|
|
15
|
+
*
|
|
16
|
+
* Typed unions are collections of typed objects identified by their `$type`
|
|
17
|
+
* field. Can be "open" (accept unknown types) or "closed" (only accept
|
|
18
|
+
* known types).
|
|
19
|
+
*
|
|
20
|
+
* @template TValidators - Tuple of {@link TypedRefSchema} or {@link TypedObjectSchema} instances
|
|
21
|
+
* @template TClosed - Whether the union is closed (rejects unknown $types)
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const embedUnion = new TypedUnionSchema([
|
|
26
|
+
* l.typedRef(() => imageSchema),
|
|
27
|
+
* l.typedRef(() => videoSchema),
|
|
28
|
+
* ], true) // closed - only accepts images and videos
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
12
31
|
export class TypedUnionSchema<
|
|
13
|
-
const TValidators extends readonly
|
|
32
|
+
const TValidators extends readonly (
|
|
33
|
+
| TypedRefSchema
|
|
34
|
+
| TypedObjectSchema
|
|
35
|
+
)[] = [],
|
|
14
36
|
const TClosed extends boolean = boolean,
|
|
15
37
|
> extends Schema<
|
|
16
38
|
TClosed extends true
|
|
@@ -26,7 +48,8 @@ export class TypedUnionSchema<
|
|
|
26
48
|
) {
|
|
27
49
|
// @NOTE In order to avoid circular dependency issues, we don't access the
|
|
28
50
|
// refs's schema (or $type) here. Instead, we access them lazily when first
|
|
29
|
-
// needed.
|
|
51
|
+
// needed. The biggest issue with this strategy is that we can't throw
|
|
52
|
+
// early if the refs contain multiple refs with the same $type.
|
|
30
53
|
|
|
31
54
|
super()
|
|
32
55
|
}
|
|
@@ -66,6 +89,36 @@ export class TypedUnionSchema<
|
|
|
66
89
|
}
|
|
67
90
|
}
|
|
68
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Creates a typed union schema for Lexicon unions.
|
|
94
|
+
*
|
|
95
|
+
* Typed unions discriminate variants by their `$type` field. Can be open
|
|
96
|
+
* (accepts unknown types, useful for extensibility) or closed (strict).
|
|
97
|
+
*
|
|
98
|
+
* @param refs - Array of typed refs for the union variants
|
|
99
|
+
* @param closed - Whether to reject unknown $type values
|
|
100
|
+
* @returns A new {@link TypedUnionSchema} instance
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* // Closed union - only accepts known types
|
|
105
|
+
* const embedSchema = l.typedUnion([
|
|
106
|
+
* l.typedRef(() => imageViewSchema),
|
|
107
|
+
* l.typedRef(() => videoViewSchema),
|
|
108
|
+
* l.typedRef(() => externalViewSchema),
|
|
109
|
+
* ], true)
|
|
110
|
+
*
|
|
111
|
+
* // Open union - accepts unknown types for forward compatibility
|
|
112
|
+
* const feedItemSchema = l.typedUnion([
|
|
113
|
+
* l.typedRef(() => postSchema),
|
|
114
|
+
* l.typedRef(() => repostSchema),
|
|
115
|
+
* ], false) // unknown types pass through
|
|
116
|
+
*
|
|
117
|
+
* // Get all known $types
|
|
118
|
+
* console.log(embedSchema.$types)
|
|
119
|
+
* // ['app.bsky.embed.images#view', 'app.bsky.embed.video#view', ...]
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
69
122
|
/*@__NO_SIDE_EFFECTS__*/
|
|
70
123
|
export function typedUnion<
|
|
71
124
|
const R extends readonly TypedRefSchema[],
|
package/src/schema/union.ts
CHANGED
|
@@ -8,8 +8,29 @@ import {
|
|
|
8
8
|
Validator,
|
|
9
9
|
} from '../core.js'
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Type representing a non-empty tuple of validators for union schemas.
|
|
13
|
+
*
|
|
14
|
+
* Requires at least one validator in the tuple.
|
|
15
|
+
*/
|
|
11
16
|
export type UnionSchemaValidators = readonly [Validator, ...Validator[]]
|
|
12
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Schema for validating values that match one of several possible schemas.
|
|
20
|
+
*
|
|
21
|
+
* Tries each validator in order until one succeeds. If all validators fail,
|
|
22
|
+
* returns a combined error from all attempts.
|
|
23
|
+
*
|
|
24
|
+
* @template TValidators - Tuple type of the validators in the union
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const schema = new UnionSchema([l.string(), l.integer()])
|
|
29
|
+
* schema.validate('hello') // success
|
|
30
|
+
* schema.validate(42) // success
|
|
31
|
+
* schema.validate(true) // fails
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
13
34
|
export class UnionSchema<
|
|
14
35
|
const TValidators extends UnionSchemaValidators = any,
|
|
15
36
|
> extends Schema<
|
|
@@ -34,6 +55,30 @@ export class UnionSchema<
|
|
|
34
55
|
}
|
|
35
56
|
}
|
|
36
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Creates a union schema that accepts values matching any of the provided schemas.
|
|
60
|
+
*
|
|
61
|
+
* Validators are tried in order. Use `discriminatedUnion()` for better
|
|
62
|
+
* performance when discriminating on a known property.
|
|
63
|
+
*
|
|
64
|
+
* @param validators - Non-empty array of validators to try
|
|
65
|
+
* @returns A new {@link UnionSchema} instance
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* // String or number
|
|
70
|
+
* const stringOrNumber = l.union([l.string(), l.integer()])
|
|
71
|
+
*
|
|
72
|
+
* // Nullable value
|
|
73
|
+
* const nullableString = l.union([l.string(), l.null()])
|
|
74
|
+
*
|
|
75
|
+
* // Multiple object types
|
|
76
|
+
* const mediaSchema = l.union([
|
|
77
|
+
* l.object({ type: l.literal('image'), url: l.string() }),
|
|
78
|
+
* l.object({ type: l.literal('video'), url: l.string(), duration: l.integer() }),
|
|
79
|
+
* ])
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
37
82
|
/*@__NO_SIDE_EFFECTS__*/
|
|
38
83
|
export function union<const TValidators extends UnionSchemaValidators>(
|
|
39
84
|
validators: TValidators,
|