@oh-my-pi/omptype 17.2.6 → 17.2.7
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 +17 -2
- package/README.md +83 -14
- package/dist/js/ark.js +16 -0
- package/dist/js/compile.js +747 -0
- package/dist/js/errors.js +199 -0
- package/dist/js/index.js +12 -0
- package/dist/js/infer.js +2 -0
- package/dist/js/interp.js +476 -0
- package/dist/js/ir.js +930 -0
- package/dist/js/json-schema.js +273 -0
- package/dist/js/keywords.js +233 -0
- package/dist/js/type.js +1078 -0
- package/dist/js/typebox.js +346 -0
- package/dist/js/zod.js +269 -0
- package/dist/types/ark.d.ts +3 -11
- package/dist/types/compile.d.ts +2 -0
- package/dist/types/errors.d.ts +51 -15
- package/dist/types/index.d.ts +3 -4
- package/dist/types/infer.d.ts +107 -30
- package/dist/types/interp.d.ts +5 -3
- package/dist/types/ir.d.ts +76 -7
- package/dist/types/json-schema.d.ts +6 -1
- package/dist/types/keywords.d.ts +7 -0
- package/dist/types/type.d.ts +238 -49
- package/dist/types/zod.d.ts +1 -1
- package/package.json +20 -8
- package/src/ark.ts +4 -14
- package/src/compile.ts +432 -54
- package/src/errors.ts +146 -34
- package/src/index.ts +3 -4
- package/src/infer.ts +284 -77
- package/src/interp.ts +153 -9
- package/src/ir.ts +636 -89
- package/src/json-schema.ts +109 -14
- package/src/keywords.ts +270 -0
- package/src/type.ts +1302 -147
- package/src/typebox.ts +1 -1
- package/src/zod.ts +40 -27
package/src/typebox.ts
CHANGED
|
@@ -149,7 +149,7 @@ function applyMeta<T>(schema: RuntimeType<T>, opts?: Meta): CompatRuntime<T> {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
function withJsonSchemaKeywords<T>(schema: CompatRuntime<T>, keywords: Record<string, unknown>): CompatRuntime<T> {
|
|
152
|
-
const emitBase = schema.toJsonSchema;
|
|
152
|
+
const emitBase = schema.toJsonSchema.bind(schema);
|
|
153
153
|
schema.toJsonSchema = options => ({ ...emitBase(options), ...keywords });
|
|
154
154
|
return schema;
|
|
155
155
|
}
|
package/src/zod.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { OmpTypeError } from "./errors";
|
|
1
|
+
import { type OmpErrors, OmpTypeError } from "./errors";
|
|
2
2
|
import { type EmbeddableSchema, embed, type IR, IR_BRAND, type PropIR } from "./ir";
|
|
3
|
-
import { type
|
|
3
|
+
import { type NarrowContext, type Type, type } from "./type";
|
|
4
4
|
|
|
5
5
|
interface OptionalSchemaMarker {
|
|
6
6
|
readonly _optional: true;
|
|
@@ -11,6 +11,15 @@ interface RefineOptions {
|
|
|
11
11
|
error?: string;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
interface Decoratable<out Out> extends EmbeddableSchema {
|
|
15
|
+
(value: unknown): Out | OmpErrors;
|
|
16
|
+
narrow(predicate: (value: Out, context: NarrowContext) => unknown): Decoratable<Out>;
|
|
17
|
+
pipe<Next>(transform: (value: Out, context: NarrowContext) => Next): Decoratable<Exclude<Next, OmpErrors>>;
|
|
18
|
+
or(def: unknown): Decoratable<unknown>;
|
|
19
|
+
describe(description: string): Decoratable<Out>;
|
|
20
|
+
default(value: Out | (() => Out)): Decoratable<Out>;
|
|
21
|
+
}
|
|
22
|
+
|
|
14
23
|
export interface ZodLikeIssue {
|
|
15
24
|
path: PropertyKey[];
|
|
16
25
|
message: string;
|
|
@@ -21,7 +30,7 @@ export type ZodLikeSafeParseResult<Out> =
|
|
|
21
30
|
| { success: false; error: { message: string; issues: ZodLikeIssue[] } };
|
|
22
31
|
|
|
23
32
|
/** A callable omptype schema carrying the Zod-v4-style fluent surface. */
|
|
24
|
-
export interface ZodLikeSchema<out Out> extends Type<Out> {
|
|
33
|
+
export interface ZodLikeSchema<out Out> extends Type<Out, unknown> {
|
|
25
34
|
readonly _output: Out;
|
|
26
35
|
/** @internal Used while composing object property IR. */
|
|
27
36
|
readonly isOptional: boolean;
|
|
@@ -47,7 +56,7 @@ export interface ZodLikeSchema<out Out> extends Type<Out> {
|
|
|
47
56
|
partial(): Out extends object ? ZodLikeSchema<Partial<Out>> : ZodLikeSchema<Out>;
|
|
48
57
|
}
|
|
49
58
|
|
|
50
|
-
function schemaFromIR<Out>(ir: IR):
|
|
59
|
+
function schemaFromIR<Out>(ir: IR): Decoratable<Out> {
|
|
51
60
|
const embedded: EmbeddableSchema = {
|
|
52
61
|
[IR_BRAND]: true,
|
|
53
62
|
ir,
|
|
@@ -55,23 +64,19 @@ function schemaFromIR<Out>(ir: IR): FluentType<Out> {
|
|
|
55
64
|
hasDefault: false,
|
|
56
65
|
run: value => value,
|
|
57
66
|
};
|
|
58
|
-
return type.raw(embedded) as
|
|
67
|
+
return type.raw(embedded) as unknown as Decoratable<Out>;
|
|
59
68
|
}
|
|
60
69
|
|
|
61
|
-
function
|
|
62
|
-
let next =
|
|
70
|
+
function restrictBase<Out>(source: Decoratable<Out>, ir: IR): Decoratable<Out> {
|
|
71
|
+
let next = source.hasSteps
|
|
72
|
+
? schemaFromIR<Out>({ k: "morph", input: ir, fn: value => source(value) })
|
|
73
|
+
: schemaFromIR<Out>(ir);
|
|
63
74
|
if (source.description !== undefined) next = next.describe(source.description);
|
|
64
75
|
if (source.hasDefault) next = next.default(source.defaultValue as Out | (() => Out));
|
|
65
76
|
return next;
|
|
66
77
|
}
|
|
67
78
|
|
|
68
|
-
function
|
|
69
|
-
let next = schemaFromIR<Out>(ir);
|
|
70
|
-
if (source.hasSteps) next = next.pipe(value => source(value)) as FluentType<Out>;
|
|
71
|
-
return withMeta(source, next);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function lengthBound(kind: "min" | "max", schema: FluentType<unknown>, bound: number): void {
|
|
79
|
+
function lengthBound(kind: "min" | "max", schema: Decoratable<unknown>, bound: number): void {
|
|
75
80
|
if (schema.ir.k !== "string" && schema.ir.k !== "array") return;
|
|
76
81
|
if (!Number.isSafeInteger(bound) || bound < 0) {
|
|
77
82
|
throw new OmpTypeError(`${kind} length must be a nonnegative safe integer`);
|
|
@@ -98,8 +103,8 @@ function isStringKeyIR(ir: IR): boolean {
|
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
function decorate<Out>(schema:
|
|
102
|
-
const next = (inner:
|
|
106
|
+
function decorate<Out>(schema: Decoratable<Out>, optional = false): ZodLikeSchema<Out> {
|
|
107
|
+
const next = (inner: Decoratable<Out>, nextOptional = optional): ZodLikeSchema<Out> => decorate(inner, nextOptional);
|
|
103
108
|
const withObjectExtras = (extras: "keep" | "reject" | "delete"): ZodLikeSchema<Out> => {
|
|
104
109
|
if (schema.ir.k !== "object") throw new OmpTypeError("object mode requires an object schema");
|
|
105
110
|
return next(restrictBase(schema, { ...schema.ir, extras }));
|
|
@@ -181,21 +186,21 @@ function decorate<Out>(schema: FluentType<Out>, optional = false): ZodLikeSchema
|
|
|
181
186
|
return next(restrictBase(schema, { ...schema.ir, url: true }));
|
|
182
187
|
},
|
|
183
188
|
optional(): ZodLikeSchema<Out | undefined> & OptionalSchemaMarker {
|
|
184
|
-
const widened = schema.or(type.raw("undefined")) as
|
|
189
|
+
const widened = schema.or(type.raw("undefined")) as Decoratable<Out | undefined>;
|
|
185
190
|
return decorate(widened, true) as ZodLikeSchema<Out | undefined> & OptionalSchemaMarker;
|
|
186
191
|
},
|
|
187
192
|
nullable(): ZodLikeSchema<Out | null> {
|
|
188
|
-
return decorate(schema.or(type.raw("null")) as
|
|
193
|
+
return decorate(schema.or(type.raw("null")) as Decoratable<Out | null>, optional);
|
|
189
194
|
},
|
|
190
195
|
default(
|
|
191
196
|
value: Exclude<Out, undefined> | (() => Exclude<Out, undefined>),
|
|
192
197
|
): ZodLikeSchema<Exclude<Out, undefined>> {
|
|
193
198
|
type DefaultOut = Exclude<Out, undefined>;
|
|
194
|
-
const widened = schema.or(type.raw("undefined")) as
|
|
199
|
+
const widened = schema.or(type.raw("undefined")) as Decoratable<Out | undefined>;
|
|
195
200
|
const piped = widened.pipe(output => {
|
|
196
201
|
if (output !== undefined) return output as DefaultOut;
|
|
197
202
|
return typeof value === "function" ? (value as () => DefaultOut)() : value;
|
|
198
|
-
}) as
|
|
203
|
+
}) as Decoratable<DefaultOut>;
|
|
199
204
|
return decorate(piped.default(value as DefaultOut | (() => DefaultOut)));
|
|
200
205
|
},
|
|
201
206
|
describe(description: string): ZodLikeSchema<Out> {
|
|
@@ -221,7 +226,7 @@ function decorate<Out>(schema: FluentType<Out>, optional = false): ZodLikeSchema
|
|
|
221
226
|
}
|
|
222
227
|
return typeof fallback === "function" ? (fallback as () => Out)() : fallback;
|
|
223
228
|
});
|
|
224
|
-
return decorate(caught as
|
|
229
|
+
return decorate(caught as Decoratable<Out>, optional);
|
|
225
230
|
},
|
|
226
231
|
strict(): ZodLikeSchema<Out> {
|
|
227
232
|
return withObjectExtras("reject");
|
|
@@ -242,6 +247,10 @@ function decorate<Out>(schema: FluentType<Out>, optional = false): ZodLikeSchema
|
|
|
242
247
|
}) as unknown as ZodLikeSchema<Out>;
|
|
243
248
|
}
|
|
244
249
|
|
|
250
|
+
function decorateUnknown(schema: Decoratable<unknown>): ZodLikeSchema<unknown> {
|
|
251
|
+
return decorate(schema);
|
|
252
|
+
}
|
|
253
|
+
|
|
245
254
|
export type infer<T> = T extends { readonly _output: infer Out } ? Out : never;
|
|
246
255
|
|
|
247
256
|
type SchemaOutput<Schema> = Schema extends { readonly _output: infer Out } ? Out : never;
|
|
@@ -254,7 +263,7 @@ type ObjectOutput<S extends Shape> = {
|
|
|
254
263
|
type Simplify<T> = { [K in keyof T]: T[K] };
|
|
255
264
|
type UnionOutput<Schemas extends readonly ZodLikeSchema<unknown>[]> = SchemaOutput<Schemas[number]>;
|
|
256
265
|
|
|
257
|
-
function objectSchema<const S extends Shape>(shape: S): ZodLikeSchema<
|
|
266
|
+
function objectSchema<const S extends Shape>(shape: S): ZodLikeSchema<ObjectOutput<S>> {
|
|
258
267
|
const props: PropIR[] = [];
|
|
259
268
|
for (const key in shape) {
|
|
260
269
|
const member = shape[key];
|
|
@@ -266,18 +275,21 @@ function objectSchema<const S extends Shape>(shape: S): ZodLikeSchema<Simplify<O
|
|
|
266
275
|
}
|
|
267
276
|
props.push(prop);
|
|
268
277
|
}
|
|
269
|
-
return
|
|
278
|
+
return decorateUnknown(schemaFromIR<unknown>({ k: "object", props, extras: "delete" })) as unknown as ZodLikeSchema<
|
|
279
|
+
ObjectOutput<S>
|
|
280
|
+
>;
|
|
270
281
|
}
|
|
271
282
|
|
|
272
283
|
export const string = (): ZodLikeSchema<string> => decorate(schemaFromIR(type.string.ir));
|
|
273
284
|
export const number = (): ZodLikeSchema<number> => decorate(schemaFromIR(type.number.ir));
|
|
274
285
|
export const boolean = (): ZodLikeSchema<boolean> => decorate(schemaFromIR(type.boolean.ir));
|
|
275
|
-
export const literal = <const Value>(value: Value): ZodLikeSchema<Value> =>
|
|
286
|
+
export const literal = <const Value>(value: Value): ZodLikeSchema<Value> =>
|
|
287
|
+
decorate(schemaFromIR<Value>(type.enumerated(value).ir));
|
|
276
288
|
const enumSchema = <const Values extends readonly [string, ...string[]]>(
|
|
277
289
|
values: Values,
|
|
278
290
|
): ZodLikeSchema<Values[number]> => {
|
|
279
291
|
if (values.length === 0) throw new OmpTypeError("enum requires at least one value");
|
|
280
|
-
return decorate(type.enumerated(...values));
|
|
292
|
+
return decorate(schemaFromIR<Values[number]>(type.enumerated(...values).ir));
|
|
281
293
|
};
|
|
282
294
|
|
|
283
295
|
export { enumSchema as enum };
|
|
@@ -312,8 +324,9 @@ export const record = <Key extends string, Value>(
|
|
|
312
324
|
};
|
|
313
325
|
export const unknown = (): ZodLikeSchema<unknown> => decorate(schemaFromIR(type.unknown.ir));
|
|
314
326
|
export const any = (): ZodLikeSchema<unknown> => decorate(schemaFromIR(type.unknown.ir));
|
|
315
|
-
const nullSchema = (): ZodLikeSchema<null> => decorate(type.raw("null") as
|
|
316
|
-
const undefinedSchema = (): ZodLikeSchema<undefined> =>
|
|
327
|
+
const nullSchema = (): ZodLikeSchema<null> => decorate(type.raw("null") as unknown as Decoratable<null>);
|
|
328
|
+
const undefinedSchema = (): ZodLikeSchema<undefined> =>
|
|
329
|
+
decorate(type.raw("undefined") as unknown as Decoratable<undefined>);
|
|
317
330
|
|
|
318
331
|
export { nullSchema as null, undefinedSchema as undefined };
|
|
319
332
|
|