zodvex 0.7.1-beta.8 → 0.7.1-beta.9

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.
Files changed (55) hide show
  1. package/dist/boundaryHelpers.d.ts +1 -1
  2. package/dist/boundaryHelpers.d.ts.map +1 -1
  3. package/dist/client/index.js +2 -1
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/codec.d.ts +1 -1
  6. package/dist/core/index.js +104 -102
  7. package/dist/core/index.js.map +1 -1
  8. package/dist/index.js +130 -123
  9. package/dist/index.js.map +1 -1
  10. package/dist/mini/index.d.ts +26 -27
  11. package/dist/mini/index.d.ts.map +1 -1
  12. package/dist/mini/index.js +104 -102
  13. package/dist/mini/index.js.map +1 -1
  14. package/dist/mini/server/index.d.ts +10 -0
  15. package/dist/mini/server/index.d.ts.map +1 -0
  16. package/dist/mini/server/index.js +2240 -0
  17. package/dist/mini/server/index.js.map +1 -0
  18. package/dist/model.d.ts +37 -25
  19. package/dist/model.d.ts.map +1 -1
  20. package/dist/react/index.js +2 -1
  21. package/dist/react/index.js.map +1 -1
  22. package/dist/schema.d.ts +24 -6
  23. package/dist/schema.d.ts.map +1 -1
  24. package/dist/schemaHelpers.d.ts +28 -6
  25. package/dist/schemaHelpers.d.ts.map +1 -1
  26. package/dist/server/index.js +66 -59
  27. package/dist/server/index.js.map +1 -1
  28. package/dist/serverUtils.d.ts +2 -1
  29. package/dist/serverUtils.d.ts.map +1 -1
  30. package/dist/stripUndefined.d.ts +9 -0
  31. package/dist/stripUndefined.d.ts.map +1 -0
  32. package/dist/types.d.ts +4 -5
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/utils.d.ts +5 -5
  35. package/dist/utils.d.ts.map +1 -1
  36. package/dist/zod-core.d.ts +1 -1
  37. package/dist/zod-core.d.ts.map +1 -1
  38. package/dist/zx.d.ts +3 -4
  39. package/dist/zx.d.ts.map +1 -1
  40. package/package.json +8 -2
  41. package/src/boundaryHelpers.ts +3 -4
  42. package/src/builders.ts +3 -3
  43. package/src/codec.ts +1 -1
  44. package/src/db.ts +2 -2
  45. package/src/mini/index.ts +39 -32
  46. package/src/mini/server/index.ts +13 -0
  47. package/src/model.ts +53 -22
  48. package/src/schema.ts +41 -18
  49. package/src/schemaHelpers.ts +56 -23
  50. package/src/serverUtils.ts +2 -2
  51. package/src/stripUndefined.ts +29 -0
  52. package/src/types.ts +5 -5
  53. package/src/utils.ts +8 -25
  54. package/src/zod-core.ts +2 -1
  55. package/src/zx.ts +3 -3
@@ -10,7 +10,7 @@ export type BoundaryHelpersOptions = {
10
10
  * How to handle decode failures (schema validation errors on wire data).
11
11
  *
12
12
  * - `'warn'` (default): log a console.warn and return raw wire data untransformed.
13
- * - `'throw'`: throw a ZodvexDecodeError (extends z.ZodError).
13
+ * - `'throw'`: throw a ZodvexDecodeError (extends z.ZodError). // zod-ok
14
14
  */
15
15
  onDecodeError?: 'warn' | 'throw';
16
16
  };
