kitcn 0.22.0 → 0.23.0

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.
@@ -1,4 +1,4 @@
1
- import { H as ConvexContext, W as LazyCaller } from "../../procedure-name-exVcmr_p.js";
1
+ import { H as ConvexContext, W as LazyCaller } from "../../procedure-name-C55TynK3.js";
2
2
  import { t as GetTokenOptions } from "../../token-B9Bjcqug.js";
3
3
 
4
4
  //#region src/auth-nextjs/index.d.ts
@@ -1,6 +1,6 @@
1
1
  import { t as getToken } from "../../token-xlpENMVn.js";
2
2
  import { n as defaultIsUnauthorized } from "../../error-Bvo7YEhk.js";
3
- import { t as createCallerFactory } from "../../caller-factory-DHywSoGZ.js";
3
+ import { t as createCallerFactory } from "../../caller-factory-CWa0ELLD.js";
4
4
 
5
5
  //#region src/auth-nextjs/index.ts
6
6
  /** biome-ignore-all lint/suspicious/noExplicitAny: lib */
@@ -1,7 +1,6 @@
1
- import { i as pick } from "./upstream-BR6sBLg3.js";
2
1
  import { o as vRequired, t as addFieldsToValidator } from "./validators-C7LelqTN.js";
3
2
  import { n as customCtx, t as NoOp } from "./customFunctions-DxEEO4Dq.js";
4
- import { s as getTransformer } from "./transformer-C6pGVHqx.js";
3
+ import { s as getTransformer } from "./transformer-yZuBWo8v.js";
5
4
  import { ConvexError, v } from "convex/values";
6
5
  import { HttpRouter, actionGeneric, httpActionGeneric, internalActionGeneric, internalMutationGeneric, internalQueryGeneric, mutationGeneric, queryGeneric } from "convex/server";
7
6
  import { z } from "zod";
@@ -501,25 +500,43 @@ function withSystemFields(tableName, zObject) {
501
500
  _creationTime: z$1.number()
502
501
  };
503
502
  }
