@kontsedal/olas-zod 0.0.2 → 0.0.4

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.cjs CHANGED
@@ -1,16 +1,15 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _kontsedal_olas_core = require("@kontsedal/olas-core");
2
3
  let zod = require("zod");
3
4
  //#region src/index.ts
4
5
  /**
5
- * Wrap a Zod schema as an Olas validator. Returns a sync or async Validator
6
- * depending on whether the schema requires async parsing (e.g. `.refine(async ...)`).
6
+ * Wrap a Zod schema as an Olas validator. Zod 4 implements Standard Schema
7
+ * v1, so this is now a thin alias over the cross-library `validator(...)`
8
+ * from `@kontsedal/olas-core`. Kept under its existing name for back-compat
9
+ * and for code that intentionally signals "this is a Zod schema."
7
10
  */
8
11
  function zodValidator(schema) {
9
- return (value, signal) => {
10
- const result = schema.safeParse(value);
11
- if (result.success) return null;
12
- return result.error.issues[0]?.message ?? "Invalid";
13
- };
12
+ return (0, _kontsedal_olas_core.validator)(schema);
14
13
  }
15
14
  /**
16
15
  * Async variant for schemas with `.refine(async ...)` or `.transform(async ...)`.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["z"],"sources":["../src/index.ts"],"sourcesContent":["import type { Ctx, Field, FieldArray, Form, Validator } from '@kontsedal/olas-core'\nimport { z } from 'zod'\n\n/**\n * Wrap a Zod schema as an Olas validator. Returns a sync or async Validator\n * depending on whether the schema requires async parsing (e.g. `.refine(async ...)`).\n */\nexport function zodValidator<T>(schema: z.ZodType<T>): Validator<T> {\n return (value, signal) => {\n // signal isn't used by Zod (parsing is sync) — kept for interface parity.\n void signal\n const result = schema.safeParse(value)\n if (result.success) return null\n return result.error.issues[0]?.message ?? 'Invalid'\n }\n}\n\n/**\n * Async variant for schemas with `.refine(async ...)` or `.transform(async ...)`.\n * Returns a Promise<string | null>.\n */\nexport function zodValidatorAsync<T>(schema: z.ZodType<T>): Validator<T> {\n return async (value, signal) => {\n void signal\n const result = await schema.safeParseAsync(value)\n if (result.success) return null\n return result.error.issues[0]?.message ?? 'Invalid'\n }\n}\n\n/**\n * Run the schema and report only **root-level** issues (those with empty\n * `path`). Leaf issues are already covered by `zodValidator(propSchema)` on\n * each leaf field — surfacing them here would double-count.\n *\n * Used by `formFromZod` to lift root-level `.refine(...)` rules into a\n * form-level validator. Returns `null` when every issue belongs to a leaf\n * (or there are no issues at all).\n */\nexport function rootOnlyZodValidator<T>(schema: z.ZodType<T>): Validator<T> {\n return (value, signal) => {\n void signal\n const result = schema.safeParse(value)\n if (result.success) return null\n for (const issue of result.error.issues) {\n if (issue.path.length === 0) return issue.message\n }\n return null\n }\n}\n\n// Zod 4 typed every wrapper as `z.ZodType`-compatible; the public unwrap path\n// is `.unwrap()` for optional/nullable and `.def.innerType` for default.\ntype AnyZodType = z.ZodType\n\n// Strip the outer optional/nullable/default wrappers to find the inner schema.\nfunction unwrap(schema: AnyZodType): AnyZodType {\n let s: AnyZodType = schema\n // Unwrap default + optional + nullable, in any combination.\n for (let i = 0; i < 5; i++) {\n if (s instanceof z.ZodDefault) {\n // ZodDefault stores the inner schema on `def.innerType`. The runtime\n // shape is stable across 3.x and 4.x; the public type just shifts.\n s = (s as unknown as { def: { innerType: AnyZodType } }).def.innerType\n } else if (s instanceof z.ZodOptional) {\n s = (s as z.ZodOptional<AnyZodType>).unwrap() as AnyZodType\n } else if (s instanceof z.ZodNullable) {\n s = (s as z.ZodNullable<AnyZodType>).unwrap() as AnyZodType\n } else {\n return s\n }\n }\n return s\n}\n\nfunction defaultInitial(schema: AnyZodType): unknown {\n // Honor Zod default if present.\n if (schema instanceof z.ZodDefault) {\n const raw = (schema as unknown as { def: { defaultValue: unknown } }).def.defaultValue\n return typeof raw === 'function' ? (raw as () => unknown)() : raw\n }\n const inner = unwrap(schema)\n if (inner instanceof z.ZodString) return ''\n if (inner instanceof z.ZodNumber) return 0\n if (inner instanceof z.ZodBoolean) return false\n if (inner instanceof z.ZodArray) return []\n if (inner instanceof z.ZodEnum) {\n // Zod 4 widened ZodEnum's options to support record-style enums. The\n // runtime values are still iterable; pick the first.\n const opts = (inner as unknown as { options: readonly unknown[] }).options\n const first = opts[0]\n return typeof first === 'string' ? first : ''\n }\n // For unknown/any/dates etc., undefined is the safest starting point.\n return undefined\n}\n\ntype AnyForm = Form<Record<string, Field<any> | Form<any> | FieldArray<any>>>\n\n// Strip the same wrappers as the runtime `unwrap` helper, at the type level.\ntype UnwrapZod<S> =\n S extends z.ZodDefault<infer Inner>\n ? UnwrapZod<Inner>\n : S extends z.ZodOptional<infer Inner>\n ? UnwrapZod<Inner>\n : S extends z.ZodNullable<infer Inner>\n ? UnwrapZod<Inner>\n : S\n\n/**\n * Recursively map a Zod schema to its Olas form leaf:\n * - `ZodObject<S>` → `Form<{ [K]: ZodToLeaf<S[K]> }>`\n * - `ZodArray<E>` → `FieldArray<ZodToLeaf<E>>` (when E is object/array)\n * or `FieldArray<Field<infer<E>>>` for primitive elements.\n * - everything else → `Field<infer<S>>`.\n *\n * `ZodToLeaf<S>` matches what `buildLeaf(ctx, s, ...)` returns at runtime,\n * so the public `formFromZod<T>` can publish a precise structural type\n * without the consumer needing a hand-written `CardForm = Form<{...}>` cast.\n */\nexport type ZodToLeaf<S> =\n UnwrapZod<S> extends z.ZodObject<infer RawShape>\n ? Form<{ [K in keyof RawShape]: ZodToLeaf<RawShape[K]> }>\n : UnwrapZod<S> extends z.ZodArray<infer Element>\n ? FieldArray<ZodToLeaf<Element> extends Form<any> | Field<any> ? ZodToLeaf<Element> : never>\n : Field<z.infer<UnwrapZod<S> & z.ZodType>>\n\n/**\n * Walk a Zod schema and emit the equivalent Olas Form / FieldArray / Field\n * tree, with validators auto-attached.\n *\n * - `z.object(...)` → `Form`\n * - `z.array(...)` → `FieldArray` (recurses on the element)\n * - leaf schemas → `Field` with `zodValidator(...)` attached\n *\n * Each leaf's initial value is the Zod default if present, otherwise an empty\n * value for that type (`''` for strings, `0` for numbers, etc.).\n *\n * The return type is structurally precise — `form.fields.title.value` is\n * `string` (not `string | boolean | …`), `form.fields.subtasks.add(...)`\n * accepts the exact item shape, etc. Consumers do not need to hand-write\n * a `CardForm = Form<{...}>` matching the schema.\n */\n/**\n * Per-leaf extra validators keyed by dotted path. Match the leaf field's\n * position inside the schema:\n *\n * - top-level: `'title'`\n * - nested form: `'address.street'`\n *\n * `FieldArray` items aren't separately addressable — the schema walker\n * generates one factory per array, so a path of `'tags'` matches the\n * `FieldArray` (validators attached there apply to the array as a whole;\n * use Olas's `FieldArrayOptions.validators` shape). Per-element rules\n * already live on the Zod element schema and are attached automatically.\n *\n * Validators run alongside `zodValidator(schema)` — both must pass.\n */\nexport type ExtraValidators = Record<string, Validator<any>>\n\nexport type FormFromZodOptions<T extends z.ZodObject<z.ZodRawShape>> = {\n initials?: Partial<z.infer<T>>\n extraValidators?: ExtraValidators\n}\n\nexport function formFromZod<T extends z.ZodObject<z.ZodRawShape>>(\n ctx: Ctx,\n schema: T,\n options?: FormFromZodOptions<T>,\n): Form<{ [K in keyof T['shape']]: ZodToLeaf<T['shape'][K]> }> {\n return buildForm(ctx, schema, options?.initials, '', options?.extraValidators, schema) as never\n}\n\nfunction buildForm(\n ctx: Ctx,\n schema: z.ZodObject<z.ZodRawShape>,\n initials: Record<string, unknown> | undefined,\n path: string,\n extras: ExtraValidators | undefined,\n /**\n * The original top-level schema. Passed only when constructing the ROOT\n * form — nested `buildForm` calls (from object-typed leaves) pass\n * `undefined`. Used to attach a root-only Zod validator so\n * `z.object({...}).refine(fn)` rules surface as form-level errors\n * without double-reporting leaf issues. See `rootOnlyZodValidator`.\n */\n rootSchema?: z.ZodObject<z.ZodRawShape>,\n): AnyForm {\n const shape = schema.shape\n const fields: Record<string, Field<unknown> | Form<any> | FieldArray<any>> = {}\n for (const key of Object.keys(shape)) {\n const propSchema = shape[key] as AnyZodType\n const initial = initials?.[key]\n const leafPath = path === '' ? key : `${path}.${key}`\n fields[key] = buildLeaf(ctx, propSchema, initial, leafPath, extras)\n }\n // Lift root-level `.refine(...)` checks on the top-level object into a\n // form-level validator. Leaf checks remain owned by leaf-level\n // `zodValidator(propSchema)`; `rootOnlyZodValidator` filters to issues\n // whose `path` is empty so leaf issues are not double-reported.\n if (rootSchema !== undefined) {\n return ctx.form(fields, {\n validators: [rootOnlyZodValidator(rootSchema as z.ZodType<unknown>) as never],\n }) as AnyForm\n }\n return ctx.form(fields) as AnyForm\n}\n\nfunction buildLeaf(\n ctx: Ctx,\n schema: AnyZodType,\n initial: unknown,\n path: string,\n extras: ExtraValidators | undefined,\n): Field<unknown> | Form<any> | FieldArray<any> {\n const inner = unwrap(schema)\n\n if (inner instanceof z.ZodObject) {\n return buildForm(\n ctx,\n inner as z.ZodObject<z.ZodRawShape>,\n initial as Record<string, unknown> | undefined,\n path,\n extras,\n )\n }\n\n if (inner instanceof z.ZodArray) {\n const elementSchema = (inner as z.ZodArray<AnyZodType>).element as AnyZodType\n return ctx.fieldArray(\n // Array items aren't enumerable at schema-build time; we don't extend\n // the dotted path with an index here. Per-item validators belong on\n // the Zod element schema (which `buildLeaf` already wraps via\n // `zodValidator`).\n (itemInitial) =>\n buildLeaf(ctx, elementSchema, itemInitial, path, extras) as Field<unknown> | Form<any>,\n initial !== undefined ? { initial: initial as Array<unknown> } : undefined,\n )\n }\n\n const ini = initial !== undefined ? initial : defaultInitial(schema)\n const validators: Array<Validator<unknown>> = [zodValidator(schema as z.ZodType<unknown>)]\n const extra = extras?.[path]\n if (extra !== undefined) validators.push(extra as Validator<unknown>)\n return ctx.field(ini, validators)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["z"],"sources":["../src/index.ts"],"sourcesContent":["import {\n type Ctx,\n type Field,\n type FieldArray,\n type Form,\n type StandardSchemaV1,\n validator as standardValidator,\n type Validator,\n} from '@kontsedal/olas-core'\nimport { z } from 'zod'\n\n/**\n * Wrap a Zod schema as an Olas validator. Zod 4 implements Standard Schema\n * v1, so this is now a thin alias over the cross-library `validator(...)`\n * from `@kontsedal/olas-core`. Kept under its existing name for back-compat\n * and for code that intentionally signals \"this is a Zod schema.\"\n */\nexport function zodValidator<T>(schema: z.ZodType<T>): Validator<T> {\n return standardValidator(schema as unknown as StandardSchemaV1<T, T>)\n}\n\n/**\n * Async variant for schemas with `.refine(async ...)` or `.transform(async ...)`.\n * Returns a Promise<string | null>.\n */\nexport function zodValidatorAsync<T>(schema: z.ZodType<T>): Validator<T> {\n return async (value, signal) => {\n void signal\n const result = await schema.safeParseAsync(value)\n if (result.success) return null\n return result.error.issues[0]?.message ?? 'Invalid'\n }\n}\n\n/**\n * Run the schema and report only **root-level** issues (those with empty\n * `path`). Leaf issues are already covered by `zodValidator(propSchema)` on\n * each leaf field — surfacing them here would double-count.\n *\n * Used by `formFromZod` to lift root-level `.refine(...)` rules into a\n * form-level validator. Returns `null` when every issue belongs to a leaf\n * (or there are no issues at all).\n */\nexport function rootOnlyZodValidator<T>(schema: z.ZodType<T>): Validator<T> {\n return (value, signal) => {\n void signal\n const result = schema.safeParse(value)\n if (result.success) return null\n for (const issue of result.error.issues) {\n if (issue.path.length === 0) return issue.message\n }\n return null\n }\n}\n\n// Zod 4 typed every wrapper as `z.ZodType`-compatible; the public unwrap path\n// is `.unwrap()` for optional/nullable and `.def.innerType` for default.\ntype AnyZodType = z.ZodType\n\n// Strip the outer optional/nullable/default wrappers to find the inner schema.\nfunction unwrap(schema: AnyZodType): AnyZodType {\n let s: AnyZodType = schema\n // Unwrap default + optional + nullable, in any combination.\n for (let i = 0; i < 5; i++) {\n if (s instanceof z.ZodDefault) {\n // ZodDefault stores the inner schema on `def.innerType`. The runtime\n // shape is stable across 3.x and 4.x; the public type just shifts.\n s = (s as unknown as { def: { innerType: AnyZodType } }).def.innerType\n } else if (s instanceof z.ZodOptional) {\n s = (s as z.ZodOptional<AnyZodType>).unwrap() as AnyZodType\n } else if (s instanceof z.ZodNullable) {\n s = (s as z.ZodNullable<AnyZodType>).unwrap() as AnyZodType\n } else {\n return s\n }\n }\n return s\n}\n\nfunction defaultInitial(schema: AnyZodType): unknown {\n // Honor Zod default if present.\n if (schema instanceof z.ZodDefault) {\n const raw = (schema as unknown as { def: { defaultValue: unknown } }).def.defaultValue\n return typeof raw === 'function' ? (raw as () => unknown)() : raw\n }\n const inner = unwrap(schema)\n if (inner instanceof z.ZodString) return ''\n if (inner instanceof z.ZodNumber) return 0\n if (inner instanceof z.ZodBoolean) return false\n if (inner instanceof z.ZodArray) return []\n if (inner instanceof z.ZodEnum) {\n // Zod 4 widened ZodEnum's options to support record-style enums. The\n // runtime values are still iterable; pick the first.\n const opts = (inner as unknown as { options: readonly unknown[] }).options\n const first = opts[0]\n return typeof first === 'string' ? first : ''\n }\n // For unknown/any/dates etc., undefined is the safest starting point.\n return undefined\n}\n\ntype AnyForm = Form<Record<string, Field<any> | Form<any> | FieldArray<any>>>\n\n// Strip the same wrappers as the runtime `unwrap` helper, at the type level.\ntype UnwrapZod<S> =\n S extends z.ZodDefault<infer Inner>\n ? UnwrapZod<Inner>\n : S extends z.ZodOptional<infer Inner>\n ? UnwrapZod<Inner>\n : S extends z.ZodNullable<infer Inner>\n ? UnwrapZod<Inner>\n : S\n\n/**\n * Recursively map a Zod schema to its Olas form leaf:\n * - `ZodObject<S>` → `Form<{ [K]: ZodToLeaf<S[K]> }>`\n * - `ZodArray<E>` → `FieldArray<ZodToLeaf<E>>` (when E is object/array)\n * or `FieldArray<Field<infer<E>>>` for primitive elements.\n * - everything else → `Field<infer<S>>`.\n *\n * `ZodToLeaf<S>` matches what `buildLeaf(ctx, s, ...)` returns at runtime,\n * so the public `formFromZod<T>` can publish a precise structural type\n * without the consumer needing a hand-written `CardForm = Form<{...}>` cast.\n */\nexport type ZodToLeaf<S> =\n UnwrapZod<S> extends z.ZodObject<infer RawShape>\n ? Form<{ [K in keyof RawShape]: ZodToLeaf<RawShape[K]> }>\n : UnwrapZod<S> extends z.ZodArray<infer Element>\n ? FieldArray<ZodToLeaf<Element> extends Form<any> | Field<any> ? ZodToLeaf<Element> : never>\n : Field<z.infer<UnwrapZod<S> & z.ZodType>>\n\n/**\n * Walk a Zod schema and emit the equivalent Olas Form / FieldArray / Field\n * tree, with validators auto-attached.\n *\n * - `z.object(...)` → `Form`\n * - `z.array(...)` → `FieldArray` (recurses on the element)\n * - leaf schemas → `Field` with `zodValidator(...)` attached\n *\n * Each leaf's initial value is the Zod default if present, otherwise an empty\n * value for that type (`''` for strings, `0` for numbers, etc.).\n *\n * The return type is structurally precise — `form.fields.title.value` is\n * `string` (not `string | boolean | …`), `form.fields.subtasks.add(...)`\n * accepts the exact item shape, etc. Consumers do not need to hand-write\n * a `CardForm = Form<{...}>` matching the schema.\n */\n/**\n * Per-leaf extra validators keyed by dotted path. Match the leaf field's\n * position inside the schema:\n *\n * - top-level: `'title'`\n * - nested form: `'address.street'`\n *\n * `FieldArray` items aren't separately addressable — the schema walker\n * generates one factory per array, so a path of `'tags'` matches the\n * `FieldArray` (validators attached there apply to the array as a whole;\n * use Olas's `FieldArrayOptions.validators` shape). Per-element rules\n * already live on the Zod element schema and are attached automatically.\n *\n * Validators run alongside `zodValidator(schema)` — both must pass.\n */\nexport type ExtraValidators = Record<string, Validator<any>>\n\nexport type FormFromZodOptions<T extends z.ZodObject<z.ZodRawShape>> = {\n initials?: Partial<z.infer<T>>\n extraValidators?: ExtraValidators\n}\n\nexport function formFromZod<T extends z.ZodObject<z.ZodRawShape>>(\n ctx: Ctx,\n schema: T,\n options?: FormFromZodOptions<T>,\n): Form<{ [K in keyof T['shape']]: ZodToLeaf<T['shape'][K]> }> {\n return buildForm(ctx, schema, options?.initials, '', options?.extraValidators, schema) as never\n}\n\nfunction buildForm(\n ctx: Ctx,\n schema: z.ZodObject<z.ZodRawShape>,\n initials: Record<string, unknown> | undefined,\n path: string,\n extras: ExtraValidators | undefined,\n /**\n * The original top-level schema. Passed only when constructing the ROOT\n * form — nested `buildForm` calls (from object-typed leaves) pass\n * `undefined`. Used to attach a root-only Zod validator so\n * `z.object({...}).refine(fn)` rules surface as form-level errors\n * without double-reporting leaf issues. See `rootOnlyZodValidator`.\n */\n rootSchema?: z.ZodObject<z.ZodRawShape>,\n): AnyForm {\n const shape = schema.shape\n const fields: Record<string, Field<unknown> | Form<any> | FieldArray<any>> = {}\n for (const key of Object.keys(shape)) {\n const propSchema = shape[key] as AnyZodType\n const initial = initials?.[key]\n const leafPath = path === '' ? key : `${path}.${key}`\n fields[key] = buildLeaf(ctx, propSchema, initial, leafPath, extras)\n }\n // Lift root-level `.refine(...)` checks on the top-level object into a\n // form-level validator. Leaf checks remain owned by leaf-level\n // `zodValidator(propSchema)`; `rootOnlyZodValidator` filters to issues\n // whose `path` is empty so leaf issues are not double-reported.\n if (rootSchema !== undefined) {\n return ctx.form(fields, {\n validators: [rootOnlyZodValidator(rootSchema as z.ZodType<unknown>) as never],\n }) as AnyForm\n }\n return ctx.form(fields) as AnyForm\n}\n\nfunction buildLeaf(\n ctx: Ctx,\n schema: AnyZodType,\n initial: unknown,\n path: string,\n extras: ExtraValidators | undefined,\n): Field<unknown> | Form<any> | FieldArray<any> {\n const inner = unwrap(schema)\n\n if (inner instanceof z.ZodObject) {\n return buildForm(\n ctx,\n inner as z.ZodObject<z.ZodRawShape>,\n initial as Record<string, unknown> | undefined,\n path,\n extras,\n )\n }\n\n if (inner instanceof z.ZodArray) {\n const elementSchema = (inner as z.ZodArray<AnyZodType>).element as AnyZodType\n return ctx.fieldArray(\n // Array items aren't enumerable at schema-build time; we don't extend\n // the dotted path with an index here. Per-item validators belong on\n // the Zod element schema (which `buildLeaf` already wraps via\n // `zodValidator`).\n (itemInitial) =>\n buildLeaf(ctx, elementSchema, itemInitial, path, extras) as Field<unknown> | Form<any>,\n initial !== undefined ? { initial: initial as Array<unknown> } : undefined,\n )\n }\n\n const ini = initial !== undefined ? initial : defaultInitial(schema)\n const validators: Array<Validator<unknown>> = [zodValidator(schema as z.ZodType<unknown>)]\n const extra = extras?.[path]\n if (extra !== undefined) validators.push(extra as Validator<unknown>)\n return ctx.field(ini, validators)\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,aAAgB,QAAoC;CAClE,QAAA,GAAA,qBAAA,WAAyB,MAA2C;AACtE;;;;;AAMA,SAAgB,kBAAqB,QAAoC;CACvE,OAAO,OAAO,OAAO,WAAW;EAE9B,MAAM,SAAS,MAAM,OAAO,eAAe,KAAK;EAChD,IAAI,OAAO,SAAS,OAAO;EAC3B,OAAO,OAAO,MAAM,OAAO,IAAI,WAAW;CAC5C;AACF;;;;;;;;;;AAWA,SAAgB,qBAAwB,QAAoC;CAC1E,QAAQ,OAAO,WAAW;EAExB,MAAM,SAAS,OAAO,UAAU,KAAK;EACrC,IAAI,OAAO,SAAS,OAAO;EAC3B,KAAK,MAAM,SAAS,OAAO,MAAM,QAC/B,IAAI,MAAM,KAAK,WAAW,GAAG,OAAO,MAAM;EAE5C,OAAO;CACT;AACF;AAOA,SAAS,OAAO,QAAgC;CAC9C,IAAI,IAAgB;CAEpB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,IAAI,aAAaA,IAAAA,EAAE,YAGjB,IAAK,EAAoD,IAAI;MACxD,IAAI,aAAaA,IAAAA,EAAE,aACxB,IAAK,EAAgC,OAAO;MACvC,IAAI,aAAaA,IAAAA,EAAE,aACxB,IAAK,EAAgC,OAAO;MAE5C,OAAO;CAGX,OAAO;AACT;AAEA,SAAS,eAAe,QAA6B;CAEnD,IAAI,kBAAkBA,IAAAA,EAAE,YAAY;EAClC,MAAM,MAAO,OAAyD,IAAI;EAC1E,OAAO,OAAO,QAAQ,aAAc,IAAsB,IAAI;CAChE;CACA,MAAM,QAAQ,OAAO,MAAM;CAC3B,IAAI,iBAAiBA,IAAAA,EAAE,WAAW,OAAO;CACzC,IAAI,iBAAiBA,IAAAA,EAAE,WAAW,OAAO;CACzC,IAAI,iBAAiBA,IAAAA,EAAE,YAAY,OAAO;CAC1C,IAAI,iBAAiBA,IAAAA,EAAE,UAAU,OAAO,CAAC;CACzC,IAAI,iBAAiBA,IAAAA,EAAE,SAAS;EAI9B,MAAM,QADQ,MAAqD,QAChD;EACnB,OAAO,OAAO,UAAU,WAAW,QAAQ;CAC7C;AAGF;AAsEA,SAAgB,YACd,KACA,QACA,SAC6D;CAC7D,OAAO,UAAU,KAAK,QAAQ,SAAS,UAAU,IAAI,SAAS,iBAAiB,MAAM;AACvF;AAEA,SAAS,UACP,KACA,QACA,UACA,MACA,QAQA,YACS;CACT,MAAM,QAAQ,OAAO;CACrB,MAAM,SAAuE,CAAC;CAC9E,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GAAG;EACpC,MAAM,aAAa,MAAM;EACzB,MAAM,UAAU,WAAW;EAE3B,OAAO,OAAO,UAAU,KAAK,YAAY,SADxB,SAAS,KAAK,MAAM,GAAG,KAAK,GAAG,OACY,MAAM;CACpE;CAKA,IAAI,eAAe,KAAA,GACjB,OAAO,IAAI,KAAK,QAAQ,EACtB,YAAY,CAAC,qBAAqB,UAAgC,CAAU,EAC9E,CAAC;CAEH,OAAO,IAAI,KAAK,MAAM;AACxB;AAEA,SAAS,UACP,KACA,QACA,SACA,MACA,QAC8C;CAC9C,MAAM,QAAQ,OAAO,MAAM;CAE3B,IAAI,iBAAiBA,IAAAA,EAAE,WACrB,OAAO,UACL,KACA,OACA,SACA,MACA,MACF;CAGF,IAAI,iBAAiBA,IAAAA,EAAE,UAAU;EAC/B,MAAM,gBAAiB,MAAiC;EACxD,OAAO,IAAI,YAKR,gBACC,UAAU,KAAK,eAAe,aAAa,MAAM,MAAM,GACzD,YAAY,KAAA,IAAY,EAAW,QAA0B,IAAI,KAAA,CACnE;CACF;CAEA,MAAM,MAAM,YAAY,KAAA,IAAY,UAAU,eAAe,MAAM;CACnE,MAAM,aAAwC,CAAC,aAAa,MAA4B,CAAC;CACzF,MAAM,QAAQ,SAAS;CACvB,IAAI,UAAU,KAAA,GAAW,WAAW,KAAK,KAA2B;CACpE,OAAO,IAAI,MAAM,KAAK,UAAU;AAClC"}
package/dist/index.d.cts CHANGED
@@ -3,8 +3,10 @@ import { z } from "zod";
3
3
 
4
4
  //#region src/index.d.ts
5
5
  /**
6
- * Wrap a Zod schema as an Olas validator. Returns a sync or async Validator
7
- * depending on whether the schema requires async parsing (e.g. `.refine(async ...)`).
6
+ * Wrap a Zod schema as an Olas validator. Zod 4 implements Standard Schema
7
+ * v1, so this is now a thin alias over the cross-library `validator(...)`
8
+ * from `@kontsedal/olas-core`. Kept under its existing name for back-compat
9
+ * and for code that intentionally signals "this is a Zod schema."
8
10
  */
9
11
  declare function zodValidator<T>(schema: z.ZodType<T>): Validator<T>;
10
12
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;AAOA;;iBAAgB,YAAA,GAAA,CAAgB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;;;;;iBAcjD,iBAAA,GAAA,CAAqB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;;;;;;;;;;iBAkBtD,oBAAA,GAAA,CAAwB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;AAAA,KA6DpE,SAAA,MACH,CAAA,SAAU,CAAA,CAAE,UAAA,gBACR,SAAA,CAAU,KAAA,IACV,CAAA,SAAU,CAAA,CAAE,WAAA,gBACV,SAAA,CAAU,KAAA,IACV,CAAA,SAAU,CAAA,CAAE,WAAA,gBACV,SAAA,CAAU,KAAA,IACV,CAAA;;;;;;;;;;;;KAaE,SAAA,MACV,SAAA,CAAU,CAAA,UAAW,CAAA,CAAE,SAAA,mBACnB,IAAA,eAAmB,QAAA,GAAW,SAAA,CAAU,QAAA,CAAS,CAAA,QACjD,SAAA,CAAU,CAAA,UAAW,CAAA,CAAE,QAAA,kBACrB,UAAA,CAAW,SAAA,CAAU,OAAA,UAAiB,IAAA,QAAY,KAAA,QAAa,SAAA,CAAU,OAAA,aACzE,KAAA,CAAM,CAAA,CAAE,KAAA,CAAM,SAAA,CAAU,CAAA,IAAK,CAAA,CAAE,OAAA;;;AAxGgC;AAkBvE;;;;;;;;;;;;;;;;;AAA0E;AAUzE;;;;;;;;;;KA6GW,eAAA,GAAkB,MAAM,SAAS,SAAA;AAAA,KAEjC,kBAAA,WAA6B,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA;EACrD,QAAA,GAAW,OAAA,CAAQ,CAAA,CAAE,KAAA,CAAM,CAAA;EAC3B,eAAA,GAAkB,eAAA;AAAA;AAAA,iBAGJ,WAAA,WAAsB,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,EAAA,CAClD,GAAA,EAAK,GAAA,EACL,MAAA,EAAQ,CAAA,EACR,OAAA,GAAU,kBAAA,CAAmB,CAAA,IAC5B,IAAA,eAAmB,CAAA,YAAa,SAAA,CAAU,CAAA,UAAW,CAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;AAiBA;;;;iBAAgB,YAAA,GAAA,CAAgB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;;;;;iBAQjD,iBAAA,GAAA,CAAqB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;;;;;;;;AARJ;AAQlE;iBAkBgB,oBAAA,GAAA,CAAwB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;AAAA,KA6DpE,SAAA,MACH,CAAA,SAAU,CAAA,CAAE,UAAA,gBACR,SAAA,CAAU,KAAA,IACV,CAAA,SAAU,CAAA,CAAE,WAAA,gBACV,SAAA,CAAU,KAAA,IACV,CAAA,SAAU,CAAA,CAAE,WAAA,gBACV,SAAA,CAAU,KAAA,IACV,CAAA;;;;;;;;;;;;KAaE,SAAA,MACV,SAAA,CAAU,CAAA,UAAW,CAAA,CAAE,SAAA,mBACnB,IAAA,eAAmB,QAAA,GAAW,SAAA,CAAU,QAAA,CAAS,CAAA,QACjD,SAAA,CAAU,CAAA,UAAW,CAAA,CAAE,QAAA,kBACrB,UAAA,CAAW,SAAA,CAAU,OAAA,UAAiB,IAAA,QAAY,KAAA,QAAa,SAAA,CAAU,OAAA,aACzE,KAAA,CAAM,CAAA,CAAE,KAAA,CAAM,SAAA,CAAU,CAAA,IAAK,CAAA,CAAE,OAAA;AAxGgC;AAkBvE;;;;;;;;;;;;;;;;;AAA0E;AAUzE;;;;;;;;;;;;KA6GW,eAAA,GAAkB,MAAM,SAAS,SAAA;AAAA,KAEjC,kBAAA,WAA6B,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA;EACrD,QAAA,GAAW,OAAA,CAAQ,CAAA,CAAE,KAAA,CAAM,CAAA;EAC3B,eAAA,GAAkB,eAAA;AAAA;AAAA,iBAGJ,WAAA,WAAsB,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,EAAA,CAClD,GAAA,EAAK,GAAA,EACL,MAAA,EAAQ,CAAA,EACR,OAAA,GAAU,kBAAA,CAAmB,CAAA,IAC5B,IAAA,eAAmB,CAAA,YAAa,SAAA,CAAU,CAAA,UAAW,CAAA"}
package/dist/index.d.mts CHANGED
@@ -1,10 +1,12 @@
1
- import { z } from "zod";
2
1
  import { Ctx, Field, FieldArray, Form, Validator } from "@kontsedal/olas-core";
2
+ import { z } from "zod";
3
3
 
4
4
  //#region src/index.d.ts
5
5
  /**
6
- * Wrap a Zod schema as an Olas validator. Returns a sync or async Validator
7
- * depending on whether the schema requires async parsing (e.g. `.refine(async ...)`).
6
+ * Wrap a Zod schema as an Olas validator. Zod 4 implements Standard Schema
7
+ * v1, so this is now a thin alias over the cross-library `validator(...)`
8
+ * from `@kontsedal/olas-core`. Kept under its existing name for back-compat
9
+ * and for code that intentionally signals "this is a Zod schema."
8
10
  */
9
11
  declare function zodValidator<T>(schema: z.ZodType<T>): Validator<T>;
10
12
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;AAOA;;iBAAgB,YAAA,GAAA,CAAgB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;;;;;iBAcjD,iBAAA,GAAA,CAAqB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;;;;;;;;;;iBAkBtD,oBAAA,GAAA,CAAwB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;AAAA,KA6DpE,SAAA,MACH,CAAA,SAAU,CAAA,CAAE,UAAA,gBACR,SAAA,CAAU,KAAA,IACV,CAAA,SAAU,CAAA,CAAE,WAAA,gBACV,SAAA,CAAU,KAAA,IACV,CAAA,SAAU,CAAA,CAAE,WAAA,gBACV,SAAA,CAAU,KAAA,IACV,CAAA;;;;;;;;;;;;KAaE,SAAA,MACV,SAAA,CAAU,CAAA,UAAW,CAAA,CAAE,SAAA,mBACnB,IAAA,eAAmB,QAAA,GAAW,SAAA,CAAU,QAAA,CAAS,CAAA,QACjD,SAAA,CAAU,CAAA,UAAW,CAAA,CAAE,QAAA,kBACrB,UAAA,CAAW,SAAA,CAAU,OAAA,UAAiB,IAAA,QAAY,KAAA,QAAa,SAAA,CAAU,OAAA,aACzE,KAAA,CAAM,CAAA,CAAE,KAAA,CAAM,SAAA,CAAU,CAAA,IAAK,CAAA,CAAE,OAAA;;;AAxGgC;AAkBvE;;;;;;;;;;;;;;;;;AAA0E;AAUzE;;;;;;;;;;KA6GW,eAAA,GAAkB,MAAM,SAAS,SAAA;AAAA,KAEjC,kBAAA,WAA6B,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA;EACrD,QAAA,GAAW,OAAA,CAAQ,CAAA,CAAE,KAAA,CAAM,CAAA;EAC3B,eAAA,GAAkB,eAAA;AAAA;AAAA,iBAGJ,WAAA,WAAsB,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,EAAA,CAClD,GAAA,EAAK,GAAA,EACL,MAAA,EAAQ,CAAA,EACR,OAAA,GAAU,kBAAA,CAAmB,CAAA,IAC5B,IAAA,eAAmB,CAAA,YAAa,SAAA,CAAU,CAAA,UAAW,CAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;AAiBA;;;;iBAAgB,YAAA,GAAA,CAAgB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;;;;;iBAQjD,iBAAA,GAAA,CAAqB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;;;;;;;;AARJ;AAQlE;iBAkBgB,oBAAA,GAAA,CAAwB,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,CAAA,IAAK,SAAA,CAAU,CAAA;AAAA,KA6DpE,SAAA,MACH,CAAA,SAAU,CAAA,CAAE,UAAA,gBACR,SAAA,CAAU,KAAA,IACV,CAAA,SAAU,CAAA,CAAE,WAAA,gBACV,SAAA,CAAU,KAAA,IACV,CAAA,SAAU,CAAA,CAAE,WAAA,gBACV,SAAA,CAAU,KAAA,IACV,CAAA;;;;;;;;;;;;KAaE,SAAA,MACV,SAAA,CAAU,CAAA,UAAW,CAAA,CAAE,SAAA,mBACnB,IAAA,eAAmB,QAAA,GAAW,SAAA,CAAU,QAAA,CAAS,CAAA,QACjD,SAAA,CAAU,CAAA,UAAW,CAAA,CAAE,QAAA,kBACrB,UAAA,CAAW,SAAA,CAAU,OAAA,UAAiB,IAAA,QAAY,KAAA,QAAa,SAAA,CAAU,OAAA,aACzE,KAAA,CAAM,CAAA,CAAE,KAAA,CAAM,SAAA,CAAU,CAAA,IAAK,CAAA,CAAE,OAAA;AAxGgC;AAkBvE;;;;;;;;;;;;;;;;;AAA0E;AAUzE;;;;;;;;;;;;KA6GW,eAAA,GAAkB,MAAM,SAAS,SAAA;AAAA,KAEjC,kBAAA,WAA6B,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA;EACrD,QAAA,GAAW,OAAA,CAAQ,CAAA,CAAE,KAAA,CAAM,CAAA;EAC3B,eAAA,GAAkB,eAAA;AAAA;AAAA,iBAGJ,WAAA,WAAsB,CAAA,CAAE,SAAA,CAAU,CAAA,CAAE,WAAA,EAAA,CAClD,GAAA,EAAK,GAAA,EACL,MAAA,EAAQ,CAAA,EACR,OAAA,GAAU,kBAAA,CAAmB,CAAA,IAC5B,IAAA,eAAmB,CAAA,YAAa,SAAA,CAAU,CAAA,UAAW,CAAA"}
package/dist/index.mjs CHANGED
@@ -1,15 +1,14 @@
1
+ import { validator } from "@kontsedal/olas-core";
1
2
  import { z } from "zod";
2
3
  //#region src/index.ts
3
4
  /**
4
- * Wrap a Zod schema as an Olas validator. Returns a sync or async Validator
5
- * depending on whether the schema requires async parsing (e.g. `.refine(async ...)`).
5
+ * Wrap a Zod schema as an Olas validator. Zod 4 implements Standard Schema
6
+ * v1, so this is now a thin alias over the cross-library `validator(...)`
7
+ * from `@kontsedal/olas-core`. Kept under its existing name for back-compat
8
+ * and for code that intentionally signals "this is a Zod schema."
6
9
  */
7
10
  function zodValidator(schema) {
8
- return (value, signal) => {
9
- const result = schema.safeParse(value);
10
- if (result.success) return null;
11
- return result.error.issues[0]?.message ?? "Invalid";
12
- };
11
+ return validator(schema);
13
12
  }
14
13
  /**
15
14
  * Async variant for schemas with `.refine(async ...)` or `.transform(async ...)`.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { Ctx, Field, FieldArray, Form, Validator } from '@kontsedal/olas-core'\nimport { z } from 'zod'\n\n/**\n * Wrap a Zod schema as an Olas validator. Returns a sync or async Validator\n * depending on whether the schema requires async parsing (e.g. `.refine(async ...)`).\n */\nexport function zodValidator<T>(schema: z.ZodType<T>): Validator<T> {\n return (value, signal) => {\n // signal isn't used by Zod (parsing is sync) — kept for interface parity.\n void signal\n const result = schema.safeParse(value)\n if (result.success) return null\n return result.error.issues[0]?.message ?? 'Invalid'\n }\n}\n\n/**\n * Async variant for schemas with `.refine(async ...)` or `.transform(async ...)`.\n * Returns a Promise<string | null>.\n */\nexport function zodValidatorAsync<T>(schema: z.ZodType<T>): Validator<T> {\n return async (value, signal) => {\n void signal\n const result = await schema.safeParseAsync(value)\n if (result.success) return null\n return result.error.issues[0]?.message ?? 'Invalid'\n }\n}\n\n/**\n * Run the schema and report only **root-level** issues (those with empty\n * `path`). Leaf issues are already covered by `zodValidator(propSchema)` on\n * each leaf field — surfacing them here would double-count.\n *\n * Used by `formFromZod` to lift root-level `.refine(...)` rules into a\n * form-level validator. Returns `null` when every issue belongs to a leaf\n * (or there are no issues at all).\n */\nexport function rootOnlyZodValidator<T>(schema: z.ZodType<T>): Validator<T> {\n return (value, signal) => {\n void signal\n const result = schema.safeParse(value)\n if (result.success) return null\n for (const issue of result.error.issues) {\n if (issue.path.length === 0) return issue.message\n }\n return null\n }\n}\n\n// Zod 4 typed every wrapper as `z.ZodType`-compatible; the public unwrap path\n// is `.unwrap()` for optional/nullable and `.def.innerType` for default.\ntype AnyZodType = z.ZodType\n\n// Strip the outer optional/nullable/default wrappers to find the inner schema.\nfunction unwrap(schema: AnyZodType): AnyZodType {\n let s: AnyZodType = schema\n // Unwrap default + optional + nullable, in any combination.\n for (let i = 0; i < 5; i++) {\n if (s instanceof z.ZodDefault) {\n // ZodDefault stores the inner schema on `def.innerType`. The runtime\n // shape is stable across 3.x and 4.x; the public type just shifts.\n s = (s as unknown as { def: { innerType: AnyZodType } }).def.innerType\n } else if (s instanceof z.ZodOptional) {\n s = (s as z.ZodOptional<AnyZodType>).unwrap() as AnyZodType\n } else if (s instanceof z.ZodNullable) {\n s = (s as z.ZodNullable<AnyZodType>).unwrap() as AnyZodType\n } else {\n return s\n }\n }\n return s\n}\n\nfunction defaultInitial(schema: AnyZodType): unknown {\n // Honor Zod default if present.\n if (schema instanceof z.ZodDefault) {\n const raw = (schema as unknown as { def: { defaultValue: unknown } }).def.defaultValue\n return typeof raw === 'function' ? (raw as () => unknown)() : raw\n }\n const inner = unwrap(schema)\n if (inner instanceof z.ZodString) return ''\n if (inner instanceof z.ZodNumber) return 0\n if (inner instanceof z.ZodBoolean) return false\n if (inner instanceof z.ZodArray) return []\n if (inner instanceof z.ZodEnum) {\n // Zod 4 widened ZodEnum's options to support record-style enums. The\n // runtime values are still iterable; pick the first.\n const opts = (inner as unknown as { options: readonly unknown[] }).options\n const first = opts[0]\n return typeof first === 'string' ? first : ''\n }\n // For unknown/any/dates etc., undefined is the safest starting point.\n return undefined\n}\n\ntype AnyForm = Form<Record<string, Field<any> | Form<any> | FieldArray<any>>>\n\n// Strip the same wrappers as the runtime `unwrap` helper, at the type level.\ntype UnwrapZod<S> =\n S extends z.ZodDefault<infer Inner>\n ? UnwrapZod<Inner>\n : S extends z.ZodOptional<infer Inner>\n ? UnwrapZod<Inner>\n : S extends z.ZodNullable<infer Inner>\n ? UnwrapZod<Inner>\n : S\n\n/**\n * Recursively map a Zod schema to its Olas form leaf:\n * - `ZodObject<S>` → `Form<{ [K]: ZodToLeaf<S[K]> }>`\n * - `ZodArray<E>` → `FieldArray<ZodToLeaf<E>>` (when E is object/array)\n * or `FieldArray<Field<infer<E>>>` for primitive elements.\n * - everything else → `Field<infer<S>>`.\n *\n * `ZodToLeaf<S>` matches what `buildLeaf(ctx, s, ...)` returns at runtime,\n * so the public `formFromZod<T>` can publish a precise structural type\n * without the consumer needing a hand-written `CardForm = Form<{...}>` cast.\n */\nexport type ZodToLeaf<S> =\n UnwrapZod<S> extends z.ZodObject<infer RawShape>\n ? Form<{ [K in keyof RawShape]: ZodToLeaf<RawShape[K]> }>\n : UnwrapZod<S> extends z.ZodArray<infer Element>\n ? FieldArray<ZodToLeaf<Element> extends Form<any> | Field<any> ? ZodToLeaf<Element> : never>\n : Field<z.infer<UnwrapZod<S> & z.ZodType>>\n\n/**\n * Walk a Zod schema and emit the equivalent Olas Form / FieldArray / Field\n * tree, with validators auto-attached.\n *\n * - `z.object(...)` → `Form`\n * - `z.array(...)` → `FieldArray` (recurses on the element)\n * - leaf schemas → `Field` with `zodValidator(...)` attached\n *\n * Each leaf's initial value is the Zod default if present, otherwise an empty\n * value for that type (`''` for strings, `0` for numbers, etc.).\n *\n * The return type is structurally precise — `form.fields.title.value` is\n * `string` (not `string | boolean | …`), `form.fields.subtasks.add(...)`\n * accepts the exact item shape, etc. Consumers do not need to hand-write\n * a `CardForm = Form<{...}>` matching the schema.\n */\n/**\n * Per-leaf extra validators keyed by dotted path. Match the leaf field's\n * position inside the schema:\n *\n * - top-level: `'title'`\n * - nested form: `'address.street'`\n *\n * `FieldArray` items aren't separately addressable — the schema walker\n * generates one factory per array, so a path of `'tags'` matches the\n * `FieldArray` (validators attached there apply to the array as a whole;\n * use Olas's `FieldArrayOptions.validators` shape). Per-element rules\n * already live on the Zod element schema and are attached automatically.\n *\n * Validators run alongside `zodValidator(schema)` — both must pass.\n */\nexport type ExtraValidators = Record<string, Validator<any>>\n\nexport type FormFromZodOptions<T extends z.ZodObject<z.ZodRawShape>> = {\n initials?: Partial<z.infer<T>>\n extraValidators?: ExtraValidators\n}\n\nexport function formFromZod<T extends z.ZodObject<z.ZodRawShape>>(\n ctx: Ctx,\n schema: T,\n options?: FormFromZodOptions<T>,\n): Form<{ [K in keyof T['shape']]: ZodToLeaf<T['shape'][K]> }> {\n return buildForm(ctx, schema, options?.initials, '', options?.extraValidators, schema) as never\n}\n\nfunction buildForm(\n ctx: Ctx,\n schema: z.ZodObject<z.ZodRawShape>,\n initials: Record<string, unknown> | undefined,\n path: string,\n extras: ExtraValidators | undefined,\n /**\n * The original top-level schema. Passed only when constructing the ROOT\n * form — nested `buildForm` calls (from object-typed leaves) pass\n * `undefined`. Used to attach a root-only Zod validator so\n * `z.object({...}).refine(fn)` rules surface as form-level errors\n * without double-reporting leaf issues. See `rootOnlyZodValidator`.\n */\n rootSchema?: z.ZodObject<z.ZodRawShape>,\n): AnyForm {\n const shape = schema.shape\n const fields: Record<string, Field<unknown> | Form<any> | FieldArray<any>> = {}\n for (const key of Object.keys(shape)) {\n const propSchema = shape[key] as AnyZodType\n const initial = initials?.[key]\n const leafPath = path === '' ? key : `${path}.${key}`\n fields[key] = buildLeaf(ctx, propSchema, initial, leafPath, extras)\n }\n // Lift root-level `.refine(...)` checks on the top-level object into a\n // form-level validator. Leaf checks remain owned by leaf-level\n // `zodValidator(propSchema)`; `rootOnlyZodValidator` filters to issues\n // whose `path` is empty so leaf issues are not double-reported.\n if (rootSchema !== undefined) {\n return ctx.form(fields, {\n validators: [rootOnlyZodValidator(rootSchema as z.ZodType<unknown>) as never],\n }) as AnyForm\n }\n return ctx.form(fields) as AnyForm\n}\n\nfunction buildLeaf(\n ctx: Ctx,\n schema: AnyZodType,\n initial: unknown,\n path: string,\n extras: ExtraValidators | undefined,\n): Field<unknown> | Form<any> | FieldArray<any> {\n const inner = unwrap(schema)\n\n if (inner instanceof z.ZodObject) {\n return buildForm(\n ctx,\n inner as z.ZodObject<z.ZodRawShape>,\n initial as Record<string, unknown> | undefined,\n path,\n extras,\n )\n }\n\n if (inner instanceof z.ZodArray) {\n const elementSchema = (inner as z.ZodArray<AnyZodType>).element as AnyZodType\n return ctx.fieldArray(\n // Array items aren't enumerable at schema-build time; we don't extend\n // the dotted path with an index here. Per-item validators belong on\n // the Zod element schema (which `buildLeaf` already wraps via\n // `zodValidator`).\n (itemInitial) =>\n buildLeaf(ctx, elementSchema, itemInitial, path, extras) as Field<unknown> | Form<any>,\n initial !== undefined ? { initial: initial as Array<unknown> } : undefined,\n )\n }\n\n const ini = initial !== undefined ? initial : defaultInitial(schema)\n const validators: Array<Validator<unknown>> = [zodValidator(schema as z.ZodType<unknown>)]\n const extra = extras?.[path]\n if (extra !== undefined) validators.push(extra as Validator<unknown>)\n return ctx.field(ini, validators)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["standardValidator"],"sources":["../src/index.ts"],"sourcesContent":["import {\n type Ctx,\n type Field,\n type FieldArray,\n type Form,\n type StandardSchemaV1,\n validator as standardValidator,\n type Validator,\n} from '@kontsedal/olas-core'\nimport { z } from 'zod'\n\n/**\n * Wrap a Zod schema as an Olas validator. Zod 4 implements Standard Schema\n * v1, so this is now a thin alias over the cross-library `validator(...)`\n * from `@kontsedal/olas-core`. Kept under its existing name for back-compat\n * and for code that intentionally signals \"this is a Zod schema.\"\n */\nexport function zodValidator<T>(schema: z.ZodType<T>): Validator<T> {\n return standardValidator(schema as unknown as StandardSchemaV1<T, T>)\n}\n\n/**\n * Async variant for schemas with `.refine(async ...)` or `.transform(async ...)`.\n * Returns a Promise<string | null>.\n */\nexport function zodValidatorAsync<T>(schema: z.ZodType<T>): Validator<T> {\n return async (value, signal) => {\n void signal\n const result = await schema.safeParseAsync(value)\n if (result.success) return null\n return result.error.issues[0]?.message ?? 'Invalid'\n }\n}\n\n/**\n * Run the schema and report only **root-level** issues (those with empty\n * `path`). Leaf issues are already covered by `zodValidator(propSchema)` on\n * each leaf field — surfacing them here would double-count.\n *\n * Used by `formFromZod` to lift root-level `.refine(...)` rules into a\n * form-level validator. Returns `null` when every issue belongs to a leaf\n * (or there are no issues at all).\n */\nexport function rootOnlyZodValidator<T>(schema: z.ZodType<T>): Validator<T> {\n return (value, signal) => {\n void signal\n const result = schema.safeParse(value)\n if (result.success) return null\n for (const issue of result.error.issues) {\n if (issue.path.length === 0) return issue.message\n }\n return null\n }\n}\n\n// Zod 4 typed every wrapper as `z.ZodType`-compatible; the public unwrap path\n// is `.unwrap()` for optional/nullable and `.def.innerType` for default.\ntype AnyZodType = z.ZodType\n\n// Strip the outer optional/nullable/default wrappers to find the inner schema.\nfunction unwrap(schema: AnyZodType): AnyZodType {\n let s: AnyZodType = schema\n // Unwrap default + optional + nullable, in any combination.\n for (let i = 0; i < 5; i++) {\n if (s instanceof z.ZodDefault) {\n // ZodDefault stores the inner schema on `def.innerType`. The runtime\n // shape is stable across 3.x and 4.x; the public type just shifts.\n s = (s as unknown as { def: { innerType: AnyZodType } }).def.innerType\n } else if (s instanceof z.ZodOptional) {\n s = (s as z.ZodOptional<AnyZodType>).unwrap() as AnyZodType\n } else if (s instanceof z.ZodNullable) {\n s = (s as z.ZodNullable<AnyZodType>).unwrap() as AnyZodType\n } else {\n return s\n }\n }\n return s\n}\n\nfunction defaultInitial(schema: AnyZodType): unknown {\n // Honor Zod default if present.\n if (schema instanceof z.ZodDefault) {\n const raw = (schema as unknown as { def: { defaultValue: unknown } }).def.defaultValue\n return typeof raw === 'function' ? (raw as () => unknown)() : raw\n }\n const inner = unwrap(schema)\n if (inner instanceof z.ZodString) return ''\n if (inner instanceof z.ZodNumber) return 0\n if (inner instanceof z.ZodBoolean) return false\n if (inner instanceof z.ZodArray) return []\n if (inner instanceof z.ZodEnum) {\n // Zod 4 widened ZodEnum's options to support record-style enums. The\n // runtime values are still iterable; pick the first.\n const opts = (inner as unknown as { options: readonly unknown[] }).options\n const first = opts[0]\n return typeof first === 'string' ? first : ''\n }\n // For unknown/any/dates etc., undefined is the safest starting point.\n return undefined\n}\n\ntype AnyForm = Form<Record<string, Field<any> | Form<any> | FieldArray<any>>>\n\n// Strip the same wrappers as the runtime `unwrap` helper, at the type level.\ntype UnwrapZod<S> =\n S extends z.ZodDefault<infer Inner>\n ? UnwrapZod<Inner>\n : S extends z.ZodOptional<infer Inner>\n ? UnwrapZod<Inner>\n : S extends z.ZodNullable<infer Inner>\n ? UnwrapZod<Inner>\n : S\n\n/**\n * Recursively map a Zod schema to its Olas form leaf:\n * - `ZodObject<S>` → `Form<{ [K]: ZodToLeaf<S[K]> }>`\n * - `ZodArray<E>` → `FieldArray<ZodToLeaf<E>>` (when E is object/array)\n * or `FieldArray<Field<infer<E>>>` for primitive elements.\n * - everything else → `Field<infer<S>>`.\n *\n * `ZodToLeaf<S>` matches what `buildLeaf(ctx, s, ...)` returns at runtime,\n * so the public `formFromZod<T>` can publish a precise structural type\n * without the consumer needing a hand-written `CardForm = Form<{...}>` cast.\n */\nexport type ZodToLeaf<S> =\n UnwrapZod<S> extends z.ZodObject<infer RawShape>\n ? Form<{ [K in keyof RawShape]: ZodToLeaf<RawShape[K]> }>\n : UnwrapZod<S> extends z.ZodArray<infer Element>\n ? FieldArray<ZodToLeaf<Element> extends Form<any> | Field<any> ? ZodToLeaf<Element> : never>\n : Field<z.infer<UnwrapZod<S> & z.ZodType>>\n\n/**\n * Walk a Zod schema and emit the equivalent Olas Form / FieldArray / Field\n * tree, with validators auto-attached.\n *\n * - `z.object(...)` → `Form`\n * - `z.array(...)` → `FieldArray` (recurses on the element)\n * - leaf schemas → `Field` with `zodValidator(...)` attached\n *\n * Each leaf's initial value is the Zod default if present, otherwise an empty\n * value for that type (`''` for strings, `0` for numbers, etc.).\n *\n * The return type is structurally precise — `form.fields.title.value` is\n * `string` (not `string | boolean | …`), `form.fields.subtasks.add(...)`\n * accepts the exact item shape, etc. Consumers do not need to hand-write\n * a `CardForm = Form<{...}>` matching the schema.\n */\n/**\n * Per-leaf extra validators keyed by dotted path. Match the leaf field's\n * position inside the schema:\n *\n * - top-level: `'title'`\n * - nested form: `'address.street'`\n *\n * `FieldArray` items aren't separately addressable — the schema walker\n * generates one factory per array, so a path of `'tags'` matches the\n * `FieldArray` (validators attached there apply to the array as a whole;\n * use Olas's `FieldArrayOptions.validators` shape). Per-element rules\n * already live on the Zod element schema and are attached automatically.\n *\n * Validators run alongside `zodValidator(schema)` — both must pass.\n */\nexport type ExtraValidators = Record<string, Validator<any>>\n\nexport type FormFromZodOptions<T extends z.ZodObject<z.ZodRawShape>> = {\n initials?: Partial<z.infer<T>>\n extraValidators?: ExtraValidators\n}\n\nexport function formFromZod<T extends z.ZodObject<z.ZodRawShape>>(\n ctx: Ctx,\n schema: T,\n options?: FormFromZodOptions<T>,\n): Form<{ [K in keyof T['shape']]: ZodToLeaf<T['shape'][K]> }> {\n return buildForm(ctx, schema, options?.initials, '', options?.extraValidators, schema) as never\n}\n\nfunction buildForm(\n ctx: Ctx,\n schema: z.ZodObject<z.ZodRawShape>,\n initials: Record<string, unknown> | undefined,\n path: string,\n extras: ExtraValidators | undefined,\n /**\n * The original top-level schema. Passed only when constructing the ROOT\n * form — nested `buildForm` calls (from object-typed leaves) pass\n * `undefined`. Used to attach a root-only Zod validator so\n * `z.object({...}).refine(fn)` rules surface as form-level errors\n * without double-reporting leaf issues. See `rootOnlyZodValidator`.\n */\n rootSchema?: z.ZodObject<z.ZodRawShape>,\n): AnyForm {\n const shape = schema.shape\n const fields: Record<string, Field<unknown> | Form<any> | FieldArray<any>> = {}\n for (const key of Object.keys(shape)) {\n const propSchema = shape[key] as AnyZodType\n const initial = initials?.[key]\n const leafPath = path === '' ? key : `${path}.${key}`\n fields[key] = buildLeaf(ctx, propSchema, initial, leafPath, extras)\n }\n // Lift root-level `.refine(...)` checks on the top-level object into a\n // form-level validator. Leaf checks remain owned by leaf-level\n // `zodValidator(propSchema)`; `rootOnlyZodValidator` filters to issues\n // whose `path` is empty so leaf issues are not double-reported.\n if (rootSchema !== undefined) {\n return ctx.form(fields, {\n validators: [rootOnlyZodValidator(rootSchema as z.ZodType<unknown>) as never],\n }) as AnyForm\n }\n return ctx.form(fields) as AnyForm\n}\n\nfunction buildLeaf(\n ctx: Ctx,\n schema: AnyZodType,\n initial: unknown,\n path: string,\n extras: ExtraValidators | undefined,\n): Field<unknown> | Form<any> | FieldArray<any> {\n const inner = unwrap(schema)\n\n if (inner instanceof z.ZodObject) {\n return buildForm(\n ctx,\n inner as z.ZodObject<z.ZodRawShape>,\n initial as Record<string, unknown> | undefined,\n path,\n extras,\n )\n }\n\n if (inner instanceof z.ZodArray) {\n const elementSchema = (inner as z.ZodArray<AnyZodType>).element as AnyZodType\n return ctx.fieldArray(\n // Array items aren't enumerable at schema-build time; we don't extend\n // the dotted path with an index here. Per-item validators belong on\n // the Zod element schema (which `buildLeaf` already wraps via\n // `zodValidator`).\n (itemInitial) =>\n buildLeaf(ctx, elementSchema, itemInitial, path, extras) as Field<unknown> | Form<any>,\n initial !== undefined ? { initial: initial as Array<unknown> } : undefined,\n )\n }\n\n const ini = initial !== undefined ? initial : defaultInitial(schema)\n const validators: Array<Validator<unknown>> = [zodValidator(schema as z.ZodType<unknown>)]\n const extra = extras?.[path]\n if (extra !== undefined) validators.push(extra as Validator<unknown>)\n return ctx.field(ini, validators)\n}\n"],"mappings":";;;;;;;;;AAiBA,SAAgB,aAAgB,QAAoC;CAClE,OAAOA,UAAkB,MAA2C;AACtE;;;;;AAMA,SAAgB,kBAAqB,QAAoC;CACvE,OAAO,OAAO,OAAO,WAAW;EAE9B,MAAM,SAAS,MAAM,OAAO,eAAe,KAAK;EAChD,IAAI,OAAO,SAAS,OAAO;EAC3B,OAAO,OAAO,MAAM,OAAO,IAAI,WAAW;CAC5C;AACF;;;;;;;;;;AAWA,SAAgB,qBAAwB,QAAoC;CAC1E,QAAQ,OAAO,WAAW;EAExB,MAAM,SAAS,OAAO,UAAU,KAAK;EACrC,IAAI,OAAO,SAAS,OAAO;EAC3B,KAAK,MAAM,SAAS,OAAO,MAAM,QAC/B,IAAI,MAAM,KAAK,WAAW,GAAG,OAAO,MAAM;EAE5C,OAAO;CACT;AACF;AAOA,SAAS,OAAO,QAAgC;CAC9C,IAAI,IAAgB;CAEpB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,IAAI,aAAa,EAAE,YAGjB,IAAK,EAAoD,IAAI;MACxD,IAAI,aAAa,EAAE,aACxB,IAAK,EAAgC,OAAO;MACvC,IAAI,aAAa,EAAE,aACxB,IAAK,EAAgC,OAAO;MAE5C,OAAO;CAGX,OAAO;AACT;AAEA,SAAS,eAAe,QAA6B;CAEnD,IAAI,kBAAkB,EAAE,YAAY;EAClC,MAAM,MAAO,OAAyD,IAAI;EAC1E,OAAO,OAAO,QAAQ,aAAc,IAAsB,IAAI;CAChE;CACA,MAAM,QAAQ,OAAO,MAAM;CAC3B,IAAI,iBAAiB,EAAE,WAAW,OAAO;CACzC,IAAI,iBAAiB,EAAE,WAAW,OAAO;CACzC,IAAI,iBAAiB,EAAE,YAAY,OAAO;CAC1C,IAAI,iBAAiB,EAAE,UAAU,OAAO,CAAC;CACzC,IAAI,iBAAiB,EAAE,SAAS;EAI9B,MAAM,QADQ,MAAqD,QAChD;EACnB,OAAO,OAAO,UAAU,WAAW,QAAQ;CAC7C;AAGF;AAsEA,SAAgB,YACd,KACA,QACA,SAC6D;CAC7D,OAAO,UAAU,KAAK,QAAQ,SAAS,UAAU,IAAI,SAAS,iBAAiB,MAAM;AACvF;AAEA,SAAS,UACP,KACA,QACA,UACA,MACA,QAQA,YACS;CACT,MAAM,QAAQ,OAAO;CACrB,MAAM,SAAuE,CAAC;CAC9E,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GAAG;EACpC,MAAM,aAAa,MAAM;EACzB,MAAM,UAAU,WAAW;EAE3B,OAAO,OAAO,UAAU,KAAK,YAAY,SADxB,SAAS,KAAK,MAAM,GAAG,KAAK,GAAG,OACY,MAAM;CACpE;CAKA,IAAI,eAAe,KAAA,GACjB,OAAO,IAAI,KAAK,QAAQ,EACtB,YAAY,CAAC,qBAAqB,UAAgC,CAAU,EAC9E,CAAC;CAEH,OAAO,IAAI,KAAK,MAAM;AACxB;AAEA,SAAS,UACP,KACA,QACA,SACA,MACA,QAC8C;CAC9C,MAAM,QAAQ,OAAO,MAAM;CAE3B,IAAI,iBAAiB,EAAE,WACrB,OAAO,UACL,KACA,OACA,SACA,MACA,MACF;CAGF,IAAI,iBAAiB,EAAE,UAAU;EAC/B,MAAM,gBAAiB,MAAiC;EACxD,OAAO,IAAI,YAKR,gBACC,UAAU,KAAK,eAAe,aAAa,MAAM,MAAM,GACzD,YAAY,KAAA,IAAY,EAAW,QAA0B,IAAI,KAAA,CACnE;CACF;CAEA,MAAM,MAAM,YAAY,KAAA,IAAY,UAAU,eAAe,MAAM;CACnE,MAAM,aAAwC,CAAC,aAAa,MAA4B,CAAC;CACzF,MAAM,QAAQ,SAAS;CACvB,IAAI,UAAU,KAAA,GAAW,WAAW,KAAK,KAA2B;CACpE,OAAO,IAAI,MAAM,KAAK,UAAU;AAClC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontsedal/olas-zod",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Olas Zod integration — zodValidator and formFromZod for end-to-end typed forms.",
5
5
  "keywords": [
6
6
  "olas",
@@ -46,11 +46,11 @@
46
46
  "sideEffects": false,
47
47
  "peerDependencies": {
48
48
  "zod": "^4.0.0",
49
- "@kontsedal/olas-core": "^0.0.2"
49
+ "@kontsedal/olas-core": "^0.0.4"
50
50
  },
51
51
  "devDependencies": {
52
52
  "zod": "^4.4.3",
53
- "@kontsedal/olas-core": "^0.0.2"
53
+ "@kontsedal/olas-core": "^0.0.4"
54
54
  },
55
55
  "publishConfig": {
56
56
  "access": "public"
package/src/index.ts CHANGED
@@ -1,18 +1,22 @@
1
- import type { Ctx, Field, FieldArray, Form, Validator } from '@kontsedal/olas-core'
1
+ import {
2
+ type Ctx,
3
+ type Field,
4
+ type FieldArray,
5
+ type Form,
6
+ type StandardSchemaV1,
7
+ validator as standardValidator,
8
+ type Validator,
9
+ } from '@kontsedal/olas-core'
2
10
  import { z } from 'zod'
3
11
 
4
12
  /**
5
- * Wrap a Zod schema as an Olas validator. Returns a sync or async Validator
6
- * depending on whether the schema requires async parsing (e.g. `.refine(async ...)`).
13
+ * Wrap a Zod schema as an Olas validator. Zod 4 implements Standard Schema
14
+ * v1, so this is now a thin alias over the cross-library `validator(...)`
15
+ * from `@kontsedal/olas-core`. Kept under its existing name for back-compat
16
+ * and for code that intentionally signals "this is a Zod schema."
7
17
  */
8
18
  export function zodValidator<T>(schema: z.ZodType<T>): Validator<T> {
9
- return (value, signal) => {
10
- // signal isn't used by Zod (parsing is sync) — kept for interface parity.
11
- void signal
12
- const result = schema.safeParse(value)
13
- if (result.success) return null
14
- return result.error.issues[0]?.message ?? 'Invalid'
15
- }
19
+ return standardValidator(schema as unknown as StandardSchemaV1<T, T>)
16
20
  }
17
21
 
18
22
  /**