@@ -1 +1 @@
1
- {"version":3,"file":"boundaryHelpers.d.ts","sourceRoot":"","sources":["../src/boundaryHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAA;AAsBjD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC,CAAA;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;gBAEd,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,OAAO;CAMzE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB;sBAgBlE,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,GAAG,KAAG,GAAG;wBA4BpD,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,cAAc,GAAG,KAAG,GAAG;EAsBxF;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
1
+ {"version":3,"file":"boundaryHelpers.d.ts","sourceRoot":"","sources":["../src/boundaryHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAG5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAA;AAsBjD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC,CAAA;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;gBAEd,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,OAAO;CAMzE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB;sBAgBlE,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,GAAG,KAAG,GAAG;wBA4BpD,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,cAAc,GAAG,KAAG,GAAG;EAsBxF;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
@@ -1,6 +1,5 @@
1
1
  import { ConvexClient } from 'convex/browser';
2
2
  import { safeParse, $ZodError, encode, $ZodCodec, $ZodObject, $ZodArray, $ZodOptional, $ZodNullable, $ZodDefault } from 'zod/v4/core';
3
- import 'zod';
4
3
 
5
4
  // src/client/zodvexClient.ts
6
5
 
@@ -62,6 +61,8 @@ function safeEncode(schema, value) {
62
61
  throw e;
63
62
  }
64
63
  }
64
+
65
+ // src/stripUndefined.ts
65
66
  function stripUndefined(value) {
66
67
  if (value === null || value === void 0) {
67
68
  return value;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/normalizeCodecPaths.ts","../../src/utils.ts","../../src/boundaryHelpers.ts","../../src/client/zodvexClient.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import {\n $ZodArray,\n $ZodCodec,\n $ZodDefault,\n $ZodError,\n $ZodNullable,\n $ZodObject,\n $ZodOptional,\n $ZodType,\n encode\n} from './zod-core'\n\n/**\n * Unwraps ZodOptional/ZodNullable/ZodDefault wrappers to get the structural type.\n */\nfunction unwrapOuter(schema: $ZodType): $ZodType {\n let current: $ZodType = schema\n for (let i = 0; i < 10; i++) {\n if (\n current instanceof $ZodOptional ||\n current instanceof $ZodNullable ||\n current instanceof $ZodDefault\n ) {\n current = current._zod.def.innerType\n continue\n }\n break\n }\n return current\n}\n\n/**\n * Walks a path through a schema tree, truncating at codec boundaries.\n * When a codec is encountered, the path is cut — any deeper segments\n * are wire-internal and should not be exposed to consumers.\n */\nfunction truncateAtCodecBoundary(path: (string | number)[], schema: $ZodType): (string | number)[] {\n const result: (string | number)[] = []\n let current: $ZodType = schema\n\n for (const segment of path) {\n current = unwrapOuter(current)\n\n // If we've landed on a codec, everything from here is wire-internal — stop\n if (current instanceof $ZodCodec) {\n break\n }\n\n // Descend into objects\n if (current instanceof $ZodObject && typeof segment === 'string') {\n const fieldSchema = current._zod.def.shape[segment] as $ZodType | undefined\n if (!fieldSchema) {\n // Unknown field — include segment and stop\n result.push(segment)\n break\n }\n\n result.push(segment)\n\n const unwrapped = unwrapOuter(fieldSchema)\n if (unwrapped instanceof $ZodCodec) {\n // Hit a codec boundary — truncate here\n break\n }\n\n current = fieldSchema\n continue\n }\n\n // Descend into arrays\n if (current instanceof $ZodArray && typeof segment === 'number') {\n result.push(segment)\n current = current._zod.def.element\n continue\n }\n\n // For anything else (unions, records, etc.), include segment and continue\n result.push(segment)\n }\n\n return result\n}\n\n/**\n * Normalizes ZodError paths by truncating at codec boundaries.\n *\n * When z.encode() throws a ZodError, the paths reflect the wire schema\n * structure (e.g., [\"email\", \"value\"] for a custom codec).\n * This function strips the wire-internal segments so consumers see\n * clean field-level paths (e.g., [\"email\"]).\n */\nexport function normalizeCodecPaths(error: $ZodError, schema: $ZodType): $ZodError {\n const normalized = error.issues.map(issue => ({\n ...issue,\n path: truncateAtCodecBoundary(issue.path as (string | number)[], schema)\n }))\n return new $ZodError(normalized)\n}\n\n/**\n * Encodes a value through a Zod schema, normalizing codec-internal\n * path segments in any ZodError before re-throwing.\n *\n * Drop-in replacement for `z.encode(schema, value)` at client boundaries.\n */\nexport function safeEncode(schema: $ZodType, value: unknown): unknown {\n try {\n return encode(schema, value)\n } catch (e) {\n if (e instanceof $ZodError) throw normalizeCodecPaths(e as $ZodError, schema)\n throw e\n }\n}\n","import { z } from 'zod'\nimport {\n $ZodArray,\n $ZodCodec,\n $ZodDate,\n $ZodDefault,\n $ZodNullable,\n $ZodObject,\n $ZodOptional,\n $ZodRecord,\n $ZodTuple,\n $ZodType,\n $ZodUnion,\n type input as zinput\n} from './zod-core'\n\n// Private copy — importing from ./mapping pulls convex/values into client bundles\n// (mapping/utils.ts imports `v` from convex/values which is server-only).\nfunction getObjectShape(obj: any): Record<string, any> {\n if (obj instanceof $ZodObject) return obj._zod.def.shape as Record<string, any>\n if (obj && typeof obj === 'object' && typeof obj.shape === 'object')\n return obj.shape as Record<string, any>\n return {}\n}\n\nexport function pick<T extends Record<string, any>, K extends keyof T>(\n obj: T,\n keys: K[]\n): Pick<T, K> {\n const result = {} as Pick<T, K>\n for (const key of keys) {\n if (key in obj) result[key] = obj[key]\n }\n return result\n}\n\n// Typed identity helper for returns schemas\nexport function returnsAs<R extends $ZodType>() {\n return <T extends zinput<R>>(v: T) => v\n}\n\n/**\n * Recursively strips undefined values from objects for Convex serialization.\n * Convex rejects objects with explicit undefined properties, so we need to\n * remove them before returning from handlers.\n *\n * Only processes plain objects (Object.prototype). Class instances, Dates,\n * and other non-plain objects are passed through unchanged.\n *\n * @param value - The value to strip undefined from\n * @returns The value with undefined properties removed from plain objects\n */\nexport function stripUndefined<T>(value: T): T {\n if (value === null || value === undefined) {\n return value\n }\n\n if (Array.isArray(value)) {\n return value.map(stripUndefined) as T\n }\n\n // Only process plain objects (not class instances, Dates, etc.)\n if (typeof value === 'object' && value.constructor === Object) {\n const result: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(value)) {\n if (val !== undefined) {\n result[key] = stripUndefined(val)\n }\n }\n return result as T\n }\n\n return value\n}\n\n// Helper: standard Convex paginate() result schema\nexport function zPaginated<T extends $ZodType>(item: T) {\n return z.object({\n page: z.array(item),\n isDone: z.boolean(),\n continueCursor: z.optional(z.nullable(z.string()))\n })\n}\n\n/**\n * Maps Date fields to number fields for docSchema generation.\n * Handles Date, Date.optional(), Date.nullable(), and Date.default() cases.\n * Returns the original field for non-Date types.\n *\n * @deprecated Use `zx.date()` instead for automatic Date ↔ timestamp conversion.\n */\nexport function mapDateFieldToNumber(field: $ZodType): $ZodType {\n // Direct Date field\n if (field instanceof $ZodDate) {\n return z.number()\n }\n\n // Optional Date field\n if (field instanceof $ZodOptional && field._zod.def.innerType instanceof $ZodDate) {\n return z.optional(z.number())\n }\n\n // Nullable Date field\n if (field instanceof $ZodNullable && field._zod.def.innerType instanceof $ZodDate) {\n return z.nullable(z.number())\n }\n\n // Date with default value\n if (field instanceof $ZodDefault) {\n const inner = field._zod.def.innerType\n if (inner instanceof $ZodDate) {\n return z.optional(z.number())\n }\n }\n\n // Non-Date field - return as-is\n return field\n}\n\n// Schema picking utilities (moved from pick.ts for consolidation)\ntype Mask = readonly string[] | Record<string, boolean | 1 | true>\n\nfunction toKeys(mask: Mask): string[] {\n if (Array.isArray(mask)) return mask.map(String)\n return Object.keys(mask).filter(k => !!(mask as any)[k])\n}\n\n/**\n * Returns a plain shape object containing only the selected fields.\n * Accepts either a ZodObject or a raw shape object.\n */\nexport function pickShape(\n schemaOrShape: z.ZodObject<any> | Record<string, any>,\n mask: Mask\n): Record<string, any> {\n const keys = toKeys(mask)\n const shape =\n schemaOrShape instanceof $ZodObject ? getObjectShape(schemaOrShape) : schemaOrShape || {}\n\n const out: Record<string, any> = {}\n for (const k of keys) {\n if (k in shape) out[k] = (shape as any)[k]\n }\n return out\n}\n\n// Builds a fresh Zod object from the selected fields (avoids Zod's .pick())\nexport function safePick(schema: z.ZodObject<any>, mask: Mask): z.ZodObject<any> {\n return z.object(pickShape(schema, mask))\n}\n\n/**\n * Convenience: omit a set of keys by building the complement.\n * Avoids using Zod's .omit() which can cause type depth issues.\n */\nexport function safeOmit(schema: z.ZodObject<any>, mask: Mask): z.ZodObject<any> {\n const shape = getObjectShape(schema)\n const omit = new Set(toKeys(mask))\n const keep = Object.keys(shape).filter(k => !omit.has(k))\n const picked = pickShape(schema, keep)\n return z.object(picked)\n}\n\n/**\n * Recursively checks if a schema contains native z.date().\n * Stops recursion at ZodCodec boundaries since codecs handle their own transforms.\n */\nfunction containsNativeZodDate(schema: $ZodType): boolean {\n // Check if this is a native ZodDate (not our codec)\n if (schema instanceof $ZodDate) {\n return true\n }\n\n // Codecs handle their own transforms - don't recurse into them\n if (schema instanceof $ZodCodec) {\n return false\n }\n\n // Recurse into wrappers - cast unwrap result to ZodTypeAny for Zod v4 compatibility\n if (\n schema instanceof $ZodOptional ||\n schema instanceof $ZodNullable ||\n schema instanceof $ZodDefault\n ) {\n return containsNativeZodDate(schema._zod.def.innerType)\n }\n\n // Recurse into objects\n if (schema instanceof $ZodObject) {\n return Object.values(schema._zod.def.shape).some(field => containsNativeZodDate(field))\n }\n\n // Recurse into arrays\n if (schema instanceof $ZodArray) {\n return containsNativeZodDate(schema._zod.def.element)\n }\n\n // Recurse into unions\n if (schema instanceof $ZodUnion) {\n return schema._zod.def.options.some(opt => containsNativeZodDate(opt))\n }\n\n // Recurse into records\n if (schema instanceof $ZodRecord) {\n return containsNativeZodDate(schema._zod.def.valueType)\n }\n\n // Recurse into tuples\n if (schema instanceof $ZodTuple) {\n const items = schema._zod.def.items\n return items ? items.some(item => containsNativeZodDate(item)) : false\n }\n\n return false\n}\n\n/**\n * Throws if schema contains native z.date() which isn't compatible with Convex.\n * Guides users to use zx.date() instead.\n *\n * @param schema - The Zod schema to check\n * @param context - Context for the error message (args, returns, schema)\n * @throws Error with migration guidance if z.date() is found\n */\nexport function assertNoNativeZodDate(\n schema: $ZodType,\n context: 'args' | 'returns' | 'schema'\n): void {\n if (containsNativeZodDate(schema)) {\n throw new Error(\n `[zodvex] Native z.date() found in ${context}. ` +\n `Convex stores dates as timestamps (numbers), which z.date() cannot parse.\\n\\n` +\n `Fix: Replace z.date() with zx.date()\\n\\n` +\n `Before: { createdAt: z.date() }\\n` +\n `After: { createdAt: zx.date() }\\n\\n` +\n `zx.date() is a codec that handles timestamp ↔ Date conversion automatically.`\n )\n }\n}\n","import type { FunctionReference } from 'convex/server'\nimport type { z } from 'zod'\nimport type { $ZodIssue } from 'zod/v4/core'\nimport { safeEncode } from './normalizeCodecPaths'\nimport type { AnyRegistry } from './types'\nimport { stripUndefined } from './utils'\nimport { $ZodError, safeParse } from './zod-core'\n\n/**\n * Resolves a Convex FunctionReference to its string path.\n *\n * Mirrors `getFunctionName` from `convex/server` but without the server import.\n * Reads the well-known `Symbol.for('functionName')` that Convex attaches to all\n * function references — the same symbol used by Convex's own browser client.\n */\nconst functionNameSymbol = Symbol.for('functionName')\n\nfunction resolveFunctionPath(ref: FunctionReference<any, any, any, any>): string {\n if (typeof ref === 'string') return ref\n const name = (ref as any)[functionNameSymbol]\n if (!name) {\n throw new Error(\n `Expected a Convex function reference (e.g. api.file.func), but received ${JSON.stringify(ref)}`\n )\n }\n return name\n}\n\n/**\n * Options for codec helper behavior.\n */\nexport type BoundaryHelpersOptions = {\n /**\n * How to handle decode failures (schema validation errors on wire data).\n *\n * - `'warn'` (default): log a console.warn and return raw wire data untransformed.\n * - `'throw'`: throw a ZodvexDecodeError (extends z.ZodError).\n */\n onDecodeError?: 'warn' | 'throw'\n}\n\n/**\n * Decode error with function path and wire data context.\n * Extends $ZodError from zod/v4/core for compatibility with both zod and zod/mini.\n * instanceof $ZodError checks work in both variants.\n */\nexport class ZodvexDecodeError extends $ZodError {\n readonly functionPath: string\n readonly wireData: unknown\n\n constructor(functionPath: string, issues: $ZodIssue[], wireData: unknown) {\n super(issues)\n this.functionPath = functionPath\n this.wireData = wireData\n this.name = 'ZodvexDecodeError'\n }\n}\n\n/**\n * Creates shared encode/decode helpers bound to a zodvex registry.\n *\n * These are the core primitives used by all codec boundary implementations:\n * - `encodeArgs`: runtime types -> wire format (e.g., Date -> timestamp number)\n * - `decodeResult`: wire format -> runtime types (e.g., timestamp number -> Date)\n *\n * Both look up the function reference in the registry to find the appropriate\n * Zod schema, then apply the codec transform. Functions not in the registry\n * (or without the relevant schema) pass through unchanged.\n *\n * @param registry - A map of function paths to `{ args?, returns? }` Zod schemas.\n * Typically generated by zodvex codegen into `_zodvex/api.ts`.\n * @param options - Optional configuration for decode error behavior.\n */\nexport function createBoundaryHelpers(registry: AnyRegistry, options?: BoundaryHelpersOptions) {\n const onDecodeError = options?.onDecodeError ?? 'warn'\n const warnedPaths = new Set<string>()\n\n /**\n * Encode args from runtime types to wire format.\n *\n * Uses `safeEncode` (not raw `z.encode`) to normalize codec-internal\n * error paths in ZodErrors, then strips undefined values for Convex\n * serialization compatibility.\n *\n * Passthrough when:\n * - args is null/undefined\n * - function is not in the registry\n * - registry entry has no args schema\n */\n function encodeArgs(ref: FunctionReference<any, any, any, any>, args: any): any {\n if (args == null) return args\n const path = resolveFunctionPath(ref)\n const entry = registry[path]\n if (!entry?.args) {\n if (entry === undefined && !warnedPaths.has(path)) {\n warnedPaths.add(path)\n console.debug(\n `[zodvex] No registry entry for \"${path}\" — args will not be codec-encoded. ` +\n 'If this function uses zodvex wrappers, run `zodvex generate` to update the registry.'\n )\n }\n return args\n }\n return stripUndefined(safeEncode(entry.args, args))\n }\n\n /**\n * Decode a wire result back to runtime types.\n *\n * Uses `.safeParse()` to decode. On failure:\n * - 'warn' (default): logs warning, returns raw wireResult\n * - 'throw': throws ZodvexDecodeError (extends z.ZodError)\n *\n * Passthrough when:\n * - function is not in the registry\n * - registry entry has no returns schema\n */\n function decodeResult(ref: FunctionReference<any, any, any, any>, wireResult: any): any {\n const path = resolveFunctionPath(ref)\n const entry = registry[path]\n if (!entry?.returns) return wireResult\n\n const result = safeParse(entry.returns, wireResult)\n if (result.success) return result.data\n\n if (onDecodeError === 'throw') {\n throw new ZodvexDecodeError(path, result.error.issues, wireResult)\n }\n\n // Default: warn and return raw wire data\n const preview = JSON.stringify(wireResult)\n const truncated = preview.length > 200 ? `${preview.slice(0, 200)}...` : preview\n console.warn(\n `[zodvex] Decode failed for ${path}: ${result.error.issues.map((i: $ZodIssue) => `${i.path.join('.')}: ${i.message}`).join(', ')}. Returning raw wire data. Preview: ${truncated}`\n )\n return wireResult\n }\n\n return { encodeArgs, decodeResult }\n}\n\nexport type BoundaryHelpers = ReturnType<typeof createBoundaryHelpers>\n","import type { AuthTokenFetcher } from 'convex/browser'\nimport { ConvexClient } from 'convex/browser'\nimport type { FunctionArgs, FunctionReference, FunctionReturnType } from 'convex/server'\nimport type { BoundaryHelpersOptions } from '../boundaryHelpers'\nimport { createBoundaryHelpers } from '../boundaryHelpers'\nimport type { AnyRegistry } from '../types'\n\nexport type ZodvexClientOptions = (\n | { url: string; token?: string | null }\n | { client: ConvexClient }\n) &\n BoundaryHelpersOptions\n\n/** Wrap a static token string as an AuthTokenFetcher for ConvexClient */\nfunction tokenToFetcher(token: string): AuthTokenFetcher {\n return async () => token\n}\n\nexport class ZodvexClient<R extends AnyRegistry = AnyRegistry> {\n readonly convex: ConvexClient\n private codec: ReturnType<typeof createBoundaryHelpers>\n\n constructor(registry: R, options: ZodvexClientOptions) {\n this.codec = createBoundaryHelpers(registry, { onDecodeError: options.onDecodeError })\n if ('client' in options) {\n this.convex = options.client\n } else {\n this.convex = new ConvexClient(options.url)\n if (options.token) this.convex.setAuth(tokenToFetcher(options.token))\n }\n }\n\n async query<Q extends FunctionReference<'query', any, any, any>>(\n ref: Q,\n args: Q['_args']\n ): Promise<Q['_returnType']> {\n const wireResult = await this.convex.query(\n ref,\n this.codec.encodeArgs(ref, args) as FunctionArgs<Q>\n )\n return this.codec.decodeResult(ref, wireResult)\n }\n\n async mutate<M extends FunctionReference<'mutation', any, any, any>>(\n ref: M,\n args: M['_args']\n ): Promise<M['_returnType']> {\n const wireResult = await this.convex.mutation(\n ref,\n this.codec.encodeArgs(ref, args) as FunctionArgs<M>\n )\n return this.codec.decodeResult(ref, wireResult)\n }\n\n subscribe<Q extends FunctionReference<'query', any, any, any>>(\n ref: Q,\n args: Q['_args'],\n callback: (result: Q['_returnType']) => void\n ): () => void {\n const wireArgs = this.codec.encodeArgs(ref, args) as FunctionArgs<Q>\n return this.convex.onUpdate(ref, wireArgs, (wireResult: FunctionReturnType<Q>) => {\n callback(this.codec.decodeResult(ref, wireResult))\n })\n }\n\n setAuth(token: string | null) {\n this.convex.setAuth(async () => token)\n }\n\n async close() {\n await this.convex.close()\n }\n}\n\nexport function createZodvexClient<R extends AnyRegistry>(\n registry: R,\n options: ZodvexClientOptions\n): ZodvexClient<R> {\n return new ZodvexClient(registry, options)\n}\n"]}
1
+ {"version":3,"sources":["../../src/normalizeCodecPaths.ts","../../src/stripUndefined.ts","../../src/boundaryHelpers.ts","../../src/client/zodvexClient.ts"],"names":[],"mappings":";;;;;;AAeA,SAAS,YAAY,MAAA,EAA4B;AAC/C,EAAA,IAAI,OAAA,GAAoB,MAAA;AACxB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,IACE,OAAA,YAAmB,YAAA,IACnB,OAAA,YAAmB,YAAA,IACnB,mBAAmB,WAAA,EACnB;AACA,MAAA,OAAA,GAAU,OAAA,CAAQ,KAAK,GAAA,CAAI,SAAA;AAC3B,MAAA;AAAA,IACF;AACA,IAAA;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAOA,SAAS,uBAAA,CAAwB,MAA2B,MAAA,EAAuC;AACjG,EAAA,MAAM,SAA8B,EAAC;AACrC,EAAA,IAAI,OAAA,GAAoB,MAAA;AAExB,EAAA,KAAA,MAAW,WAAW,IAAA,EAAM;AAC1B,IAAA,OAAA,GAAU,YAAY,OAAO,CAAA;AAG7B,IAAA,IAAI,mBAAmB,SAAA,EAAW;AAChC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,OAAA,YAAmB,UAAA,IAAc,OAAO,OAAA,KAAY,QAAA,EAAU;AAChE,MAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,OAAO,CAAA;AAClD,MAAA,IAAI,CAAC,WAAA,EAAa;AAEhB,QAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,QAAA;AAAA,MACF;AAEA,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AAEnB,MAAA,MAAM,SAAA,GAAY,YAAY,WAAW,CAAA;AACzC,MAAA,IAAI,qBAAqB,SAAA,EAAW;AAElC,QAAA;AAAA,MACF;AAEA,MAAA,OAAA,GAAU,WAAA;AACV,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,OAAA,YAAmB,SAAA,IAAa,OAAO,OAAA,KAAY,QAAA,EAAU;AAC/D,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAA,GAAU,OAAA,CAAQ,KAAK,GAAA,CAAI,OAAA;AAC3B,MAAA;AAAA,IACF;AAGA,IAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,EACrB;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,mBAAA,CAAoB,OAAkB,MAAA,EAA6B;AACjF,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAA,KAAA,MAAU;AAAA,IAC5C,GAAG,KAAA;AAAA,IACH,IAAA,EAAM,uBAAA,CAAwB,KAAA,CAAM,IAAA,EAA6B,MAAM;AAAA,GACzE,CAAE,CAAA;AACF,EAAA,OAAO,IAAI,UAAU,UAAU,CAAA;AACjC;AAQO,SAAS,UAAA,CAAW,QAAkB,KAAA,EAAyB;AACpE,EAAA,IAAI;AACF,IAAA,OAAO,MAAA,CAAO,QAAQ,KAAK,CAAA;AAAA,EAC7B,SAAS,CAAA,EAAG;AACV,IAAA,IAAI,CAAA,YAAa,SAAA,EAAW,MAAM,mBAAA,CAAoB,GAAgB,MAAM,CAAA;AAC5E,IAAA,MAAM,CAAA;AAAA,EACR;AACF;;;ACzGO,SAAS,eAAkB,KAAA,EAAa;AAC7C,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,KAAA,CAAM,IAAI,cAAc,CAAA;AAAA,EACjC;AAGA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,gBAAgB,MAAA,EAAQ;AAC7D,IAAA,MAAM,SAAkC,EAAC;AACzC,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC9C,MAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,QAAA,MAAA,CAAO,GAAG,CAAA,GAAI,cAAA,CAAe,GAAG,CAAA;AAAA,MAClC;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO,KAAA;AACT;;;ACdA,IAAM,kBAAA,mBAAqB,MAAA,CAAO,GAAA,CAAI,cAAc,CAAA;AAEpD,SAAS,oBAAoB,GAAA,EAAoD;AAC/E,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,GAAA;AACpC,EAAA,MAAM,IAAA,GAAQ,IAAY,kBAAkB,CAAA;AAC5C,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,wEAAA,EAA2E,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,KAChG;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAoBO,IAAM,iBAAA,GAAN,cAAgC,SAAA,CAAU;AAAA,EACtC,YAAA;AAAA,EACA,QAAA;AAAA,EAET,WAAA,CAAY,YAAA,EAAsB,MAAA,EAAqB,QAAA,EAAmB;AACxE,IAAA,KAAA,CAAM,MAAM,CAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AACpB,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AAAA,EACd;AACF,CAAA;AAiBO,SAAS,qBAAA,CAAsB,UAAuB,OAAA,EAAkC;AAC7F,EAAA,MAAM,aAAA,GAAgB,SAAS,aAAA,IAAiB,MAAA;AAChD,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AAcpC,EAAA,SAAS,UAAA,CAAW,KAA4C,IAAA,EAAgB;AAC9E,IAAA,IAAI,IAAA,IAAQ,MAAM,OAAO,IAAA;AACzB,IAAA,MAAM,IAAA,GAAO,oBAAoB,GAAG,CAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,SAAS,IAAI,CAAA;AAC3B,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAChB,MAAA,IAAI,UAAU,MAAA,IAAa,CAAC,WAAA,CAAY,GAAA,CAAI,IAAI,CAAA,EAAG;AACjD,QAAA,WAAA,CAAY,IAAI,IAAI,CAAA;AACpB,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN,mCAAmC,IAAI,CAAA,+HAAA;AAAA,SAEzC;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,cAAA,CAAe,UAAA,CAAW,KAAA,CAAM,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,EACpD;AAaA,EAAA,SAAS,YAAA,CAAa,KAA4C,UAAA,EAAsB;AACtF,IAAA,MAAM,IAAA,GAAO,oBAAoB,GAAG,CAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,SAAS,IAAI,CAAA;AAC3B,IAAA,IAAI,CAAC,KAAA,EAAO,OAAA,EAAS,OAAO,UAAA;AAE5B,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,KAAA,CAAM,OAAA,EAAS,UAAU,CAAA;AAClD,IAAA,IAAI,MAAA,CAAO,OAAA,EAAS,OAAO,MAAA,CAAO,IAAA;AAElC,IAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,MAAA,MAAM,IAAI,iBAAA,CAAkB,IAAA,EAAM,MAAA,CAAO,KAAA,CAAM,QAAQ,UAAU,CAAA;AAAA,IACnE;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,UAAU,CAAA;AACzC,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,MAAA,GAAS,GAAA,GAAM,CAAA,EAAG,QAAQ,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA,GAAA,CAAA,GAAQ,OAAA;AACzE,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,CAAA,2BAAA,EAA8B,IAAI,CAAA,EAAA,EAAK,MAAA,CAAO,KAAA,CAAM,OAAO,GAAA,CAAI,CAAC,CAAA,KAAiB,CAAA,EAAG,CAAA,CAAE,IAAA,CAAK,KAAK,GAAG,CAAC,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,EAAE,IAAA,CAAK,IAAI,CAAC,CAAA,oCAAA,EAAuC,SAAS,CAAA;AAAA,KAClL;AACA,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,OAAO,EAAE,YAAY,YAAA,EAAa;AACpC;;;AC5HA,SAAS,eAAe,KAAA,EAAiC;AACvD,EAAA,OAAO,YAAY,KAAA;AACrB;AAEO,IAAM,eAAN,MAAwD;AAAA,EACpD,MAAA;AAAA,EACD,KAAA;AAAA,EAER,WAAA,CAAY,UAAa,OAAA,EAA8B;AACrD,IAAA,IAAA,CAAK,QAAQ,qBAAA,CAAsB,QAAA,EAAU,EAAE,aAAA,EAAe,OAAA,CAAQ,eAAe,CAAA;AACrF,IAAA,IAAI,YAAY,OAAA,EAAS;AACvB,MAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AAAA,IACxB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAA,GAAS,IAAI,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AAC1C,MAAA,IAAI,OAAA,CAAQ,OAAO,IAAA,CAAK,MAAA,CAAO,QAAQ,cAAA,CAAe,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,CACJ,GAAA,EACA,IAAA,EAC2B;AAC3B,IAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MACnC,GAAA;AAAA,MACA,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,GAAA,EAAK,IAAI;AAAA,KACjC;AACA,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,GAAA,EAAK,UAAU,CAAA;AAAA,EAChD;AAAA,EAEA,MAAM,MAAA,CACJ,GAAA,EACA,IAAA,EAC2B;AAC3B,IAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,MAAA,CAAO,QAAA;AAAA,MACnC,GAAA;AAAA,MACA,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,GAAA,EAAK,IAAI;AAAA,KACjC;AACA,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,GAAA,EAAK,UAAU,CAAA;AAAA,EAChD;AAAA,EAEA,SAAA,CACE,GAAA,EACA,IAAA,EACA,QAAA,EACY;AACZ,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,KAAK,IAAI,CAAA;AAChD,IAAA,OAAO,KAAK,MAAA,CAAO,QAAA,CAAS,GAAA,EAAK,QAAA,EAAU,CAAC,UAAA,KAAsC;AAChF,MAAA,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,GAAA,EAAK,UAAU,CAAC,CAAA;AAAA,IACnD,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,QAAQ,KAAA,EAAsB;AAC5B,IAAA,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,YAAY,KAAK,CAAA;AAAA,EACvC;AAAA,EAEA,MAAM,KAAA,GAAQ;AACZ,IAAA,MAAM,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,EAC1B;AACF;AAEO,SAAS,kBAAA,CACd,UACA,OAAA,EACiB;AACjB,EAAA,OAAO,IAAI,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAC3C","file":"index.js","sourcesContent":["import {\n $ZodArray,\n $ZodCodec,\n $ZodDefault,\n $ZodError,\n $ZodNullable,\n $ZodObject,\n $ZodOptional,\n $ZodType,\n encode\n} from './zod-core'\n\n/**\n * Unwraps ZodOptional/ZodNullable/ZodDefault wrappers to get the structural type.\n */\nfunction unwrapOuter(schema: $ZodType): $ZodType {\n let current: $ZodType = schema\n for (let i = 0; i < 10; i++) {\n if (\n current instanceof $ZodOptional ||\n current instanceof $ZodNullable ||\n current instanceof $ZodDefault\n ) {\n current = current._zod.def.innerType\n continue\n }\n break\n }\n return current\n}\n\n/**\n * Walks a path through a schema tree, truncating at codec boundaries.\n * When a codec is encountered, the path is cut — any deeper segments\n * are wire-internal and should not be exposed to consumers.\n */\nfunction truncateAtCodecBoundary(path: (string | number)[], schema: $ZodType): (string | number)[] {\n const result: (string | number)[] = []\n let current: $ZodType = schema\n\n for (const segment of path) {\n current = unwrapOuter(current)\n\n // If we've landed on a codec, everything from here is wire-internal — stop\n if (current instanceof $ZodCodec) {\n break\n }\n\n // Descend into objects\n if (current instanceof $ZodObject && typeof segment === 'string') {\n const fieldSchema = current._zod.def.shape[segment] as $ZodType | undefined\n if (!fieldSchema) {\n // Unknown field — include segment and stop\n result.push(segment)\n break\n }\n\n result.push(segment)\n\n const unwrapped = unwrapOuter(fieldSchema)\n if (unwrapped instanceof $ZodCodec) {\n // Hit a codec boundary — truncate here\n break\n }\n\n current = fieldSchema\n continue\n }\n\n // Descend into arrays\n if (current instanceof $ZodArray && typeof segment === 'number') {\n result.push(segment)\n current = current._zod.def.element\n continue\n }\n\n // For anything else (unions, records, etc.), include segment and continue\n result.push(segment)\n }\n\n return result\n}\n\n/**\n * Normalizes ZodError paths by truncating at codec boundaries.\n *\n * When z.encode() throws a ZodError, the paths reflect the wire schema\n * structure (e.g., [\"email\", \"value\"] for a custom codec).\n * This function strips the wire-internal segments so consumers see\n * clean field-level paths (e.g., [\"email\"]).\n */\nexport function normalizeCodecPaths(error: $ZodError, schema: $ZodType): $ZodError {\n const normalized = error.issues.map(issue => ({\n ...issue,\n path: truncateAtCodecBoundary(issue.path as (string | number)[], schema)\n }))\n return new $ZodError(normalized)\n}\n\n/**\n * Encodes a value through a Zod schema, normalizing codec-internal\n * path segments in any ZodError before re-throwing.\n *\n * Drop-in replacement for `z.encode(schema, value)` at client boundaries.\n */\nexport function safeEncode(schema: $ZodType, value: unknown): unknown {\n try {\n return encode(schema, value)\n } catch (e) {\n if (e instanceof $ZodError) throw normalizeCodecPaths(e as $ZodError, schema)\n throw e\n }\n}\n","/**\n * Recursively strips `undefined` values from objects and arrays.\n * Used by codec encode/decode to clean wire data.\n *\n * Extracted to its own module so client-safe code (boundaryHelpers)\n * can import it without pulling in zod via utils.ts.\n */\nexport function stripUndefined<T>(value: T): T {\n if (value === null || value === undefined) {\n return value\n }\n\n if (Array.isArray(value)) {\n return value.map(stripUndefined) as T\n }\n\n // Only process plain objects (not class instances, Dates, etc.)\n if (typeof value === 'object' && value.constructor === Object) {\n const result: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(value)) {\n if (val !== undefined) {\n result[key] = stripUndefined(val)\n }\n }\n return result as T\n }\n\n return value\n}\n","import type { FunctionReference } from 'convex/server'\nimport type { $ZodIssue } from 'zod/v4/core'\nimport { safeEncode } from './normalizeCodecPaths'\nimport { stripUndefined } from './stripUndefined'\nimport type { AnyRegistry } from './types'\nimport { $ZodError, safeParse } from './zod-core'\n\n/**\n * Resolves a Convex FunctionReference to its string path.\n *\n * Mirrors `getFunctionName` from `convex/server` but without the server import.\n * Reads the well-known `Symbol.for('functionName')` that Convex attaches to all\n * function references — the same symbol used by Convex's own browser client.\n */\nconst functionNameSymbol = Symbol.for('functionName')\n\nfunction resolveFunctionPath(ref: FunctionReference<any, any, any, any>): string {\n if (typeof ref === 'string') return ref\n const name = (ref as any)[functionNameSymbol]\n if (!name) {\n throw new Error(\n `Expected a Convex function reference (e.g. api.file.func), but received ${JSON.stringify(ref)}`\n )\n }\n return name\n}\n\n/**\n * Options for codec helper behavior.\n */\nexport type BoundaryHelpersOptions = {\n /**\n * How to handle decode failures (schema validation errors on wire data).\n *\n * - `'warn'` (default): log a console.warn and return raw wire data untransformed.\n * - `'throw'`: throw a ZodvexDecodeError (extends z.ZodError). // zod-ok\n */\n onDecodeError?: 'warn' | 'throw'\n}\n\n/**\n * Decode error with function path and wire data context.\n * Extends $ZodError from zod/v4/core for compatibility with both zod and zod/mini.\n * instanceof $ZodError checks work in both variants.\n */\nexport class ZodvexDecodeError extends $ZodError {\n readonly functionPath: string\n readonly wireData: unknown\n\n constructor(functionPath: string, issues: $ZodIssue[], wireData: unknown) {\n super(issues)\n this.functionPath = functionPath\n this.wireData = wireData\n this.name = 'ZodvexDecodeError'\n }\n}\n\n/**\n * Creates shared encode/decode helpers bound to a zodvex registry.\n *\n * These are the core primitives used by all codec boundary implementations:\n * - `encodeArgs`: runtime types -> wire format (e.g., Date -> timestamp number)\n * - `decodeResult`: wire format -> runtime types (e.g., timestamp number -> Date)\n *\n * Both look up the function reference in the registry to find the appropriate\n * Zod schema, then apply the codec transform. Functions not in the registry\n * (or without the relevant schema) pass through unchanged.\n *\n * @param registry - A map of function paths to `{ args?, returns? }` Zod schemas.\n * Typically generated by zodvex codegen into `_zodvex/api.ts`.\n * @param options - Optional configuration for decode error behavior.\n */\nexport function createBoundaryHelpers(registry: AnyRegistry, options?: BoundaryHelpersOptions) {\n const onDecodeError = options?.onDecodeError ?? 'warn'\n const warnedPaths = new Set<string>()\n\n /**\n * Encode args from runtime types to wire format.\n *\n * Uses `safeEncode` (not raw `z.encode`) to normalize codec-internal\n * error paths in ZodErrors, then strips undefined values for Convex\n * serialization compatibility.\n *\n * Passthrough when:\n * - args is null/undefined\n * - function is not in the registry\n * - registry entry has no args schema\n */\n function encodeArgs(ref: FunctionReference<any, any, any, any>, args: any): any {\n if (args == null) return args\n const path = resolveFunctionPath(ref)\n const entry = registry[path]\n if (!entry?.args) {\n if (entry === undefined && !warnedPaths.has(path)) {\n warnedPaths.add(path)\n console.debug(\n `[zodvex] No registry entry for \"${path}\" — args will not be codec-encoded. ` +\n 'If this function uses zodvex wrappers, run `zodvex generate` to update the registry.'\n )\n }\n return args\n }\n return stripUndefined(safeEncode(entry.args, args))\n }\n\n /**\n * Decode a wire result back to runtime types.\n *\n * Uses `.safeParse()` to decode. On failure:\n * - 'warn' (default): logs warning, returns raw wireResult\n * - 'throw': throws ZodvexDecodeError (extends z.ZodError) // zod-ok\n *\n * Passthrough when:\n * - function is not in the registry\n * - registry entry has no returns schema\n */\n function decodeResult(ref: FunctionReference<any, any, any, any>, wireResult: any): any {\n const path = resolveFunctionPath(ref)\n const entry = registry[path]\n if (!entry?.returns) return wireResult\n\n const result = safeParse(entry.returns, wireResult)\n if (result.success) return result.data\n\n if (onDecodeError === 'throw') {\n throw new ZodvexDecodeError(path, result.error.issues, wireResult)\n }\n\n // Default: warn and return raw wire data\n const preview = JSON.stringify(wireResult)\n const truncated = preview.length > 200 ? `${preview.slice(0, 200)}...` : preview\n console.warn(\n `[zodvex] Decode failed for ${path}: ${result.error.issues.map((i: $ZodIssue) => `${i.path.join('.')}: ${i.message}`).join(', ')}. Returning raw wire data. Preview: ${truncated}`\n )\n return wireResult\n }\n\n return { encodeArgs, decodeResult }\n}\n\nexport type BoundaryHelpers = ReturnType<typeof createBoundaryHelpers>\n","import type { AuthTokenFetcher } from 'convex/browser'\nimport { ConvexClient } from 'convex/browser'\nimport type { FunctionArgs, FunctionReference, FunctionReturnType } from 'convex/server'\nimport type { BoundaryHelpersOptions } from '../boundaryHelpers'\nimport { createBoundaryHelpers } from '../boundaryHelpers'\nimport type { AnyRegistry } from '../types'\n\nexport type ZodvexClientOptions = (\n | { url: string; token?: string | null }\n | { client: ConvexClient }\n) &\n BoundaryHelpersOptions\n\n/** Wrap a static token string as an AuthTokenFetcher for ConvexClient */\nfunction tokenToFetcher(token: string): AuthTokenFetcher {\n return async () => token\n}\n\nexport class ZodvexClient<R extends AnyRegistry = AnyRegistry> {\n readonly convex: ConvexClient\n private codec: ReturnType<typeof createBoundaryHelpers>\n\n constructor(registry: R, options: ZodvexClientOptions) {\n this.codec = createBoundaryHelpers(registry, { onDecodeError: options.onDecodeError })\n if ('client' in options) {\n this.convex = options.client\n } else {\n this.convex = new ConvexClient(options.url)\n if (options.token) this.convex.setAuth(tokenToFetcher(options.token))\n }\n }\n\n async query<Q extends FunctionReference<'query', any, any, any>>(\n ref: Q,\n args: Q['_args']\n ): Promise<Q['_returnType']> {\n const wireResult = await this.convex.query(\n ref,\n this.codec.encodeArgs(ref, args) as FunctionArgs<Q>\n )\n return this.codec.decodeResult(ref, wireResult)\n }\n\n async mutate<M extends FunctionReference<'mutation', any, any, any>>(\n ref: M,\n args: M['_args']\n ): Promise<M['_returnType']> {\n const wireResult = await this.convex.mutation(\n ref,\n this.codec.encodeArgs(ref, args) as FunctionArgs<M>\n )\n return this.codec.decodeResult(ref, wireResult)\n }\n\n subscribe<Q extends FunctionReference<'query', any, any, any>>(\n ref: Q,\n args: Q['_args'],\n callback: (result: Q['_returnType']) => void\n ): () => void {\n const wireArgs = this.codec.encodeArgs(ref, args) as FunctionArgs<Q>\n return this.convex.onUpdate(ref, wireArgs, (wireResult: FunctionReturnType<Q>) => {\n callback(this.codec.decodeResult(ref, wireResult))\n })\n }\n\n setAuth(token: string | null) {\n this.convex.setAuth(async () => token)\n }\n\n async close() {\n await this.convex.close()\n }\n}\n\nexport function createZodvexClient<R extends AnyRegistry>(\n registry: R,\n options: ZodvexClientOptions\n): ZodvexClient<R> {\n return new ZodvexClient(registry, options)\n}\n"]}
package/dist/codec.d.ts CHANGED
@@ -33,7 +33,7 @@ export declare function encodePartialDoc<S extends $ZodType>(schema: S, partial:
33
33
  *
34
34
  * @example
35
35
  * ```typescript
36
- * type MyCodec = ZodvexCodec<z.ZodObject<{ ts: z.ZodNumber }>, z.ZodCustom<Date>>
36
+ * type MyCodec = ZodvexCodec<z.ZodObject<{ ts: z.ZodNumber }>, z.ZodCustom<Date>> // zod-ok
37
37
  *
38
38
  * function myCodec(): MyCodec {
39
39
  * return zodvexCodec(
@@ -1,4 +1,4 @@
1
- import { $ZodError, encode, $ZodDate, $ZodOptional, $ZodNullable, $ZodDefault, $ZodObject, $ZodType, parse, globalRegistry, safeParse, $ZodCodec, $ZodArray, $ZodLazy, $ZodTuple, $ZodRecord, $ZodEnum, $ZodLiteral, $ZodUnion, $ZodNumber, $ZodCustom, clone, $ZodDiscriminatedUnion } from 'zod/v4/core';
1
+ import { $ZodError, encode, $ZodObject, $ZodType, $ZodDate, $ZodOptional, $ZodNullable, $ZodDefault, parse, globalRegistry, safeParse, $ZodCodec, $ZodArray, $ZodLazy, $ZodTuple, $ZodRecord, $ZodEnum, $ZodLiteral, $ZodUnion, $ZodNumber, $ZodCustom, clone, $ZodDiscriminatedUnion } from 'zod/v4/core';
2
2
  import { z } from 'zod';
3
3
  import { v } from 'convex/values';
4
4
 
@@ -62,15 +62,8 @@ function safeEncode(schema, value) {
62
62
  throw e;
63
63
  }
64
64
  }
65
- function getObjectShape(obj) {
66
- if (obj instanceof $ZodObject) return obj._zod.def.shape;
67
- if (obj && typeof obj === "object" && typeof obj.shape === "object")
68
- return obj.shape;
69
- return {};
70
- }
71
- function returnsAs() {
72
- return (v7) => v7;
73
- }
65
+
66
+ // src/stripUndefined.ts
74
67
  function stripUndefined(value) {
75
68
  if (value === null || value === void 0) {
76
69
  return value;
@@ -89,96 +82,6 @@ function stripUndefined(value) {
89
82
  }
90
83
  return value;
91
84
  }
92
- function zPaginated(item) {
93
- return z.object({
94
- page: z.array(item),
95
- isDone: z.boolean(),
96
- continueCursor: z.optional(z.nullable(z.string()))
97
- });
98
- }
99
- function mapDateFieldToNumber(field) {
100
- if (field instanceof $ZodDate) {
101
- return z.number();
102
- }
103
- if (field instanceof $ZodOptional && field._zod.def.innerType instanceof $ZodDate) {
104
- return z.optional(z.number());
105
- }
106
- if (field instanceof $ZodNullable && field._zod.def.innerType instanceof $ZodDate) {
107
- return z.nullable(z.number());
108
- }
109
- if (field instanceof $ZodDefault) {
110
- const inner = field._zod.def.innerType;
111
- if (inner instanceof $ZodDate) {
112
- return z.optional(z.number());
113
- }
114
- }
115
- return field;
116
- }
117
- function toKeys(mask) {
118
- if (Array.isArray(mask)) return mask.map(String);
119
- return Object.keys(mask).filter((k) => !!mask[k]);
120
- }
121
- function pickShape(schemaOrShape, mask) {
122
- const keys = toKeys(mask);
123
- const shape = schemaOrShape instanceof $ZodObject ? getObjectShape(schemaOrShape) : schemaOrShape || {};
124
- const out = {};
125
- for (const k of keys) {
126
- if (k in shape) out[k] = shape[k];
127
- }
128
- return out;
129
- }
130
- function safePick(schema, mask) {
131
- return z.object(pickShape(schema, mask));
132
- }
133
- function safeOmit(schema, mask) {
134
- const shape = getObjectShape(schema);
135
- const omit = new Set(toKeys(mask));
136
- const keep = Object.keys(shape).filter((k) => !omit.has(k));
137
- const picked = pickShape(schema, keep);
138
- return z.object(picked);
139
- }
140
- function containsNativeZodDate(schema) {
141
- if (schema instanceof $ZodDate) {
142
- return true;
143
- }
144
- if (schema instanceof $ZodCodec) {
145
- return false;
146
- }
147
- if (schema instanceof $ZodOptional || schema instanceof $ZodNullable || schema instanceof $ZodDefault) {
148
- return containsNativeZodDate(schema._zod.def.innerType);
149
- }
150
- if (schema instanceof $ZodObject) {
151
- return Object.values(schema._zod.def.shape).some((field) => containsNativeZodDate(field));
152
- }
153
- if (schema instanceof $ZodArray) {
154
- return containsNativeZodDate(schema._zod.def.element);
155
- }
156
- if (schema instanceof $ZodUnion) {
157
- return schema._zod.def.options.some((opt) => containsNativeZodDate(opt));
158
- }
159
- if (schema instanceof $ZodRecord) {
160
- return containsNativeZodDate(schema._zod.def.valueType);
161
- }
162
- if (schema instanceof $ZodTuple) {
163
- const items = schema._zod.def.items;
164
- return items ? items.some((item) => containsNativeZodDate(item)) : false;
165
- }
166
- return false;
167
- }
168
- function assertNoNativeZodDate(schema, context) {
169
- if (containsNativeZodDate(schema)) {
170
- throw new Error(
171
- `[zodvex] Native z.date() found in ${context}. Convex stores dates as timestamps (numbers), which z.date() cannot parse.
172
-
173
- Fix: Replace z.date() with zx.date()
174
-
175
- Before: { createdAt: z.date() }
176
- After: { createdAt: zx.date() }
177
-
178
- zx.date() is a codec that handles timestamp \u2194 Date conversion automatically.`
179
- );
180
- }
181
- }
182
85
 
183
86
  // src/boundaryHelpers.ts
184
87
  var functionNameSymbol = /* @__PURE__ */ Symbol.for("functionName");
@@ -399,7 +302,7 @@ function isZid(schema) {
399
302
  const metadata2 = registryHelpers.getMetadata(schema);
400
303
  return metadata2?.isConvexId === true && metadata2?.tableName && typeof metadata2.tableName === "string";
401
304
  }
402
- function getObjectShape2(obj) {
305
+ function getObjectShape(obj) {
403
306
  if (obj instanceof $ZodObject) {
404
307
  return obj._zod.def.shape;
405
308
  }
@@ -672,6 +575,105 @@ function zodToConvexFields(zod) {
672
575
  }
673
576
  return result;
674
577
  }
578
+ function getObjectShape3(obj) {
579
+ if (obj instanceof $ZodObject) return obj._zod.def.shape;
580
+ if (obj && typeof obj === "object" && typeof obj.shape === "object")
581
+ return obj.shape;
582
+ return {};
583
+ }
584
+ function returnsAs() {
585
+ return (v7) => v7;
586
+ }
587
+ function zPaginated(item) {
588
+ return z.object({
589
+ page: z.array(item),
590
+ isDone: z.boolean(),
591
+ continueCursor: z.optional(z.nullable(z.string()))
592
+ });
593
+ }
594
+ function mapDateFieldToNumber(field) {
595
+ if (field instanceof $ZodDate) {
596
+ return z.number();
597
+ }
598
+ if (field instanceof $ZodOptional && field._zod.def.innerType instanceof $ZodDate) {
599
+ return z.optional(z.number());
600
+ }
601
+ if (field instanceof $ZodNullable && field._zod.def.innerType instanceof $ZodDate) {
602
+ return z.nullable(z.number());
603
+ }
604
+ if (field instanceof $ZodDefault) {
605
+ const inner = field._zod.def.innerType;
606
+ if (inner instanceof $ZodDate) {
607
+ return z.optional(z.number());
608
+ }
609
+ }
610
+ return field;
611
+ }
612
+ function toKeys(mask) {
613
+ if (Array.isArray(mask)) return mask.map(String);
614
+ return Object.keys(mask).filter((k) => !!mask[k]);
615
+ }
616
+ function pickShape(schemaOrShape, mask) {
617
+ const keys = toKeys(mask);
618
+ const shape = schemaOrShape instanceof $ZodObject ? getObjectShape3(schemaOrShape) : schemaOrShape || {};
619
+ const out = {};
620
+ for (const k of keys) {
621
+ if (k in shape) out[k] = shape[k];
622
+ }
623
+ return out;
624
+ }
625
+ function safePick(schema, mask) {
626
+ return z.object(pickShape(schema, mask));
627
+ }
628
+ function safeOmit(schema, mask) {
629
+ const shape = getObjectShape3(schema);
630
+ const omit = new Set(toKeys(mask));
631
+ const keep = Object.keys(shape).filter((k) => !omit.has(k));
632
+ const picked = pickShape(schema, keep);
633
+ return z.object(picked);
634
+ }
635
+ function containsNativeZodDate(schema) {
636
+ if (schema instanceof $ZodDate) {
637
+ return true;
638
+ }
639
+ if (schema instanceof $ZodCodec) {
640
+ return false;
641
+ }
642
+ if (schema instanceof $ZodOptional || schema instanceof $ZodNullable || schema instanceof $ZodDefault) {
643
+ return containsNativeZodDate(schema._zod.def.innerType);
644
+ }
645
+ if (schema instanceof $ZodObject) {
646
+ return Object.values(schema._zod.def.shape).some((field) => containsNativeZodDate(field));
647
+ }
648
+ if (schema instanceof $ZodArray) {
649
+ return containsNativeZodDate(schema._zod.def.element);
650
+ }
651
+ if (schema instanceof $ZodUnion) {
652
+ return schema._zod.def.options.some((opt) => containsNativeZodDate(opt));
653
+ }
654
+ if (schema instanceof $ZodRecord) {
655
+ return containsNativeZodDate(schema._zod.def.valueType);
656
+ }
657
+ if (schema instanceof $ZodTuple) {
658
+ const items = schema._zod.def.items;
659
+ return items ? items.some((item) => containsNativeZodDate(item)) : false;
660
+ }
661
+ return false;
662
+ }
663
+ function assertNoNativeZodDate(schema, context) {
664
+ if (containsNativeZodDate(schema)) {
665
+ throw new Error(
666
+ `[zodvex] Native z.date() found in ${context}. Convex stores dates as timestamps (numbers), which z.date() cannot parse.
667
+
668
+ Fix: Replace z.date() with zx.date()
669
+
670
+ Before: { createdAt: z.date() }
671
+ After: { createdAt: zx.date() }
672
+
673
+ zx.date() is a codec that handles timestamp \u2194 Date conversion automatically.`
674
+ );
675
+ }
676
+ }
675
677
 
676
678
  // src/codec.ts
677
679
  function convexCodec(schema) {
@@ -1078,6 +1080,6 @@ var zFormResult = (dataSchema) => z.discriminatedUnion("success", [
1078
1080
  z.object({ success: z.literal(false), data: dataSchema, error: zFormError })
1079
1081
  ]);
1080
1082
 
1081
- export { ZodvexDecodeError, composeOverrides, convexCodec, createBoundaryHelpers, decodeDoc, defineZodModel, encodeDoc, encodePartialDoc, extractCodec, failure, formFailure, formSuccess, getObjectShape2 as getObjectShape, getZidTableName, isZidSchema, mapDateFieldToNumber, normalizeCodecPaths, ok, pickShape, readFnArgs, readFnReturns, returnsAs, safeEncode, safeOmit, safePick, stripUndefined, success, toJSONSchema, zFormError, zFormResult, zMutationResult, zPaginated, zVoidMutationResult, zid, zodToConvex, zodToConvexFields, zodvexCodec, zodvexJSONSchemaOverride, zx };
1083
+ export { ZodvexDecodeError, composeOverrides, convexCodec, createBoundaryHelpers, decodeDoc, defineZodModel, encodeDoc, encodePartialDoc, extractCodec, failure, formFailure, formSuccess, getObjectShape, getZidTableName, isZidSchema, mapDateFieldToNumber, normalizeCodecPaths, ok, pickShape, readFnArgs, readFnReturns, returnsAs, safeEncode, safeOmit, safePick, stripUndefined, success, toJSONSchema, zFormError, zFormResult, zMutationResult, zPaginated, zVoidMutationResult, zid, zodToConvex, zodToConvexFields, zodvexCodec, zodvexJSONSchemaOverride, zx };
1082
1084
  //# sourceMappingURL=index.js.map
1083
1085
  //# sourceMappingURL=index.js.map