@atproto/lex-schema 0.1.5 → 0.1.6
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 +14 -0
- package/dist/core/$type.d.ts +2 -2
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js.map +1 -1
- package/dist/core/record-key.d.ts +1 -1
- package/dist/core/record-key.d.ts.map +1 -1
- package/dist/core/record-key.js.map +1 -1
- package/dist/core/schema.d.ts +3 -2
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +1 -1
- package/dist/core/schema.js.map +1 -1
- package/dist/core/standard-schema.d.ts +2 -2
- package/dist/core/standard-schema.d.ts.map +1 -1
- package/dist/core/standard-schema.js.map +1 -1
- package/dist/core/string-format.d.ts +2 -2
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/validation-error.d.ts +1 -1
- package/dist/core/validation-error.d.ts.map +1 -1
- package/dist/core/validation-error.js +1 -1
- package/dist/core/validation-error.js.map +1 -1
- package/dist/core/validator.d.ts +1 -1
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +1 -1
- package/dist/core/validator.js.map +1 -1
- package/dist/helpers.d.ts +2 -2
- 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 +1 -1
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +1 -1
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +1 -1
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +2 -2
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.js +1 -1
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.js +1 -1
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +1 -1
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +3 -3
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.js +1 -1
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +1 -1
- package/dist/schema/dict.d.ts.map +1 -1
- package/dist/schema/dict.js +1 -1
- package/dist/schema/dict.js.map +1 -1
- package/dist/schema/discriminated-union.d.ts +1 -1
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +2 -1
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.js +1 -1
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.js +1 -1
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +1 -1
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +3 -1
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/lex-map.d.ts +1 -1
- package/dist/schema/lex-map.d.ts.map +1 -1
- package/dist/schema/lex-map.js +1 -1
- package/dist/schema/lex-map.js.map +1 -1
- package/dist/schema/lex-value.d.ts +1 -1
- package/dist/schema/lex-value.d.ts.map +1 -1
- package/dist/schema/lex-value.js +1 -1
- package/dist/schema/lex-value.js.map +1 -1
- package/dist/schema/literal.js +1 -1
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.js +1 -1
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.js +1 -1
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +1 -1
- package/dist/schema/nullable.d.ts.map +1 -1
- package/dist/schema/nullable.js +1 -1
- package/dist/schema/nullable.js.map +1 -1
- package/dist/schema/object.d.ts +2 -1
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +1 -1
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +2 -1
- package/dist/schema/optional.d.ts.map +1 -1
- package/dist/schema/optional.js +2 -1
- package/dist/schema/optional.js.map +1 -1
- package/dist/schema/params.d.ts +1 -1
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +1 -1
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +3 -2
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +2 -1
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +1 -1
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +1 -0
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +1 -1
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +1 -1
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +2 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +1 -1
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +2 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +2 -2
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +1 -1
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +1 -1
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +1 -1
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +2 -2
- package/dist/schema/refine.d.ts.map +1 -1
- package/dist/schema/refine.js +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/regexp.js +1 -1
- package/dist/schema/regexp.js.map +1 -1
- package/dist/schema/string.d.ts +2 -2
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +1 -1
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +3 -2
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js +2 -0
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +1 -1
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +1 -1
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +2 -2
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +1 -1
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +1 -1
- package/dist/schema/typed-ref.d.ts.map +1 -1
- package/dist/schema/typed-ref.js +1 -1
- package/dist/schema/typed-ref.js.map +1 -1
- package/dist/schema/typed-union.d.ts +1 -1
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +3 -1
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +1 -1
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +1 -1
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown.js +1 -1
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema/with-default.d.ts +1 -1
- package/dist/schema/with-default.d.ts.map +1 -1
- package/dist/schema/with-default.js +1 -1
- package/dist/schema/with-default.js.map +1 -1
- package/package.json +6 -10
- package/src/core/$type.test.ts +0 -24
- package/src/core/$type.ts +0 -199
- package/src/core/record-key.ts +0 -85
- package/src/core/result.ts +0 -15
- package/src/core/schema.ts +0 -412
- package/src/core/standard-schema.test.ts +0 -124
- package/src/core/standard-schema.ts +0 -31
- package/src/core/string-format.ts +0 -411
- package/src/core/types.ts +0 -120
- package/src/core/validation-error.ts +0 -134
- package/src/core/validation-issue.ts +0 -340
- package/src/core/validator.ts +0 -636
- package/src/core.ts +0 -9
- package/src/external.ts +0 -3
- package/src/helpers.test.ts +0 -694
- package/src/helpers.ts +0 -222
- package/src/index.ts +0 -3
- package/src/schema/array.test.ts +0 -251
- package/src/schema/array.ts +0 -126
- package/src/schema/blob.test.ts +0 -733
- package/src/schema/blob.ts +0 -150
- package/src/schema/boolean.test.ts +0 -118
- package/src/schema/boolean.ts +0 -46
- package/src/schema/bytes.test.ts +0 -227
- package/src/schema/bytes.ts +0 -81
- package/src/schema/cid.test.ts +0 -125
- package/src/schema/cid.ts +0 -69
- package/src/schema/custom.test.ts +0 -414
- package/src/schema/custom.ts +0 -106
- package/src/schema/dict.test.ts +0 -181
- package/src/schema/dict.ts +0 -122
- package/src/schema/discriminated-union.test.ts +0 -676
- package/src/schema/discriminated-union.ts +0 -196
- package/src/schema/enum.test.ts +0 -398
- package/src/schema/enum.ts +0 -77
- package/src/schema/integer.test.ts +0 -314
- package/src/schema/integer.ts +0 -86
- package/src/schema/intersection.test.ts +0 -33
- package/src/schema/intersection.ts +0 -113
- package/src/schema/lex-map.test.ts +0 -593
- package/src/schema/lex-map.ts +0 -63
- package/src/schema/lex-value.test.ts +0 -81
- package/src/schema/lex-value.ts +0 -86
- package/src/schema/literal.test.ts +0 -533
- package/src/schema/literal.ts +0 -70
- package/src/schema/never.test.ts +0 -175
- package/src/schema/never.ts +0 -56
- package/src/schema/null.test.ts +0 -80
- package/src/schema/null.ts +0 -49
- package/src/schema/nullable.test.ts +0 -470
- package/src/schema/nullable.ts +0 -74
- package/src/schema/object.test.ts +0 -69
- package/src/schema/object.ts +0 -136
- package/src/schema/optional.test.ts +0 -479
- package/src/schema/optional.ts +0 -92
- package/src/schema/params.test.ts +0 -1118
- package/src/schema/params.ts +0 -371
- package/src/schema/payload.test.ts +0 -340
- package/src/schema/payload.ts +0 -204
- package/src/schema/permission-set.test.ts +0 -613
- package/src/schema/permission-set.ts +0 -86
- package/src/schema/permission.test.ts +0 -537
- package/src/schema/permission.ts +0 -63
- package/src/schema/procedure.test.ts +0 -324
- package/src/schema/procedure.ts +0 -98
- package/src/schema/query.test.ts +0 -348
- package/src/schema/query.ts +0 -86
- package/src/schema/record.test.ts +0 -812
- package/src/schema/record.ts +0 -217
- package/src/schema/ref.test.ts +0 -349
- package/src/schema/ref.ts +0 -103
- package/src/schema/refine.test.ts +0 -579
- package/src/schema/refine.ts +0 -153
- package/src/schema/regexp.test.ts +0 -577
- package/src/schema/regexp.ts +0 -82
- package/src/schema/string.test.ts +0 -773
- package/src/schema/string.ts +0 -229
- package/src/schema/subscription.test.ts +0 -499
- package/src/schema/subscription.ts +0 -108
- package/src/schema/token.test.ts +0 -152
- package/src/schema/token.ts +0 -103
- package/src/schema/typed-object.test.ts +0 -745
- package/src/schema/typed-object.ts +0 -181
- package/src/schema/typed-ref.test.ts +0 -796
- package/src/schema/typed-ref.ts +0 -126
- package/src/schema/typed-union.test.ts +0 -355
- package/src/schema/typed-union.ts +0 -130
- package/src/schema/union.test.ts +0 -191
- package/src/schema/union.ts +0 -89
- package/src/schema/unknown.test.ts +0 -313
- package/src/schema/unknown.ts +0 -47
- package/src/schema/with-default.ts +0 -81
- package/src/schema.ts +0 -43
- package/src/util/array-agg.test.ts +0 -42
- package/src/util/array-agg.ts +0 -44
- package/src/util/assertion-util.ts +0 -1
- package/src/util/if-any.ts +0 -3
- package/src/util/lazy-property.ts +0 -14
- package/src/util/memoize.ts +0 -37
- package/tsconfig.build.json +0 -12
- package/tsconfig.json +0 -7
- package/tsconfig.tests.json +0 -8
package/src/helpers.ts
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { LexErrorData } from '@atproto/lex-data'
|
|
2
|
-
import {
|
|
3
|
-
AtIdentifierString,
|
|
4
|
-
InferOutput,
|
|
5
|
-
NsidString,
|
|
6
|
-
RecordKeyValue,
|
|
7
|
-
Restricted,
|
|
8
|
-
Schema,
|
|
9
|
-
assertAtIdentifierString,
|
|
10
|
-
assertStringFormat,
|
|
11
|
-
} from './core.js'
|
|
12
|
-
import {
|
|
13
|
-
InferPayload,
|
|
14
|
-
InferPayloadBody,
|
|
15
|
-
InferPayloadEncoding,
|
|
16
|
-
InferRecordKey,
|
|
17
|
-
Procedure,
|
|
18
|
-
Query,
|
|
19
|
-
RecordSchema,
|
|
20
|
-
Subscription,
|
|
21
|
-
object,
|
|
22
|
-
optional,
|
|
23
|
-
regexp,
|
|
24
|
-
string,
|
|
25
|
-
} from './schema.js'
|
|
26
|
-
|
|
27
|
-
export type Main<T> = T | { main: T }
|
|
28
|
-
|
|
29
|
-
export function getMain<T extends object>(ns: Main<T>): T {
|
|
30
|
-
return 'main' in ns ? ns.main : ns
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Every XRPC implementation should translate `application/json` and `text/*`
|
|
35
|
-
* payloads into their native equivalent ({@link LexValue} or string). Binary
|
|
36
|
-
* data payloads, however, can be represented differently depending on the
|
|
37
|
-
* environment and use case (e.g. `Uint8Array`, `Blob`, `Buffer`,
|
|
38
|
-
* `ReadableStream`, etc.). This type is a placeholder to represent binary data
|
|
39
|
-
* when not explicitly provided.
|
|
40
|
-
*/
|
|
41
|
-
export type BinaryData = Restricted<'Binary data'>
|
|
42
|
-
|
|
43
|
-
export type InferMethodParams<
|
|
44
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
45
|
-
> =
|
|
46
|
-
M extends Procedure<any, infer TParams, any, any, any>
|
|
47
|
-
? InferOutput<TParams>
|
|
48
|
-
: M extends Query<any, infer TParams, any, any>
|
|
49
|
-
? InferOutput<TParams>
|
|
50
|
-
: M extends Subscription<any, infer TParams, any, any>
|
|
51
|
-
? InferOutput<TParams>
|
|
52
|
-
: never
|
|
53
|
-
|
|
54
|
-
export type InferMethodInput<
|
|
55
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
56
|
-
B = BinaryData,
|
|
57
|
-
> =
|
|
58
|
-
M extends Procedure<any, any, infer TInput, any, any>
|
|
59
|
-
? InferPayload<TInput, B>
|
|
60
|
-
: undefined
|
|
61
|
-
|
|
62
|
-
export type InferMethodInputBody<
|
|
63
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
64
|
-
B = BinaryData,
|
|
65
|
-
> =
|
|
66
|
-
M extends Procedure<any, any, infer TInput, any, any>
|
|
67
|
-
? InferPayloadBody<TInput, B>
|
|
68
|
-
: undefined
|
|
69
|
-
|
|
70
|
-
export type InferMethodInputEncoding<
|
|
71
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
72
|
-
> =
|
|
73
|
-
M extends Procedure<any, any, infer TInput, any, any>
|
|
74
|
-
? InferPayloadEncoding<TInput>
|
|
75
|
-
: undefined
|
|
76
|
-
|
|
77
|
-
export type InferMethodOutput<
|
|
78
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
79
|
-
B = BinaryData,
|
|
80
|
-
> =
|
|
81
|
-
M extends Procedure<any, any, any, infer TOutput, any>
|
|
82
|
-
? InferPayload<TOutput, B>
|
|
83
|
-
: M extends Query<any, any, infer TOutput, any>
|
|
84
|
-
? InferPayload<TOutput, B>
|
|
85
|
-
: undefined
|
|
86
|
-
|
|
87
|
-
export type InferMethodOutputBody<
|
|
88
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
89
|
-
B = BinaryData,
|
|
90
|
-
> =
|
|
91
|
-
M extends Procedure<any, any, any, infer TOutput, any>
|
|
92
|
-
? InferPayloadBody<TOutput, B>
|
|
93
|
-
: M extends Query<any, any, infer TOutput, any>
|
|
94
|
-
? InferPayloadBody<TOutput, B>
|
|
95
|
-
: undefined
|
|
96
|
-
|
|
97
|
-
export type InferMethodOutputEncoding<
|
|
98
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
99
|
-
> =
|
|
100
|
-
M extends Procedure<any, any, any, infer TOutput, any>
|
|
101
|
-
? InferPayloadEncoding<TOutput>
|
|
102
|
-
: M extends Query<any, any, infer TOutput, any>
|
|
103
|
-
? InferPayloadEncoding<TOutput>
|
|
104
|
-
: undefined
|
|
105
|
-
|
|
106
|
-
export type InferMethodMessage<
|
|
107
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
108
|
-
> =
|
|
109
|
-
M extends Subscription<any, any, infer TMessage, any>
|
|
110
|
-
? InferOutput<TMessage>
|
|
111
|
-
: undefined
|
|
112
|
-
|
|
113
|
-
export type InferMethodError<
|
|
114
|
-
//
|
|
115
|
-
M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
|
|
116
|
-
> = M extends { errors: readonly (infer E extends string)[] } ? E : never
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* @see {@link https://atproto.com/specs/xrpc#error-responses}
|
|
120
|
-
*/
|
|
121
|
-
export const lexErrorDataSchema = object({
|
|
122
|
-
// type name of the error (generic ASCII constant, no whitespace)
|
|
123
|
-
error: regexp(/^[\w_-]+$/, 'Expected ASCII constant with no whitespace'),
|
|
124
|
-
// description of the error, appropriate for display to humans
|
|
125
|
-
message: optional(string()),
|
|
126
|
-
}) satisfies Schema<LexErrorData>
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Helper function to construct AT Protocol URIs with compile-time & runtime
|
|
130
|
-
* validation of their components. This function supports different use cases,
|
|
131
|
-
* including constructing URIs from raw strings or from RecordSchema instances,
|
|
132
|
-
* ensuring that the resulting URI adheres to the expected format.
|
|
133
|
-
*
|
|
134
|
-
* @throws {TypeError} If the arguments do not match the interface
|
|
135
|
-
* @throws {Error} If AT-URI components are invalid
|
|
136
|
-
*
|
|
137
|
-
* @example
|
|
138
|
-
* ```typescript
|
|
139
|
-
* import { atUri } from '@atproto/lex'
|
|
140
|
-
* import { app } from '#/lexicons/index.js'
|
|
141
|
-
*
|
|
142
|
-
* // Constructing a URI from raw components
|
|
143
|
-
* const uri1 = atUri('did:example:123', 'app.bsky.feed.post', 'my-post')
|
|
144
|
-
*
|
|
145
|
-
* // Constructing a URI from a RecordSchema instance
|
|
146
|
-
* const uri2 = atUri('did:example:123', app.bsky.feed.post, 'my-post')
|
|
147
|
-
*
|
|
148
|
-
* // Literal rkey can be omitted
|
|
149
|
-
* const uri3 = atUri('did:example:123', app.bsky.actor.profile) // rkey 'self' is implied
|
|
150
|
-
*
|
|
151
|
-
* // Invalid URIs will throw errors
|
|
152
|
-
* atUri('invalid authority', 'app.bsky.feed.post', 'my-post') // throws
|
|
153
|
-
* atUri('did:example:123', 'invalid collection', 'my-post') // throws
|
|
154
|
-
* atUri('did:example:123', 'app.bsky.feed.post', '..') // throws
|
|
155
|
-
* ```
|
|
156
|
-
*/
|
|
157
|
-
export function atUri<const TAuthority extends AtIdentifierString>(
|
|
158
|
-
authority: TAuthority,
|
|
159
|
-
): `at://${TAuthority}`
|
|
160
|
-
export function atUri<
|
|
161
|
-
const TAuthority extends AtIdentifierString,
|
|
162
|
-
const TCollection extends NsidString,
|
|
163
|
-
const TRecordKey extends RecordKeyValue,
|
|
164
|
-
>(
|
|
165
|
-
authority: TAuthority,
|
|
166
|
-
nsid: TCollection,
|
|
167
|
-
rkey: TRecordKey extends '..' | '.' ? never : TRecordKey,
|
|
168
|
-
): `at://${TAuthority}/${TCollection}/${TRecordKey}`
|
|
169
|
-
export function atUri<
|
|
170
|
-
const TAuthority extends AtIdentifierString,
|
|
171
|
-
const TRecord extends RecordSchema,
|
|
172
|
-
>(
|
|
173
|
-
authority: TAuthority,
|
|
174
|
-
record: TRecord['key'] extends `literal:${string}` ? Main<TRecord> : never,
|
|
175
|
-
): `at://${TAuthority}/${TRecord['$type']}/${InferRecordKey<TRecord>}`
|
|
176
|
-
export function atUri<
|
|
177
|
-
const TAuthority extends AtIdentifierString,
|
|
178
|
-
const TRecord extends RecordSchema,
|
|
179
|
-
const TRecordKey extends InferRecordKey<TRecord>,
|
|
180
|
-
>(
|
|
181
|
-
authority: TAuthority,
|
|
182
|
-
record: Main<TRecord>,
|
|
183
|
-
rkey: TRecordKey extends '..' | '.' ? never : TRecordKey,
|
|
184
|
-
): `at://${TAuthority}/${TRecord['$type']}/${TRecordKey}`
|
|
185
|
-
export function atUri(
|
|
186
|
-
authority: AtIdentifierString,
|
|
187
|
-
record?: string | Main<RecordSchema>,
|
|
188
|
-
rkey?: string,
|
|
189
|
-
) {
|
|
190
|
-
/**
|
|
191
|
-
* @NOTE because we are encoding potentially untrusted input into a URI, we
|
|
192
|
-
* validate the input against the AT Protocol constraints, ensuring that no
|
|
193
|
-
* invalid URIs can be generated.
|
|
194
|
-
*/
|
|
195
|
-
switch (typeof record) {
|
|
196
|
-
case 'undefined': {
|
|
197
|
-
assertAtIdentifierString(authority)
|
|
198
|
-
return `at://${authority}`
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
case 'string': {
|
|
202
|
-
if (!rkey) {
|
|
203
|
-
throw new TypeError('Record key is required when record is a string')
|
|
204
|
-
}
|
|
205
|
-
assertAtIdentifierString(authority)
|
|
206
|
-
assertStringFormat(record, 'nsid')
|
|
207
|
-
assertStringFormat(rkey, 'record-key')
|
|
208
|
-
return `at://${authority}/${record}/${rkey}`
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
default: {
|
|
212
|
-
// @NOTE The use of a schema assumes that the collection ($type) is a
|
|
213
|
-
// valid NSID that can safely be included in the URI without additional
|
|
214
|
-
// checks.
|
|
215
|
-
assertAtIdentifierString(authority)
|
|
216
|
-
const schema = getMain(record)
|
|
217
|
-
// @NOTE parsing will apply defaults, so that literal keys will be
|
|
218
|
-
// properly validated and included in the URI.
|
|
219
|
-
return `at://${authority}/${schema.$type}/${schema.keySchema.parse(rkey)}`
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
package/src/index.ts
DELETED
package/src/schema/array.test.ts
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { array } from './array.js'
|
|
3
|
-
import { integer } from './integer.js'
|
|
4
|
-
import { object } from './object.js'
|
|
5
|
-
import { string } from './string.js'
|
|
6
|
-
|
|
7
|
-
describe('ArraySchema', () => {
|
|
8
|
-
describe('validation', () => {
|
|
9
|
-
it('validates arrays with string items', () => {
|
|
10
|
-
const schema = array(string())
|
|
11
|
-
const result = schema.safeValidate(['hello', 'world'])
|
|
12
|
-
expect(result).toMatchObject({ success: true })
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('validates arrays with integer items', () => {
|
|
16
|
-
const schema = array(integer())
|
|
17
|
-
const result = schema.safeValidate([1, 2, 3])
|
|
18
|
-
expect(result).toMatchObject({ success: true })
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('validates arrays with object items', () => {
|
|
22
|
-
const schema = array(
|
|
23
|
-
object({
|
|
24
|
-
name: string(),
|
|
25
|
-
age: integer(),
|
|
26
|
-
}),
|
|
27
|
-
)
|
|
28
|
-
const result = schema.safeValidate([
|
|
29
|
-
{ name: 'Alice', age: 30 },
|
|
30
|
-
{ name: 'Bob', age: 25 },
|
|
31
|
-
])
|
|
32
|
-
expect(result).toMatchObject({ success: true })
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('validates empty arrays', () => {
|
|
36
|
-
const schema = array(string())
|
|
37
|
-
const result = schema.safeValidate([])
|
|
38
|
-
expect(result).toMatchObject({ success: true })
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('rejects non-array values', () => {
|
|
42
|
-
const schema = array(string())
|
|
43
|
-
const result = schema.safeValidate('not an array')
|
|
44
|
-
expect(result).toMatchObject({ success: false })
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('rejects null values', () => {
|
|
48
|
-
const schema = array(string())
|
|
49
|
-
const result = schema.safeValidate(null)
|
|
50
|
-
expect(result).toMatchObject({ success: false })
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('rejects undefined values', () => {
|
|
54
|
-
const schema = array(string())
|
|
55
|
-
const result = schema.safeValidate(undefined)
|
|
56
|
-
expect(result).toMatchObject({ success: false })
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
it('rejects objects that look like arrays', () => {
|
|
60
|
-
const schema = array(string())
|
|
61
|
-
const result = schema.safeValidate({ 0: 'a', 1: 'b', length: 2 })
|
|
62
|
-
expect(result).toMatchObject({ success: false })
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('rejects arrays with invalid items', () => {
|
|
66
|
-
const schema = array(integer())
|
|
67
|
-
const result = schema.safeValidate([1, 2, 'three'])
|
|
68
|
-
expect(result).toMatchObject({ success: false })
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('rejects arrays with some invalid items', () => {
|
|
72
|
-
const schema = array(string())
|
|
73
|
-
const result = schema.safeValidate(['valid', null, 'also valid'])
|
|
74
|
-
expect(result).toMatchObject({ success: false })
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('rejects single values', () => {
|
|
78
|
-
const schema = array(string())
|
|
79
|
-
const result = schema.safeValidate(3)
|
|
80
|
-
expect(result).toMatchObject({
|
|
81
|
-
success: false,
|
|
82
|
-
reason: expect.objectContaining({
|
|
83
|
-
message: expect.stringContaining(
|
|
84
|
-
'Expected array value type (got 3) at $',
|
|
85
|
-
),
|
|
86
|
-
}),
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
describe('minLength constraint', () => {
|
|
92
|
-
it('validates arrays meeting minLength', () => {
|
|
93
|
-
const schema = array(string(), { minLength: 2 })
|
|
94
|
-
const result = schema.safeParse(['a', 'b'])
|
|
95
|
-
expect(result).toMatchObject({ success: true })
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it('validates arrays exceeding minLength', () => {
|
|
99
|
-
const schema = array(string(), { minLength: 2 })
|
|
100
|
-
const result = schema.safeParse(['a', 'b', 'c'])
|
|
101
|
-
expect(result).toMatchObject({ success: true })
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('rejects arrays below minLength', () => {
|
|
105
|
-
const schema = array(string(), { minLength: 3 })
|
|
106
|
-
const result = schema.safeParse(['a', 'b'])
|
|
107
|
-
expect(result).toMatchObject({ success: false })
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('rejects empty arrays when minLength is set', () => {
|
|
111
|
-
const schema = array(string(), { minLength: 1 })
|
|
112
|
-
const result = schema.safeParse([])
|
|
113
|
-
expect(result).toMatchObject({ success: false })
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it('validates empty arrays when minLength is 0', () => {
|
|
117
|
-
const schema = array(string(), { minLength: 0 })
|
|
118
|
-
const result = schema.safeParse([])
|
|
119
|
-
expect(result).toMatchObject({ success: true })
|
|
120
|
-
})
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
describe('maxLength constraint', () => {
|
|
124
|
-
it('validates arrays meeting maxLength', () => {
|
|
125
|
-
const schema = array(string(), { maxLength: 3 })
|
|
126
|
-
const result = schema.safeParse(['a', 'b', 'c'])
|
|
127
|
-
expect(result).toMatchObject({ success: true })
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it('validates arrays below maxLength', () => {
|
|
131
|
-
const schema = array(string(), { maxLength: 3 })
|
|
132
|
-
const result = schema.safeParse(['a', 'b'])
|
|
133
|
-
expect(result).toMatchObject({ success: true })
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
it('rejects arrays exceeding maxLength', () => {
|
|
137
|
-
const schema = array(string(), { maxLength: 2 })
|
|
138
|
-
const result = schema.safeParse(['a', 'b', 'c'])
|
|
139
|
-
expect(result).toMatchObject({ success: false })
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('validates empty arrays with maxLength', () => {
|
|
143
|
-
const schema = array(string(), { maxLength: 5 })
|
|
144
|
-
const result = schema.safeParse([])
|
|
145
|
-
expect(result).toMatchObject({ success: true })
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
it('rejects empty arrays when maxLength is 0', () => {
|
|
149
|
-
const schema = array(string(), { maxLength: 0 })
|
|
150
|
-
const result = schema.safeParse(['a'])
|
|
151
|
-
expect(result).toMatchObject({ success: false })
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
it('validates empty arrays when maxLength is 0', () => {
|
|
155
|
-
const schema = array(string(), { maxLength: 0 })
|
|
156
|
-
const result = schema.safeParse([])
|
|
157
|
-
expect(result).toMatchObject({ success: true })
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
describe('minLength and maxLength together', () => {
|
|
162
|
-
it('validates arrays within range', () => {
|
|
163
|
-
const schema = array(string(), {
|
|
164
|
-
minLength: 2,
|
|
165
|
-
maxLength: 4,
|
|
166
|
-
})
|
|
167
|
-
const result = schema.safeParse(['a', 'b', 'c'])
|
|
168
|
-
expect(result).toMatchObject({ success: true })
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
it('validates arrays at min boundary', () => {
|
|
172
|
-
const schema = array(string(), {
|
|
173
|
-
minLength: 2,
|
|
174
|
-
maxLength: 4,
|
|
175
|
-
})
|
|
176
|
-
const result = schema.safeParse(['a', 'b'])
|
|
177
|
-
expect(result).toMatchObject({ success: true })
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
it('validates arrays at max boundary', () => {
|
|
181
|
-
const schema = array(string(), {
|
|
182
|
-
minLength: 2,
|
|
183
|
-
maxLength: 4,
|
|
184
|
-
})
|
|
185
|
-
const result = schema.safeParse(['a', 'b', 'c', 'd'])
|
|
186
|
-
expect(result).toMatchObject({ success: true })
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
it('rejects arrays below minLength', () => {
|
|
190
|
-
const schema = array(string(), {
|
|
191
|
-
minLength: 2,
|
|
192
|
-
maxLength: 4,
|
|
193
|
-
})
|
|
194
|
-
const result = schema.safeParse(['a'])
|
|
195
|
-
expect(result).toMatchObject({ success: false })
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
it('rejects arrays above maxLength', () => {
|
|
199
|
-
const schema = array(string(), {
|
|
200
|
-
minLength: 2,
|
|
201
|
-
maxLength: 4,
|
|
202
|
-
})
|
|
203
|
-
const result = schema.safeParse(['a', 'b', 'c', 'd', 'e'])
|
|
204
|
-
expect(result).toMatchObject({ success: false })
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
it('validates single-length range', () => {
|
|
208
|
-
const schema = array(string(), {
|
|
209
|
-
minLength: 3,
|
|
210
|
-
maxLength: 3,
|
|
211
|
-
})
|
|
212
|
-
const result = schema.safeParse(['a', 'b', 'c'])
|
|
213
|
-
expect(result).toMatchObject({ success: true })
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
it('rejects arrays not matching exact length', () => {
|
|
217
|
-
const schema = array(string(), {
|
|
218
|
-
minLength: 3,
|
|
219
|
-
maxLength: 3,
|
|
220
|
-
})
|
|
221
|
-
const result = schema.safeParse(['a', 'b'])
|
|
222
|
-
expect(result).toMatchObject({ success: false })
|
|
223
|
-
})
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
describe('nested arrays', () => {
|
|
227
|
-
it('validates arrays of arrays', () => {
|
|
228
|
-
const schema = array(array(string()))
|
|
229
|
-
const result = schema.safeParse([
|
|
230
|
-
['a', 'b'],
|
|
231
|
-
['c', 'd'],
|
|
232
|
-
])
|
|
233
|
-
expect(result).toMatchObject({ success: true })
|
|
234
|
-
})
|
|
235
|
-
|
|
236
|
-
it('rejects invalid nested arrays', () => {
|
|
237
|
-
const schema = array(array(integer()))
|
|
238
|
-
const result = schema.safeParse([
|
|
239
|
-
[1, 2],
|
|
240
|
-
[3, 'four'],
|
|
241
|
-
])
|
|
242
|
-
expect(result).toMatchObject({ success: false })
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
it('validates deeply nested arrays', () => {
|
|
246
|
-
const schema = array(array(array(integer())))
|
|
247
|
-
const result = schema.safeParse([[[1, 2], [3]], [[4, 5, 6]]])
|
|
248
|
-
expect(result).toMatchObject({ success: true })
|
|
249
|
-
})
|
|
250
|
-
})
|
|
251
|
-
})
|
package/src/schema/array.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
InferInput,
|
|
3
|
-
InferOutput,
|
|
4
|
-
Schema,
|
|
5
|
-
ValidationContext,
|
|
6
|
-
Validator,
|
|
7
|
-
} from '../core.js'
|
|
8
|
-
import { memoizedTransformer } from '../util/memoize.js'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Configuration options for array schema validation.
|
|
12
|
-
*
|
|
13
|
-
* @property minLength - Minimum number of items in the array
|
|
14
|
-
* @property maxLength - Maximum number of items in the array
|
|
15
|
-
*/
|
|
16
|
-
export type ArraySchemaOptions = {
|
|
17
|
-
minLength?: number
|
|
18
|
-
maxLength?: number
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Schema for validating arrays where all items match a given schema.
|
|
23
|
-
*
|
|
24
|
-
* Validates that the input is an array, checks length constraints, and
|
|
25
|
-
* validates each item against the provided item schema.
|
|
26
|
-
*
|
|
27
|
-
* @template TItem - The validator type for array items
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* ```ts
|
|
31
|
-
* const schema = new ArraySchema(l.string(), { maxLength: 10 })
|
|
32
|
-
* const result = schema.validate(['a', 'b', 'c'])
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export class ArraySchema<const TItem extends Validator> extends Schema<
|
|
36
|
-
Array<InferInput<TItem>>,
|
|
37
|
-
Array<InferOutput<TItem>>
|
|
38
|
-
> {
|
|
39
|
-
readonly type = 'array' as const
|
|
40
|
-
|
|
41
|
-
constructor(
|
|
42
|
-
readonly validator: TItem,
|
|
43
|
-
readonly options: ArraySchemaOptions = {},
|
|
44
|
-
) {
|
|
45
|
-
super()
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
validateInContext(input: unknown, ctx: ValidationContext) {
|
|
49
|
-
if (!Array.isArray(input)) {
|
|
50
|
-
return ctx.issueUnexpectedType(input, 'array')
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const { minLength, maxLength } = this.options
|
|
54
|
-
|
|
55
|
-
if (minLength != null && input.length < minLength) {
|
|
56
|
-
return ctx.issueTooSmall(input, 'array', minLength, input.length)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (maxLength != null && input.length > maxLength) {
|
|
60
|
-
return ctx.issueTooBig(input, 'array', maxLength, input.length)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let copy: undefined | unknown[]
|
|
64
|
-
|
|
65
|
-
for (let i = 0; i < input.length; i++) {
|
|
66
|
-
const result = ctx.validateChild(input, i, this.validator)
|
|
67
|
-
if (!result.success) return result
|
|
68
|
-
|
|
69
|
-
if (result.value !== input[i]) {
|
|
70
|
-
if (ctx.options.mode === 'validate') {
|
|
71
|
-
// In "validate" mode, we can't modify the input, so we issue an error
|
|
72
|
-
return ctx.issueInvalidPropertyValue(input, i, [result.value])
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Copy on write (but only if we did not already make a copy)
|
|
76
|
-
copy ??= Array.from(input)
|
|
77
|
-
copy[i] = result.value
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return ctx.success(copy ?? input)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Creates an array schema that validates each item against the provided schema.
|
|
87
|
-
*
|
|
88
|
-
* @param items - Schema to validate each array item against
|
|
89
|
-
* @param options - Optional length constraints
|
|
90
|
-
* @returns A new {@link ArraySchema} instance
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* ```ts
|
|
94
|
-
* // Array of strings
|
|
95
|
-
* const tagsSchema = l.array(l.string())
|
|
96
|
-
*
|
|
97
|
-
* // Array with length constraints
|
|
98
|
-
* const limitedSchema = l.array(l.integer(), { maxLength: 100 })
|
|
99
|
-
*
|
|
100
|
-
* // Array of objects
|
|
101
|
-
* const usersSchema = l.array(l.object({
|
|
102
|
-
* name: l.string(),
|
|
103
|
-
* age: l.integer(),
|
|
104
|
-
* }))
|
|
105
|
-
*
|
|
106
|
-
* // Non-empty array
|
|
107
|
-
* const nonEmptySchema = l.array(l.string(), { minLength: 1 })
|
|
108
|
-
* ```
|
|
109
|
-
*/
|
|
110
|
-
/*@__NO_SIDE_EFFECTS__*/
|
|
111
|
-
function arraySchema<const TValidator extends Validator>(
|
|
112
|
-
items: TValidator,
|
|
113
|
-
options?: ArraySchemaOptions,
|
|
114
|
-
): ArraySchema<TValidator>
|
|
115
|
-
function arraySchema<
|
|
116
|
-
const TValue,
|
|
117
|
-
const TValidator extends Validator<TValue> = Validator<TValue>,
|
|
118
|
-
>(items: TValidator, options?: ArraySchemaOptions): ArraySchema<TValidator>
|
|
119
|
-
function arraySchema<const TValidator extends Validator>(
|
|
120
|
-
items: TValidator,
|
|
121
|
-
options?: ArraySchemaOptions,
|
|
122
|
-
) {
|
|
123
|
-
return new ArraySchema<TValidator>(items, options)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export const array = /*#__PURE__*/ memoizedTransformer(arraySchema)
|