toolcraft-schema 0.0.42 → 0.0.44
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/dist/index.d.ts +19 -9
- package/dist/index.js +36 -9
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ type JsonSchemaEnumValue = EnumValue | null;
|
|
|
16
16
|
type NumberJsonType = "number" | "integer";
|
|
17
17
|
type NonEmptyReadonlyArray<T> = readonly [T, ...T[]];
|
|
18
18
|
type ObjectShape = Record<string, AnySchema>;
|
|
19
|
+
type EmptyOptions = Record<never, never>;
|
|
19
20
|
type SchemaScope = "cli" | "mcp" | "sdk";
|
|
20
21
|
type StringMetadata = {
|
|
21
22
|
format?: string;
|
|
@@ -56,6 +57,13 @@ type SchemaOptions<TDefault> = {
|
|
|
56
57
|
scope?: readonly SchemaScope[];
|
|
57
58
|
global?: boolean;
|
|
58
59
|
};
|
|
60
|
+
type WithNullable<TSchema extends AnySchema, TOptions extends {
|
|
61
|
+
nullable?: boolean;
|
|
62
|
+
}> = TOptions extends {
|
|
63
|
+
readonly nullable: true;
|
|
64
|
+
} ? TSchema & {
|
|
65
|
+
readonly nullable: true;
|
|
66
|
+
} : TSchema;
|
|
59
67
|
export interface SchemaBase<TKind extends SchemaKind, TStatic> {
|
|
60
68
|
readonly kind: TKind;
|
|
61
69
|
readonly description?: string;
|
|
@@ -116,14 +124,16 @@ export interface OptionalSchema<TInner extends AnySchema> extends SchemaBase<"op
|
|
|
116
124
|
readonly inner: TInner;
|
|
117
125
|
}
|
|
118
126
|
export type AnySchema = StringSchema | NumberSchema | BooleanSchema | EnumSchema<NonEmptyReadonlyArray<EnumValue>> | ArraySchema<AnySchema> | ObjectSchema<ObjectShape> | OptionalSchema<AnySchema> | OneOfSchema<Record<string, ObjectSchema<any>>, string> | UnionSchema<readonly ObjectSchema<any>[]> | RecordSchema<AnySchema> | JsonValueSchema;
|
|
119
|
-
export type Static<TSchema extends AnySchema> = TSchema extends
|
|
127
|
+
export type Static<TSchema extends AnySchema> = TSchema extends {
|
|
128
|
+
readonly nullable: true;
|
|
129
|
+
} ? TSchema extends SchemaBase<any, infer TStatic> ? TStatic | null : never : TSchema extends SchemaBase<any, infer TStatic> ? TStatic : never;
|
|
120
130
|
export declare const S: {
|
|
121
|
-
readonly String:
|
|
122
|
-
readonly Number:
|
|
131
|
+
readonly String: <const TOptions extends SchemaOptions<string> & StringMetadata = EmptyOptions>(options?: TOptions) => WithNullable<StringSchema, TOptions>;
|
|
132
|
+
readonly Number: <const TOptions extends SchemaOptions<number> & NumberMetadata & {
|
|
123
133
|
jsonType?: NumberJsonType;
|
|
124
|
-
}) => NumberSchema
|
|
125
|
-
readonly Boolean:
|
|
126
|
-
readonly Enum: <const TValues extends NonEmptyReadonlyArray<EnumValue
|
|
134
|
+
} = EmptyOptions>(options?: TOptions) => WithNullable<NumberSchema, TOptions>;
|
|
135
|
+
readonly Boolean: <const TOptions extends SchemaOptions<boolean> = EmptyOptions>(options?: TOptions) => WithNullable<BooleanSchema, TOptions>;
|
|
136
|
+
readonly Enum: <const TValues extends NonEmptyReadonlyArray<EnumValue>, const TOptions extends SchemaOptions<TValues[number]> & {
|
|
127
137
|
jsonType?: "integer";
|
|
128
138
|
labels?: Partial<Record<string, string>>;
|
|
129
139
|
loadOptions?: (() => Array<{
|
|
@@ -133,9 +143,9 @@ export declare const S: {
|
|
|
133
143
|
label: string;
|
|
134
144
|
value: string;
|
|
135
145
|
}>>);
|
|
136
|
-
}) => EnumSchema<TValues>;
|
|
137
|
-
readonly Array: <TItem extends AnySchema
|
|
138
|
-
readonly Object: <const TShape extends ObjectShape
|
|
146
|
+
} = EmptyOptions>(values: TValues, options?: TOptions) => WithNullable<EnumSchema<TValues>, TOptions>;
|
|
147
|
+
readonly Array: <TItem extends AnySchema, const TOptions extends SchemaOptions<Array<Static<TItem>>> & ArrayMetadata = EmptyOptions>(item: TItem, options?: TOptions) => WithNullable<ArraySchema<TItem>, TOptions>;
|
|
148
|
+
readonly Object: <const TShape extends ObjectShape, const TOptions extends SchemaOptions<InferObject<TShape>> & ObjectMetadata = EmptyOptions>(shape: TShape, options?: TOptions) => WithNullable<ObjectSchema<TShape>, TOptions>;
|
|
139
149
|
readonly Optional: <TInner extends AnySchema>(inner: TInner) => OptionalSchema<TInner>;
|
|
140
150
|
readonly OneOf: typeof OneOf;
|
|
141
151
|
readonly Union: typeof Union;
|
package/dist/index.js
CHANGED
|
@@ -50,9 +50,7 @@ function withArrayMetadata(schema, jsonSchema) {
|
|
|
50
50
|
return withMetadata(schema, jsonSchema);
|
|
51
51
|
}
|
|
52
52
|
function withObjectMetadata(schema, jsonSchema) {
|
|
53
|
-
|
|
54
|
-
jsonSchema.additionalProperties = schema.additionalProperties;
|
|
55
|
-
}
|
|
53
|
+
jsonSchema.additionalProperties = schema.additionalProperties ?? false;
|
|
56
54
|
return withMetadata(schema, jsonSchema);
|
|
57
55
|
}
|
|
58
56
|
function getEnumJsonType(values) {
|
|
@@ -95,6 +93,20 @@ function assertFiniteNumber(value, name) {
|
|
|
95
93
|
throw new Error(`${name} must be finite`);
|
|
96
94
|
}
|
|
97
95
|
}
|
|
96
|
+
function assertMinMaxOrder(minimum, maximum, minimumName, maximumName) {
|
|
97
|
+
if (minimum !== undefined && maximum !== undefined && minimum > maximum) {
|
|
98
|
+
throw new Error(`${minimumName} must be less than or equal to ${maximumName}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function assertValidDefault(schema) {
|
|
102
|
+
if (schema.default === undefined) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const result = validate(schema, schema.default);
|
|
106
|
+
if (!result.ok) {
|
|
107
|
+
throw new Error(`default must satisfy schema: ${result.issues[0]?.message ?? "invalid default"}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
98
110
|
function assertPattern(pattern) {
|
|
99
111
|
if (pattern === undefined) {
|
|
100
112
|
return;
|
|
@@ -133,31 +145,39 @@ export const S = {
|
|
|
133
145
|
String(options = {}) {
|
|
134
146
|
assertNonNegativeInteger(options.minLength, "minLength");
|
|
135
147
|
assertNonNegativeInteger(options.maxLength, "maxLength");
|
|
148
|
+
assertMinMaxOrder(options.minLength, options.maxLength, "minLength", "maxLength");
|
|
136
149
|
assertPattern(options.pattern);
|
|
137
|
-
|
|
150
|
+
const schema = {
|
|
138
151
|
kind: "string",
|
|
139
152
|
...options
|
|
140
153
|
};
|
|
154
|
+
assertValidDefault(schema);
|
|
155
|
+
return schema;
|
|
141
156
|
},
|
|
142
157
|
Number(options = {}) {
|
|
143
158
|
assertFiniteNumber(options.minimum, "minimum");
|
|
144
159
|
assertFiniteNumber(options.maximum, "maximum");
|
|
160
|
+
assertMinMaxOrder(options.minimum, options.maximum, "minimum", "maximum");
|
|
145
161
|
assertFiniteNumber(options.default, "default");
|
|
146
162
|
if (options.jsonType === "integer" &&
|
|
147
163
|
options.default !== undefined &&
|
|
148
164
|
!Number.isInteger(options.default)) {
|
|
149
165
|
throw new Error("default must be an integer");
|
|
150
166
|
}
|
|
151
|
-
|
|
167
|
+
const schema = {
|
|
152
168
|
kind: "number",
|
|
153
169
|
...options
|
|
154
170
|
};
|
|
171
|
+
assertValidDefault(schema);
|
|
172
|
+
return schema;
|
|
155
173
|
},
|
|
156
174
|
Boolean(options = {}) {
|
|
157
|
-
|
|
175
|
+
const schema = {
|
|
158
176
|
kind: "boolean",
|
|
159
177
|
...options
|
|
160
178
|
};
|
|
179
|
+
assertValidDefault(schema);
|
|
180
|
+
return schema;
|
|
161
181
|
},
|
|
162
182
|
Enum(values, options = {}) {
|
|
163
183
|
assertValidEnumValues(values);
|
|
@@ -165,27 +185,34 @@ export const S = {
|
|
|
165
185
|
values.some((value) => typeof value !== "number" || !Number.isInteger(value))) {
|
|
166
186
|
throw new Error("Integer enum values must be integers");
|
|
167
187
|
}
|
|
168
|
-
|
|
188
|
+
const schema = {
|
|
169
189
|
kind: "enum",
|
|
170
190
|
values,
|
|
171
191
|
...options
|
|
172
192
|
};
|
|
193
|
+
assertValidDefault(schema);
|
|
194
|
+
return schema;
|
|
173
195
|
},
|
|
174
196
|
Array(item, options = {}) {
|
|
175
197
|
assertNonNegativeInteger(options.minItems, "minItems");
|
|
176
198
|
assertNonNegativeInteger(options.maxItems, "maxItems");
|
|
177
|
-
|
|
199
|
+
assertMinMaxOrder(options.minItems, options.maxItems, "minItems", "maxItems");
|
|
200
|
+
const schema = {
|
|
178
201
|
kind: "array",
|
|
179
202
|
item,
|
|
180
203
|
...options
|
|
181
204
|
};
|
|
205
|
+
assertValidDefault(schema);
|
|
206
|
+
return schema;
|
|
182
207
|
},
|
|
183
208
|
Object(shape, options = {}) {
|
|
184
|
-
|
|
209
|
+
const schema = {
|
|
185
210
|
kind: "object",
|
|
186
211
|
shape,
|
|
187
212
|
...options
|
|
188
213
|
};
|
|
214
|
+
assertValidDefault(schema);
|
|
215
|
+
return schema;
|
|
189
216
|
},
|
|
190
217
|
Optional(inner) {
|
|
191
218
|
return {
|