503
+ /**
504
+ * Single-pass `pick` over own keys, preserving `obj`'s insertion order.
505
+ *
506
+ * The shared `pick` helper is `Object.fromEntries(Object.entries(obj).filter(
507
+ * ([k]) => keys.includes(k)))`, i.e. O(fields^2) with three intermediate
508
+ * allocations. This runs on every request, so it gets a Set instead.
509
+ */
510
+ function pickKeys(obj, keys) {
511
+ const result = {};
512
+ for (const key of Object.keys(obj)) if (keys.has(key)) result[key] = obj[key];
513
+ return result;
514
+ }
504
515
  function customFnBuilder(builder, customization) {
505
516
  const customInput = customization.input ?? NoOp.input;
506
517
  const inputArgs = customization.args ?? NoOp.args;
507
518
  return function customBuilder(fn) {
508
- const { args, handler = fn, skipConvexValidation = false, returns: maybeObject, ...extra } = fn;
519
+ const { args, handler = fn, skipConvexValidation = false, skipZodReturnsValidation = false, returns: maybeObject, ...extra } = fn;
509
520
  const returns = maybeObject && !(maybeObject instanceof zCore.$ZodType) ? z$1.object(maybeObject) : maybeObject;
510
521
  const returnValidator = returns && !skipConvexValidation ? { returns: zodOutputToConvex(returns) } : null;
522
+ const parseReturns = returns && !skipZodReturnsValidation ? (value) => returns.parseAsync(value === void 0 ? null : value) : null;
511
523
  if (args) {
512
524
  let argsValidator = args;
513
525
  if (argsValidator instanceof zCore.$ZodType) if (argsValidator instanceof zCore.$ZodObject) argsValidator = argsValidator._zod.def.shape;
514
526
  else throw new Error("Unsupported zod type as args validator: " + argsValidator.constructor.name);
515
527
  const convexValidator = zodToConvexFields(argsValidator);
528
+ const inputArgKeys = Object.keys(inputArgs);
529
+ const inputArgKeySet = new Set(inputArgKeys);
530
+ const argKeySet = new Set(Object.keys(argsValidator));
531
+ let argsSchema;
516
532
  return builder({
517
533
  args: skipConvexValidation ? void 0 : addFieldsToValidator(convexValidator, inputArgs),
518
534
  ...returnValidator,
519
535
  handler: async (ctx, allArgs) => {
520
- const added = await customInput(ctx, pick(allArgs, Object.keys(inputArgs)), extra);
521
- const rawArgs = pick(allArgs, Object.keys(argsValidator));
522
- const parsed = await z$1.object(argsValidator).safeParseAsync(rawArgs);
536
+ const added = await customInput(ctx, inputArgKeys.length === 0 ? {} : pickKeys(allArgs, inputArgKeySet), extra);
537
+ const rawArgs = pickKeys(allArgs, argKeySet);
538
+ argsSchema ??= z$1.object(argsValidator);
539
+ const parsed = await argsSchema.safeParseAsync(rawArgs);
523
540
  if (!parsed.success) throw new ConvexError({ ZodError: JSON.parse(JSON.stringify(parsed.error.issues, null, 2)) });
524
541
  const args = parsed.data;
525
542
  const ret = await handler({
@@ -529,7 +546,7 @@ function customFnBuilder(builder, customization) {
529
546
  ...args,
530
547
  ...added.args
531
548
  });
532
- const result = returns ? await returns.parseAsync(ret === void 0 ? null : ret) : ret;
549
+ const result = parseReturns ? await parseReturns(ret) : ret;
533
550
  if (added.onSuccess) await added.onSuccess({
534
551
  ctx,
535
552
  args,
@@ -551,7 +568,7 @@ function customFnBuilder(builder, customization) {
551
568
  ...args,
552
569
  ...added.args
553
570
  });
554
- const result = returns ? await returns.parseAsync(ret === void 0 ? null : ret) : ret;
571
+ const result = parseReturns ? await parseReturns(ret) : ret;
555
572
  if (added.onSuccess) await added.onSuccess({
556
573
  ctx,
557
574
  args,
@@ -971,29 +988,51 @@ function getBaseSchema(schema) {
971
988
  if (schema instanceof z.ZodDefault) return getBaseSchema(schema._def.innerType);
972
989
  return schema;
973
990
  }
974
- function isArraySchema(schema) {
975
- return getBaseSchema(schema) instanceof z.ZodArray;
976
- }
977
- function isNumberSchema(schema) {
978
- return getBaseSchema(schema) instanceof z.ZodNumber;
979
- }
980
- function isBooleanSchema(schema) {
981
- return getBaseSchema(schema) instanceof z.ZodBoolean;
991
+ /**
992
+ * Resolve each field's coercion kind from the query schema, once.
993
+ *
994
+ * The kind is a static property of the schema, but zod 4 overrides
995
+ * `Symbol.hasInstance`, so leaving it in the request path pays a `Set.has`
996
+ * per unwrap step per field per request.
997
+ *
998
+ * Fields absent from the map fall through to the raw string(s) branch, which
999
+ * is also where a non-`ZodObject` query schema lands (it has no readable
1000
+ * shape, so it gets no coercion at all).
1001
+ */
1002
+ function buildQueryCoercion(schema) {
1003
+ const coercion = /* @__PURE__ */ new Map();
1004
+ if (!(schema instanceof z.ZodObject)) return coercion;
1005
+ for (const [key, fieldSchema] of Object.entries(schema.shape)) {
1006
+ const base = getBaseSchema(fieldSchema);
1007
+ if (base instanceof z.ZodArray) coercion.set(key, "array");
1008
+ else if (base instanceof z.ZodNumber) coercion.set(key, "number");
1009
+ else if (base instanceof z.ZodBoolean) coercion.set(key, "boolean");
1010
+ }
1011
+ return coercion;
982
1012
  }
983
- function parseQueryParams(url, schema) {
1013
+ function parseQueryParams(url, coercion) {
984
1014
  const params = {};
985
- const keys = new Set(url.searchParams.keys());
986
- const shape = schema instanceof z.ZodObject ? schema.shape : {};
987
- for (const key of keys) {
988
- const values = url.searchParams.getAll(key);
989
- const fieldSchema = shape[key];
990
- if (fieldSchema) if (isArraySchema(fieldSchema)) params[key] = values;
991
- else if (isNumberSchema(fieldSchema)) params[key] = Number(values[0]);
992
- else if (isBooleanSchema(fieldSchema)) {
1015
+ const collected = /* @__PURE__ */ new Map();
1016
+ for (const [key, value] of url.searchParams) {
1017
+ const existing = collected.get(key);
1018
+ if (existing) existing.push(value);
1019
+ else collected.set(key, [value]);
1020
+ }
1021
+ for (const [key, values] of collected) switch (coercion.get(key)) {
1022
+ case "array":
1023
+ params[key] = values;
1024
+ break;
1025
+ case "number":
1026
+ params[key] = Number(values[0]);
1027
+ break;
1028
+ case "boolean": {
993
1029
  const val = values[0].toLowerCase();
994
1030
  params[key] = val === "true" || val === "1";
995
- } else params[key] = values.length === 1 ? values[0] : values;
996
- else params[key] = values.length === 1 ? values[0] : values;
1031
+ break;
1032
+ }
1033
+ default:
1034
+ params[key] = values.length === 1 ? values[0] : values;
1035
+ break;
997
1036
  }
998
1037
  return params;
999
1038
  }
@@ -1017,6 +1056,7 @@ function resolveHttpProcedureInfo(def) {
1017
1056
  function createProcedure(def, handler, _type) {
1018
1057
  if (!def.route) throw new Error("Route must be defined before action. Use .route(path, method) first.");
1019
1058
  const middlewareProcedure = resolveHttpProcedureInfo(def);
1059
+ const queryCoercion = buildQueryCoercion(def.querySchema);
1020
1060
  /**
1021
1061
  * Hono-compatible handler function.
1022
1062
  * When used with HttpRouterWithHono, Convex ctx is passed via c.env.
@@ -1046,7 +1086,7 @@ function createProcedure(def, handler, _type) {
1046
1086
  }
1047
1087
  let parsedQuery;
1048
1088
  if (def.querySchema) {
1049
- const queryParams = parseQueryParams(url, def.querySchema);
1089
+ const queryParams = parseQueryParams(url, queryCoercion);
1050
1090
  try {
1051
1091
  parsedQuery = def.querySchema.parse(queryParams);
1052
1092
  } catch (error) {
@@ -1720,24 +1760,18 @@ const replaceUnencodableInputTypes = (schema) => {
1720
1760
  * unchanged) but carries no checks, transforms, or defaults. cRPC's own
1721
1761
  * `.input()` parse stays the single authoritative one, so refinements and
1722
1762
  * transforms never run twice.
1763
+ *
1764
+ * Throws when the shape has no Convex equivalent, which is also the
1765
+ * feasibility test `resolveConvexArgsShape` steps down its fallback ladder on.
1723
1766
  */
1724
- const toWireShape = (shape) => {
1725
- try {
1726
- return convexToZodFields(zodToConvexFields(shape));
1727
- } catch {
1728
- return shape;
1729
- }
1730
- };
1767
+ const toWireShape = (shape) => convexToZodFields(zodToConvexFields(shape));
1731
1768
  const resolveConvexArgsShape = (inputShape) => {
1732
1769
  if (!inputShape) return;
1733
- const rawSchema = z.object(inputShape);
1734
1770
  try {
1735
- zodToConvex(rawSchema);
1736
1771
  return toWireShape(inputShape);
1737
1772
  } catch {
1738
- const compatibleSchema = replaceUnencodableInputTypes(rawSchema);
1773
+ const compatibleSchema = replaceUnencodableInputTypes(z.object(inputShape));
1739
1774
  try {
1740
- zodToConvex(compatibleSchema);
1741
1775
  return toWireShape(compatibleSchema.shape);
1742
1776
  } catch {
1743
1777
  return Object.fromEntries(Object.keys(inputShape).map((key) => [key, z.any()]));
@@ -1760,6 +1794,29 @@ const relaxSupersededKeys = (schema, superseded) => {
1760
1794
  return schema;
1761
1795
  }
1762
1796
  };
1797
+ const buildInputPlan = (inputSchemas) => {
1798
+ if (inputSchemas.length === 1) return {
1799
+ entries: [],
1800
+ single: inputSchemas[0]
1801
+ };
1802
+ const ownerOf = /* @__PURE__ */ new Map();
1803
+ inputSchemas.forEach((schema, index) => {
1804
+ for (const key of Object.keys(schema.shape)) ownerOf.set(key, index);
1805
+ });
1806
+ return { entries: inputSchemas.map((schema, index) => {
1807
+ const keys = Object.keys(schema.shape);
1808
+ const owned = [];
1809
+ const superseded = /* @__PURE__ */ new Set();
1810
+ for (const key of keys) if (ownerOf.get(key) === index) owned.push(key);
1811
+ else superseded.add(key);
1812
+ return {
1813
+ keys,
1814
+ owned,
1815
+ scoped: relaxSupersededKeys(schema, [...superseded]),
1816
+ superseded
1817
+ };
1818
+ }) };
1819
+ };
1763
1820
  /**
1764
1821
  * Parse the wire payload through every `.input()` schema.
1765
1822
  *
@@ -1768,20 +1825,14 @@ const relaxSupersededKeys = (schema, superseded) => {
1768
1825
  * so object-level checks run against the shape they were written for without an
1769
1826
  * earlier, superseded declaration vetoing the payload.
1770
1827
  */
1771
- const parseInput = (inputSchemas, value) => {
1828
+ const parseInput = (plan, value) => {
1772
1829
  try {
1773
- if (inputSchemas.length === 1) return inputSchemas[0].parse(value);
1774
- const ownerOf = /* @__PURE__ */ new Map();
1775
- inputSchemas.forEach((schema, index) => {
1776
- for (const key of Object.keys(schema.shape)) ownerOf.set(key, index);
1777
- });
1830
+ if (plan.single) return plan.single.parse(value);
1831
+ const { entries } = plan;
1778
1832
  const source = isPlainObject(value) ? value : {};
1779
1833
  const parsed = {};
1780
- for (let index = inputSchemas.length - 1; index >= 0; index -= 1) {
1781
- const schema = inputSchemas[index];
1782
- const keys = Object.keys(schema.shape);
1783
- const superseded = new Set(keys.filter((key) => ownerOf.get(key) !== index));
1784
- const scoped = relaxSupersededKeys(schema, [...superseded]);
1834
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
1835
+ const { keys, owned, scoped, superseded } = entries[index];
1785
1836
  const narrowed = {};
1786
1837
  for (const key of keys) {
1787
1838
  if (superseded.has(key)) {
@@ -1791,7 +1842,7 @@ const parseInput = (inputSchemas, value) => {
1791
1842
  if (Object.hasOwn(source, key)) narrowed[key] = source[key];
1792
1843
  }
1793
1844
  const result = scoped.parse(narrowed);
1794
- for (const key of keys) if (ownerOf.get(key) === index && key in result) parsed[key] = result[key];
1845
+ for (const key of owned) if (key in result) parsed[key] = result[key];
1795
1846
  }
1796
1847
  return parsed;
1797
1848
  } catch (cause) {
@@ -1877,19 +1928,21 @@ var ProcedureBuilder = class {
1877
1928
  _createFunction(handler, baseFunction, customFn, fnType) {
1878
1929
  const { middlewares, inputSchemas, outputSchema, meta, procedureName, functionConfig, isInternal } = this._def;
1879
1930
  const convexArgs = resolveConvexArgsShape(this._getMergedInput());
1931
+ const inputPlan = buildInputPlan(inputSchemas);
1880
1932
  const customFunction = customFn(baseFunction, customCtx(async (_ctx) => withConvexSafeRunners(await functionConfig.createContext(_ctx))));
1881
- const returnsSchema = resolveConvexReturnsSchema(outputSchema);
1882
- const typedReturnsSchema = returnsSchema;
1933
+ const typedReturnsSchema = resolveConvexReturnsSchema(outputSchema);
1883
1934
  const typedArgs = convexArgs ?? {};
1884
- const shouldValidateOutputWithZod = !!outputSchema && returnsSchema !== outputSchema;
1885
1935
  const resolvedProcedureName = procedureName ?? inferProcedureNameFromCallsite();
1886
1936
  let fn;
1887
1937
  fn = customFunction({
1888
1938
  args: typedArgs,
1889
- ...typedReturnsSchema ? { returns: typedReturnsSchema } : {},
1939
+ ...typedReturnsSchema ? {
1940
+ returns: typedReturnsSchema,
1941
+ skipZodReturnsValidation: true
1942
+ } : {},
1890
1943
  handler: async (ctx, rawInput) => {
1891
1944
  const decodedInput = functionConfig.transformer.input.deserialize(rawInput);
1892
- const parsedInput = inputSchemas.length > 0 ? parseInput(inputSchemas, decodedInput) : decodedInput;
1945
+ const parsedInput = inputSchemas.length > 0 ? parseInput(inputPlan, decodedInput) : decodedInput;
1893
1946
  const getRawInput = async () => parsedInput;
1894
1947
  try {
1895
1948
  const result = await executeMiddlewares(middlewares, ctx, meta, resolveProcedureInfo(fnType, resolvedProcedureName, fn), parsedInput, getRawInput, async ({ ctx: resolvedCtx, input: resolvedInput }) => {
@@ -1898,7 +1951,7 @@ var ProcedureBuilder = class {
1898
1951
  input: resolvedInput === parsedInput ? parsedInput : functionConfig.transformer.input.deserialize(resolvedInput ?? parsedInput)
1899
1952
  });
1900
1953
  });
1901
- const validatedOutput = shouldValidateOutputWithZod ? outputSchema.parse(result.output) : result.output;
1954
+ const validatedOutput = outputSchema ? await outputSchema.parseAsync(result.output) : result.output;
1902
1955
  return functionConfig.transformer.output.serialize(validatedOutput);
1903
1956
  } catch (cause) {
1904
1957
  const err = toCRPCError(cause);
@@ -1,6 +1,6 @@
1
1
  import { n as defaultIsUnauthorized } from "./error-Bvo7YEhk.js";
2
2
  import { i as getFunctionType, n as getFuncRef, t as buildMetaIndex } from "./meta-utils-D9K4fICl.js";
3
- import { s as getTransformer } from "./transformer-C6pGVHqx.js";
3
+ import { s as getTransformer } from "./transformer-yZuBWo8v.js";
4
4
  import { fetchAction, fetchMutation, fetchQuery } from "convex/nextjs";
5
5
 
6
6
  //#region src/server/caller.ts
@@ -1,5 +1,5 @@
1
- import { A as DataTransformer, F as decodeWire, I as defaultCRPCTransformer, L as encodeWire, M as WireCodec, N as createTaggedTransformer, O as CombinedDataTransformer, P as dateWireCodec, R as getTransformer, a as HttpProcedureCall, c as InferHttpInput, i as HttpErrorCode, j as DataTransformerOptions, k as DATE_CODEC_TAG, l as InferHttpOutput, n as HttpClientError, o as HttpRouteInfo, r as HttpClientFromRouter, s as HttpRouteMap, t as HttpClient, u as isHttpClientError, z as identityTransformer } from "../http-types-zsMHb_QN.js";
2
- import { A as HttpInputArgs, C as ReservedMutationOptions, D as VanillaMutation, E as VanillaAction, F as replaceUrlParam, M as RESERVED_KEYS, N as buildSearchParams, O as HttpClientOptions, P as executeHttpRequest, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, a as BaseInfiniteQueryOptsParam, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, h as FnMeta, i as BaseConvexQueryOptions, j as HttpProxyBaseOptions, k as HttpFormValue, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, n as BaseConvexActionOptions, o as ConvexActionKey, p as ExtractPaginatedItem, r as BaseConvexInfiniteQueryOptions, s as ConvexInfiniteQueryMeta, t as AuthType, u as ConvexQueryKey, v as Meta, w as ReservedQueryOptions, x as PaginationOpts, y as MutationVariables } from "../types-jNTcza_a.js";
1
+ import { A as DataTransformer, F as decodeWire, I as defaultCRPCTransformer, L as encodeWire, M as WireCodec, N as createTaggedTransformer, O as CombinedDataTransformer, P as dateWireCodec, R as getTransformer, a as HttpProcedureCall, c as InferHttpInput, i as HttpErrorCode, j as DataTransformerOptions, k as DATE_CODEC_TAG, l as InferHttpOutput, n as HttpClientError, o as HttpRouteInfo, r as HttpClientFromRouter, s as HttpRouteMap, t as HttpClient, u as isHttpClientError, z as identityTransformer } from "../http-types-BoSDAh4Y.js";
2
+ import { A as HttpInputArgs, C as ReservedMutationOptions, D as VanillaMutation, E as VanillaAction, F as replaceUrlParam, M as RESERVED_KEYS, N as buildSearchParams, O as HttpClientOptions, P as executeHttpRequest, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, a as BaseInfiniteQueryOptsParam, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, h as FnMeta, i as BaseConvexQueryOptions, j as HttpProxyBaseOptions, k as HttpFormValue, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, n as BaseConvexActionOptions, o as ConvexActionKey, p as ExtractPaginatedItem, r as BaseConvexInfiniteQueryOptions, s as ConvexInfiniteQueryMeta, t as AuthType, u as ConvexQueryKey, v as Meta, w as ReservedQueryOptions, x as PaginationOpts, y as MutationVariables } from "../types-C0Xl7P8K.js";
3
3
  import { FunctionArgs, FunctionReference } from "convex/server";
4
4
 
5
5
  //#region src/crpc/auth-error.d.ts
@@ -1,5 +1,5 @@
1
1
  import { a as isCRPCErrorCode, i as isCRPCError, n as defaultIsUnauthorized, r as isCRPCClientError, t as CRPCClientError } from "../error-Bvo7YEhk.js";
2
- import { a as defaultCRPCTransformer, c as identityTransformer, i as decodeWire, n as createTaggedTransformer, o as encodeWire, r as dateWireCodec, s as getTransformer, t as DATE_CODEC_TAG } from "../transformer-C6pGVHqx.js";
2
+ import { a as defaultCRPCTransformer, c as identityTransformer, i as decodeWire, n as createTaggedTransformer, o as encodeWire, r as dateWireCodec, s as getTransformer, t as DATE_CODEC_TAG } from "../transformer-yZuBWo8v.js";
3
3
  import { a as buildSearchParams, c as HttpClientError, i as RESERVED_KEYS, l as isHttpClientError, n as convexInfiniteQueryOptions, o as executeHttpRequest, r as convexQuery, s as replaceUrlParam, t as convexAction } from "../query-options-C_eBSIXG.js";
4
4
 
5
5
  //#region src/crpc/auth-error.ts
@@ -30,6 +30,18 @@ interface WireCodec {
30
30
  decode(value: unknown): unknown;
31
31
  encode(value: unknown): unknown;
32
32
  isType(value: unknown): boolean;
33
+ /**
34
+ * Declares that `isType` only ever claims a value where
35
+ * `typeof value === 'object' && value !== null` - never a primitive, a
36
+ * function, `null` or `undefined`.
37
+ *
38
+ * Lets `serialize` skip codec dispatch on primitives, which are the majority
39
+ * of visited nodes. It is opt-in because an arbitrary predicate cannot be
40
+ * classified by sampling values: a codec that claims, say, one specific
41
+ * number would be misread as object-only and silently lose its encoding.
42
+ * Codecs that leave it unset keep full dispatch.
43
+ */
44
+ readonly objectsOnly?: boolean;
33
45
  readonly tag: `$${string}`;
34
46
  }
35
47
  /**
@@ -51,6 +63,9 @@ declare const defaultCRPCTransformer: DataTransformer;
51
63
  /**
52
64
  * Normalize transformer config to split input/output shape.
53
65
  * User transformers are additive and always composed with default Date handling.
66
+ *
67
+ * Idempotent: passing a transformer this function already resolved returns it
68
+ * unchanged.
54
69
  */
55
70
  declare const getTransformer: (transformer?: DataTransformerOptions) => CombinedDataTransformer;
56
71
  /**
@@ -1,4 +1,4 @@
1
- import { a as createMiddlewareFactory } from "./builder-Dwy6D2QA.js";
1
+ import { a as createMiddlewareFactory } from "./builder-CsxVc5xC.js";
2
2
 
3
3
  //#region src/plugins/middleware.ts
4
4
  const PLUGIN_CONFIG_RESOLVERS = Symbol.for("kitcn:PluginConfigResolvers");
@@ -1,3 +1,3 @@
1
- import { n as resolvePluginOptions, t as definePlugin } from "../middleware-qzHEHaDy.js";
1
+ import { n as resolvePluginOptions, t as definePlugin } from "../middleware-DUd1Sj39.js";
2
2
 
3
3
  export { definePlugin, resolvePluginOptions };
@@ -1,5 +1,5 @@
1
- import { i as decodeWire, o as encodeWire } from "./transformer-C6pGVHqx.js";
2
- import { _ as CRPCError } from "./builder-Dwy6D2QA.js";
1
+ import { i as decodeWire, o as encodeWire } from "./transformer-yZuBWo8v.js";
2
+ import { _ as CRPCError } from "./builder-CsxVc5xC.js";
3
3
  import { z } from "zod";
4
4
 
5
5
  //#region src/server/env.ts
@@ -1,5 +1,5 @@
1
1
  import { t as VRequired } from "./validators-BhsByJeg.js";
2
- import { C as HttpProcedure, D as ProcedureMeta, R as getTransformer, S as HttpMethod, c as InferHttpInput, d as CRPCHttpRouter, j as DataTransformerOptions, l as InferHttpOutput, p as HttpRouterRecord, w as HttpProcedureBuilderDef, x as HttpHandlerOpts } from "./http-types-zsMHb_QN.js";
2
+ import { C as HttpProcedure, D as ProcedureMeta, R as getTransformer, S as HttpMethod, c as InferHttpInput, d as CRPCHttpRouter, j as DataTransformerOptions, l as InferHttpOutput, p as HttpRouterRecord, w as HttpProcedureBuilderDef, x as HttpHandlerOpts } from "./http-types-BoSDAh4Y.js";
3
3
  import { g as UnsetMarker, i as IntersectIfDefined, o as MiddlewareBuilder, p as Overwrite$1, s as MiddlewareFunction, t as AnyMiddleware } from "./types-CnTpHR1F.js";
4
4
  import { ConvexError, GenericId, GenericValidator, ObjectType, OptionalProperty, PropertyValidators, VAny, VArray, VBoolean, VBytes, VFloat64, VId, VInt64, VLiteral, VNull, VObject, VOptional, VRecord, VString, VUnion, Validator, Value as Value$1 } from "convex/values";
5
5
  import { ActionBuilder, ArgsArrayToObject, DefaultFunctionArgs, FunctionReference, FunctionReturnType, FunctionVisibility, GenericActionCtx, GenericDataModel, GenericMutationCtx, GenericQueryCtx, MutationBuilder, QueryBuilder, RegisteredAction, RegisteredMutation, RegisteredQuery, TableNamesInDataModel } from "convex/server";
@@ -497,14 +497,17 @@ declare function withSystemFields<Table extends string, T extends {
497
497
  * arguments. If the customization requires arguments, however, the resulting
498
498
  * builder will require argument validation too.
499
499
  */
500
- type CustomBuilder<FuncType extends 'query' | 'mutation' | 'action', CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, InputCtx, Visibility extends FunctionVisibility, ExtraArgs extends Record<string, any>> = <ArgsValidator extends ZodFields | zCore.$ZodObject<any> | void, ReturnsZodValidator extends zCore.$ZodType | ZodFields | void = void, ReturnValue extends ReturnValueInput<ReturnsZodValidator> = any>(func: ({
500
+ type CustomBuilder<FuncType extends 'query' | 'mutation' | 'action', CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, InputCtx, Visibility extends FunctionVisibility, ExtraArgs extends Record<string, any>> = <ArgsValidator extends ZodFields | zCore.$ZodObject<any> | void, ReturnsZodValidator extends zCore.$ZodType | ZodFields | void = void, SkipZodReturnsValidation extends boolean = false, ReturnValue extends ReturnValueForHandler<ReturnsZodValidator, SkipZodReturnsValidation> = any>(func: ({
501
501
  /**
502
502
  * Specify the arguments to the function as a Zod validator.
503
503
  */
504
504
  args?: ArgsValidator;
505
505
  handler: (ctx: Overwrite<InputCtx, CustomCtx>, ...args: ArgsForHandlerType<ArgsOutput<ArgsValidator>, CustomMadeArgs>) => ReturnValue;
506
506
  /**
507
- * Validates the value returned by the function.
507
+ * Validates the value returned by the function, and declares the
508
+ * Convex `returns` validator from the schema's output type. The Zod
509
+ * parse runs first, so the handler returns the schema's *input* type
510
+ * and the client receives its *output* type.
508
511
  * Note: you can't pass an object directly without wrapping it
509
512
  * in `z.object()`.
510
513
  */
@@ -514,12 +517,23 @@ type CustomBuilder<FuncType extends 'query' | 'mutation' | 'action', CustomArgsV
514
517
  * in case you're seeing performance issues with validating twice.
515
518
  */
516
519
  skipConvexValidation?: boolean;
517
- } & { [key in keyof ExtraArgs as key extends 'args' | 'handler' | 'skipConvexValidation' | 'returns' ? never : key]: ExtraArgs[key] }) | ((ctx: Overwrite<InputCtx, CustomCtx>, ...args: ArgsForHandlerType<ArgsOutput<ArgsValidator>, CustomMadeArgs>) => ReturnValue)) => Registration<FuncType, Visibility, ArgsArrayToObject<CustomArgsValidator extends Record<string, never> ? ArgsInput<ArgsValidator> : ArgsInput<ArgsValidator> extends [infer A] ? [Expand<A & ObjectType<CustomArgsValidator>>] : [ObjectType<CustomArgsValidator>]>, ReturnsZodValidator extends void ? ReturnValue : ReturnValueOutput<ReturnsZodValidator>>;
520
+ /**
521
+ * If true, `returns` only declares the Convex validator and the return
522
+ * type - the Zod parse is skipped. The handler's value reaches Convex
523
+ * unchanged, so it must already be the schema's *output* type, which
524
+ * is what the handler is then typed as.
525
+ *
526
+ * For callers that already parse the response themselves. Combined
527
+ * with `skipConvexValidation`, nothing validates the return value.
528
+ */
529
+ skipZodReturnsValidation?: SkipZodReturnsValidation;
530
+ } & { [key in keyof ExtraArgs as key extends 'args' | 'handler' | 'skipConvexValidation' | 'skipZodReturnsValidation' | 'returns' ? never : key]: ExtraArgs[key] }) | ((ctx: Overwrite<InputCtx, CustomCtx>, ...args: ArgsForHandlerType<ArgsOutput<ArgsValidator>, CustomMadeArgs>) => ReturnValue)) => Registration<FuncType, Visibility, ArgsArrayToObject<CustomArgsValidator extends Record<string, never> ? ArgsInput<ArgsValidator> : ArgsInput<ArgsValidator> extends [infer A] ? [Expand<A & ObjectType<CustomArgsValidator>>] : [ObjectType<CustomArgsValidator>]>, ReturnsZodValidator extends void ? ReturnValue : ReturnValueOutput<ReturnsZodValidator>>;
518
531
  type ArgsForHandlerType<OneOrZeroArgs extends [] | [Record<string, any>], CustomMadeArgs extends Record<string, any>> = CustomMadeArgs extends Record<string, never> ? OneOrZeroArgs : OneOrZeroArgs extends [infer A] ? [Expand<A & CustomMadeArgs>] : [CustomMadeArgs];
519
532
  type NullToUndefinedOrNull<T> = T extends null ? T | undefined | void : T;
520
533
  type Returns<T> = Promise<NullToUndefinedOrNull<T>> | NullToUndefinedOrNull<T>;
521
534
  type ReturnValueInput<ReturnsValidator extends zCore.$ZodType | ZodFields | void> = [ReturnsValidator] extends [zCore.$ZodType] ? Returns<zCore.input<ReturnsValidator>> : [ReturnsValidator] extends [ZodFields] ? Returns<zCore.input<zCore.$ZodObject<ReturnsValidator>>> : any;
522
535
  type ReturnValueOutput<ReturnsValidator extends zCore.$ZodType | ZodFields | void> = [ReturnsValidator] extends [zCore.$ZodType] ? Returns<zCore.output<ReturnsValidator>> : [ReturnsValidator] extends [ZodFields] ? Returns<zCore.output<zCore.$ZodObject<ReturnsValidator, zCore.$strict>>> : any;
536
+ type ReturnValueForHandler<ReturnsValidator extends zCore.$ZodType | ZodFields | void, SkipZodReturnsValidation extends boolean> = SkipZodReturnsValidation extends true ? ReturnValueOutput<ReturnsValidator> : ReturnValueInput<ReturnsValidator>;
523
537
  type ArgsInput<ArgsValidator extends ZodFields | zCore.$ZodObject<any> | void> = [ArgsValidator] extends [zCore.$ZodObject<any>] ? [zCore.input<ArgsValidator>] : ArgsValidator extends Record<string, never> ? [{}] : [ArgsValidator] extends [Record<string, z$1.ZodTypeAny>] ? [zCore.input<zCore.$ZodObject<ArgsValidator, zCore.$strict>>] : OneArgArray;
524
538
  type ArgsOutput<ArgsValidator extends ZodFields | zCore.$ZodObject<any> | void> = [ArgsValidator] extends [zCore.$ZodObject<any>] ? [zCore.output<ArgsValidator>] : [ArgsValidator] extends [ZodFields] ? [zCore.output<zCore.$ZodObject<ArgsValidator, zCore.$strict>>] : OneArgArray;
525
539
  type Overwrite<T, U> = Omit<T, keyof U> & U;
@@ -814,7 +828,7 @@ declare class QueryProcedureBuilder<TBaseCtx, TContext, TContextOverrides extend
814
828
  query<TResult>(handler: (opts: {
815
829
  ctx: Overwrite$1<TContext, TContextOverrides>;
816
830
  input: InferInput<TInput>;
817
- }) => Promise<TOutput extends z.ZodTypeAny ? z.infer<TOutput> : TResult>): Record<string, unknown> & CRPCFunctionTypeHint<InferClientInput<TClientInput>, TOutput extends z.ZodTypeAny ? z.infer<TOutput> : TResult>;
831
+ }) => Promise<TOutput extends z.ZodTypeAny ? z.input<TOutput> : TResult>): Record<string, unknown> & CRPCFunctionTypeHint<InferClientInput<TClientInput>, TOutput extends z.ZodTypeAny ? z.output<TOutput> : TResult>;
818
832
  /** Mark as internal - returns chainable builder using internal function */
819
833
  internal(): QueryProcedureBuilder<TBaseCtx, TContext, TContextOverrides, TInput, TClientInput, TOutput, TMeta>;
820
834
  }
@@ -842,7 +856,7 @@ declare class MutationProcedureBuilder<TBaseCtx, TContext, TContextOverrides ext
842
856
  mutation<TResult>(handler: (opts: {
843
857
  ctx: Overwrite$1<TContext, TContextOverrides>;
844
858
  input: InferInput<TInput>;
845
- }) => Promise<TOutput extends z.ZodTypeAny ? z.infer<TOutput> : TResult>): Record<string, unknown> & CRPCFunctionTypeHint<InferClientInput<TInput>, TOutput extends z.ZodTypeAny ? z.infer<TOutput> : TResult>;
859
+ }) => Promise<TOutput extends z.ZodTypeAny ? z.input<TOutput> : TResult>): Record<string, unknown> & CRPCFunctionTypeHint<InferClientInput<TInput>, TOutput extends z.ZodTypeAny ? z.output<TOutput> : TResult>;
846
860
  /** Mark as internal - returns chainable builder using internal function */
847
861
  internal(): MutationProcedureBuilder<TBaseCtx, TContext, TContextOverrides, TInput, TOutput, TMeta>;
848
862
  }
@@ -866,7 +880,7 @@ declare class ActionProcedureBuilder<TBaseCtx, TContext, TContextOverrides exten
866
880
  action<TResult>(handler: (opts: {
867
881
  ctx: Overwrite$1<TContext, TContextOverrides>;
868
882
  input: InferInput<TInput>;
869
- }) => Promise<TOutput extends z.ZodTypeAny ? z.infer<TOutput> : TResult>): Record<string, unknown> & CRPCFunctionTypeHint<InferClientInput<TInput>, TOutput extends z.ZodTypeAny ? z.infer<TOutput> : TResult>;
883
+ }) => Promise<TOutput extends z.ZodTypeAny ? z.input<TOutput> : TResult>): Record<string, unknown> & CRPCFunctionTypeHint<InferClientInput<TInput>, TOutput extends z.ZodTypeAny ? z.output<TOutput> : TResult>;
870
884
  /** Mark as internal - returns chainable builder using internal function */
871
885
  internal(): ActionProcedureBuilder<TBaseCtx, TContext, TContextOverrides, TInput, TOutput, TMeta>;
872
886
  }
@@ -1,6 +1,6 @@
1
1
  import { u as requireMutationCtx } from "../api-entry-N3nBOlI2.js";
2
- import { _ as CRPCError } from "../builder-Dwy6D2QA.js";
3
- import { t as definePlugin } from "../middleware-qzHEHaDy.js";
2
+ import { _ as CRPCError } from "../builder-CsxVc5xC.js";
3
+ import { t as definePlugin } from "../middleware-DUd1Sj39.js";
4
4
  import { v } from "convex/values";
5
5
  import { mutationGeneric, queryGeneric } from "convex/server";
6
6
 
@@ -278,6 +278,7 @@ const DATE_CODEC_TAG = "$date";
278
278
  */
279
279
  const dateWireCodec = {
280
280
  tag: DATE_CODEC_TAG,
281
+ objectsOnly: true,
281
282
  isType: (value) => value instanceof Date,
282
283
  encode: (value) => value.getTime(),
283
284
  decode: (value) => {
@@ -286,6 +287,40 @@ const dateWireCodec = {
286
287
  }
287
288
  };
288
289
  /**
290
+ * One value per primitive `typeof` result, plus the values the object fast path
291
+ * would otherwise skip.
292
+ */
293
+ const PRIMITIVE_PROBES = [
294
+ void 0,
295
+ null,
296
+ "",
297
+ 0,
298
+ NaN,
299
+ false,
300
+ 0n,
301
+ Symbol("kitcn.codec.probe"),
302
+ () => void 0
303
+ ];
304
+ /**
305
+ * Falsify an `objectsOnly` declaration against representative primitives.
306
+ *
307
+ * Sampling cannot prove a predicate object-only, so it never *infers* the
308
+ * capability - it only rejects the misdeclarations it can catch
309
+ * (`typeof value === 'bigint'`, `value === null`, ...) before they silently
310
+ * drop a value's wire encoding. A codec that throws on a probe owns that.
311
+ */
312
+ const assertObjectsOnly = (codec) => {
313
+ for (const probe of PRIMITIVE_PROBES) {
314
+ let claimed = false;
315
+ try {
316
+ claimed = codec.isType(probe);
317
+ } catch {
318
+ continue;
319
+ }
320
+ if (claimed) throw new Error(`Wire codec '${codec.tag}' declares objectsOnly, but isType() claims ${probe === null ? "null" : typeof probe}. Drop objectsOnly so the codec keeps receiving non-object values.`);
321
+ }
322
+ };
323
+ /**
289
324
  * Build a recursive tagged transformer from codecs.
290
325
  */
291
326
  const createTaggedTransformer = (codecs) => {
@@ -293,9 +328,12 @@ const createTaggedTransformer = (codecs) => {
293
328
  for (const codec of codecs) {
294
329
  if (!codec.tag.startsWith("$")) throw new Error(`Invalid wire codec tag '${codec.tag}'. Tags must start with '$'.`);
295
330
  if (codecByTag.has(codec.tag)) throw new Error(`Duplicate wire codec tag '${codec.tag}'.`);
331
+ if (codec.objectsOnly) assertObjectsOnly(codec);
296
332
  codecByTag.set(codec.tag, codec);
297
333
  }
334
+ const skipNonObjects = codecs.every((codec) => codec.objectsOnly === true);
298
335
  const serialize = (value) => {
336
+ if (skipNonObjects && (value === null || typeof value !== "object")) return value;
299
337
  for (const codec of codecs) if (codec.isType(value)) return {
300
338
  [CODEC_MARKER_KEY]: CODEC_MARKER_VALUE,
301
339
  [CODEC_TAG_KEY]: codec.tag,
@@ -329,6 +367,7 @@ const createTaggedTransformer = (codecs) => {
329
367
  return value;
330
368
  };
331
369
  const deserialize = (value) => {
370
+ if (value === null || typeof value !== "object") return value;
332
371
  if (Array.isArray(value)) {
333
372
  let result;
334
373
  for (let index = 0; index < value.length; index += 1) {
@@ -394,16 +433,20 @@ const normalizeCustomTransformer = (transformer) => {
394
433
  * - deserialize: default(Date) -> user
395
434
  */
396
435
  const composeWithDefault = (transformer) => {
397
- if (!transformer) return defaultCRPCTransformer;
436
+ if (!transformer || transformer === defaultCRPCTransformer) return defaultCRPCTransformer;
398
437
  return {
399
438
  serialize: (value) => defaultCRPCTransformer.serialize(transformer.serialize(value)),
400
439
  deserialize: (value) => transformer.deserialize(defaultCRPCTransformer.deserialize(value))
401
440
  };
402
441
  };
403
442
  const transformerCache = /* @__PURE__ */ new WeakMap();
443
+ transformerCache.set(DEFAULT_COMBINED_TRANSFORMER, DEFAULT_COMBINED_TRANSFORMER);
404
444
  /**
405
445
  * Normalize transformer config to split input/output shape.
406
446
  * User transformers are additive and always composed with default Date handling.
447
+ *
448
+ * Idempotent: passing a transformer this function already resolved returns it
449
+ * unchanged.
407
450
  */
408
451
  const getTransformer = (transformer) => {
409
452
  if (!transformer) return DEFAULT_COMBINED_TRANSFORMER;
@@ -416,6 +459,7 @@ const getTransformer = (transformer) => {
416
459
  output: composeWithDefault(custom?.output)
417
460
  };
418
461
  transformerCache.set(cacheKey, resolved);
462
+ transformerCache.set(resolved, resolved);
419
463
  return resolved;
420
464
  };
421
465
  /**
@@ -2577,7 +2621,9 @@ const useInfiniteQueryInternal = (query, args, options) => {
2577
2621
  enabled,
2578
2622
  meta,
2579
2623
  queryOptions,
2580
- placeholderData
2624
+ placeholderData,
2625
+ authType,
2626
+ isAuthLoading
2581
2627
  ]),
2582
2628
  combine: useCallback((results) => {
2583
2629
  const allItems = [];
@@ -1,7 +1,7 @@
1
1
  import { n as DeepPartial, o as Simplify, r as DistributiveOmit } from "../types-DF2cg_w0.js";
2
- import { C as HttpProcedure, d as CRPCHttpRouter, j as DataTransformerOptions, p as HttpRouterRecord } from "../http-types-zsMHb_QN.js";
2
+ import { C as HttpProcedure, d as CRPCHttpRouter, j as DataTransformerOptions, p as HttpRouterRecord } from "../http-types-BoSDAh4Y.js";
3
3
  import { g as UnsetMarker } from "../types-CnTpHR1F.js";
4
- import { A as HttpInputArgs, C as ReservedMutationOptions$1, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, o as ConvexActionKey, p as ExtractPaginatedItem, s as ConvexInfiniteQueryMeta, u as ConvexQueryKey, w as ReservedQueryOptions$1, y as MutationVariables } from "../types-jNTcza_a.js";
4
+ import { A as HttpInputArgs, C as ReservedMutationOptions$1, S as ReservedInfiniteQueryOptions, T as StaticQueryOptsParam, _ as IsPaginated, b as PaginatedFnMeta, c as ConvexMutationKey, d as ConvexQueryMeta, f as EmptyObject, g as InfiniteQueryInput, l as ConvexQueryHookOptions, m as FUNC_REF_SYMBOL, o as ConvexActionKey, p as ExtractPaginatedItem, s as ConvexInfiniteQueryMeta, u as ConvexQueryKey, w as ReservedQueryOptions$1, y as MutationVariables } from "../types-C0Xl7P8K.js";
5
5
  import { FunctionArgs, FunctionReference, FunctionReturnType } from "convex/server";
6
6
  import { z } from "zod";
7
7
  import { DefaultError, QueryFilters, SkipToken, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
package/dist/rsc/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { n as defaultIsUnauthorized } from "../error-Bvo7YEhk.js";
2
2
  import { n as getFuncRef, r as getFunctionMeta, t as buildMetaIndex } from "../meta-utils-D9K4fICl.js";
3
- import { o as encodeWire, s as getTransformer } from "../transformer-C6pGVHqx.js";
3
+ import { o as encodeWire, s as getTransformer } from "../transformer-yZuBWo8v.js";
4
4
  import { n as convexInfiniteQueryOptions, o as executeHttpRequest, r as convexQuery } from "../query-options-C_eBSIXG.js";
5
5
  import { convexToJson } from "convex/values";
6
6
  import { getFunctionName } from "convex/server";
@@ -1,5 +1,5 @@
1
- import { $ as ActionProcedureBuilder, A as CRPCError, B as RuntimeEnv, C as createProcedureHandlerFactory, Ct as zCustomQuery, D as WithHttpRouter, Dt as zodToConvex, E as typedProcedureResolver, Et as zodOutputToConvexFields, F as getCRPCErrorFromUnknown, G as createLazyCaller, H as ConvexContext, I as getHTTPStatusCodeFromError, J as ServerCaller, K as CallerMeta, L as isCRPCError, M as CRPCErrorData, N as CRPC_ERROR_CODES_BY_KEY, O as inferApiInputs, Ot as zodToConvexFields, P as CRPC_ERROR_CODE_TO_HTTP, Q as getGeneratedValue, R as toCRPCError, S as createProcedureCallerFactory, St as zCustomMutation, T as getGeneratedFunctionReference, Tt as zodOutputToConvex, U as createCallerFactory, V as createEnv, W as LazyCaller, X as createApiLeaf, Y as createServerCaller, Z as createGeneratedFunctionReference, _ as ProcedureSchedulableCallerFromRegistry, _t as ZodValidatorFromConvex, a as CreateProcedureCallerFactoryOptions, at as initCRPC, b as createGenericCallerFactory, bt as withSystemFields, c as GeneratedRegistryCallerFactory, ct as extractPathParams, d as GeneratedRegistryHandlerForContext, dt as ConvexValidatorFromZod, et as CRPCFunctionTypeHint, f as ProcedureActionCallerFromRegistry, ft as ConvexValidatorFromZodOutput, g as ProcedureFromFunctionReference, gt as ZodFromValidatorBase, h as ProcedureDefinition, ht as Zid, i as registerProcedureNameLookup, it as createMiddlewareFactory, j as CRPCErrorCode, k as inferApiOutputs, l as GeneratedRegistryCallerForContext, lt as handleHttpError, m as ProcedureCallerFromRegistry, mt as ZCustomCtx, n as ProcedureNameLookup, nt as ProcedureBuilder, o as GeneratedProcedureRegistry, ot as HttpProcedureBuilder, p as ProcedureCaller, pt as CustomBuilder, q as CallerOpts, r as inferProcedureNameFromCallsite, rt as QueryProcedureBuilder, s as GeneratedProcedureRegistryEntry, st as createHttpProcedureBuilder, t as ProcedureNameEntry, tt as MutationProcedureBuilder, u as GeneratedRegistryHandlerFactory, ut as matchPathParams, v as ProcedureScheduleCallerFromRegistry, vt as convexToZod, w as defineProcedure, wt as zid, x as createGenericHandlerFactory, xt as zCustomAction, y as createGeneratedRegistryRuntime, yt as convexToZodFields, z as CreateEnvOptions } from "../procedure-name-exVcmr_p.js";
2
- import { C as HttpProcedure, D as ProcedureMeta, E as InferHttpInput, S as HttpMethod, T as HttpRouteDefinition, _ as extractRouteMap, b as HttpActionHandler, d as CRPCHttpRouter, f as HttpRouterDef, g as createHttpRouterFactory, h as createHttpRouter, m as HttpRouterWithHono, p as HttpRouterRecord, v as CRPCHonoHandler, w as HttpProcedureBuilderDef, x as HttpHandlerOpts, y as HttpActionConstructor } from "../http-types-zsMHb_QN.js";
1
+ import { $ as ActionProcedureBuilder, A as CRPCError, B as RuntimeEnv, C as createProcedureHandlerFactory, Ct as zCustomQuery, D as WithHttpRouter, Dt as zodToConvex, E as typedProcedureResolver, Et as zodOutputToConvexFields, F as getCRPCErrorFromUnknown, G as createLazyCaller, H as ConvexContext, I as getHTTPStatusCodeFromError, J as ServerCaller, K as CallerMeta, L as isCRPCError, M as CRPCErrorData, N as CRPC_ERROR_CODES_BY_KEY, O as inferApiInputs, Ot as zodToConvexFields, P as CRPC_ERROR_CODE_TO_HTTP, Q as getGeneratedValue, R as toCRPCError, S as createProcedureCallerFactory, St as zCustomMutation, T as getGeneratedFunctionReference, Tt as zodOutputToConvex, U as createCallerFactory, V as createEnv, W as LazyCaller, X as createApiLeaf, Y as createServerCaller, Z as createGeneratedFunctionReference, _ as ProcedureSchedulableCallerFromRegistry, _t as ZodValidatorFromConvex, a as CreateProcedureCallerFactoryOptions, at as initCRPC, b as createGenericCallerFactory, bt as withSystemFields, c as GeneratedRegistryCallerFactory, ct as extractPathParams, d as GeneratedRegistryHandlerForContext, dt as ConvexValidatorFromZod, et as CRPCFunctionTypeHint, f as ProcedureActionCallerFromRegistry, ft as ConvexValidatorFromZodOutput, g as ProcedureFromFunctionReference, gt as ZodFromValidatorBase, h as ProcedureDefinition, ht as Zid, i as registerProcedureNameLookup, it as createMiddlewareFactory, j as CRPCErrorCode, k as inferApiOutputs, l as GeneratedRegistryCallerForContext, lt as handleHttpError, m as ProcedureCallerFromRegistry, mt as ZCustomCtx, n as ProcedureNameLookup, nt as ProcedureBuilder, o as GeneratedProcedureRegistry, ot as HttpProcedureBuilder, p as ProcedureCaller, pt as CustomBuilder, q as CallerOpts, r as inferProcedureNameFromCallsite, rt as QueryProcedureBuilder, s as GeneratedProcedureRegistryEntry, st as createHttpProcedureBuilder, t as ProcedureNameEntry, tt as MutationProcedureBuilder, u as GeneratedRegistryHandlerFactory, ut as matchPathParams, v as ProcedureScheduleCallerFromRegistry, vt as convexToZod, w as defineProcedure, wt as zid, x as createGenericHandlerFactory, xt as zCustomAction, y as createGeneratedRegistryRuntime, yt as convexToZodFields, z as CreateEnvOptions } from "../procedure-name-C55TynK3.js";
2
+ import { C as HttpProcedure, D as ProcedureMeta, E as InferHttpInput, S as HttpMethod, T as HttpRouteDefinition, _ as extractRouteMap, b as HttpActionHandler, d as CRPCHttpRouter, f as HttpRouterDef, g as createHttpRouterFactory, h as createHttpRouter, m as HttpRouterWithHono, p as HttpRouterRecord, v as CRPCHonoHandler, w as HttpProcedureBuilderDef, x as HttpHandlerOpts, y as HttpActionConstructor } from "../http-types-BoSDAh4Y.js";
3
3
  import { a as MergeZodObjects, c as MiddlewareMarker, d as MiddlewareProcedureType, f as MiddlewareResult, g as UnsetMarker, h as Simplify, i as IntersectIfDefined, l as MiddlewareNext, m as ResolveIfSet, n as AnyMiddlewareBuilder, o as MiddlewareBuilder, p as Overwrite, r as GetRawInputFn, s as MiddlewareFunction, t as AnyMiddleware, u as MiddlewareProcedureInfo } from "../types-CnTpHR1F.js";
4
4
  import { a as isMutationCtx, c as isSchedulerCtx, d as requireQueryCtx, f as requireRunMutationCtx, i as isActionCtx, l as requireActionCtx, n as RunMutationCtx, o as isQueryCtx, p as requireSchedulerCtx, r as SchedulerCtx, s as isRunMutationCtx, t as GenericCtx, u as requireMutationCtx } from "../context-utils-BBUtBqjN.js";
5
5
  export { ActionProcedureBuilder, AnyMiddleware, AnyMiddlewareBuilder, CRPCError, CRPCErrorCode, CRPCErrorData, CRPCFunctionTypeHint, CRPCHonoHandler, CRPCHttpRouter, CRPC_ERROR_CODES_BY_KEY, CRPC_ERROR_CODE_TO_HTTP, CallerMeta, CallerOpts, ConvexContext, ConvexValidatorFromZod, ConvexValidatorFromZodOutput, CreateEnvOptions, CreateProcedureCallerFactoryOptions, CustomBuilder, GeneratedProcedureRegistry, GeneratedProcedureRegistryEntry, GeneratedRegistryCallerFactory, GeneratedRegistryCallerForContext, GeneratedRegistryHandlerFactory, GeneratedRegistryHandlerForContext, GenericCtx, GetRawInputFn, HttpActionConstructor, HttpActionHandler, HttpHandlerOpts, HttpMethod, HttpProcedure, HttpProcedureBuilder, HttpProcedureBuilderDef, HttpRouteDefinition, HttpRouterDef, HttpRouterRecord, HttpRouterWithHono, InferHttpInput, IntersectIfDefined, LazyCaller, MergeZodObjects, MiddlewareBuilder, MiddlewareFunction, MiddlewareMarker, MiddlewareNext, MiddlewareProcedureInfo, MiddlewareProcedureType, MiddlewareResult, MutationProcedureBuilder, Overwrite, ProcedureActionCallerFromRegistry, ProcedureBuilder, ProcedureCaller, ProcedureCallerFromRegistry, ProcedureDefinition, ProcedureFromFunctionReference, ProcedureMeta, ProcedureNameEntry, ProcedureNameLookup, ProcedureSchedulableCallerFromRegistry, ProcedureScheduleCallerFromRegistry, QueryProcedureBuilder, ResolveIfSet, RunMutationCtx, RuntimeEnv, SchedulerCtx, ServerCaller, Simplify, UnsetMarker, WithHttpRouter, ZCustomCtx, Zid, ZodFromValidatorBase, ZodValidatorFromConvex, convexToZod, convexToZodFields, createApiLeaf, createCallerFactory, createEnv, createGeneratedFunctionReference, createGeneratedRegistryRuntime, createGenericCallerFactory, createGenericHandlerFactory, createHttpProcedureBuilder, createHttpRouter, createHttpRouterFactory, createLazyCaller, createMiddlewareFactory, createProcedureCallerFactory, createProcedureHandlerFactory, createServerCaller, defineProcedure, extractPathParams, extractRouteMap, getCRPCErrorFromUnknown, getGeneratedFunctionReference, getGeneratedValue, getHTTPStatusCodeFromError, handleHttpError, inferApiInputs, inferApiOutputs, inferProcedureNameFromCallsite, initCRPC, isActionCtx, isCRPCError, isMutationCtx, isQueryCtx, isRunMutationCtx, isSchedulerCtx, matchPathParams, registerProcedureNameLookup, requireActionCtx, requireMutationCtx, requireQueryCtx, requireRunMutationCtx, requireSchedulerCtx, toCRPCError, typedProcedureResolver, withSystemFields, zCustomAction, zCustomMutation, zCustomQuery, zid, zodOutputToConvex, zodOutputToConvexFields, zodToConvex, zodToConvexFields };
@@ -1,6 +1,6 @@
1
1
  import { a as isMutationCtx, c as isSchedulerCtx, d as requireQueryCtx, f as requireRunMutationCtx, i as isActionCtx, l as requireActionCtx, n as createGeneratedFunctionReference, o as isQueryCtx, p as requireSchedulerCtx, r as getGeneratedValue, s as isRunMutationCtx, t as createApiLeaf, u as requireMutationCtx } from "../api-entry-N3nBOlI2.js";
2
- import { n as createLazyCaller, r as createServerCaller, t as createCallerFactory } from "../caller-factory-DHywSoGZ.js";
3
- import { A as zid, C as toCRPCError, D as zCustomAction, E as withSystemFields, M as zodOutputToConvexFields, N as zodToConvex, O as zCustomMutation, P as zodToConvexFields, S as isCRPCError, T as convexToZodFields, _ as CRPCError, a as createMiddlewareFactory, b as getCRPCErrorFromUnknown, c as registerProcedureNameLookup, d as createHttpRouterFactory, f as extractRouteMap, g as matchPathParams, h as handleHttpError, i as QueryProcedureBuilder, j as zodOutputToConvex, k as zCustomQuery, l as HttpRouterWithHono, m as extractPathParams, n as MutationProcedureBuilder, o as initCRPC, p as createHttpProcedureBuilder, r as ProcedureBuilder, s as inferProcedureNameFromCallsite, t as ActionProcedureBuilder, u as createHttpRouter, v as CRPC_ERROR_CODES_BY_KEY, w as convexToZod, x as getHTTPStatusCodeFromError, y as CRPC_ERROR_CODE_TO_HTTP } from "../builder-Dwy6D2QA.js";
4
- import { a as createProcedureHandlerFactory, c as typedProcedureResolver, i as createProcedureCallerFactory, l as createEnv, n as createGenericCallerFactory, o as defineProcedure, r as createGenericHandlerFactory, s as getGeneratedFunctionReference, t as createGeneratedRegistryRuntime } from "../procedure-caller-JB9kjYsy.js";
2
+ import { n as createLazyCaller, r as createServerCaller, t as createCallerFactory } from "../caller-factory-CWa0ELLD.js";
3
+ import { A as zid, C as toCRPCError, D as zCustomAction, E as withSystemFields, M as zodOutputToConvexFields, N as zodToConvex, O as zCustomMutation, P as zodToConvexFields, S as isCRPCError, T as convexToZodFields, _ as CRPCError, a as createMiddlewareFactory, b as getCRPCErrorFromUnknown, c as registerProcedureNameLookup, d as createHttpRouterFactory, f as extractRouteMap, g as matchPathParams, h as handleHttpError, i as QueryProcedureBuilder, j as zodOutputToConvex, k as zCustomQuery, l as HttpRouterWithHono, m as extractPathParams, n as MutationProcedureBuilder, o as initCRPC, p as createHttpProcedureBuilder, r as ProcedureBuilder, s as inferProcedureNameFromCallsite, t as ActionProcedureBuilder, u as createHttpRouter, v as CRPC_ERROR_CODES_BY_KEY, w as convexToZod, x as getHTTPStatusCodeFromError, y as CRPC_ERROR_CODE_TO_HTTP } from "../builder-CsxVc5xC.js";
4
+ import { a as createProcedureHandlerFactory, c as typedProcedureResolver, i as createProcedureCallerFactory, l as createEnv, n as createGenericCallerFactory, o as defineProcedure, r as createGenericHandlerFactory, s as getGeneratedFunctionReference, t as createGeneratedRegistryRuntime } from "../procedure-caller-DQxnLBS_.js";
5
5
 
6
6
  export { ActionProcedureBuilder, CRPCError, CRPC_ERROR_CODES_BY_KEY, CRPC_ERROR_CODE_TO_HTTP, HttpRouterWithHono, MutationProcedureBuilder, ProcedureBuilder, QueryProcedureBuilder, convexToZod, convexToZodFields, createApiLeaf, createCallerFactory, createEnv, createGeneratedFunctionReference, createGeneratedRegistryRuntime, createGenericCallerFactory, createGenericHandlerFactory, createHttpProcedureBuilder, createHttpRouter, createHttpRouterFactory, createLazyCaller, createMiddlewareFactory, createProcedureCallerFactory, createProcedureHandlerFactory, createServerCaller, defineProcedure, extractPathParams, extractRouteMap, getCRPCErrorFromUnknown, getGeneratedFunctionReference, getGeneratedValue, getHTTPStatusCodeFromError, handleHttpError, inferProcedureNameFromCallsite, initCRPC, isActionCtx, isCRPCError, isMutationCtx, isQueryCtx, isRunMutationCtx, isSchedulerCtx, matchPathParams, registerProcedureNameLookup, requireActionCtx, requireMutationCtx, requireQueryCtx, requireRunMutationCtx, requireSchedulerCtx, toCRPCError, typedProcedureResolver, withSystemFields, zCustomAction, zCustomMutation, zCustomQuery, zid, zodOutputToConvex, zodOutputToConvexFields, zodToConvex, zodToConvexFields };
@@ -579,6 +579,7 @@ const DATE_CODEC_TAG = "$date";
579
579
  */
580
580
  const dateWireCodec = {
581
581
  tag: DATE_CODEC_TAG,
582
+ objectsOnly: true,
582
583
  isType: (value) => value instanceof Date,
583
584
  encode: (value) => value.getTime(),
584
585
  decode: (value) => {
@@ -587,6 +588,40 @@ const dateWireCodec = {
587
588
  }
588
589
  };
589
590
  /**
591
+ * One value per primitive `typeof` result, plus the values the object fast path
592
+ * would otherwise skip.
593
+ */
594
+ const PRIMITIVE_PROBES = [
595
+ void 0,
596
+ null,
597
+ "",
598
+ 0,
599
+ NaN,
600
+ false,
601
+ 0n,
602
+ Symbol("kitcn.codec.probe"),
603
+ () => void 0
604
+ ];
605
+ /**
606
+ * Falsify an `objectsOnly` declaration against representative primitives.
607
+ *
608
+ * Sampling cannot prove a predicate object-only, so it never *infers* the
609
+ * capability - it only rejects the misdeclarations it can catch
610
+ * (`typeof value === 'bigint'`, `value === null`, ...) before they silently
611
+ * drop a value's wire encoding. A codec that throws on a probe owns that.
612
+ */
613
+ const assertObjectsOnly = (codec) => {
614
+ for (const probe of PRIMITIVE_PROBES) {
615
+ let claimed = false;
616
+ try {
617
+ claimed = codec.isType(probe);
618
+ } catch {
619
+ continue;
620
+ }
621
+ if (claimed) throw new Error(`Wire codec '${codec.tag}' declares objectsOnly, but isType() claims ${probe === null ? "null" : typeof probe}. Drop objectsOnly so the codec keeps receiving non-object values.`);
622
+ }
623
+ };
624
+ /**
590
625
  * Build a recursive tagged transformer from codecs.
591
626
  */
592
627
  const createTaggedTransformer = (codecs) => {
@@ -594,9 +629,12 @@ const createTaggedTransformer = (codecs) => {
594
629
  for (const codec of codecs) {
595
630
  if (!codec.tag.startsWith("$")) throw new Error(`Invalid wire codec tag '${codec.tag}'. Tags must start with '$'.`);
596
631
  if (codecByTag.has(codec.tag)) throw new Error(`Duplicate wire codec tag '${codec.tag}'.`);
632
+ if (codec.objectsOnly) assertObjectsOnly(codec);
597
633
  codecByTag.set(codec.tag, codec);
598
634
  }
635
+ const skipNonObjects = codecs.every((codec) => codec.objectsOnly === true);
599
636
  const serialize = (value) => {
637
+ if (skipNonObjects && (value === null || typeof value !== "object")) return value;
600
638
  for (const codec of codecs) if (codec.isType(value)) return {
601
639
  [CODEC_MARKER_KEY]: CODEC_MARKER_VALUE,
602
640
  [CODEC_TAG_KEY]: codec.tag,
@@ -630,6 +668,7 @@ const createTaggedTransformer = (codecs) => {
630
668
  return value;
631
669
  };
632
670
  const deserialize = (value) => {
671
+ if (value === null || typeof value !== "object") return value;
633
672
  if (Array.isArray(value)) {
634
673
  let result;
635
674
  for (let index = 0; index < value.length; index += 1) {
@@ -695,16 +734,20 @@ const normalizeCustomTransformer = (transformer) => {
695
734
  * - deserialize: default(Date) -> user
696
735
  */
697
736
  const composeWithDefault = (transformer) => {
698
- if (!transformer) return defaultCRPCTransformer;
737
+ if (!transformer || transformer === defaultCRPCTransformer) return defaultCRPCTransformer;
699
738
  return {
700
739
  serialize: (value) => defaultCRPCTransformer.serialize(transformer.serialize(value)),
701
740
  deserialize: (value) => transformer.deserialize(defaultCRPCTransformer.deserialize(value))
702
741
  };
703
742
  };
704
743
  const transformerCache = /* @__PURE__ */ new WeakMap();
744
+ transformerCache.set(DEFAULT_COMBINED_TRANSFORMER, DEFAULT_COMBINED_TRANSFORMER);
705
745
  /**
706
746
  * Normalize transformer config to split input/output shape.
707
747
  * User transformers are additive and always composed with default Date handling.
748
+ *
749
+ * Idempotent: passing a transformer this function already resolved returns it
750
+ * unchanged.
708
751
  */
709
752
  const getTransformer = (transformer) => {
710
753
  if (!transformer) return DEFAULT_COMBINED_TRANSFORMER;
@@ -717,6 +760,7 @@ const getTransformer = (transformer) => {
717
760
  output: composeWithDefault(custom?.output)
718
761
  };
719
762
  transformerCache.set(cacheKey, resolved);
763
+ transformerCache.set(resolved, resolved);
720
764
  return resolved;
721
765
  };
722
766
  /**
@@ -27,6 +27,7 @@ const DATE_CODEC_TAG = "$date";
27
27
  */
28
28
  const dateWireCodec = {
29
29
  tag: DATE_CODEC_TAG,
30
+ objectsOnly: true,
30
31
  isType: (value) => value instanceof Date,
31
32
  encode: (value) => value.getTime(),
32
33
  decode: (value) => {
@@ -35,6 +36,40 @@ const dateWireCodec = {
35
36
  }
36
37
  };
37
38
  /**
39
+ * One value per primitive `typeof` result, plus the values the object fast path
40
+ * would otherwise skip.
41
+ */
42
+ const PRIMITIVE_PROBES = [
43
+ void 0,
44
+ null,
45
+ "",
46
+ 0,
47
+ NaN,
48
+ false,
49
+ 0n,
50
+ Symbol("kitcn.codec.probe"),
51
+ () => void 0
52
+ ];
53
+ /**
54
+ * Falsify an `objectsOnly` declaration against representative primitives.
55
+ *
56
+ * Sampling cannot prove a predicate object-only, so it never *infers* the
57
+ * capability - it only rejects the misdeclarations it can catch
58
+ * (`typeof value === 'bigint'`, `value === null`, ...) before they silently
59
+ * drop a value's wire encoding. A codec that throws on a probe owns that.
60
+ */
61
+ const assertObjectsOnly = (codec) => {
62
+ for (const probe of PRIMITIVE_PROBES) {
63
+ let claimed = false;
64
+ try {
65
+ claimed = codec.isType(probe);
66
+ } catch {
67
+ continue;
68
+ }
69
+ if (claimed) throw new Error(`Wire codec '${codec.tag}' declares objectsOnly, but isType() claims ${probe === null ? "null" : typeof probe}. Drop objectsOnly so the codec keeps receiving non-object values.`);
70
+ }
71
+ };
72
+ /**
38
73
  * Build a recursive tagged transformer from codecs.
39
74
  */
40
75
  const createTaggedTransformer = (codecs) => {
@@ -42,9 +77,12 @@ const createTaggedTransformer = (codecs) => {
42
77
  for (const codec of codecs) {
43
78
  if (!codec.tag.startsWith("$")) throw new Error(`Invalid wire codec tag '${codec.tag}'. Tags must start with '$'.`);
44
79
  if (codecByTag.has(codec.tag)) throw new Error(`Duplicate wire codec tag '${codec.tag}'.`);
80
+ if (codec.objectsOnly) assertObjectsOnly(codec);
45
81
  codecByTag.set(codec.tag, codec);
46
82
  }
83
+ const skipNonObjects = codecs.every((codec) => codec.objectsOnly === true);
47
84
  const serialize = (value) => {
85
+ if (skipNonObjects && (value === null || typeof value !== "object")) return value;
48
86
  for (const codec of codecs) if (codec.isType(value)) return {
49
87
  [CODEC_MARKER_KEY]: CODEC_MARKER_VALUE,
50
88
  [CODEC_TAG_KEY]: codec.tag,
@@ -78,6 +116,7 @@ const createTaggedTransformer = (codecs) => {
78
116
  return value;
79
117
  };
80
118
  const deserialize = (value) => {
119
+ if (value === null || typeof value !== "object") return value;
81
120
  if (Array.isArray(value)) {
82
121
  let result;
83
122
  for (let index = 0; index < value.length; index += 1) {
@@ -153,16 +192,20 @@ const normalizeCustomTransformer = (transformer) => {
153
192
  * - deserialize: default(Date) -> user
154
193
  */
155
194
  const composeWithDefault = (transformer) => {
156
- if (!transformer) return defaultCRPCTransformer;
195
+ if (!transformer || transformer === defaultCRPCTransformer) return defaultCRPCTransformer;
157
196
  return {
158
197
  serialize: (value) => defaultCRPCTransformer.serialize(transformer.serialize(value)),
159
198
  deserialize: (value) => transformer.deserialize(defaultCRPCTransformer.deserialize(value))
160
199
  };
161
200
  };
162
201
  const transformerCache = /* @__PURE__ */ new WeakMap();
202
+ transformerCache.set(DEFAULT_COMBINED_TRANSFORMER, DEFAULT_COMBINED_TRANSFORMER);
163
203
  /**
164
204
  * Normalize transformer config to split input/output shape.
165
205
  * User transformers are additive and always composed with default Date handling.
206
+ *
207
+ * Idempotent: passing a transformer this function already resolved returns it
208
+ * unchanged.
166
209
  */
167
210
  const getTransformer = (transformer) => {
168
211
  if (!transformer) return DEFAULT_COMBINED_TRANSFORMER;
@@ -175,6 +218,7 @@ const getTransformer = (transformer) => {
175
218
  output: composeWithDefault(custom?.output)
176
219
  };
177
220
  transformerCache.set(cacheKey, resolved);
221
+ transformerCache.set(resolved, resolved);
178
222
  return resolved;
179
223
  };
180
224
  /**
@@ -1,4 +1,4 @@
1
- import { O as CombinedDataTransformer, n as HttpClientError } from "./http-types-zsMHb_QN.js";
1
+ import { O as CombinedDataTransformer, n as HttpClientError } from "./http-types-BoSDAh4Y.js";
2
2
  import { FunctionArgs, FunctionReference, FunctionReturnType } from "convex/server";
3
3
 
4
4
  //#region src/crpc/http-client.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitcn",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "kitcn - React Query integration and CLI tools for Convex",
5
5
  "keywords": [
6
6
  "convex",