@atproto/lex-schema 0.0.4 → 0.0.5
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 +37 -0
- package/dist/core/$type.d.ts +7 -0
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js.map +1 -1
- package/dist/core/result.d.ts +7 -6
- package/dist/core/result.d.ts.map +1 -1
- package/dist/core/result.js +9 -8
- package/dist/core/result.js.map +1 -1
- package/dist/core/string-format.d.ts +37 -26
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js +66 -59
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/types.d.ts +3 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/external.d.ts +7 -6
- package/dist/external.d.ts.map +1 -1
- package/dist/external.js +1 -0
- package/dist/external.js.map +1 -1
- package/dist/helpers.d.ts +36 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +3 -0
- package/dist/helpers.js.map +1 -0
- package/dist/schema/blob.d.ts +1 -0
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +32 -18
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/custom.js +1 -1
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/integer.js +1 -1
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/params.d.ts +0 -1
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +17 -15
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +28 -0
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/procedure.d.ts +3 -6
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +1 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +3 -5
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +1 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +13 -12
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/refine.js +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/subscription.d.ts +4 -7
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/typed-object.d.ts +7 -6
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +1 -4
- package/dist/schema/union.js.map +1 -1
- package/dist/util/assertion-util.d.ts +8 -0
- package/dist/util/assertion-util.d.ts.map +1 -0
- package/dist/util/assertion-util.js +31 -0
- package/dist/util/assertion-util.js.map +1 -0
- package/dist/validation/schema.d.ts +21 -2
- package/dist/validation/schema.d.ts.map +1 -1
- package/dist/validation/schema.js +25 -2
- package/dist/validation/schema.js.map +1 -1
- package/dist/validation/validation-error.d.ts.map +1 -1
- package/dist/validation/validation-error.js +3 -3
- package/dist/validation/validation-error.js.map +1 -1
- package/dist/validation/validation-issue.js +10 -2
- package/dist/validation/validation-issue.js.map +1 -1
- package/dist/validation/validator.d.ts +4 -3
- package/dist/validation/validator.d.ts.map +1 -1
- package/dist/validation/validator.js +13 -10
- package/dist/validation/validator.js.map +1 -1
- package/package.json +2 -2
- package/src/core/$type.ts +4 -0
- package/src/core/result.ts +9 -8
- package/src/core/string-format.ts +88 -68
- package/src/core/types.ts +4 -0
- package/src/external.ts +9 -8
- package/src/helpers.test.ts +486 -0
- package/src/helpers.ts +61 -0
- package/src/schema/blob.test.ts +2 -4
- package/src/schema/blob.ts +31 -23
- package/src/schema/custom.test.ts +5 -5
- package/src/schema/custom.ts +1 -1
- package/src/schema/integer.ts +1 -1
- package/src/schema/params.ts +0 -7
- package/src/schema/payload.ts +67 -34
- package/src/schema/permission-set.test.ts +36 -36
- package/src/schema/procedure.test.ts +1 -62
- package/src/schema/procedure.ts +8 -20
- package/src/schema/query.test.ts +22 -69
- package/src/schema/query.ts +7 -14
- package/src/schema/record.ts +8 -4
- package/src/schema/refine.ts +1 -1
- package/src/schema/subscription.test.ts +30 -93
- package/src/schema/subscription.ts +11 -24
- package/src/schema/typed-object.ts +7 -3
- package/src/schema/union.ts +1 -4
- package/src/util/assertion-util.ts +40 -0
- package/src/validation/schema.ts +29 -4
- package/src/validation/validation-error.ts +4 -4
- package/src/validation/validation-issue.ts +12 -2
- package/src/validation/validator.ts +16 -12
- package/tsconfig.tests.json +1 -1
|
@@ -1,33 +1,20 @@
|
|
|
1
1
|
import { NsidString } from '../core.js'
|
|
2
|
-
import { Infer } from '../validation.js'
|
|
3
|
-
import { ObjectSchema } from './object.js'
|
|
2
|
+
import { Infer, Schema } from '../validation.js'
|
|
4
3
|
import { ParamsSchema } from './params.js'
|
|
5
|
-
import { RefSchema } from './ref.js'
|
|
6
|
-
import { TypedUnionSchema } from './typed-union.js'
|
|
7
4
|
|
|
8
|
-
export type InferSubscriptionParameters<S extends Subscription> =
|
|
9
|
-
S
|
|
10
|
-
|
|
11
|
-
: never
|
|
5
|
+
export type InferSubscriptionParameters<S extends Subscription> = Infer<
|
|
6
|
+
S['parameters']
|
|
7
|
+
>
|
|
12
8
|
|
|
13
|
-
export type InferSubscriptionMessage<S extends Subscription> =
|
|
14
|
-
S
|
|
15
|
-
|
|
16
|
-
any,
|
|
17
|
-
infer M extends RefSchema | TypedUnionSchema | ObjectSchema
|
|
18
|
-
>
|
|
19
|
-
? Infer<M>
|
|
20
|
-
: unknown
|
|
9
|
+
export type InferSubscriptionMessage<S extends Subscription> = Infer<
|
|
10
|
+
S['message']
|
|
11
|
+
>
|
|
21
12
|
|
|
22
13
|
export class Subscription<
|
|
23
|
-
TNsid extends NsidString =
|
|
24
|
-
TParameters extends ParamsSchema =
|
|
25
|
-
TMessage extends
|
|
26
|
-
|
|
27
|
-
| RefSchema
|
|
28
|
-
| TypedUnionSchema
|
|
29
|
-
| ObjectSchema = any,
|
|
30
|
-
TErrors extends undefined | readonly string[] = any,
|
|
14
|
+
TNsid extends NsidString = NsidString,
|
|
15
|
+
TParameters extends ParamsSchema = ParamsSchema,
|
|
16
|
+
TMessage extends Schema = Schema,
|
|
17
|
+
TErrors extends undefined | readonly string[] = undefined | readonly string[],
|
|
31
18
|
> {
|
|
32
19
|
readonly type = 'subscription' as const
|
|
33
20
|
|
|
@@ -7,15 +7,16 @@ import {
|
|
|
7
7
|
Validator,
|
|
8
8
|
ValidatorContext,
|
|
9
9
|
} from '../validation.js'
|
|
10
|
+
import { TypedObject } from './typed-union.js'
|
|
10
11
|
|
|
11
12
|
export type TypedObjectSchemaOutput<
|
|
12
13
|
T extends $Type,
|
|
13
|
-
S extends Validator<{ [
|
|
14
|
+
S extends Validator<{ [k: string]: unknown }>,
|
|
14
15
|
> = Simplify<Infer<S> & { $type?: T }>
|
|
15
16
|
|
|
16
17
|
export class TypedObjectSchema<
|
|
17
18
|
const T extends $Type = any,
|
|
18
|
-
const S extends Validator<{ [
|
|
19
|
+
const S extends Validator<{ [k: string]: unknown }> = any,
|
|
19
20
|
> extends Schema<TypedObjectSchemaOutput<T, S>> {
|
|
20
21
|
constructor(
|
|
21
22
|
readonly $type: T,
|
|
@@ -26,7 +27,10 @@ export class TypedObjectSchema<
|
|
|
26
27
|
|
|
27
28
|
isTypeOf<X extends Record<string, unknown>>(
|
|
28
29
|
value: X,
|
|
29
|
-
): value is
|
|
30
|
+
): value is Exclude<
|
|
31
|
+
X extends { $type?: T } ? X : X & { $type?: T },
|
|
32
|
+
TypedObject
|
|
33
|
+
> {
|
|
30
34
|
return value.$type === undefined || value.$type === this.$type
|
|
31
35
|
}
|
|
32
36
|
|
package/src/schema/union.ts
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type AssertFn<T> = <I extends string>(input: I) => asserts input is I & T
|
|
2
|
+
export type CastFn<T> = <I extends string>(input: I) => I & T
|
|
3
|
+
export type CheckFn<T> = <I extends string>(input: I) => input is I & T
|
|
4
|
+
|
|
5
|
+
export function createAssertFunction<T extends string>(
|
|
6
|
+
checkFn: (input: string) => input is T,
|
|
7
|
+
errorMessage?: string,
|
|
8
|
+
): AssertFn<T>
|
|
9
|
+
export function createAssertFunction<T extends string>(
|
|
10
|
+
checkFn: (input: string) => boolean,
|
|
11
|
+
errorMessage?: string,
|
|
12
|
+
): AssertFn<T>
|
|
13
|
+
export function createAssertFunction<T extends string>(
|
|
14
|
+
checkFn: (input: string) => boolean,
|
|
15
|
+
errorMessage = 'Invalid format',
|
|
16
|
+
): AssertFn<T> {
|
|
17
|
+
return (input: string) => {
|
|
18
|
+
if (!checkFn(input)) throw new Error(errorMessage)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
23
|
+
export function createCastFunction<T>(assertFn: AssertFn<T>): CastFn<T> {
|
|
24
|
+
return <I extends string>(input: I) => {
|
|
25
|
+
assertFn(input)
|
|
26
|
+
return input as I & T
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/*@__NO_SIDE_EFFECTS__ */
|
|
31
|
+
export function createCheckFunction<T>(assertFn: AssertFn<T>): CheckFn<T> {
|
|
32
|
+
return <I extends string>(input: I): input is I & T => {
|
|
33
|
+
try {
|
|
34
|
+
assertFn(input)
|
|
35
|
+
return true
|
|
36
|
+
} catch {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/validation/schema.ts
CHANGED
|
@@ -5,17 +5,42 @@ import {
|
|
|
5
5
|
ValidatorContext,
|
|
6
6
|
} from './validator.js'
|
|
7
7
|
|
|
8
|
-
export abstract class Schema<Output> implements Validator<Output> {
|
|
9
|
-
declare readonly ['
|
|
8
|
+
export abstract class Schema<Output = any> implements Validator<Output> {
|
|
9
|
+
declare readonly ['__lex']: { output: Output }
|
|
10
10
|
|
|
11
11
|
abstract validateInContext(
|
|
12
12
|
input: unknown,
|
|
13
13
|
ctx: ValidatorContext,
|
|
14
14
|
): ValidationResult<Output>
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @note use {@link check}() instead of {@link assert}() if you encounter a
|
|
18
|
+
* `ts(2775)` error and you are not able to fully type the validator. This
|
|
19
|
+
* will typically arise in generic contexts, where the narrowed type is not
|
|
20
|
+
* needed.
|
|
21
|
+
*/
|
|
16
22
|
assert(input: unknown): asserts input is Output {
|
|
17
23
|
const result = this.safeParse(input, { allowTransform: false })
|
|
18
|
-
if (!result.success) throw result.
|
|
24
|
+
if (!result.success) throw result.reason
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Alias for {@link assert}(). Most useful in generic contexts where the
|
|
29
|
+
* validator is not exactly typed, allowing to avoid "_Assertions require
|
|
30
|
+
* every name in the call target to be declared with an explicit type
|
|
31
|
+
* annotation. ts(2775)_" errors.
|
|
32
|
+
*/
|
|
33
|
+
check(input: unknown): void {
|
|
34
|
+
this.assert(input)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Casts the input (by validating it) to the output type if it matches the
|
|
39
|
+
* schema, otherwise throws. This is the same as calling {@link parse}() with
|
|
40
|
+
* `allowTransform: false`.
|
|
41
|
+
*/
|
|
42
|
+
cast<I>(input: I): I & Output {
|
|
43
|
+
return this.parse(input, { allowTransform: false })
|
|
19
44
|
}
|
|
20
45
|
|
|
21
46
|
matches(input: unknown): input is Output {
|
|
@@ -34,7 +59,7 @@ export abstract class Schema<Output> implements Validator<Output> {
|
|
|
34
59
|
parse(input: unknown, options?: ValidationOptions): Output
|
|
35
60
|
parse(input: unknown, options?: ValidationOptions): Output {
|
|
36
61
|
const result = this.safeParse(input, options)
|
|
37
|
-
if (!result.success) throw result.
|
|
62
|
+
if (!result.success) throw result.reason
|
|
38
63
|
return result.value
|
|
39
64
|
}
|
|
40
65
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ResultFailure,
|
|
1
|
+
import { ResultFailure, failureReason } from '../core.js'
|
|
2
2
|
import { arrayAgg } from '../util/array-agg.js'
|
|
3
3
|
import {
|
|
4
4
|
Issue,
|
|
@@ -20,17 +20,17 @@ export class ValidationError extends Error {
|
|
|
20
20
|
static fromFailures(
|
|
21
21
|
failures: ResultFailure<ValidationError>[],
|
|
22
22
|
): ValidationError {
|
|
23
|
-
if (failures.length === 1) return failures[0]
|
|
23
|
+
if (failures.length === 1) return failureReason(failures[0])
|
|
24
24
|
const issues = failures.flatMap(extractFailureIssues)
|
|
25
25
|
return new ValidationError(issues, {
|
|
26
26
|
// Keep the original errors as the cause chain
|
|
27
|
-
cause: failures.map(
|
|
27
|
+
cause: failures.map(failureReason),
|
|
28
28
|
})
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function extractFailureIssues(result: ResultFailure<ValidationError>) {
|
|
33
|
-
return result.
|
|
33
|
+
return result.reason.issues
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function aggregateIssues(issues: Issue[]): Issue[] {
|
|
@@ -184,8 +184,18 @@ function stringifyType(value: unknown): string {
|
|
|
184
184
|
if (value instanceof Set) return 'set'
|
|
185
185
|
return 'object'
|
|
186
186
|
case 'number':
|
|
187
|
-
if (Number.isInteger(value))
|
|
188
|
-
|
|
187
|
+
if (Number.isInteger(value) && Number.isSafeInteger(value)) {
|
|
188
|
+
return 'integer'
|
|
189
|
+
}
|
|
190
|
+
if (Number.isNaN(value)) {
|
|
191
|
+
return 'NaN'
|
|
192
|
+
}
|
|
193
|
+
if (value === Infinity) {
|
|
194
|
+
return 'Infinity'
|
|
195
|
+
}
|
|
196
|
+
if (value === -Infinity) {
|
|
197
|
+
return '-Infinity'
|
|
198
|
+
}
|
|
189
199
|
return 'float'
|
|
190
200
|
default:
|
|
191
201
|
return typeof value
|
|
@@ -25,7 +25,7 @@ export type ValidationOptions = {
|
|
|
25
25
|
allowTransform?: boolean
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export type Infer<T extends Validator> = T['
|
|
28
|
+
export type Infer<T extends Validator> = T['__lex']['output']
|
|
29
29
|
|
|
30
30
|
export interface Validator<Output = any> {
|
|
31
31
|
/**
|
|
@@ -34,7 +34,7 @@ export interface Validator<Output = any> {
|
|
|
34
34
|
*
|
|
35
35
|
* @deprecated **INTERNAL API, DO NOT USE**.
|
|
36
36
|
*/
|
|
37
|
-
readonly ['
|
|
37
|
+
readonly ['__lex']: { output: Output }
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* @internal **INTERNAL API**: use {@link ValidatorContext.validate} instead
|
|
@@ -162,24 +162,28 @@ export class ValidatorContext {
|
|
|
162
162
|
return success(value)
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
failure(
|
|
166
|
-
return failure(
|
|
165
|
+
failure(reason: ValidationError): ValidationFailure {
|
|
166
|
+
return failure(reason)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
issue(issue: Issue) {
|
|
170
|
+
return this.failure(new ValidationError([...this.issues, issue]))
|
|
167
171
|
}
|
|
168
172
|
|
|
169
173
|
issueInvalidValue(input: unknown, values: readonly unknown[]) {
|
|
170
|
-
return this.
|
|
174
|
+
return this.issue(new IssueInvalidValue(this.path, input, values))
|
|
171
175
|
}
|
|
172
176
|
|
|
173
177
|
issueInvalidType(input: unknown, expected: string) {
|
|
174
|
-
return this.
|
|
178
|
+
return this.issue(new IssueInvalidType(this.path, input, [expected]))
|
|
175
179
|
}
|
|
176
180
|
|
|
177
181
|
issueRequiredKey(input: object, key: PropertyKey) {
|
|
178
|
-
return this.
|
|
182
|
+
return this.issue(new IssueRequiredKey(this.path, input, key))
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
issueInvalidFormat(input: unknown, format: string, msg?: string) {
|
|
182
|
-
return this.
|
|
186
|
+
return this.issue(new IssueInvalidFormat(this.path, input, format, msg))
|
|
183
187
|
}
|
|
184
188
|
|
|
185
189
|
issueTooBig(
|
|
@@ -188,7 +192,7 @@ export class ValidatorContext {
|
|
|
188
192
|
max: number,
|
|
189
193
|
actual: number,
|
|
190
194
|
) {
|
|
191
|
-
return this.
|
|
195
|
+
return this.issue(new IssueTooBig(this.path, input, max, type, actual))
|
|
192
196
|
}
|
|
193
197
|
|
|
194
198
|
issueTooSmall(
|
|
@@ -197,7 +201,7 @@ export class ValidatorContext {
|
|
|
197
201
|
min: number,
|
|
198
202
|
actual: number,
|
|
199
203
|
) {
|
|
200
|
-
return this.
|
|
204
|
+
return this.issue(new IssueTooSmall(this.path, input, min, type, actual))
|
|
201
205
|
}
|
|
202
206
|
|
|
203
207
|
issueInvalidPropertyValue<I>(
|
|
@@ -207,7 +211,7 @@ export class ValidatorContext {
|
|
|
207
211
|
) {
|
|
208
212
|
const value = input[property]
|
|
209
213
|
const path = this.concatPath(property)
|
|
210
|
-
return this.
|
|
214
|
+
return this.issue(new IssueInvalidValue(path, value, values))
|
|
211
215
|
}
|
|
212
216
|
|
|
213
217
|
issueInvalidPropertyType<I>(
|
|
@@ -217,6 +221,6 @@ export class ValidatorContext {
|
|
|
217
221
|
) {
|
|
218
222
|
const value = input[property]
|
|
219
223
|
const path = this.concatPath(property)
|
|
220
|
-
return this.
|
|
224
|
+
return this.issue(new IssueInvalidType(path, value, [expected]))
|
|
221
225
|
}
|
|
222
226
|
}
|