zodvex 0.7.7-beta.1 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/cli/index.js +296 -81
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/client/index.js +2 -2
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/codegen/index.js +211 -28
  6. package/dist/codegen/index.js.map +1 -1
  7. package/dist/core/index.js +33 -16
  8. package/dist/core/index.js.map +1 -1
  9. package/dist/index.js +33 -16
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal/boundaryHelpers.d.ts +2 -15
  12. package/dist/internal/boundaryHelpers.d.ts.map +1 -1
  13. package/dist/internal/registry.d.ts.map +1 -1
  14. package/dist/internal/zx.d.ts.map +1 -1
  15. package/dist/internal/zxDateBrand.d.ts +5 -0
  16. package/dist/internal/zxDateBrand.d.ts.map +1 -0
  17. package/dist/legacy/index.js +21 -10
  18. package/dist/legacy/index.js.map +1 -1
  19. package/dist/mini/client/index.js +2 -2
  20. package/dist/mini/client/index.js.map +1 -1
  21. package/dist/mini/index.js +33 -16
  22. package/dist/mini/index.js.map +1 -1
  23. package/dist/mini/react/index.js +2 -2
  24. package/dist/mini/react/index.js.map +1 -1
  25. package/dist/mini/server/index.js +23 -12
  26. package/dist/mini/server/index.js.map +1 -1
  27. package/dist/public/cli/commands.d.ts.map +1 -1
  28. package/dist/public/codegen/discover.d.ts.map +1 -1
  29. package/dist/public/codegen/discovery-hooks.d.ts +2 -1
  30. package/dist/public/codegen/discovery-hooks.d.ts.map +1 -1
  31. package/dist/public/codegen/extractCodec.d.ts.map +1 -1
  32. package/dist/public/codegen/tsconfigPaths.d.ts +41 -0
  33. package/dist/public/codegen/tsconfigPaths.d.ts.map +1 -0
  34. package/dist/public/codegen/zodToSource.d.ts.map +1 -1
  35. package/dist/react/index.js +2 -2
  36. package/dist/react/index.js.map +1 -1
  37. package/dist/server/index.js +23 -12
  38. package/dist/server/index.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/internal/boundaryHelpers.ts +15 -3
  41. package/src/internal/registry.ts +12 -9
  42. package/src/internal/zx.ts +12 -9
  43. package/src/internal/zxDateBrand.ts +34 -0
  44. package/src/public/cli/commands.ts +59 -17
  45. package/src/public/codegen/discover.ts +27 -15
  46. package/src/public/codegen/discovery-hooks.ts +42 -3
  47. package/src/public/codegen/extractCodec.ts +5 -11
  48. package/src/public/codegen/tsconfigPaths.ts +224 -0
  49. package/src/public/codegen/zodToSource.ts +5 -6
@@ -100,9 +100,9 @@ var ZodvexDecodeError = class extends $ZodError {
100
100
  this.name = "ZodvexDecodeError";
101
101
  }
102
102
  };
