@yuhere/js-jsonrpc2 2.1.13 → 2.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -9
- package/SKILL.md +95 -4
- package/dist/cli/demo-methods.js +77 -0
- package/dist/core/llm-tools.js +41 -42
- package/dist/schema/json/index.d.ts +1 -1
- package/dist/schema/json/primitives.d.ts +56 -72
- package/dist/schema/json/primitives.js +86 -79
- package/dist/schema/z/protocol.d.ts +1 -1
- package/htdoc/assets/{index-CqI7vRAS.js → index-WpdfQ_L9.js} +166 -94
- package/htdoc/assets/index-WpdfQ_L9.js.map +1 -0
- package/htdoc/index.html +1 -1
- package/package.json +1 -1
- package/htdoc/assets/index-CqI7vRAS.js.map +0 -1
|
@@ -9,20 +9,37 @@ export type JSONValue = JSONPrimitive | JSONValue[] | {
|
|
|
9
9
|
[key: string]: JSONValue;
|
|
10
10
|
};
|
|
11
11
|
export type SchemaKind = string;
|
|
12
|
-
export interface
|
|
12
|
+
export interface BaseSchemaDescription {
|
|
13
13
|
kind: SchemaKind;
|
|
14
14
|
description?: string;
|
|
15
|
-
/**
|
|
16
|
-
* 该值是否允许为 null。
|
|
17
|
-
*
|
|
18
|
-
* 唯一真相来源:由 `NullableSchema` 及其子类通过 `.nullable(bool)` 设置,
|
|
19
|
-
* `UnknownSchema` / `NullSchema` 不使用该字段(它们本身就接受 null)。
|
|
20
|
-
* `kind` 永远表示值的真实形状,不会被 nullability 污染。
|
|
21
|
-
*/
|
|
22
15
|
nullable?: boolean;
|
|
16
|
+
validate?: boolean;
|
|
23
17
|
constraints?: Record<string, unknown>;
|
|
24
|
-
children?: Record<string, unknown>;
|
|
25
18
|
}
|
|
19
|
+
export interface LeafSchemaDescription extends BaseSchemaDescription {
|
|
20
|
+
kind: "string" | "number" | "boolean" | "literal" | "enum" | "unknown" | "null";
|
|
21
|
+
}
|
|
22
|
+
export interface ObjectSchemaDescription extends BaseSchemaDescription {
|
|
23
|
+
kind: "object";
|
|
24
|
+
properties: Record<string, SchemaDescription>;
|
|
25
|
+
}
|
|
26
|
+
export interface ArraySchemaDescription extends BaseSchemaDescription {
|
|
27
|
+
kind: "array";
|
|
28
|
+
element: SchemaDescription;
|
|
29
|
+
}
|
|
30
|
+
export interface RecordSchemaDescription extends BaseSchemaDescription {
|
|
31
|
+
kind: "record";
|
|
32
|
+
value: SchemaDescription;
|
|
33
|
+
}
|
|
34
|
+
export interface UnionSchemaDescription extends BaseSchemaDescription {
|
|
35
|
+
kind: "union";
|
|
36
|
+
options: SchemaDescription[];
|
|
37
|
+
}
|
|
38
|
+
export interface TupleSchemaDescription extends BaseSchemaDescription {
|
|
39
|
+
kind: "tuple";
|
|
40
|
+
elements: SchemaDescription[];
|
|
41
|
+
}
|
|
42
|
+
export type SchemaDescription = LeafSchemaDescription | ObjectSchemaDescription | ArraySchemaDescription | RecordSchemaDescription | UnionSchemaDescription | TupleSchemaDescription;
|
|
26
43
|
export declare class SchemaValidationError extends Error {
|
|
27
44
|
readonly path: string[];
|
|
28
45
|
constructor(message: string, path?: string[]);
|
|
@@ -33,17 +50,19 @@ export declare class SchemaValidationError extends Error {
|
|
|
33
50
|
* 只负责 description 与描述输出;nullability 由 `NullableSchema` 提供。
|
|
34
51
|
* `UnknownSchema` / `NullSchema` 直接继承本类——它们天然接受 null,
|
|
35
52
|
* 不需要 `.nullable()`。
|
|
53
|
+
*
|
|
54
|
+
* 运行时校验可通过 `.validate(false)` 关闭:关闭后 `parse` / `safeParse`
|
|
55
|
+
* 直接返回输入,不再调用 `_parse`(仍可用于签名描述)。
|
|
36
56
|
*/
|
|
37
57
|
export declare abstract class Schema<T> {
|
|
38
58
|
abstract readonly kind: SchemaKind;
|
|
39
|
-
private description
|
|
40
|
-
|
|
59
|
+
private description;
|
|
60
|
+
private _validateEnabled;
|
|
41
61
|
describe(description: string): this;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*/
|
|
62
|
+
validate(value?: boolean): this;
|
|
63
|
+
isValidateEnabled(): boolean;
|
|
45
64
|
protected cloneWith(updates: Record<string, unknown>): this;
|
|
46
|
-
getDescription(): string
|
|
65
|
+
getDescription(): string;
|
|
47
66
|
parse(input: unknown): T;
|
|
48
67
|
safeParse(input: unknown): {
|
|
49
68
|
success: true;
|
|
@@ -84,7 +103,7 @@ export declare class StringSchema<K extends string = "string"> extends NullableS
|
|
|
84
103
|
min(value: number): this;
|
|
85
104
|
max(value: number): this;
|
|
86
105
|
protected _parseValue(input: unknown, path: string[]): string;
|
|
87
|
-
protected _describe():
|
|
106
|
+
protected _describe(): LeafSchemaDescription;
|
|
88
107
|
protected validateBound(value: number): void;
|
|
89
108
|
}
|
|
90
109
|
export declare class NumberSchema extends NullableSchema<number> {
|
|
@@ -95,28 +114,22 @@ export declare class NumberSchema extends NullableSchema<number> {
|
|
|
95
114
|
min(value: number): this;
|
|
96
115
|
max(value: number): this;
|
|
97
116
|
protected _parseValue(input: unknown, path: string[]): number;
|
|
98
|
-
protected _describe():
|
|
117
|
+
protected _describe(): LeafSchemaDescription;
|
|
99
118
|
protected validateBound(value: number): void;
|
|
100
119
|
}
|
|
101
120
|
export declare class BooleanSchema extends NullableSchema<boolean> {
|
|
102
121
|
readonly kind: "boolean";
|
|
103
122
|
constructor();
|
|
104
123
|
protected _parseValue(input: unknown, path: string[]): boolean;
|
|
105
|
-
protected _describe():
|
|
124
|
+
protected _describe(): LeafSchemaDescription;
|
|
106
125
|
}
|
|
107
|
-
/**
|
|
108
|
-
* 字面量只支持 string / number / boolean。
|
|
109
|
-
*
|
|
110
|
-
* null 由 `s.null()` 表达;需要「该字面量或 null」时,对字面量调用
|
|
111
|
-
* `.nullable()`。`literal(null)` 会抛 TypeError。
|
|
112
|
-
*/
|
|
113
126
|
export type LiteralValue = string | number | boolean;
|
|
114
127
|
export declare class LiteralSchema<const T extends LiteralValue> extends NullableSchema<T> {
|
|
115
128
|
private readonly expected;
|
|
116
129
|
readonly kind: "literal";
|
|
117
130
|
constructor(expected: T);
|
|
118
131
|
protected _parseValue(input: unknown, path: string[]): T;
|
|
119
|
-
protected _describe():
|
|
132
|
+
protected _describe(): LeafSchemaDescription;
|
|
120
133
|
}
|
|
121
134
|
export declare class ArraySchema<T> extends NullableSchema<T[]> {
|
|
122
135
|
private readonly itemSchema;
|
|
@@ -127,28 +140,25 @@ export declare class ArraySchema<T> extends NullableSchema<T[]> {
|
|
|
127
140
|
min(value: number): this;
|
|
128
141
|
max(value: number): this;
|
|
129
142
|
protected _parseValue(input: unknown, path: string[]): T[];
|
|
130
|
-
protected _describe():
|
|
143
|
+
protected _describe(): ArraySchemaDescription;
|
|
131
144
|
protected validateBound(value: number): void;
|
|
132
145
|
}
|
|
133
146
|
export type ObjectShape = Record<string, Schema<unknown>>;
|
|
134
147
|
type SchemaValue<S> = S extends Schema<infer T> ? T : never;
|
|
135
|
-
type
|
|
136
|
-
[K in keyof S]: SchemaValue<S[K]>;
|
|
137
|
-
};
|
|
138
|
-
type OptionalShapeOutput<S extends ObjectShape> = {
|
|
148
|
+
export type ObjectOutput<S extends ObjectShape> = {
|
|
139
149
|
[K in keyof S]?: SchemaValue<S[K]>;
|
|
140
150
|
};
|
|
141
|
-
export declare class ObjectSchema<S extends ObjectShape
|
|
151
|
+
export declare class ObjectSchema<S extends ObjectShape> extends NullableSchema<ObjectOutput<S>> {
|
|
142
152
|
private readonly shape;
|
|
143
153
|
readonly kind: "object";
|
|
144
|
-
private
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
strict():
|
|
150
|
-
protected _parseValue(input: unknown, path: string[]):
|
|
151
|
-
protected _describe():
|
|
154
|
+
private optionalProps;
|
|
155
|
+
private allowUnknownProps;
|
|
156
|
+
constructor(shape: S);
|
|
157
|
+
optionalProperties(keys: string[]): this;
|
|
158
|
+
allowUnknownProperties(value?: boolean): this;
|
|
159
|
+
strict(value?: boolean): this;
|
|
160
|
+
protected _parseValue(input: unknown, path: string[]): ObjectOutput<S>;
|
|
161
|
+
protected _describe(): ObjectSchemaDescription;
|
|
152
162
|
}
|
|
153
163
|
export declare class RecordSchema<T> extends NullableSchema<Record<string, T>> {
|
|
154
164
|
private readonly valueSchema;
|
|
@@ -159,68 +169,42 @@ export declare class RecordSchema<T> extends NullableSchema<Record<string, T>> {
|
|
|
159
169
|
min(value: number): this;
|
|
160
170
|
max(value: number): this;
|
|
161
171
|
protected _parseValue(input: unknown, path: string[]): Record<string, T>;
|
|
162
|
-
protected _describe():
|
|
172
|
+
protected _describe(): RecordSchemaDescription;
|
|
163
173
|
protected validateBound(value: number): void;
|
|
164
174
|
}
|
|
165
|
-
/**
|
|
166
|
-
* 联合。
|
|
167
|
-
*
|
|
168
|
-
* 传入的 member schemas 会被 clone 并 `nullable(false)`——因为「某个
|
|
169
|
-
* 分支允许 null」这件事在 union 层面没有意义:null 是否允许应通过
|
|
170
|
-
* `union(...).nullable()` 统一表达。
|
|
171
|
-
*/
|
|
172
175
|
export declare class UnionSchema<const S extends readonly [Schema<unknown>, ...Schema<unknown>[]]> extends NullableSchema<SchemaValue<S[number]>> {
|
|
173
176
|
readonly kind: "union";
|
|
174
177
|
private readonly options;
|
|
175
178
|
constructor(schemas: S);
|
|
176
179
|
protected _parseValue(input: unknown, path: string[]): SchemaValue<S[number]>;
|
|
177
|
-
protected _describe():
|
|
180
|
+
protected _describe(): UnionSchemaDescription;
|
|
178
181
|
}
|
|
179
182
|
export declare class TupleSchema<const S extends readonly [Schema<unknown>, ...Schema<unknown>[]]> extends NullableSchema<SchemaValue<S[number]>[]> {
|
|
180
183
|
private readonly schemas;
|
|
181
184
|
readonly kind: "tuple";
|
|
182
185
|
constructor(schemas: S);
|
|
183
186
|
protected _parseValue(input: unknown, path: string[]): SchemaValue<S[number]>[];
|
|
184
|
-
protected _describe():
|
|
187
|
+
protected _describe(): TupleSchemaDescription;
|
|
185
188
|
}
|
|
186
|
-
/**
|
|
187
|
-
* 字符串枚举。
|
|
188
|
-
*
|
|
189
|
-
* 继承 `NullableSchema`,因此可以 `s.enum([...]).nullable()`;
|
|
190
|
-
* 它不包含嵌套 schema,所以不需要像 union 那样处理成员 nullability。
|
|
191
|
-
*/
|
|
192
189
|
export declare class EnumSchema<const T extends readonly [string, ...string[]]> extends NullableSchema<T[number]> {
|
|
193
190
|
private readonly values;
|
|
194
191
|
readonly kind: "enum";
|
|
195
192
|
private readonly allowedValues;
|
|
196
193
|
constructor(values: T);
|
|
197
194
|
protected _parseValue(input: unknown, path: string[]): T[number];
|
|
198
|
-
protected _describe():
|
|
195
|
+
protected _describe(): LeafSchemaDescription;
|
|
199
196
|
}
|
|
200
|
-
/**
|
|
201
|
-
* 校验任意 JSON 值。
|
|
202
|
-
*
|
|
203
|
-
* 不允许 undefined、非有限数字、循环引用等非 JSON 数据。
|
|
204
|
-
* null 本身就在接受范围内,因此不继承 `NullableSchema`,也不提供
|
|
205
|
-
* `.nullable()`——那是冗余的。
|
|
206
|
-
*/
|
|
207
197
|
export declare class UnknownSchema extends Schema<JSONValue> {
|
|
208
198
|
readonly kind: "unknown";
|
|
209
199
|
constructor();
|
|
210
200
|
protected _parse(input: unknown, path: string[]): JSONValue;
|
|
211
|
-
protected _describe():
|
|
201
|
+
protected _describe(): LeafSchemaDescription;
|
|
212
202
|
}
|
|
213
|
-
/**
|
|
214
|
-
* 精确的 null 值。
|
|
215
|
-
*
|
|
216
|
-
* 与 `UnknownSchema` 一样天然表达 null,不需要 `.nullable()`。
|
|
217
|
-
* 想表达「某类型或 null」用 `.nullable()`;想表达「就是 null」用 `s.null()`。
|
|
218
|
-
*/
|
|
219
203
|
export declare class NullSchema extends Schema<null> {
|
|
220
204
|
readonly kind: "null";
|
|
221
205
|
constructor();
|
|
222
206
|
protected _parse(input: unknown, path: string[]): null;
|
|
223
|
-
protected _describe():
|
|
207
|
+
protected _describe(): LeafSchemaDescription;
|
|
224
208
|
}
|
|
225
209
|
export type Infer<T extends Schema<unknown>> = T extends Schema<infer U> ? U : never;
|
|
226
210
|
export declare const primitives: {
|
|
@@ -229,7 +213,7 @@ export declare const primitives: {
|
|
|
229
213
|
boolean: () => BooleanSchema;
|
|
230
214
|
literal: <const T extends LiteralValue>(value: T) => LiteralSchema<T>;
|
|
231
215
|
array: <T>(item: Schema<T>) => ArraySchema<T>;
|
|
232
|
-
object: <S extends ObjectShape>(shape: S) => ObjectSchema<S
|
|
216
|
+
object: <S extends ObjectShape>(shape: S) => ObjectSchema<S>;
|
|
233
217
|
record: <T>(value: Schema<T>) => RecordSchema<T>;
|
|
234
218
|
union: <const S extends readonly [Schema<unknown>, ...Schema<unknown>[]]>(schemas: S) => UnionSchema<S>;
|
|
235
219
|
tuple: <const S extends readonly [Schema<unknown>, ...Schema<unknown>[]]>(schemas: S) => TupleSchema<S>;
|
|
@@ -12,18 +12,22 @@ export class SchemaValidationError extends Error {
|
|
|
12
12
|
* 只负责 description 与描述输出;nullability 由 `NullableSchema` 提供。
|
|
13
13
|
* `UnknownSchema` / `NullSchema` 直接继承本类——它们天然接受 null,
|
|
14
14
|
* 不需要 `.nullable()`。
|
|
15
|
+
*
|
|
16
|
+
* 运行时校验可通过 `.validate(false)` 关闭:关闭后 `parse` / `safeParse`
|
|
17
|
+
* 直接返回输入,不再调用 `_parse`(仍可用于签名描述)。
|
|
15
18
|
*/
|
|
16
19
|
export class Schema {
|
|
17
|
-
description;
|
|
18
|
-
|
|
19
|
-
this.description = description;
|
|
20
|
-
}
|
|
20
|
+
description = "";
|
|
21
|
+
_validateEnabled = true;
|
|
21
22
|
describe(description) {
|
|
22
23
|
return this.cloneWith({ description });
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
validate(value = true) {
|
|
26
|
+
return this.cloneWith({ _validateEnabled: value });
|
|
27
|
+
}
|
|
28
|
+
isValidateEnabled() {
|
|
29
|
+
return this._validateEnabled;
|
|
30
|
+
}
|
|
27
31
|
cloneWith(updates) {
|
|
28
32
|
const clone = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
|
|
29
33
|
return Object.assign(clone, updates);
|
|
@@ -32,6 +36,9 @@ export class Schema {
|
|
|
32
36
|
return this.description;
|
|
33
37
|
}
|
|
34
38
|
parse(input) {
|
|
39
|
+
if (!this._validateEnabled) {
|
|
40
|
+
return input;
|
|
41
|
+
}
|
|
35
42
|
return this._parse(input, []);
|
|
36
43
|
}
|
|
37
44
|
safeParse(input) {
|
|
@@ -51,6 +58,9 @@ export class Schema {
|
|
|
51
58
|
if (description !== undefined) {
|
|
52
59
|
result.description = description;
|
|
53
60
|
}
|
|
61
|
+
if (!this._validateEnabled) {
|
|
62
|
+
result.validate = false;
|
|
63
|
+
}
|
|
54
64
|
return result;
|
|
55
65
|
}
|
|
56
66
|
fail(message, path) {
|
|
@@ -118,12 +128,13 @@ export class StringSchema extends NullableSchema {
|
|
|
118
128
|
return input;
|
|
119
129
|
}
|
|
120
130
|
_describe() {
|
|
131
|
+
const constraints = buildConstraints({
|
|
132
|
+
min: this.minimum,
|
|
133
|
+
max: this.maximum,
|
|
134
|
+
});
|
|
121
135
|
return {
|
|
122
136
|
kind: this.kind,
|
|
123
|
-
constraints: {
|
|
124
|
-
...(this.minimum !== undefined ? { min: this.minimum } : {}),
|
|
125
|
-
...(this.maximum !== undefined ? { max: this.maximum } : {}),
|
|
126
|
-
},
|
|
137
|
+
...(constraints ? { constraints } : {}),
|
|
127
138
|
};
|
|
128
139
|
}
|
|
129
140
|
validateBound(value) {
|
|
@@ -160,12 +171,13 @@ export class NumberSchema extends NullableSchema {
|
|
|
160
171
|
return input;
|
|
161
172
|
}
|
|
162
173
|
_describe() {
|
|
174
|
+
const constraints = buildConstraints({
|
|
175
|
+
min: this.minimum,
|
|
176
|
+
max: this.maximum,
|
|
177
|
+
});
|
|
163
178
|
return {
|
|
164
179
|
kind: this.kind,
|
|
165
|
-
constraints: {
|
|
166
|
-
...(this.minimum !== undefined ? { min: this.minimum } : {}),
|
|
167
|
-
...(this.maximum !== undefined ? { max: this.maximum } : {}),
|
|
168
|
-
},
|
|
180
|
+
...(constraints ? { constraints } : {}),
|
|
169
181
|
};
|
|
170
182
|
}
|
|
171
183
|
validateBound(value) {
|
|
@@ -259,13 +271,14 @@ export class ArraySchema extends NullableSchema {
|
|
|
259
271
|
});
|
|
260
272
|
}
|
|
261
273
|
_describe() {
|
|
274
|
+
const constraints = buildConstraints({
|
|
275
|
+
min: this.minimum,
|
|
276
|
+
max: this.maximum,
|
|
277
|
+
});
|
|
262
278
|
return {
|
|
263
279
|
kind: this.kind,
|
|
264
|
-
constraints: {
|
|
265
|
-
|
|
266
|
-
...(this.maximum !== undefined ? { max: this.maximum } : {}),
|
|
267
|
-
},
|
|
268
|
-
children: { items: this.itemSchema.toJSON() },
|
|
280
|
+
...(constraints ? { constraints } : {}),
|
|
281
|
+
element: this.itemSchema.toJSON(),
|
|
269
282
|
};
|
|
270
283
|
}
|
|
271
284
|
validateBound(value) {
|
|
@@ -277,17 +290,29 @@ export class ArraySchema extends NullableSchema {
|
|
|
277
290
|
export class ObjectSchema extends NullableSchema {
|
|
278
291
|
shape;
|
|
279
292
|
kind = "object";
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
293
|
+
optionalProps;
|
|
294
|
+
allowUnknownProps = true;
|
|
295
|
+
constructor(shape) {
|
|
296
|
+
super();
|
|
283
297
|
this.shape = shape;
|
|
284
|
-
this.
|
|
298
|
+
this.optionalProps = Object.keys(shape);
|
|
285
299
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
300
|
+
optionalProperties(keys) {
|
|
301
|
+
for (const key of keys) {
|
|
302
|
+
if (!Object.prototype.hasOwnProperty.call(this.shape, key)) {
|
|
303
|
+
throw new TypeError(`optionalProperties: unknown property "${key}"`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return this.cloneWith({ optionalProps: [...new Set(keys)] });
|
|
307
|
+
}
|
|
308
|
+
allowUnknownProperties(value = true) {
|
|
309
|
+
return this.cloneWith({ allowUnknownProps: value });
|
|
310
|
+
}
|
|
311
|
+
strict(value = true) {
|
|
312
|
+
if (value) {
|
|
313
|
+
return this.optionalProperties([]).allowUnknownProperties(false);
|
|
314
|
+
}
|
|
315
|
+
return this.optionalProperties(Object.keys(this.shape)).allowUnknownProperties(true);
|
|
291
316
|
}
|
|
292
317
|
_parseValue(input, path) {
|
|
293
318
|
if (input === null ||
|
|
@@ -297,16 +322,17 @@ export class ObjectSchema extends NullableSchema {
|
|
|
297
322
|
}
|
|
298
323
|
const source = input;
|
|
299
324
|
const output = {};
|
|
300
|
-
|
|
325
|
+
const optional = new Set(this.optionalProps);
|
|
326
|
+
if (!this.allowUnknownProps) {
|
|
301
327
|
for (const key of Object.keys(source)) {
|
|
302
|
-
if (!(
|
|
328
|
+
if (!Object.prototype.hasOwnProperty.call(this.shape, key)) {
|
|
303
329
|
this.fail(`Unknown property "${key}"`, [...path, key]);
|
|
304
330
|
}
|
|
305
331
|
}
|
|
306
332
|
}
|
|
307
333
|
for (const [key, schema] of Object.entries(this.shape)) {
|
|
308
334
|
if (!Object.prototype.hasOwnProperty.call(source, key)) {
|
|
309
|
-
if (
|
|
335
|
+
if (!optional.has(key)) {
|
|
310
336
|
this.fail(`Missing required property "${key}"`, [...path, key]);
|
|
311
337
|
}
|
|
312
338
|
continue;
|
|
@@ -324,10 +350,9 @@ export class ObjectSchema extends NullableSchema {
|
|
|
324
350
|
throw error;
|
|
325
351
|
}
|
|
326
352
|
}
|
|
327
|
-
|
|
328
|
-
if (!this.isStrict) {
|
|
353
|
+
if (this.allowUnknownProps) {
|
|
329
354
|
for (const [key, value] of Object.entries(source)) {
|
|
330
|
-
if (!(
|
|
355
|
+
if (!Object.prototype.hasOwnProperty.call(this.shape, key)) {
|
|
331
356
|
assertJSONValue(value, [...path, key]);
|
|
332
357
|
output[key] = value;
|
|
333
358
|
}
|
|
@@ -338,13 +363,14 @@ export class ObjectSchema extends NullableSchema {
|
|
|
338
363
|
_describe() {
|
|
339
364
|
return {
|
|
340
365
|
kind: this.kind,
|
|
341
|
-
constraints: {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
key,
|
|
345
|
-
schema.toJSON(),
|
|
346
|
-
])),
|
|
366
|
+
constraints: {
|
|
367
|
+
optionalProps: [...this.optionalProps],
|
|
368
|
+
allowUnknownProps: this.allowUnknownProps,
|
|
347
369
|
},
|
|
370
|
+
properties: Object.fromEntries(Object.entries(this.shape).map(([key, schema]) => [
|
|
371
|
+
key,
|
|
372
|
+
schema.toJSON(),
|
|
373
|
+
])),
|
|
348
374
|
};
|
|
349
375
|
}
|
|
350
376
|
}
|
|
@@ -396,13 +422,14 @@ export class RecordSchema extends NullableSchema {
|
|
|
396
422
|
return output;
|
|
397
423
|
}
|
|
398
424
|
_describe() {
|
|
425
|
+
const constraints = buildConstraints({
|
|
426
|
+
min: this.minimum,
|
|
427
|
+
max: this.maximum,
|
|
428
|
+
});
|
|
399
429
|
return {
|
|
400
430
|
kind: this.kind,
|
|
401
|
-
constraints: {
|
|
402
|
-
|
|
403
|
-
...(this.maximum !== undefined ? { max: this.maximum } : {}),
|
|
404
|
-
},
|
|
405
|
-
children: { values: this.valueSchema.toJSON() },
|
|
431
|
+
...(constraints ? { constraints } : {}),
|
|
432
|
+
value: this.valueSchema.toJSON(),
|
|
406
433
|
};
|
|
407
434
|
}
|
|
408
435
|
validateBound(value) {
|
|
@@ -411,13 +438,6 @@ export class RecordSchema extends NullableSchema {
|
|
|
411
438
|
}
|
|
412
439
|
}
|
|
413
440
|
}
|
|
414
|
-
/**
|
|
415
|
-
* 联合。
|
|
416
|
-
*
|
|
417
|
-
* 传入的 member schemas 会被 clone 并 `nullable(false)`——因为「某个
|
|
418
|
-
* 分支允许 null」这件事在 union 层面没有意义:null 是否允许应通过
|
|
419
|
-
* `union(...).nullable()` 统一表达。
|
|
420
|
-
*/
|
|
421
441
|
export class UnionSchema extends NullableSchema {
|
|
422
442
|
kind = "union";
|
|
423
443
|
options;
|
|
@@ -452,9 +472,7 @@ export class UnionSchema extends NullableSchema {
|
|
|
452
472
|
_describe() {
|
|
453
473
|
return {
|
|
454
474
|
kind: this.kind,
|
|
455
|
-
|
|
456
|
-
options: this.options.map((schema) => schema.toJSON()),
|
|
457
|
-
},
|
|
475
|
+
options: this.options.map((schema) => schema.toJSON()),
|
|
458
476
|
};
|
|
459
477
|
}
|
|
460
478
|
}
|
|
@@ -483,7 +501,10 @@ export class TupleSchema extends NullableSchema {
|
|
|
483
501
|
}
|
|
484
502
|
catch (error) {
|
|
485
503
|
if (error instanceof SchemaValidationError) {
|
|
486
|
-
|
|
504
|
+
throw new SchemaValidationError(error.message, [
|
|
505
|
+
String(i),
|
|
506
|
+
...error.path,
|
|
507
|
+
]);
|
|
487
508
|
}
|
|
488
509
|
throw error;
|
|
489
510
|
}
|
|
@@ -493,18 +514,10 @@ export class TupleSchema extends NullableSchema {
|
|
|
493
514
|
_describe() {
|
|
494
515
|
return {
|
|
495
516
|
kind: this.kind,
|
|
496
|
-
|
|
497
|
-
items: this.schemas.map((schema) => schema.toJSON()),
|
|
498
|
-
},
|
|
517
|
+
elements: this.schemas.map((schema) => schema.toJSON()),
|
|
499
518
|
};
|
|
500
519
|
}
|
|
501
520
|
}
|
|
502
|
-
/**
|
|
503
|
-
* 字符串枚举。
|
|
504
|
-
*
|
|
505
|
-
* 继承 `NullableSchema`,因此可以 `s.enum([...]).nullable()`;
|
|
506
|
-
* 它不包含嵌套 schema,所以不需要像 union 那样处理成员 nullability。
|
|
507
|
-
*/
|
|
508
521
|
export class EnumSchema extends NullableSchema {
|
|
509
522
|
values;
|
|
510
523
|
kind = "enum";
|
|
@@ -527,13 +540,6 @@ export class EnumSchema extends NullableSchema {
|
|
|
527
540
|
};
|
|
528
541
|
}
|
|
529
542
|
}
|
|
530
|
-
/**
|
|
531
|
-
* 校验任意 JSON 值。
|
|
532
|
-
*
|
|
533
|
-
* 不允许 undefined、非有限数字、循环引用等非 JSON 数据。
|
|
534
|
-
* null 本身就在接受范围内,因此不继承 `NullableSchema`,也不提供
|
|
535
|
-
* `.nullable()`——那是冗余的。
|
|
536
|
-
*/
|
|
537
543
|
export class UnknownSchema extends Schema {
|
|
538
544
|
kind = "unknown";
|
|
539
545
|
constructor() {
|
|
@@ -547,12 +553,6 @@ export class UnknownSchema extends Schema {
|
|
|
547
553
|
return { kind: this.kind };
|
|
548
554
|
}
|
|
549
555
|
}
|
|
550
|
-
/**
|
|
551
|
-
* 精确的 null 值。
|
|
552
|
-
*
|
|
553
|
-
* 与 `UnknownSchema` 一样天然表达 null,不需要 `.nullable()`。
|
|
554
|
-
* 想表达「某类型或 null」用 `.nullable()`;想表达「就是 null」用 `s.null()`。
|
|
555
|
-
*/
|
|
556
556
|
export class NullSchema extends Schema {
|
|
557
557
|
kind = "null";
|
|
558
558
|
constructor() {
|
|
@@ -568,6 +568,13 @@ export class NullSchema extends Schema {
|
|
|
568
568
|
return { kind: this.kind };
|
|
569
569
|
}
|
|
570
570
|
}
|
|
571
|
+
function buildConstraints(values) {
|
|
572
|
+
const entries = Object.entries(values).filter(([, value]) => value !== undefined);
|
|
573
|
+
if (entries.length === 0) {
|
|
574
|
+
return undefined;
|
|
575
|
+
}
|
|
576
|
+
return Object.fromEntries(entries);
|
|
577
|
+
}
|
|
571
578
|
function assertJSONValue(value, path, ancestors = new Set()) {
|
|
572
579
|
if (value === null ||
|
|
573
580
|
typeof value === "string" ||
|
|
@@ -5,4 +5,4 @@ export declare const RPCRequestSchema: import("../json/index.js").ObjectSchema<{
|
|
|
5
5
|
method: import("../json/index.js").StringSchema<"string">;
|
|
6
6
|
params: import("../json/index.js").ArraySchema<import("../json/index.js").JSONValue>;
|
|
7
7
|
id: import("../json/index.js").UnionSchema<readonly [import("../json/index.js").StringSchema<"string">, import("../json/index.js").NumberSchema]>;
|
|
8
|
-
}
|
|
8
|
+
}>;
|