@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/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 FluentType, type NarrowContext, type Type, type } from "./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): FluentType<Out> {
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 FluentType<Out>;
67
+ return type.raw(embedded) as unknown as Decoratable<Out>;
59
68
  }
60
69
 
61
- function withMeta<Out>(source: FluentType<Out>, target: FluentType<Out>): FluentType<Out> {
62
- let next = target;
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 restrictBase<Out>(source: FluentType<Out>, ir: IR): FluentType<Out> {
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: FluentType<Out>, optional = false): ZodLikeSchema<Out> {
102
- const next = (inner: FluentType<Out>, nextOptional = optional): ZodLikeSchema<Out> => decorate(inner, nextOptional);
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 FluentType<Out | undefined>;
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 FluentType<Out | null>, optional);
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 FluentType<Out | undefined>;
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 FluentType<DefaultOut>;
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 FluentType<Out>, optional);
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<Simplify<ObjectOutput<S>>> {
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 decorate(schemaFromIR({ k: "object", props, extras: "delete" }));
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> => decorate(type.enumerated(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 FluentType<null>);
316
- const undefinedSchema = (): ZodLikeSchema<undefined> => decorate(type.raw("undefined") as FluentType<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