@buckeyestudio/omptype 18.4.13

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/src/zod.ts ADDED
@@ -0,0 +1,486 @@
1
+ import { type OmpErrors, OmpTypeError } from "./errors";
2
+ import { type EmbeddableSchema, embed, type IR, IR_BRAND, type PropIR } from "./ir";
3
+ import { type NarrowContext, type Type, type } from "./type";
4
+
5
+ interface OptionalSchemaMarker {
6
+ readonly _optional: true;
7
+ }
8
+
9
+ interface RefineOptions {
10
+ message?: string;
11
+ error?: string;
12
+ }
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
+
23
+ export interface SuperRefineIssue {
24
+ code?: string;
25
+ path?: PropertyKey[];
26
+ message: string;
27
+ actual?: unknown;
28
+ }
29
+
30
+ export interface SuperRefineContext {
31
+ addIssue(issue: SuperRefineIssue): void;
32
+ }
33
+
34
+ export interface ZodLikeIssue {
35
+ path: PropertyKey[];
36
+ message: string;
37
+ }
38
+
39
+ export type ZodLikeSafeParseResult<Out> =
40
+ | { success: true; data: Out }
41
+ | { success: false; error: { message: string; issues: ZodLikeIssue[] } };
42
+
43
+ /** A callable omptype schema carrying the Zod-v4-style fluent surface. */
44
+ export interface ZodLikeSchema<out Out> extends Type<Out, unknown> {
45
+ readonly _output: Out;
46
+ /** @internal Used while composing object property IR. */
47
+ readonly isOptional: boolean;
48
+ parse(value: unknown): Out;
49
+ safeParse(value: unknown): ZodLikeSafeParseResult<Out>;
50
+ min(bound: number): ZodLikeSchema<Out>;
51
+ max(bound: number): ZodLikeSchema<Out>;
52
+ int(): ZodLikeSchema<Out>;
53
+ positive(): ZodLikeSchema<Out>;
54
+ nonnegative(): ZodLikeSchema<Out>;
55
+ regex(expression: RegExp, message?: string): ZodLikeSchema<Out>;
56
+ url(): ZodLikeSchema<Out>;
57
+ optional(): ZodLikeSchema<Out | undefined> & OptionalSchemaMarker;
58
+ nullable(): ZodLikeSchema<Out | null>;
59
+ default(value: Exclude<Out, undefined> | (() => Exclude<Out, undefined>)): ZodLikeSchema<Exclude<Out, undefined>>;
60
+ describe(description: string): ZodLikeSchema<Out>;
61
+ refine(predicate: (value: Out) => unknown, messageOrOptions?: string | RefineOptions): ZodLikeSchema<Out>;
62
+ superRefine(refinement: (value: Out, ctx: SuperRefineContext) => void): ZodLikeSchema<Out>;
63
+ trim(): ZodLikeSchema<Out>;
64
+ transform<Next>(transformer: (value: Out) => Next): ZodLikeSchema<Next>;
65
+ catch(fallback: Out | (() => Out)): ZodLikeSchema<Out>;
66
+ strict(): ZodLikeSchema<Out>;
67
+ passthrough(): ZodLikeSchema<Out & Record<string, unknown>>;
68
+ strip(): ZodLikeSchema<Out>;
69
+ partial(): Out extends object ? ZodLikeSchema<Partial<Out>> : ZodLikeSchema<Out>;
70
+ }
71
+
72
+ function schemaFromIR<Out>(ir: IR): Decoratable<Out> {
73
+ const embedded: EmbeddableSchema = {
74
+ [IR_BRAND]: true,
75
+ ir,
76
+ hasSteps: false,
77
+ hasDefault: false,
78
+ run: value => value,
79
+ };
80
+ return type.raw(embedded) as unknown as Decoratable<Out>;
81
+ }
82
+
83
+ function restrictBase<Out>(source: Decoratable<Out>, ir: IR): Decoratable<Out> {
84
+ let next = source.hasSteps
85
+ ? schemaFromIR<Out>({ k: "morph", input: ir, fn: value => source(value) })
86
+ : schemaFromIR<Out>(ir);
87
+ if (source.ir.desc !== undefined) next = next.describe(source.ir.desc);
88
+ if (source.hasDefault) next = next.default(source.defaultValue as Out | (() => Out));
89
+ return next;
90
+ }
91
+
92
+ function lengthBound(kind: "min" | "max", schema: Decoratable<unknown>, bound: number): void {
93
+ if (schema.ir.k !== "string" && schema.ir.k !== "array") return;
94
+ if (!Number.isSafeInteger(bound) || bound < 0) {
95
+ throw new OmpTypeError(`${kind} length must be a nonnegative safe integer`);
96
+ }
97
+ }
98
+
99
+ function refinementMessage(messageOrOptions: string | RefineOptions | undefined): string {
100
+ if (typeof messageOrOptions === "string") return messageOrOptions;
101
+ return messageOrOptions?.message ?? messageOrOptions?.error ?? "valid (refinement failed)";
102
+ }
103
+
104
+ function isStringKeyIR(ir: IR): boolean {
105
+ switch (ir.k) {
106
+ case "string":
107
+ return true;
108
+ case "lit":
109
+ return typeof ir.v === "string";
110
+ case "union":
111
+ return ir.members.length > 0 && ir.members.every(isStringKeyIR);
112
+ case "sub":
113
+ return isStringKeyIR(ir.schema.ir);
114
+ default:
115
+ return false;
116
+ }
117
+ }
118
+
119
+ function decorate<Out>(schema: Decoratable<Out>, optional = false): ZodLikeSchema<Out> {
120
+ const next = (inner: Decoratable<Out>, nextOptional = optional): ZodLikeSchema<Out> => decorate(inner, nextOptional);
121
+ const withObjectExtras = (extras: "keep" | "reject" | "delete"): ZodLikeSchema<Out> => {
122
+ if (schema.ir.k !== "object") throw new OmpTypeError("object mode requires an object schema");
123
+ return next(restrictBase(schema, { ...schema.ir, extras }));
124
+ };
125
+ Object.defineProperty(schema, "isOptional", { value: optional, enumerable: false });
126
+
127
+ return Object.assign(schema, {
128
+ parse(value: unknown): Out {
129
+ const result = schema(value);
130
+ if (result instanceof type.errors) throw new Error(result.summary);
131
+ return result;
132
+ },
133
+ safeParse(value: unknown): ZodLikeSafeParseResult<Out> {
134
+ const result = schema(value);
135
+ if (!(result instanceof type.errors)) return { success: true, data: result };
136
+ return {
137
+ success: false,
138
+ error: {
139
+ message: result.summary,
140
+ issues: result.map(issue => ({ path: [...issue.path], message: issue.problem })),
141
+ },
142
+ };
143
+ },
144
+ min(bound: number): ZodLikeSchema<Out> {
145
+ const ir = schema.ir;
146
+ if (ir.k === "string" || ir.k === "array") {
147
+ lengthBound("min", schema, bound);
148
+ const min = ir.min === undefined ? bound : Math.max(ir.min, bound);
149
+ return next(restrictBase(schema, { ...ir, min }));
150
+ }
151
+ if (ir.k === "number") {
152
+ if (Number.isNaN(bound)) throw new OmpTypeError("number min must not be NaN");
153
+ if (ir.min !== undefined && ir.min >= bound) return next(restrictBase(schema, ir));
154
+ return next(restrictBase(schema, { ...ir, min: bound, xmin: false }));
155
+ }
156
+ if (
157
+ ir.k === "morph" &&
158
+ !schema.hasSteps &&
159
+ ir.out !== undefined &&
160
+ (ir.out.k === "string" || ir.out.k === "array")
161
+ ) {
162
+ if (!Number.isSafeInteger(bound) || bound < 0)
163
+ throw new OmpTypeError("min length must be a nonnegative safe integer");
164
+ const out = { ...ir.out, min: ir.out.min === undefined ? bound : Math.max(ir.out.min, bound) };
165
+ return next(restrictBase(schema, { ...ir, out }));
166
+ }
167
+ if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
168
+ if (!Number.isSafeInteger(bound) || bound < 0)
169
+ throw new OmpTypeError("min length must be a nonnegative safe integer");
170
+ return next(
171
+ schema.narrow((value, ctx) => {
172
+ if (typeof value === "string" || Array.isArray(value)) {
173
+ return value.length >= bound || ctx.mustBe(`at least ${bound} characters`);
174
+ }
175
+ return ctx.mustBe("a string or array");
176
+ }),
177
+ );
178
+ }
179
+ throw new OmpTypeError(`cannot apply min to ${ir.k}`);
180
+ },
181
+ max(bound: number): ZodLikeSchema<Out> {
182
+ const ir = schema.ir;
183
+ if (ir.k === "string" || ir.k === "array") {
184
+ lengthBound("max", schema, bound);
185
+ const max = ir.max === undefined ? bound : Math.min(ir.max, bound);
186
+ return next(restrictBase(schema, { ...ir, max }));
187
+ }
188
+ if (ir.k === "number") {
189
+ if (Number.isNaN(bound)) throw new OmpTypeError("number max must not be NaN");
190
+ if (ir.max !== undefined && ir.max <= bound) return next(restrictBase(schema, ir));
191
+ return next(restrictBase(schema, { ...ir, max: bound, xmax: false }));
192
+ }
193
+ if (
194
+ ir.k === "morph" &&
195
+ !schema.hasSteps &&
196
+ ir.out !== undefined &&
197
+ (ir.out.k === "string" || ir.out.k === "array")
198
+ ) {
199
+ if (!Number.isSafeInteger(bound) || bound < 0)
200
+ throw new OmpTypeError("max length must be a nonnegative safe integer");
201
+ const out = { ...ir.out, max: ir.out.max === undefined ? bound : Math.min(ir.out.max, bound) };
202
+ return next(restrictBase(schema, { ...ir, out }));
203
+ }
204
+ if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
205
+ if (!Number.isSafeInteger(bound) || bound < 0)
206
+ throw new OmpTypeError("max length must be a nonnegative safe integer");
207
+ return next(
208
+ schema.narrow((value, ctx) => {
209
+ if (typeof value === "string" || Array.isArray(value)) {
210
+ return value.length <= bound || ctx.mustBe(`at most ${bound} characters`);
211
+ }
212
+ return ctx.mustBe("a string or array");
213
+ }),
214
+ );
215
+ }
216
+ throw new OmpTypeError(`cannot apply max to ${ir.k}`);
217
+ },
218
+ int(): ZodLikeSchema<Out> {
219
+ if (schema.ir.k !== "number") throw new OmpTypeError(`cannot apply int to ${schema.ir.k}`);
220
+ return next(restrictBase(schema, { ...schema.ir, int: true }));
221
+ },
222
+ positive(): ZodLikeSchema<Out> {
223
+ if (schema.ir.k !== "number") throw new OmpTypeError(`cannot apply positive to ${schema.ir.k}`);
224
+ const ir = schema.ir;
225
+ if (ir.min !== undefined && ir.min > 0) return next(restrictBase(schema, ir));
226
+ return next(restrictBase(schema, { ...ir, min: 0, xmin: true }));
227
+ },
228
+ nonnegative(): ZodLikeSchema<Out> {
229
+ if (schema.ir.k !== "number") throw new OmpTypeError(`cannot apply nonnegative to ${schema.ir.k}`);
230
+ return this.min(0);
231
+ },
232
+ regex(expression: RegExp, message?: string): ZodLikeSchema<Out> {
233
+ const ir = schema.ir;
234
+ const isStringLike =
235
+ ir.k === "string" ||
236
+ (ir.k === "morph" && (ir.out?.k === "string" || (ir.out === undefined && ir.input.k === "string")));
237
+ if (!isStringLike) throw new OmpTypeError(`cannot apply regex to ${ir.k}`);
238
+ const expectation = message ?? `matching ${expression}`;
239
+ const narrowed = schema.narrow((value, ctx) => {
240
+ if (typeof value !== "string") return ctx.mustBe("a string");
241
+ expression.lastIndex = 0;
242
+ const matches = expression.test(value);
243
+ expression.lastIndex = 0;
244
+ return matches || ctx.mustBe(expectation);
245
+ });
246
+ return next(narrowed);
247
+ },
248
+ url(): ZodLikeSchema<Out> {
249
+ const ir = schema.ir;
250
+ if (ir.k === "string") return next(restrictBase(schema, { ...ir, url: true }));
251
+ if (ir.k === "morph" && !schema.hasSteps && ir.out !== undefined && ir.out.k === "string") {
252
+ return next(restrictBase(schema, { ...ir, out: { ...ir.out, url: true } }));
253
+ }
254
+ if (ir.k === "morph" && (schema.hasSteps || ir.out === undefined)) {
255
+ return next(
256
+ schema.narrow((value, ctx) => {
257
+ if (typeof value !== "string") return ctx.mustBe("a string");
258
+ try {
259
+ new URL(value);
260
+ return true;
261
+ } catch {
262
+ return ctx.mustBe("a valid URL");
263
+ }
264
+ }),
265
+ );
266
+ }
267
+ throw new OmpTypeError(`cannot apply url to ${ir.k}`);
268
+ },
269
+ optional(): ZodLikeSchema<Out | undefined> & OptionalSchemaMarker {
270
+ const widened = schema.or(type.raw("undefined")) as Decoratable<Out | undefined>;
271
+ return decorate(widened, true) as ZodLikeSchema<Out | undefined> & OptionalSchemaMarker;
272
+ },
273
+ nullable(): ZodLikeSchema<Out | null> {
274
+ return decorate(schema.or(type.raw("null")) as Decoratable<Out | null>, optional);
275
+ },
276
+ default(
277
+ value: Exclude<Out, undefined> | (() => Exclude<Out, undefined>),
278
+ ): ZodLikeSchema<Exclude<Out, undefined>> {
279
+ type DefaultOut = Exclude<Out, undefined>;
280
+ const widened = schema.or(type.raw("undefined")) as Decoratable<Out | undefined>;
281
+ const piped = widened.pipe(output => {
282
+ if (output !== undefined) return output as DefaultOut;
283
+ return typeof value === "function" ? (value as () => DefaultOut)() : value;
284
+ }) as Decoratable<DefaultOut>;
285
+ return decorate(piped.default(value as DefaultOut | (() => DefaultOut)));
286
+ },
287
+ describe(description: string): ZodLikeSchema<Out> {
288
+ return next(restrictBase(schema, { ...schema.ir, desc: description }).describe(description));
289
+ },
290
+ refine(predicate: (value: Out) => unknown, messageOrOptions?: string | RefineOptions): ZodLikeSchema<Out> {
291
+ const expectation = refinementMessage(messageOrOptions);
292
+ return next(schema.narrow((value, ctx) => Boolean(predicate(value)) || ctx.mustBe(expectation)));
293
+ },
294
+ superRefine(refinement: (value: Out, ctx: SuperRefineContext) => void): ZodLikeSchema<Out> {
295
+ return next(
296
+ schema.narrow((value, ctx) => {
297
+ const proxy: SuperRefineContext = {
298
+ addIssue(issue) {
299
+ ctx.error({
300
+ expected: issue.message,
301
+ path: issue.path ?? [],
302
+ ...(issue.actual !== undefined ? { actual: issue.actual } : {}),
303
+ });
304
+ },
305
+ };
306
+ refinement(value, proxy);
307
+ return true;
308
+ }),
309
+ );
310
+ },
311
+ trim(): ZodLikeSchema<Out> {
312
+ const ir = schema.ir;
313
+ if (ir.k === "string" && !schema.hasSteps) {
314
+ let trimmed = schemaFromIR<Out>({
315
+ k: "morph",
316
+ input: { k: "string" },
317
+ fn: v => (v as string).trim(),
318
+ out: ir,
319
+ });
320
+ if (schema.hasDefault) trimmed = trimmed.default(schema.defaultValue as Out | (() => Out));
321
+ return next(trimmed);
322
+ }
323
+ if (ir.k === "morph" || schema.hasSteps) {
324
+ let trimmed = schemaFromIR<Out>({
325
+ k: "morph",
326
+ input: { k: "unknown" },
327
+ fn: v => {
328
+ const r = schema(v);
329
+ if (r instanceof type.errors) return r;
330
+ if (typeof r !== "string") throw new OmpTypeError("trim requires a string output");
331
+ return r.trim();
332
+ },
333
+ out: { k: "string" },
334
+ });
335
+ if (schema.hasDefault) trimmed = trimmed.default(schema.defaultValue as Out | (() => Out));
336
+ return next(trimmed);
337
+ }
338
+ throw new OmpTypeError(`cannot apply trim to ${ir.k}`);
339
+ },
340
+ transform<Next>(transformer: (value: Out) => Next): ZodLikeSchema<Next> {
341
+ return decorate(
342
+ schema.pipe(value => transformer(value)),
343
+ optional,
344
+ );
345
+ },
346
+ catch(fallback: Out | (() => Out)): ZodLikeSchema<Out> {
347
+ const caught = type.unknown.pipe(input => {
348
+ try {
349
+ const result = schema(input);
350
+ if (!(result instanceof type.errors)) return result;
351
+ } catch {
352
+ // A caught schema is deliberately total, including user refinement/transform exceptions.
353
+ }
354
+ return typeof fallback === "function" ? (fallback as () => Out)() : fallback;
355
+ });
356
+ return decorate(caught as Decoratable<Out>, optional);
357
+ },
358
+ strict(): ZodLikeSchema<Out> {
359
+ return withObjectExtras("reject");
360
+ },
361
+ passthrough(): ZodLikeSchema<Out & Record<string, unknown>> {
362
+ return withObjectExtras("keep") as ZodLikeSchema<Out & Record<string, unknown>>;
363
+ },
364
+ strip(): ZodLikeSchema<Out> {
365
+ return withObjectExtras("delete");
366
+ },
367
+ partial(): Out extends object ? ZodLikeSchema<Partial<Out>> : ZodLikeSchema<Out> {
368
+ if (schema.ir.k !== "object") throw new OmpTypeError(`cannot apply partial to ${schema.ir.k}`);
369
+ const props = schema.ir.props.map(prop => ({ ...prop, opt: true }));
370
+ return next(restrictBase(schema, { ...schema.ir, props })) as Out extends object
371
+ ? ZodLikeSchema<Partial<Out>>
372
+ : ZodLikeSchema<Out>;
373
+ },
374
+ }) as unknown as ZodLikeSchema<Out>;
375
+ }
376
+
377
+ function decorateUnknown(schema: Decoratable<unknown>): ZodLikeSchema<unknown> {
378
+ return decorate(schema);
379
+ }
380
+
381
+ export type infer<T> = T extends { readonly _output: infer Out } ? Out : never;
382
+
383
+ type SchemaOutput<Schema> = Schema extends { readonly _output: infer Out } ? Out : never;
384
+ type Shape = Readonly<Record<string, ZodLikeSchema<unknown>>>;
385
+ type ObjectOutput<S extends Shape> = {
386
+ -readonly [K in keyof S as S[K] extends OptionalSchemaMarker ? never : K]: SchemaOutput<S[K]>;
387
+ } & {
388
+ -readonly [K in keyof S as S[K] extends OptionalSchemaMarker ? K : never]?: SchemaOutput<S[K]>;
389
+ };
390
+ type Simplify<T> = { [K in keyof T]: T[K] };
391
+ type UnionOutput<Schemas extends readonly ZodLikeSchema<unknown>[]> = SchemaOutput<Schemas[number]>;
392
+
393
+ function objectSchema<const S extends Shape>(shape: S): ZodLikeSchema<ObjectOutput<S>> {
394
+ const props: PropIR[] = [];
395
+ for (const key in shape) {
396
+ const member = shape[key];
397
+ const prop: PropIR = { key, opt: member.isOptional, val: embed(member) };
398
+ if (member.hasDefault) {
399
+ prop.hasDefault = true;
400
+ prop.def = member.defaultValue;
401
+ prop.defFactory = typeof member.defaultValue === "function";
402
+ }
403
+ props.push(prop);
404
+ }
405
+ return decorateUnknown(schemaFromIR<unknown>({ k: "object", props, extras: "delete" })) as unknown as ZodLikeSchema<
406
+ ObjectOutput<S>
407
+ >;
408
+ }
409
+
410
+ export const string = (): ZodLikeSchema<string> => decorate(schemaFromIR(type.string.ir));
411
+ export const number = (): ZodLikeSchema<number> => decorate(schemaFromIR(type.number.ir));
412
+ export const boolean = (): ZodLikeSchema<boolean> => decorate(schemaFromIR(type.boolean.ir));
413
+ export const literal = <const Value>(value: Value): ZodLikeSchema<Value> =>
414
+ decorate(schemaFromIR<Value>(type.enumerated(value).ir));
415
+ const enumSchema = <const Values extends readonly [string, ...string[]]>(
416
+ values: Values,
417
+ ): ZodLikeSchema<Values[number]> => {
418
+ if (values.length === 0) throw new OmpTypeError("enum requires at least one value");
419
+ return decorate(schemaFromIR<Values[number]>(type.enumerated(...values).ir));
420
+ };
421
+
422
+ export { enumSchema as enum };
423
+ export const union = <
424
+ const Schemas extends readonly [ZodLikeSchema<unknown>, ZodLikeSchema<unknown>, ...ZodLikeSchema<unknown>[]],
425
+ >(
426
+ schemas: Schemas,
427
+ ): ZodLikeSchema<UnionOutput<Schemas>> =>
428
+ decorate(schemaFromIR({ k: "union", members: schemas.map(schema => embed(schema)) }));
429
+ export const array = <Element>(element: ZodLikeSchema<Element>): ZodLikeSchema<Element[]> =>
430
+ decorate(schemaFromIR({ k: "array", el: embed(element) }));
431
+ export const object = <const S extends Shape>(shape: S): ZodLikeSchema<Simplify<ObjectOutput<S>>> =>
432
+ objectSchema(shape);
433
+ export function record<Key extends string, Value>(
434
+ keySchema: ZodLikeSchema<Key>,
435
+ valueSchema: ZodLikeSchema<Value>,
436
+ ): ZodLikeSchema<Record<string, Value>>;
437
+ export function record<Value>(valueSchema: ZodLikeSchema<Value>): ZodLikeSchema<Record<string, Value>>;
438
+ export function record<Key extends string, Value>(
439
+ keyOrValueSchema: ZodLikeSchema<Key> | ZodLikeSchema<Value>,
440
+ valueSchema?: ZodLikeSchema<Value>,
441
+ ): ZodLikeSchema<Record<string, Value>> {
442
+ const keySchema = (valueSchema === undefined ? string() : keyOrValueSchema) as ZodLikeSchema<Key>;
443
+ const valSchema = (valueSchema === undefined ? keyOrValueSchema : valueSchema) as ZodLikeSchema<Value>;
444
+ if (!isStringKeyIR(keySchema.ir)) throw new OmpTypeError("record keys must use a string schema");
445
+ const base = schemaFromIR<Record<string, Value>>({
446
+ k: "object",
447
+ props: [],
448
+ index: embed(valSchema),
449
+ extras: "keep",
450
+ });
451
+ const checked = base.narrow((value, ctx: NarrowContext) => {
452
+ for (const key in value) {
453
+ if (keySchema(key) instanceof type.errors) return ctx.mustBe("a record with valid string keys");
454
+ }
455
+ return true;
456
+ });
457
+ return decorate(checked);
458
+ }
459
+ export const unknown = (): ZodLikeSchema<unknown> => decorate(schemaFromIR(type.unknown.ir));
460
+ export const any = (): ZodLikeSchema<unknown> => decorate(schemaFromIR(type.unknown.ir));
461
+ const nullSchema = (): ZodLikeSchema<null> => decorate(type.raw("null") as unknown as Decoratable<null>);
462
+ const undefinedSchema = (): ZodLikeSchema<undefined> =>
463
+ decorate(type.raw("undefined") as unknown as Decoratable<undefined>);
464
+
465
+ export { nullSchema as null, undefinedSchema as undefined };
466
+
467
+ /** Runtime `z.*` facade, merged with the `z.infer` type namespace below. */
468
+ export const z = {
469
+ string,
470
+ number,
471
+ boolean,
472
+ literal,
473
+ enum: enumSchema,
474
+ union,
475
+ array,
476
+ object,
477
+ record,
478
+ unknown,
479
+ any,
480
+ null: nullSchema,
481
+ undefined: undefinedSchema,
482
+ };
483
+
484
+ export namespace z {
485
+ export type infer<Schema> = Schema extends { readonly _output: infer Out } ? Out : never;
486
+ }