103
+ var warnedPaths = /* @__PURE__ */ new Set();
103
104
  function createBoundaryHelpers(registry, options) {
104
105
  const onDecodeError = options?.onDecodeError ?? "warn";
105
- const warnedPaths = /* @__PURE__ */ new Set();
106
106
  function encodeArgs(ref, args) {
107
107
  if (args == null) return args;
108
108
  const path = resolveFunctionPath(ref);
@@ -112,7 +112,7 @@ function createBoundaryHelpers(registry, options) {
112
112
  if (entry === void 0 && !warnedPaths.has(path)) {
113
113
  warnedPaths.add(path);
114
114
  console.debug(
115
- `[zodvex] No registry entry for "${path}" \u2014 args will not be codec-encoded. If this function uses zodvex wrappers, run \`zodvex generate\` to update the registry.`
115
+ `[zodvex] No registry entry for "${path}" \u2014 args/returns pass through unencoded. This is expected when the target is a raw (non-zodvex) function; if it should be codec-aware, run \`zodvex generate\` to update the registry.`
116
116
  );
117
117
  }
118
118
  return args;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/internal/normalizeCodecPaths.ts","../../src/internal/stripUndefined.ts","../../src/internal/boundaryHelpers.ts","../../src/public/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","/**\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 | null {\n if (typeof ref === 'string') return ref\n const name = (ref as any)[functionNameSymbol]\n if (!name) return null\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 if (path == null) return args\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 if (path == null) return wireResult\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, ConnectionState, MutationOptions } from 'convex/browser'\nimport { ConvexClient } from 'convex/browser'\nimport type { FunctionArgs, FunctionReference, FunctionReturnType } from 'convex/server'\nimport type { BoundaryHelpersOptions } from '../../internal/boundaryHelpers'\nimport { createBoundaryHelpers } from '../../internal/boundaryHelpers'\nimport type { AnyRegistry } from '../../internal/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 private codec: ReturnType<typeof createBoundaryHelpers>\n private innerClient?: ConvexClient\n private url?: string\n private pendingAuthFetcher?: AuthTokenFetcher\n private pendingAuthOnChange?: (isAuthenticated: boolean) => void\n\n constructor(registry: R, options: ZodvexClientOptions) {\n this.codec = createBoundaryHelpers(registry, { onDecodeError: options.onDecodeError })\n if ('client' in options) {\n this.innerClient = options.client\n } else {\n this.url = options.url\n if (options.token) this.pendingAuthFetcher = tokenToFetcher(options.token)\n }\n }\n\n private getUrl(): string {\n if (this.url) return this.url\n throw new Error('[zodvex] ZodvexClient is missing a Convex URL.')\n }\n\n private getConvex(): ConvexClient {\n if (this.innerClient) return this.innerClient\n\n const client = new ConvexClient(this.getUrl())\n if (this.pendingAuthFetcher) {\n client.setAuth(this.pendingAuthFetcher, this.pendingAuthOnChange)\n }\n this.innerClient = client\n return client\n }\n\n get convex(): ConvexClient {\n return this.getConvex()\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.getConvex().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 options?: MutationOptions\n ): Promise<M['_returnType']> {\n const wireResult = await this.getConvex().mutation(\n ref,\n this.codec.encodeArgs(ref, args) as FunctionArgs<M>,\n options\n )\n return this.codec.decodeResult(ref, wireResult)\n }\n\n /** Alias for {@link mutate} — matches `ConvexClient.mutation` / `ZodvexReactClient.mutation`. */\n mutation<M extends FunctionReference<'mutation', any, any, any>>(\n ref: M,\n args: M['_args'],\n options?: MutationOptions\n ): Promise<M['_returnType']> {\n return this.mutate(ref, args, options)\n }\n\n async action<A extends FunctionReference<'action', any, any, any>>(\n ref: A,\n args: A['_args']\n ): Promise<A['_returnType']> {\n const wireResult = await this.getConvex().action(\n ref,\n this.codec.encodeArgs(ref, args) as FunctionArgs<A>\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 onError?: (e: Error) => void\n ): () => void {\n const wireArgs = this.codec.encodeArgs(ref, args) as FunctionArgs<Q>\n return this.getConvex().onUpdate(\n ref,\n wireArgs,\n (wireResult: FunctionReturnType<Q>) => {\n callback(this.codec.decodeResult(ref, wireResult))\n },\n onError\n )\n }\n\n /** Alias for {@link subscribe} — matches `ConvexClient.onUpdate`. */\n onUpdate<Q extends FunctionReference<'query', any, any, any>>(\n ref: Q,\n args: Q['_args'],\n callback: (result: Q['_returnType']) => void,\n onError?: (e: Error) => void\n ): () => void {\n return this.subscribe(ref, args, callback, onError)\n }\n\n /**\n * Experimental paginated subscription. Encodes args to wire and decodes each\n * page item through the registry, mirroring {@link subscribe}.\n */\n onPaginatedUpdate_experimental<Q extends FunctionReference<'query', any, any, any>>(\n ref: Q,\n args: Q['_args'],\n options: { initialNumItems: number },\n callback: (result: {\n page: Q['_returnType'][]\n isDone: boolean\n continueCursor: string\n [key: string]: unknown\n }) => void,\n onError?: (e: Error) => void\n ): ReturnType<ConvexClient['onPaginatedUpdate_experimental']> {\n const wireArgs = this.codec.encodeArgs(ref, args) as FunctionArgs<Q>\n return this.getConvex().onPaginatedUpdate_experimental(\n ref,\n wireArgs,\n options,\n (wireResult: any) => {\n callback({\n ...wireResult,\n page: wireResult.page.map((item: any) => this.codec.decodeResult(ref, item))\n })\n },\n onError\n ) as ReturnType<ConvexClient['onPaginatedUpdate_experimental']>\n }\n\n /**\n * Set the auth token. Accepts either a raw token string (convenience) or a\n * Convex `AuthTokenFetcher` plus optional `onChange` callback (parity with\n * `ConvexClient.setAuth`).\n */\n setAuth(token: string | null): void\n setAuth(fetchToken: AuthTokenFetcher, onChange?: (isAuthenticated: boolean) => void): void\n setAuth(\n tokenOrFetcher: string | null | AuthTokenFetcher,\n onChange?: (isAuthenticated: boolean) => void\n ): void {\n const fetcher: AuthTokenFetcher =\n typeof tokenOrFetcher === 'function' ? tokenOrFetcher : async () => tokenOrFetcher\n this.pendingAuthFetcher = fetcher\n this.pendingAuthOnChange = onChange\n if (this.innerClient) {\n this.innerClient.setAuth(fetcher, onChange)\n }\n }\n\n /** Returns the current auth token and its decoded claims, if authenticated. */\n getAuth(): { token: string; decoded: Record<string, any> } | undefined {\n return this.getConvex().getAuth()\n }\n\n /** Whether this client has been closed. False before the inner client is created. */\n get closed(): boolean {\n return this.innerClient?.closed ?? false\n }\n\n /** Whether this client is disabled. False before the inner client is created. */\n get disabled(): boolean {\n return this.innerClient?.disabled ?? false\n }\n\n connectionState(): ConnectionState {\n return this.getConvex().connectionState()\n }\n\n subscribeToConnectionState(cb: (state: ConnectionState) => void): () => void {\n return this.getConvex().subscribeToConnectionState(cb)\n }\n\n async close() {\n await this.getConvex().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/internal/normalizeCodecPaths.ts","../../src/internal/stripUndefined.ts","../../src/internal/boundaryHelpers.ts","../../src/public/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","/**\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 | null {\n if (typeof ref === 'string') return ref\n const name = (ref as any)[functionNameSymbol]\n if (!name) return null\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 */\n/**\n * Module-scoped so the registry-miss note fires once per path per process.\n * A per-helpers set resets on every Convex invocation (ctx is wrapped per\n * call), which spammed hot paths on every request (#101).\n */\nconst warnedPaths = new Set<string>()\n\n/** @internal Test-only: clears the process-wide registry-miss dedup set. */\nexport function __resetRegistryMissWarnings(): void {\n warnedPaths.clear()\n}\n\nexport function createBoundaryHelpers(registry: AnyRegistry, options?: BoundaryHelpersOptions) {\n const onDecodeError = options?.onDecodeError ?? 'warn'\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 if (path == null) return args\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/returns pass through unencoded. ` +\n 'This is expected when the target is a raw (non-zodvex) function; if it should be ' +\n 'codec-aware, 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 if (path == null) return wireResult\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, ConnectionState, MutationOptions } from 'convex/browser'\nimport { ConvexClient } from 'convex/browser'\nimport type { FunctionArgs, FunctionReference, FunctionReturnType } from 'convex/server'\nimport type { BoundaryHelpersOptions } from '../../internal/boundaryHelpers'\nimport { createBoundaryHelpers } from '../../internal/boundaryHelpers'\nimport type { AnyRegistry } from '../../internal/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 private codec: ReturnType<typeof createBoundaryHelpers>\n private innerClient?: ConvexClient\n private url?: string\n private pendingAuthFetcher?: AuthTokenFetcher\n private pendingAuthOnChange?: (isAuthenticated: boolean) => void\n\n constructor(registry: R, options: ZodvexClientOptions) {\n this.codec = createBoundaryHelpers(registry, { onDecodeError: options.onDecodeError })\n if ('client' in options) {\n this.innerClient = options.client\n } else {\n this.url = options.url\n if (options.token) this.pendingAuthFetcher = tokenToFetcher(options.token)\n }\n }\n\n private getUrl(): string {\n if (this.url) return this.url\n throw new Error('[zodvex] ZodvexClient is missing a Convex URL.')\n }\n\n private getConvex(): ConvexClient {\n if (this.innerClient) return this.innerClient\n\n const client = new ConvexClient(this.getUrl())\n if (this.pendingAuthFetcher) {\n client.setAuth(this.pendingAuthFetcher, this.pendingAuthOnChange)\n }\n this.innerClient = client\n return client\n }\n\n get convex(): ConvexClient {\n return this.getConvex()\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.getConvex().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 options?: MutationOptions\n ): Promise<M['_returnType']> {\n const wireResult = await this.getConvex().mutation(\n ref,\n this.codec.encodeArgs(ref, args) as FunctionArgs<M>,\n options\n )\n return this.codec.decodeResult(ref, wireResult)\n }\n\n /** Alias for {@link mutate} — matches `ConvexClient.mutation` / `ZodvexReactClient.mutation`. */\n mutation<M extends FunctionReference<'mutation', any, any, any>>(\n ref: M,\n args: M['_args'],\n options?: MutationOptions\n ): Promise<M['_returnType']> {\n return this.mutate(ref, args, options)\n }\n\n async action<A extends FunctionReference<'action', any, any, any>>(\n ref: A,\n args: A['_args']\n ): Promise<A['_returnType']> {\n const wireResult = await this.getConvex().action(\n ref,\n this.codec.encodeArgs(ref, args) as FunctionArgs<A>\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 onError?: (e: Error) => void\n ): () => void {\n const wireArgs = this.codec.encodeArgs(ref, args) as FunctionArgs<Q>\n return this.getConvex().onUpdate(\n ref,\n wireArgs,\n (wireResult: FunctionReturnType<Q>) => {\n callback(this.codec.decodeResult(ref, wireResult))\n },\n onError\n )\n }\n\n /** Alias for {@link subscribe} — matches `ConvexClient.onUpdate`. */\n onUpdate<Q extends FunctionReference<'query', any, any, any>>(\n ref: Q,\n args: Q['_args'],\n callback: (result: Q['_returnType']) => void,\n onError?: (e: Error) => void\n ): () => void {\n return this.subscribe(ref, args, callback, onError)\n }\n\n /**\n * Experimental paginated subscription. Encodes args to wire and decodes each\n * page item through the registry, mirroring {@link subscribe}.\n */\n onPaginatedUpdate_experimental<Q extends FunctionReference<'query', any, any, any>>(\n ref: Q,\n args: Q['_args'],\n options: { initialNumItems: number },\n callback: (result: {\n page: Q['_returnType'][]\n isDone: boolean\n continueCursor: string\n [key: string]: unknown\n }) => void,\n onError?: (e: Error) => void\n ): ReturnType<ConvexClient['onPaginatedUpdate_experimental']> {\n const wireArgs = this.codec.encodeArgs(ref, args) as FunctionArgs<Q>\n return this.getConvex().onPaginatedUpdate_experimental(\n ref,\n wireArgs,\n options,\n (wireResult: any) => {\n callback({\n ...wireResult,\n page: wireResult.page.map((item: any) => this.codec.decodeResult(ref, item))\n })\n },\n onError\n ) as ReturnType<ConvexClient['onPaginatedUpdate_experimental']>\n }\n\n /**\n * Set the auth token. Accepts either a raw token string (convenience) or a\n * Convex `AuthTokenFetcher` plus optional `onChange` callback (parity with\n * `ConvexClient.setAuth`).\n */\n setAuth(token: string | null): void\n setAuth(fetchToken: AuthTokenFetcher, onChange?: (isAuthenticated: boolean) => void): void\n setAuth(\n tokenOrFetcher: string | null | AuthTokenFetcher,\n onChange?: (isAuthenticated: boolean) => void\n ): void {\n const fetcher: AuthTokenFetcher =\n typeof tokenOrFetcher === 'function' ? tokenOrFetcher : async () => tokenOrFetcher\n this.pendingAuthFetcher = fetcher\n this.pendingAuthOnChange = onChange\n if (this.innerClient) {\n this.innerClient.setAuth(fetcher, onChange)\n }\n }\n\n /** Returns the current auth token and its decoded claims, if authenticated. */\n getAuth(): { token: string; decoded: Record<string, any> } | undefined {\n return this.getConvex().getAuth()\n }\n\n /** Whether this client has been closed. False before the inner client is created. */\n get closed(): boolean {\n return this.innerClient?.closed ?? false\n }\n\n /** Whether this client is disabled. False before the inner client is created. */\n get disabled(): boolean {\n return this.innerClient?.disabled ?? false\n }\n\n connectionState(): ConnectionState {\n return this.getConvex().connectionState()\n }\n\n subscribeToConnectionState(cb: (state: ConnectionState) => void): () => void {\n return this.getConvex().subscribeToConnectionState(cb)\n }\n\n async close() {\n await this.getConvex().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,7 +1,7 @@
1
- import path from 'path';
1
+ import path2 from 'path';
2
2
  import { globSync } from 'tinyglobby';
3
3
  import { z } from 'zod';
4
- import { $ZodCodec, $ZodNumber, $ZodCustom, $ZodOptional, $ZodNullable, $ZodString, $ZodBoolean, $ZodNull, $ZodUndefined, $ZodAny, $ZodObject, $ZodArray, $ZodEnum, $ZodLiteral, $ZodUnion, $ZodTuple, $ZodRecord, $ZodType, clone, $ZodDiscriminatedUnion } from 'zod/v4/core';
4
+ import { $ZodCodec, $ZodOptional, $ZodNullable, $ZodString, $ZodNumber, $ZodBoolean, $ZodNull, $ZodUndefined, $ZodAny, $ZodObject, $ZodArray, $ZodEnum, $ZodLiteral, $ZodUnion, $ZodTuple, $ZodRecord, $ZodType, clone, $ZodDiscriminatedUnion } from 'zod/v4/core';
5
5
  import 'convex/values';
6
6
  import fs from 'fs';
7
7
 
@@ -45,18 +45,34 @@ function zodvexCodec(wire, runtime, transforms) {
45
45
  return z.codec(wire, runtime, transforms);
46
46
  }
47
47
 
48
+ // src/internal/zxDateBrand.ts
49
+ var ZX_DATE_BRAND = /* @__PURE__ */ Symbol.for("zodvex.zxDate");
50
+ function brandZxDate(codec2) {
51
+ codec2[ZX_DATE_BRAND] = true;
52
+ const def = codec2._zod?.def;
53
+ if (def) def[ZX_DATE_BRAND] = true;
54
+ return codec2;
55
+ }
56
+ function isZxDateCodec(schema) {
57
+ if (!schema || typeof schema !== "object") return false;
58
+ const s = schema;
59
+ return s[ZX_DATE_BRAND] === true || s._zod?.def?.[ZX_DATE_BRAND] === true;
60
+ }
61
+
48
62
  // src/internal/zx.ts
49
63
  function date() {
50
- return zodvexCodec(
51
- z.number(),
52
- // Wire: timestamp
53
- z.custom((val) => val instanceof Date, {
54
- message: "Expected Date instance"
55
- }),
56
- {
57
- decode: (timestamp) => new Date(timestamp),
58
- encode: (date2) => date2.getTime()
59
- }
64
+ return brandZxDate(
65
+ zodvexCodec(
66
+ z.number(),
67
+ // Wire: timestamp
68
+ z.custom((val) => val instanceof Date, {
69
+ message: "Expected Date instance"
70
+ }),
71
+ {
72
+ decode: (timestamp) => new Date(timestamp),
73
+ encode: (date2) => date2.getTime()
74
+ }
75
+ )
60
76
  );
61
77
  }
62
78
  function id(tableName) {
@@ -295,9 +311,35 @@ function createSchemaUpdateSchema(name, inputSchema) {
295
311
  }
296
312
  return inputSchema;
297
313
  }
298
- var HOOKS_SOURCE = `
314
+ function buildHooksSource(aliases) {
315
+ return `
316
+ import { pathToFileURL } from 'node:url';
317
+
299
318
  const EXT_CANDIDATES = ['.ts', '.tsx', '.mts', '.js', '.mjs', '.jsx', '/index.ts', '/index.js'];
300
319
 
320
+ // tsconfig path aliases compiled by loadTsconfigAliases (#99). Bun resolves
321
+ // these natively; Node's ESM loader needs them replayed here.
322
+ const ALIASES = ${JSON.stringify(aliases)};
323
+
324
+ function aliasCandidates(specifier) {
325
+ const out = [];
326
+ for (const a of ALIASES) {
327
+ if (a.star) {
328
+ if (
329
+ specifier.length >= a.prefix.length + a.suffix.length &&
330
+ specifier.startsWith(a.prefix) &&
331
+ specifier.endsWith(a.suffix)
332
+ ) {
333
+ const captured = specifier.slice(a.prefix.length, specifier.length - a.suffix.length);
334
+ for (const t of a.targets) out.push(t.prefix + captured + t.suffix);
335
+ }
336
+ } else if (specifier === a.prefix) {
337
+ for (const t of a.targets) out.push(t.prefix);
338
+ }
339
+ }
340
+ return out;
341
+ }
342
+
301
343
  export async function resolve(specifier, context, nextResolve) {
302
344
  if (/_generated\\/api(\\.[mc]?[jt]sx?)?$/.test(specifier)) {
303
345
  return { shortCircuit: true, url: 'zodvex-stub://api' };
@@ -305,6 +347,15 @@ export async function resolve(specifier, context, nextResolve) {
305
347
  try {
306
348
  return await nextResolve(specifier, context);
307
349
  } catch (err) {
350
+ // tsconfig path aliases (e.g. '@/convex/...'). Try each mapped absolute
351
+ // path as-is, then with the usual extension/index candidates.
352
+ for (const base of aliasCandidates(specifier)) {
353
+ for (const ext of ['', ...EXT_CANDIDATES]) {
354
+ try {
355
+ return await nextResolve(pathToFileURL(base + ext).href, context);
356
+ } catch {}
357
+ }
358
+ }
308
359
  // Convex code uses extensionless relative imports (bundler resolution).
309
360
  // Bun resolves those natively; Node's ESM loader does not \u2014 retry with
310
361
  // the usual extension candidates before giving up.
@@ -349,8 +400,9 @@ export function load(url, context, nextLoad) {
349
400
  return nextLoad(url, context);
350
401
  }
351
402
  `;
403
+ }
352
404
  var hooksRegistered = false;
353
- function registerDiscoveryHooks() {
405
+ function registerDiscoveryHooks(aliases = []) {
354
406
  if (hooksRegistered) return true;
355
407
  try {
356
408
  const nodeModule = typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("node:module") : (
@@ -359,7 +411,7 @@ function registerDiscoveryHooks() {
359
411
  );
360
412
  const { register } = nodeModule;
361
413
  if (typeof register !== "function") return false;
362
- register(`data:text/javascript,${encodeURIComponent(HOOKS_SOURCE)}`);
414
+ register(`data:text/javascript,${encodeURIComponent(buildHooksSource(aliases))}`);
363
415
  hooksRegistered = true;
364
416
  return true;
365
417
  } catch {
@@ -384,8 +436,8 @@ export const components = p;
384
436
  export const httpRouter = p;
385
437
  `;
386
438
  function writeGeneratedStubs(convexDir) {
387
- const generatedDir = path.join(convexDir, "_generated");
388
- const apiPath = path.join(generatedDir, "api.ts");
439
+ const generatedDir = path2.join(convexDir, "_generated");
440
+ const apiPath = path2.join(generatedDir, "api.ts");
389
441
  let original;
390
442
  try {
391
443
  original = fs.readFileSync(apiPath, "utf8");
@@ -411,8 +463,7 @@ function findCodec(schema) {
411
463
  let current = schema;
412
464
  for (let i = 0; i < 10; i++) {
413
465
  if (current instanceof $ZodCodec) {
414
- const isZxDate = current._zod.def.in instanceof $ZodNumber && current._zod.def.out instanceof $ZodCustom;
415
- if (isZxDate) return void 0;
466
+ if (isZxDateCodec(current)) return void 0;
416
467
  return current;
417
468
  }
418
469
  if (current instanceof $ZodOptional || current instanceof $ZodNullable) {
@@ -444,6 +495,134 @@ function readFnReturns(fn) {
444
495
  }
445
496
  return meta.zodReturns;
446
497
  }
498
+ function stripJsonComments(input) {
499
+ let out = "";
500
+ let inString = false;
501
+ let inLine = false;
502
+ let inBlock = false;
503
+ for (let i = 0; i < input.length; i++) {
504
+ const ch = input[i];
505
+ const next = input[i + 1];
506
+ if (inLine) {
507
+ if (ch === "\n") {
508
+ inLine = false;
509
+ out += ch;
510
+ }
511
+ continue;
512
+ }
513
+ if (inBlock) {
514
+ if (ch === "*" && next === "/") {
515
+ inBlock = false;
516
+ i++;
517
+ }
518
+ continue;
519
+ }
520
+ if (inString) {
521
+ out += ch;
522
+ if (ch === "\\") {
523
+ out += next ?? "";
524
+ i++;
525
+ } else if (ch === '"') {
526
+ inString = false;
527
+ }
528
+ continue;
529
+ }
530
+ if (ch === '"') {
531
+ inString = true;
532
+ out += ch;
533
+ continue;
534
+ }
535
+ if (ch === "/" && next === "/") {
536
+ inLine = true;
537
+ i++;
538
+ continue;
539
+ }
540
+ if (ch === "/" && next === "*") {
541
+ inBlock = true;
542
+ i++;
543
+ continue;
544
+ }
545
+ out += ch;
546
+ }
547
+ return out.replace(/,\s*([}\]])/g, "$1");
548
+ }
549
+ function readTsconfig(configPath) {
550
+ try {
551
+ const raw = fs.readFileSync(configPath, "utf8");
552
+ return JSON.parse(stripJsonComments(raw));
553
+ } catch {
554
+ return null;
555
+ }
556
+ }
557
+ function resolvePathsFromConfig(configPath, seen) {
558
+ const abs = path2.resolve(configPath);
559
+ if (seen.has(abs)) return null;
560
+ seen.add(abs);
561
+ const config = readTsconfig(abs);
562
+ if (!config) return null;
563
+ const dir = path2.dirname(abs);
564
+ const own = config.compilerOptions?.paths;
565
+ if (own) {
566
+ const baseUrl = config.compilerOptions?.baseUrl;
567
+ return { paths: own, baseDir: baseUrl ? path2.resolve(dir, baseUrl) : dir };
568
+ }
569
+ const parents = config.extends == null ? [] : [].concat(config.extends);
570
+ for (const ref of parents) {
571
+ if (!ref.startsWith(".") && !path2.isAbsolute(ref)) continue;
572
+ let target = path2.resolve(dir, ref);
573
+ if (!target.endsWith(".json")) target += ".json";
574
+ const found = resolvePathsFromConfig(target, seen);
575
+ if (found) {
576
+ const childBase = config.compilerOptions?.baseUrl;
577
+ return childBase ? { paths: found.paths, baseDir: path2.resolve(dir, childBase) } : found;
578
+ }
579
+ }
580
+ return null;
581
+ }
582
+ function compileAliases(paths, baseDir) {
583
+ const entries = [];
584
+ for (const [pattern, targets] of Object.entries(paths)) {
585
+ const starIdx = pattern.indexOf("*");
586
+ const star = starIdx !== -1;
587
+ const prefix = star ? pattern.slice(0, starIdx) : pattern;
588
+ const suffix = star ? pattern.slice(starIdx + 1) : "";
589
+ const compiled = targets.map((t) => {
590
+ const tStar = t.indexOf("*");
591
+ const tPrefix = path2.resolve(baseDir, tStar === -1 ? t : t.slice(0, tStar));
592
+ const sep = tStar !== -1 && t.slice(0, tStar).endsWith("/") ? path2.sep : "";
593
+ return {
594
+ prefix: tPrefix + sep,
595
+ suffix: tStar === -1 ? "" : t.slice(tStar + 1)
596
+ };
597
+ });
598
+ entries.push({ prefix, suffix, star, targets: compiled });
599
+ }
600
+ return entries;
601
+ }
602
+ function loadTsconfigAliases(convexDir) {
603
+ const entries = [];
604
+ const seenPatterns = /* @__PURE__ */ new Set();
605
+ let dir = path2.resolve(convexDir);
606
+ for (let depth = 0; depth < 10; depth++) {
607
+ const configPath = path2.join(dir, "tsconfig.json");
608
+ if (fs.existsSync(configPath)) {
609
+ const found = resolvePathsFromConfig(configPath, /* @__PURE__ */ new Set());
610
+ if (found) {
611
+ for (const entry of compileAliases(found.paths, found.baseDir)) {
612
+ const key = `${entry.prefix}*${entry.suffix}`;
613
+ if (!seenPatterns.has(key)) {
614
+ seenPatterns.add(key);
615
+ entries.push(entry);
616
+ }
617
+ }
618
+ }
619
+ }
620
+ const parent = path2.dirname(dir);
621
+ if (parent === dir) break;
622
+ dir = parent;
623
+ }
624
+ return entries;
625
+ }
447
626
 
448
627
  // src/public/codegen/discover.ts
449
628
  function walkSchemaRecursive(schema, accessPath, visited, seenCodecs, results) {
@@ -587,7 +766,7 @@ async function discoverModules(convexDir) {
587
766
  const models = [];
588
767
  const functions = [];
589
768
  const codecs = [];
590
- registerDiscoveryHooks();
769
+ registerDiscoveryHooks(loadTsconfigAliases(convexDir));
591
770
  const cleanupStubs = writeGeneratedStubs(convexDir);
592
771
  const files = globSync(["**/*.{ts,js}"], {
593
772
  cwd: convexDir,
@@ -607,15 +786,15 @@ async function discoverModules(convexDir) {
607
786
  "crons.js"
608
787
  ]
609
788
  }).sort();
610
- let importFailures = 0;
789
+ const failedImports = [];
611
790
  try {
612
791
  for (const file of files) {
613
- const absPath = path.resolve(convexDir, file);
792
+ const absPath = path2.resolve(convexDir, file);
614
793
  let moduleExports;
615
794
  try {
616
795
  moduleExports = await import(absPath);
617
796
  } catch (err) {
618
- importFailures++;
797
+ failedImports.push({ file, message: err.message });
619
798
  console.warn(`[zodvex] Warning: Failed to import ${file}:`, err.message);
620
799
  continue;
621
800
  }
@@ -659,8 +838,7 @@ async function discoverModules(convexDir) {
659
838
  }
660
839
  }
661
840
  if (value instanceof $ZodCodec) {
662
- const isZxDate = value._zod.def.in instanceof $ZodNumber && value._zod.def.out instanceof $ZodCustom;
663
- if (!isZxDate) {
841
+ if (!isZxDateCodec(value)) {
664
842
  if (!codecs.some((c) => c.schema === value)) {
665
843
  codecs.push({
666
844
  exportName,
@@ -683,9 +861,14 @@ async function discoverModules(convexDir) {
683
861
  modelCodecs.push(...found);
684
862
  }
685
863
  const functionCodecs = walkFunctionCodecs(functions);
686
- if (importFailures > 0 && models.length === 0 && functions.length === 0) {
864
+ if (failedImports.length > 0 && !process.env.ZODVEX_ALLOW_IMPORT_FAILURES) {
865
+ const shown = failedImports.slice(0, 10).map((f) => ` - ${f.file}: ${f.message}`).join("\n");
866
+ const more = failedImports.length > 10 ? `
867
+ \u2026 and ${failedImports.length - 10} more` : "";
687
868
  throw new Error(
688
- `[zodvex] Discovery imported 0 modules (${importFailures} file(s) failed to load). Importing TypeScript at runtime requires Bun or Node >= 22.18 (native type stripping). Re-run with Bun (\`bunx zodvex generate\`) or upgrade Node.`
869
+ `[zodvex] ${failedImports.length} module(s) failed to import during discovery \u2014 the generated registry would be incomplete:
870
+ ${shown}${more}
871
+ Common causes: Node < 22.18 (no native TypeScript type stripping \u2014 use Bun or upgrade Node), or an import style the discovery resolver does not handle. tsconfig path aliases and extensionless relative imports are supported. Set ZODVEX_ALLOW_IMPORT_FAILURES=1 to generate anyway (skipping the failed modules).`
689
872
  );
690
873
  }
691
874
  return { models, functions, codecs, modelCodecs, functionCodecs };
@@ -710,7 +893,7 @@ function zodToSource(schema, ctx) {
710
893
  return `zx.id("${tableName}")`;
711
894
  }
712
895
  }
713
- if (schema instanceof $ZodCodec && schema._zod.def.in instanceof $ZodNumber && schema._zod.def.out instanceof $ZodCustom) {
896
+ if (schema instanceof $ZodCodec && isZxDateCodec(schema)) {
714
897
  return "zx.date()";
715
898
  }
716
899
  if (schema instanceof $ZodCodec) {