kitcn 0.12.15 → 0.12.17

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 { I as ConvexContext, R as LazyCaller } from "../../procedure-caller-DtxLmGwA.js";
1
+ import { I as ConvexContext, R as LazyCaller } from "../../procedure-caller-C15h5Iel.js";
2
2
  import { GetTokenOptions } from "@convex-dev/better-auth/utils";
3
3
 
4
4
  //#region src/auth-nextjs/index.d.ts
@@ -2197,6 +2197,7 @@ const highlighter = {
2197
2197
 
2198
2198
  //#endregion
2199
2199
  //#region src/cli/utils/project-jiti.ts
2200
+ const require$2 = createRequire(import.meta.url);
2200
2201
  const JITI_EXPORT_CONDITION_PRIORITY = [
2201
2202
  "bun",
2202
2203
  "import",
@@ -2354,11 +2355,42 @@ const ensureServerParserShim = (cwd) => {
2354
2355
  if (!fs.existsSync(shimPath) || fs.readFileSync(shimPath, "utf8") !== SERVER_PARSER_SHIM_SOURCE) fs.writeFileSync(shimPath, SERVER_PARSER_SHIM_SOURCE, "utf8");
2355
2356
  return shimPath;
2356
2357
  };
2358
+ const trimTsconfigWildcardSuffix = (value) => value.endsWith("/*") ? value.slice(0, -2) : value;
2359
+ const loadTypeScript$1 = () => {
2360
+ try {
2361
+ return require$2("typescript");
2362
+ } catch {
2363
+ return null;
2364
+ }
2365
+ };
2366
+ const buildTsconfigPathAliases = (cwd) => {
2367
+ const typescript = loadTypeScript$1();
2368
+ if (!typescript) return {};
2369
+ const configPath = typescript.findConfigFile(cwd, fs.existsSync, "tsconfig.json");
2370
+ if (!configPath) return {};
2371
+ const readResult = typescript.readConfigFile(configPath, typescript.sys.readFile);
2372
+ if (readResult.error) return {};
2373
+ const parsedConfig = typescript.parseJsonConfigFileContent(readResult.config, typescript.sys, path.dirname(configPath));
2374
+ const baseUrl = typeof parsedConfig.options.baseUrl === "string" && parsedConfig.options.baseUrl.length > 0 ? parsedConfig.options.baseUrl : path.dirname(configPath);
2375
+ const paths = parsedConfig.options.paths;
2376
+ if (!paths) return {};
2377
+ const aliases = {};
2378
+ for (const [specifier, targets] of Object.entries(paths)) {
2379
+ const firstTarget = targets[0];
2380
+ if (!firstTarget) continue;
2381
+ const aliasKey = trimTsconfigWildcardSuffix(specifier);
2382
+ const aliasTarget = trimTsconfigWildcardSuffix(firstTarget);
2383
+ if (!aliasKey || aliasKey === "*") continue;
2384
+ aliases[aliasKey] = path.resolve(baseUrl, aliasTarget);
2385
+ }
2386
+ return aliases;
2387
+ };
2357
2388
  const getProjectServerParserShimPath = (cwd = process.cwd()) => ensureServerParserShim(cwd);
2358
2389
  const createProjectJiti = (cwd = process.cwd()) => createJiti(cwd, {
2359
2390
  interopDefault: true,
2360
2391
  moduleCache: false,
2361
2392
  alias: {
2393
+ ...buildTsconfigPathAliases(cwd),
2362
2394
  ...buildLocalPackageExportAliases(cwd, "kitcn"),
2363
2395
  ...buildLocalPackageExportAliases(cwd, "convex"),
2364
2396
  "kitcn/server": getProjectServerParserShimPath(cwd)
@@ -12637,11 +12669,33 @@ function resolveRemoteConvexDeploymentKey(env) {
12637
12669
  if (selfHostedUrl) return `self-hosted-env:${selfHostedUrl}`;
12638
12670
  return "remote-env";
12639
12671
  }
12640
- async function withLocalConvexEnv(sharedDir, fn) {
12672
+ function getLocalParseEnvVars(sharedDir, backend) {
12673
+ const { functionsDir } = getConvexConfig(sharedDir);
12674
+ const rootEnvPath = join(process.cwd(), ".env");
12675
+ const backendEnvPath = join(functionsDir, "..", ".env");
12676
+ const envPaths = backend === "concave" ? [backendEnvPath, rootEnvPath] : [rootEnvPath, backendEnvPath];
12677
+ const mergedEnv = {};
12678
+ for (const envPath of envPaths) {
12679
+ if (!fs.existsSync(envPath)) continue;
12680
+ Object.assign(mergedEnv, parse(fs.readFileSync(envPath, "utf8")));
12681
+ }
12682
+ return mergedEnv;
12683
+ }
12684
+ function getLocalBackendEnvVars(sharedDir, backend) {
12641
12685
  const { functionsDir } = getConvexConfig(sharedDir);
12642
- const envPath = join(functionsDir, "..", ".env");
12643
- if (!fs.existsSync(envPath)) return fn();
12644
- const envVars = parse(fs.readFileSync(envPath, "utf8"));
12686
+ const rootEnvPath = join(process.cwd(), ".env");
12687
+ const backendEnvPath = join(functionsDir, "..", ".env");
12688
+ const envPaths = backend === "concave" ? [backendEnvPath, rootEnvPath] : [backendEnvPath];
12689
+ const mergedEnv = {};
12690
+ for (const envPath of envPaths) {
12691
+ if (!fs.existsSync(envPath)) continue;
12692
+ Object.assign(mergedEnv, parse(fs.readFileSync(envPath, "utf8")));
12693
+ }
12694
+ return mergedEnv;
12695
+ }
12696
+ async function withLocalCodegenEnv(sharedDir, backend, fn) {
12697
+ const envVars = getLocalParseEnvVars(sharedDir, backend);
12698
+ if (Object.keys(envVars).length === 0) return fn();
12645
12699
  const previousValues = /* @__PURE__ */ new Map();
12646
12700
  for (const [key, value] of Object.entries(envVars)) {
12647
12701
  previousValues.set(key, process.env[key]);
@@ -12654,12 +12708,6 @@ async function withLocalConvexEnv(sharedDir, fn) {
12654
12708
  else process.env[key] = value;
12655
12709
  }
12656
12710
  }
12657
- function getLocalConvexEnvVars(sharedDir) {
12658
- const { functionsDir } = getConvexConfig(sharedDir);
12659
- const envPath = join(functionsDir, "..", ".env");
12660
- if (!fs.existsSync(envPath)) return {};
12661
- return parse(fs.readFileSync(envPath, "utf8"));
12662
- }
12663
12711
  function parseInitCommandArgs(args) {
12664
12712
  let yes = false;
12665
12713
  let json = false;
@@ -14155,7 +14203,7 @@ async function runConfiguredCodegenDetailed(params) {
14155
14203
  realConcavePath: params.realConcavePath
14156
14204
  });
14157
14205
  const targetArgs = extractBackendRunTargetArgs(resolvedRuntimeAdapter.publicName, convexCodegenArgs);
14158
- const localConvexEnv = getLocalConvexEnvVars(sharedDir);
14206
+ const localBackendEnv = getLocalBackendEnvVars(sharedDir, resolvedRuntimeAdapter.publicName);
14159
14207
  const authEnvState = autoSyncLocalAuthEnv && resolvedRuntimeAdapter.publicName === "convex" && getAggregateBackfillDeploymentKey(targetArgs) === "local" ? resolveAuthEnvState({
14160
14208
  cwd: process.cwd(),
14161
14209
  sharedDir
@@ -14169,7 +14217,7 @@ async function runConfiguredCodegenDetailed(params) {
14169
14217
  targetArgs
14170
14218
  });
14171
14219
  } catch {}
14172
- await withLocalConvexEnv(sharedDir, async () => {
14220
+ await withLocalCodegenEnv(sharedDir, resolvedRuntimeAdapter.publicName, async () => {
14173
14221
  await generateMetaFn(sharedDir, {
14174
14222
  debug,
14175
14223
  scope: scope ?? "all",
@@ -14184,7 +14232,7 @@ async function runConfiguredCodegenDetailed(params) {
14184
14232
  stdio,
14185
14233
  cwd: process.cwd(),
14186
14234
  env: createBackendCommandEnv({
14187
- ...localConvexEnv,
14235
+ ...localBackendEnv,
14188
14236
  ...env
14189
14237
  }),
14190
14238
  reject: false
@@ -14309,7 +14357,7 @@ async function stopPersistentBootstrapProcess(process) {
14309
14357
  }
14310
14358
  }
14311
14359
  async function runLocalConvexBootstrapForInit(params) {
14312
- const localConvexEnv = getLocalConvexEnvVars(params.sharedDir);
14360
+ const localConvexEnv = getLocalBackendEnvVars(params.sharedDir, params.runtimeAdapter.publicName);
14313
14361
  const bootstrapProcess = params.execaFn(params.runtimeAdapter.command, [...params.runtimeAdapter.argsPrefix, ...params.args], {
14314
14362
  cwd: process.cwd(),
14315
14363
  env: createBackendCommandEnv({
@@ -14434,7 +14482,7 @@ async function runInitializationCodegen(params) {
14434
14482
  });
14435
14483
  try {
14436
14484
  if (bootstrap.exitCode !== 0) throw new Error(formatInitCodegenFailure(`${codegen.stdout}\n${codegen.stderr}\n${bootstrap.stdout}\n${bootstrap.stderr}`));
14437
- await withLocalConvexEnv(params.sharedDir, async () => {
14485
+ await withLocalCodegenEnv(params.sharedDir, runtimeAdapter.publicName, async () => {
14438
14486
  await params.generateMetaFn(params.sharedDir, {
14439
14487
  debug: params.debug,
14440
14488
  scope: params.config.codegen.scope ?? "all",
@@ -15205,4 +15253,4 @@ function isEntryPoint(entry, filename) {
15205
15253
  }
15206
15254
 
15207
15255
  //#endregion
15208
- export { resolvePluginPreset as $, resolveConfiguredBackend as A, runConvexInitIfNeeded as B, isInitialized as C, getConvexConfig as Ct, readPackageVersions as D, parseInitCommandArgs as E, runAfterScaffoldScript as F, trackProcess as G, runInitCommandFlow as H, runAggregateBackfillFlow as I, collectPluginScaffoldTemplates as J, withWorkingDirectory as K, runAggregatePruneFlow as L, resolveInitProjectDir as M, resolveMigrationConfig as N, resolveBackfillConfig as O, resolveRunDeps as P, resolveAddTemplateDefaults as Q, runBackendFunction as R, isEntryPoint as S, generateMeta as St, parseBackendRunJson as T, highlighter as Tt, runMigrationCreate as U, runDevSchemaBackfillIfNeeded as V, runMigrationFlow as W, promptForPluginSelection as X, filterScaffoldTemplatePathMap as Y, promptForScaffoldTemplateSelection as Z, formatInfoOutput as _, inspectPluginDependencyInstall as _t, cleanup as a, isSupportedPluginKey as at, hasRemoteConvexDeploymentEnv as b, serializeEnvValue as bt, createCommandEnv as c, assertSchemaFileExists as ct, extractBackfillCliOptions as d, getSchemaFilePath as dt, resolvePresetScaffoldTemplates as et, extractConcaveRunTargetArgs as f, readPluginLockfile as ft, formatDocsOutput as g, applyPluginDependencyInstall as gt, extractResetCliOptions as h, applyPlanningDependencyInstall as ht, buildInitializationPlan as i, getSupportedPluginKeys as it, resolveDocTopic as j, resolveCodegenTrimSegments as k, ensureConvexGitignoreEntry as l, collectInstalledPluginKeys as lt, extractMigrationDownOptions as m, applyDependencyHintsInstall as mt, applyPluginInstallPlanFiles as n, resolveTemplatesByIdOrThrow as nt, createBackendAdapter as o, buildPluginInstallPlan as ot, extractMigrationCliOptions as p, resolveSchemaInstalledPlugins as pt, createSpinner as q, assertNoRemovedDevPreRunFlag as r, getPluginCatalogEntry as rt, createBackendCommandEnv as s, resolvePluginScaffoldRoots as st, applyDependencyInstallPlan as t, resolveTemplateSelectionSource as tt, extractBackendRunTargetArgs as u, getPluginLockfilePath as ut, getAggregateBackfillDeploymentKey as v, resolveProjectScaffoldContext as vt, parseArgs as w, logger as wt, isConvexDevPreRunConflictFlag as x, stripConvexCommandNoise as xt, getDevAggregateBackfillStatePath as y, resolveAuthEnvState as yt, runConfiguredCodegen as z };
15256
+ export { resolveAddTemplateDefaults as $, resolveConfiguredBackend as A, runConvexInitIfNeeded as B, isInitialized as C, generateMeta as Ct, readPackageVersions as D, parseInitCommandArgs as E, highlighter as Et, runAfterScaffoldScript as F, trackProcess as G, runInitCommandFlow as H, runAggregateBackfillFlow as I, createSpinner as J, withLocalCodegenEnv as K, runAggregatePruneFlow as L, resolveInitProjectDir as M, resolveMigrationConfig as N, resolveBackfillConfig as O, resolveRunDeps as P, promptForScaffoldTemplateSelection as Q, runBackendFunction as R, isEntryPoint as S, stripConvexCommandNoise as St, parseBackendRunJson as T, logger as Tt, runMigrationCreate as U, runDevSchemaBackfillIfNeeded as V, runMigrationFlow as W, filterScaffoldTemplatePathMap as X, collectPluginScaffoldTemplates as Y, promptForPluginSelection as Z, formatInfoOutput as _, applyPluginDependencyInstall as _t, cleanup as a, getSupportedPluginKeys as at, hasRemoteConvexDeploymentEnv as b, resolveAuthEnvState as bt, createCommandEnv as c, resolvePluginScaffoldRoots as ct, extractBackfillCliOptions as d, getPluginLockfilePath as dt, resolvePluginPreset as et, extractConcaveRunTargetArgs as f, getSchemaFilePath as ft, formatDocsOutput as g, applyPlanningDependencyInstall as gt, extractResetCliOptions as h, applyDependencyHintsInstall as ht, buildInitializationPlan as i, getPluginCatalogEntry as it, resolveDocTopic as j, resolveCodegenTrimSegments as k, ensureConvexGitignoreEntry as l, assertSchemaFileExists as lt, extractMigrationDownOptions as m, resolveSchemaInstalledPlugins as mt, applyPluginInstallPlanFiles as n, resolveTemplateSelectionSource as nt, createBackendAdapter as o, isSupportedPluginKey as ot, extractMigrationCliOptions as p, readPluginLockfile as pt, withWorkingDirectory as q, assertNoRemovedDevPreRunFlag as r, resolveTemplatesByIdOrThrow as rt, createBackendCommandEnv as s, buildPluginInstallPlan as st, applyDependencyInstallPlan as t, resolvePresetScaffoldTemplates as tt, extractBackendRunTargetArgs as u, collectInstalledPluginKeys as ut, getAggregateBackfillDeploymentKey as v, inspectPluginDependencyInstall as vt, parseArgs as w, getConvexConfig as wt, isConvexDevPreRunConflictFlag as x, serializeEnvValue as xt, getDevAggregateBackfillStatePath as y, resolveProjectScaffoldContext as yt, runConfiguredCodegen as z };
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $ as resolvePluginPreset, A as resolveConfiguredBackend, B as runConvexInitIfNeeded, C as isInitialized, D as readPackageVersions, E as parseInitCommandArgs, F as runAfterScaffoldScript, G as trackProcess, H as runInitCommandFlow, I as runAggregateBackfillFlow, J as collectPluginScaffoldTemplates, K as withWorkingDirectory, L as runAggregatePruneFlow, M as resolveInitProjectDir, N as resolveMigrationConfig, O as resolveBackfillConfig, P as resolveRunDeps, Q as resolveAddTemplateDefaults, R as runBackendFunction, S as isEntryPoint, T as parseBackendRunJson, Tt as highlighter, U as runMigrationCreate, V as runDevSchemaBackfillIfNeeded, W as runMigrationFlow, X as promptForPluginSelection, Y as filterScaffoldTemplatePathMap, Z as promptForScaffoldTemplateSelection, _ as formatInfoOutput, _t as inspectPluginDependencyInstall, a as cleanup, at as isSupportedPluginKey, b as hasRemoteConvexDeploymentEnv, bt as serializeEnvValue, c as createCommandEnv, ct as assertSchemaFileExists, d as extractBackfillCliOptions, dt as getSchemaFilePath, et as resolvePresetScaffoldTemplates, f as extractConcaveRunTargetArgs, ft as readPluginLockfile, g as formatDocsOutput, gt as applyPluginDependencyInstall, h as extractResetCliOptions, ht as applyPlanningDependencyInstall, i as buildInitializationPlan, it as getSupportedPluginKeys, j as resolveDocTopic, k as resolveCodegenTrimSegments, l as ensureConvexGitignoreEntry, lt as collectInstalledPluginKeys, m as extractMigrationDownOptions, mt as applyDependencyHintsInstall, n as applyPluginInstallPlanFiles, nt as resolveTemplatesByIdOrThrow, o as createBackendAdapter, ot as buildPluginInstallPlan, p as extractMigrationCliOptions, pt as resolveSchemaInstalledPlugins, q as createSpinner, r as assertNoRemovedDevPreRunFlag, rt as getPluginCatalogEntry, s as createBackendCommandEnv, st as resolvePluginScaffoldRoots, t as applyDependencyInstallPlan, tt as resolveTemplateSelectionSource, u as extractBackendRunTargetArgs, ut as getPluginLockfilePath, v as getAggregateBackfillDeploymentKey, vt as resolveProjectScaffoldContext, w as parseArgs, wt as logger, x as isConvexDevPreRunConflictFlag, xt as stripConvexCommandNoise, y as getDevAggregateBackfillStatePath, yt as resolveAuthEnvState, z as runConfiguredCodegen } from "./backend-core-DA9iT-To.mjs";
2
+ import { $ as resolveAddTemplateDefaults, A as resolveConfiguredBackend, B as runConvexInitIfNeeded, C as isInitialized, D as readPackageVersions, E as parseInitCommandArgs, Et as highlighter, F as runAfterScaffoldScript, G as trackProcess, H as runInitCommandFlow, I as runAggregateBackfillFlow, J as createSpinner, K as withLocalCodegenEnv, L as runAggregatePruneFlow, M as resolveInitProjectDir, N as resolveMigrationConfig, O as resolveBackfillConfig, P as resolveRunDeps, Q as promptForScaffoldTemplateSelection, R as runBackendFunction, S as isEntryPoint, St as stripConvexCommandNoise, T as parseBackendRunJson, Tt as logger, U as runMigrationCreate, V as runDevSchemaBackfillIfNeeded, W as runMigrationFlow, X as filterScaffoldTemplatePathMap, Y as collectPluginScaffoldTemplates, Z as promptForPluginSelection, _ as formatInfoOutput, _t as applyPluginDependencyInstall, a as cleanup, at as getSupportedPluginKeys, b as hasRemoteConvexDeploymentEnv, bt as resolveAuthEnvState, c as createCommandEnv, ct as resolvePluginScaffoldRoots, d as extractBackfillCliOptions, dt as getPluginLockfilePath, et as resolvePluginPreset, f as extractConcaveRunTargetArgs, ft as getSchemaFilePath, g as formatDocsOutput, gt as applyPlanningDependencyInstall, h as extractResetCliOptions, ht as applyDependencyHintsInstall, i as buildInitializationPlan, it as getPluginCatalogEntry, j as resolveDocTopic, k as resolveCodegenTrimSegments, l as ensureConvexGitignoreEntry, lt as assertSchemaFileExists, m as extractMigrationDownOptions, mt as resolveSchemaInstalledPlugins, n as applyPluginInstallPlanFiles, nt as resolveTemplateSelectionSource, o as createBackendAdapter, ot as isSupportedPluginKey, p as extractMigrationCliOptions, pt as readPluginLockfile, q as withWorkingDirectory, r as assertNoRemovedDevPreRunFlag, rt as resolveTemplatesByIdOrThrow, s as createBackendCommandEnv, st as buildPluginInstallPlan, t as applyDependencyInstallPlan, tt as resolvePresetScaffoldTemplates, u as extractBackendRunTargetArgs, ut as collectInstalledPluginKeys, v as getAggregateBackfillDeploymentKey, vt as inspectPluginDependencyInstall, w as parseArgs, x as isConvexDevPreRunConflictFlag, xt as serializeEnvValue, y as getDevAggregateBackfillStatePath, yt as resolveProjectScaffoldContext, z as runConfiguredCodegen } from "./backend-core-Rv9NorIW.mjs";
3
3
  import fs, { existsSync, readFileSync } from "node:fs";
4
4
  import path, { delimiter, dirname, join, relative, resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
@@ -945,11 +945,13 @@ const handleDevCommand = async (argv, deps) => {
945
945
  silent: true,
946
946
  targetArgs
947
947
  });
948
- await generateMetaFn(sharedDir, {
949
- debug,
950
- silent: true,
951
- scope: "all",
952
- trimSegments
948
+ await withLocalCodegenEnv(sharedDir, backend, async () => {
949
+ await generateMetaFn(sharedDir, {
950
+ debug,
951
+ silent: true,
952
+ scope: "all",
953
+ trimSegments
954
+ });
953
955
  });
954
956
  const { runtime, watcherPath } = resolveWatcherCommand();
955
957
  const watcherProcess = execaFn(runtime, [watcherPath], {
@@ -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-DqJubRPJ.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-BLvtq_eH.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-BS63Nsug.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-DrB2VeNb.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 { o as Simplify } from "./types-BTb_4BaU.js";
2
- import { m as UnsetMarker, t as AnyMiddleware } from "./types-DEJpkIhw.js";
2
+ import { m as UnsetMarker, t as AnyMiddleware } from "./types-BqUIoMfT.js";
3
3
  import { GenericActionCtx, GenericDataModel, HttpRouter } from "convex/server";
4
4
  import { z } from "zod";
5
5
  import { Context, Hono } from "hono";
@@ -1,4 +1,4 @@
1
- import { o as MiddlewareBuilder } from "./types-DEJpkIhw.js";
1
+ import { o as MiddlewareBuilder } from "./types-BqUIoMfT.js";
2
2
 
3
3
  //#region src/plugins/middleware.d.ts
4
4
  declare const PLUGIN_CONFIG_RESOLVERS: unique symbol;
@@ -1,2 +1,2 @@
1
- import { a as PluginConfigureResolver, i as PluginConfigureInput, n as PluginApiScope, o as definePlugin, r as PluginConfigureContext, s as resolvePluginOptions, t as Plugin } from "../middleware-BL2wn3s0.js";
1
+ import { a as PluginConfigureResolver, i as PluginConfigureInput, n as PluginApiScope, o as definePlugin, r as PluginConfigureContext, s as resolvePluginOptions, t as Plugin } from "../middleware-CU0mDiRs.js";
2
2
  export { type Plugin, type PluginApiScope, type PluginConfigureContext, type PluginConfigureInput, type PluginConfigureResolver, definePlugin, resolvePluginOptions };
@@ -1,6 +1,6 @@
1
1
  import { t as VRequired } from "./validators-vzRKjBJC.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-DqJubRPJ.js";
3
- import { d as Overwrite$1, i as IntersectIfDefined, m as UnsetMarker, o as MiddlewareBuilder, s as MiddlewareFunction, t as AnyMiddleware } from "./types-DEJpkIhw.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-BS63Nsug.js";
3
+ import { d as Overwrite$1, i as IntersectIfDefined, m as UnsetMarker, o as MiddlewareBuilder, s as MiddlewareFunction, t as AnyMiddleware } from "./types-BqUIoMfT.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 } from "convex/values";
5
5
  import * as convex_server0 from "convex/server";
6
6
  import { ActionBuilder, ArgsArrayToObject, DefaultFunctionArgs, FunctionReference, FunctionReturnType, FunctionVisibility, GenericActionCtx, GenericDataModel, GenericMutationCtx, GenericQueryCtx, MutationBuilder, QueryBuilder, RegisteredAction, RegisteredMutation, RegisteredQuery, TableNamesInDataModel } from "convex/server";
@@ -1,5 +1,5 @@
1
- import { o as MiddlewareBuilder } from "../types-DEJpkIhw.js";
2
- import { t as Plugin } from "../middleware-BL2wn3s0.js";
1
+ import { o as MiddlewareBuilder } from "../types-BqUIoMfT.js";
2
+ import { t as Plugin } from "../middleware-CU0mDiRs.js";
3
3
  import * as convex_server0 from "convex/server";
4
4
 
5
5
  //#region src/ratelimit/duration.d.ts
@@ -203,7 +203,6 @@ declare const RatelimitPlugin: Plugin<"ratelimit", AnyRatelimitPluginOptions, An
203
203
  [x: string]: any;
204
204
  [x: number]: any;
205
205
  [x: symbol]: any;
206
- api: Record<string, unknown> & Record<"ratelimit", AnyRatelimitPluginOptions>;
207
206
  }, unknown>;
208
207
  }, "middleware">>;
209
208
  //#endregion
@@ -1,7 +1,7 @@
1
1
  import { n as DeepPartial, o as Simplify, r as DistributiveOmit } from "../types-BTb_4BaU.js";
2
- import { C as HttpProcedure, d as CRPCHttpRouter, j as DataTransformerOptions, p as HttpRouterRecord } from "../http-types-DqJubRPJ.js";
3
- import { m as UnsetMarker } from "../types-DEJpkIhw.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-BLvtq_eH.js";
2
+ import { C as HttpProcedure, d as CRPCHttpRouter, j as DataTransformerOptions, p as HttpRouterRecord } from "../http-types-BS63Nsug.js";
3
+ import { m as UnsetMarker } from "../types-BqUIoMfT.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-DrB2VeNb.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";
@@ -1,5 +1,5 @@
1
- import { $ as initCRPC, A as getCRPCErrorFromUnknown, B as CallerMeta, C as WithHttpRouter, D as CRPCErrorCode, E as CRPCError, F as createEnv, G as createGeneratedFunctionReference, H as ServerCaller, I as ConvexContext, J as CRPCFunctionTypeHint, K as getGeneratedValue, L as createCallerFactory, M as isCRPCError, N as toCRPCError, O as CRPC_ERROR_CODES_BY_KEY, P as CreateEnvOptions, Q as createMiddlewareFactory, R as LazyCaller, S as typedProcedureResolver, St as zodToConvexFields, T as inferApiOutputs, U as createServerCaller, V as CallerOpts, W as createApiLeaf, X as ProcedureBuilder, Y as MutationProcedureBuilder, Z as QueryProcedureBuilder, _ as createGenericHandlerFactory, _t as zCustomQuery, a as GeneratedRegistryCallerForContext, at as ConvexValidatorFromZod, b as defineProcedure, bt as zodOutputToConvexFields, c as ProcedureActionCallerFromRegistry, ct as ZCustomCtx, d as ProcedureDefinition, dt as ZodValidatorFromConvex, et as HttpProcedureBuilder, f as ProcedureFromFunctionReference, ft as convexToZod, g as createGenericCallerFactory, gt as zCustomMutation, h as createGeneratedRegistryRuntime, ht as zCustomAction, i as GeneratedRegistryCallerFactory, it as matchPathParams, j as getHTTPStatusCodeFromError, k as CRPC_ERROR_CODE_TO_HTTP, l as ProcedureCaller, lt as Zid, m as ProcedureScheduleCallerFromRegistry, mt as withSystemFields, n as GeneratedProcedureRegistry, nt as extractPathParams, o as GeneratedRegistryHandlerFactory, ot as ConvexValidatorFromZodOutput, p as ProcedureSchedulableCallerFromRegistry, pt as convexToZodFields, q as ActionProcedureBuilder, r as GeneratedProcedureRegistryEntry, rt as handleHttpError, s as GeneratedRegistryHandlerForContext, st as CustomBuilder, t as CreateProcedureCallerFactoryOptions, tt as createHttpProcedureBuilder, u as ProcedureCallerFromRegistry, ut as ZodFromValidatorBase, v as createProcedureCallerFactory, vt as zid, w as inferApiInputs, x as getGeneratedFunctionReference, xt as zodToConvex, y as createProcedureHandlerFactory, yt as zodOutputToConvex, z as createLazyCaller } from "../procedure-caller-DtxLmGwA.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-DqJubRPJ.js";
3
- import { a as MergeZodObjects, c as MiddlewareMarker, d as Overwrite, f as ResolveIfSet, i as IntersectIfDefined, l as MiddlewareNext, m as UnsetMarker, n as AnyMiddlewareBuilder, o as MiddlewareBuilder, p as Simplify, r as GetRawInputFn, s as MiddlewareFunction, t as AnyMiddleware, u as MiddlewareResult } from "../types-DEJpkIhw.js";
1
+ import { $ as initCRPC, A as getCRPCErrorFromUnknown, B as CallerMeta, C as WithHttpRouter, D as CRPCErrorCode, E as CRPCError, F as createEnv, G as createGeneratedFunctionReference, H as ServerCaller, I as ConvexContext, J as CRPCFunctionTypeHint, K as getGeneratedValue, L as createCallerFactory, M as isCRPCError, N as toCRPCError, O as CRPC_ERROR_CODES_BY_KEY, P as CreateEnvOptions, Q as createMiddlewareFactory, R as LazyCaller, S as typedProcedureResolver, St as zodToConvexFields, T as inferApiOutputs, U as createServerCaller, V as CallerOpts, W as createApiLeaf, X as ProcedureBuilder, Y as MutationProcedureBuilder, Z as QueryProcedureBuilder, _ as createGenericHandlerFactory, _t as zCustomQuery, a as GeneratedRegistryCallerForContext, at as ConvexValidatorFromZod, b as defineProcedure, bt as zodOutputToConvexFields, c as ProcedureActionCallerFromRegistry, ct as ZCustomCtx, d as ProcedureDefinition, dt as ZodValidatorFromConvex, et as HttpProcedureBuilder, f as ProcedureFromFunctionReference, ft as convexToZod, g as createGenericCallerFactory, gt as zCustomMutation, h as createGeneratedRegistryRuntime, ht as zCustomAction, i as GeneratedRegistryCallerFactory, it as matchPathParams, j as getHTTPStatusCodeFromError, k as CRPC_ERROR_CODE_TO_HTTP, l as ProcedureCaller, lt as Zid, m as ProcedureScheduleCallerFromRegistry, mt as withSystemFields, n as GeneratedProcedureRegistry, nt as extractPathParams, o as GeneratedRegistryHandlerFactory, ot as ConvexValidatorFromZodOutput, p as ProcedureSchedulableCallerFromRegistry, pt as convexToZodFields, q as ActionProcedureBuilder, r as GeneratedProcedureRegistryEntry, rt as handleHttpError, s as GeneratedRegistryHandlerForContext, st as CustomBuilder, t as CreateProcedureCallerFactoryOptions, tt as createHttpProcedureBuilder, u as ProcedureCallerFromRegistry, ut as ZodFromValidatorBase, v as createProcedureCallerFactory, vt as zid, w as inferApiInputs, x as getGeneratedFunctionReference, xt as zodToConvex, y as createProcedureHandlerFactory, yt as zodOutputToConvex, z as createLazyCaller } from "../procedure-caller-C15h5Iel.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-BS63Nsug.js";
3
+ import { a as MergeZodObjects, c as MiddlewareMarker, d as Overwrite, f as ResolveIfSet, i as IntersectIfDefined, l as MiddlewareNext, m as UnsetMarker, n as AnyMiddlewareBuilder, o as MiddlewareBuilder, p as Simplify, r as GetRawInputFn, s as MiddlewareFunction, t as AnyMiddleware, u as MiddlewareResult } from "../types-BqUIoMfT.js";
4
4
  import { a as isQueryCtx, c as requireMutationCtx, i as isMutationCtx, l as requireQueryCtx, n as RunMutationCtx, o as isRunMutationCtx, r as isActionCtx, s as requireActionCtx, t as GenericCtx, u as requireRunMutationCtx } from "../context-utils-HPC5nXzx.js";
5
5
  export { ActionProcedureBuilder, AnyMiddleware, AnyMiddlewareBuilder, CRPCError, CRPCErrorCode, 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, MiddlewareResult, MutationProcedureBuilder, Overwrite, ProcedureActionCallerFromRegistry, ProcedureBuilder, ProcedureCaller, ProcedureCallerFromRegistry, ProcedureDefinition, ProcedureFromFunctionReference, ProcedureMeta, ProcedureSchedulableCallerFromRegistry, ProcedureScheduleCallerFromRegistry, QueryProcedureBuilder, ResolveIfSet, RunMutationCtx, 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, initCRPC, isActionCtx, isCRPCError, isMutationCtx, isQueryCtx, isRunMutationCtx, matchPathParams, requireActionCtx, requireMutationCtx, requireQueryCtx, requireRunMutationCtx, toCRPCError, typedProcedureResolver, withSystemFields, zCustomAction, zCustomMutation, zCustomQuery, zid, zodOutputToConvex, zodOutputToConvexFields, zodToConvex, zodToConvexFields };
@@ -40,17 +40,22 @@ type MiddlewareResult<TContext> = {
40
40
  };
41
41
  /** Function to get raw input before validation */
42
42
  type GetRawInputFn = () => Promise<unknown>;
43
+ type CurrentMiddlewareContext<TContext, TContextOverridesIn> = Simplify<Overwrite<TContext, TContextOverridesIn>>;
44
+ type ChangedKeys<TCurrent, TNext> = { [K in keyof TNext]: K extends keyof TCurrent ? [TNext[K]] extends [TCurrent[K]] ? [TCurrent[K]] extends [TNext[K]] ? never : K : K : K }[keyof TNext];
45
+ type ContextOverridesFromNext<TCurrent, TNext> = TNext extends object ? Simplify<Pick<TNext, ChangedKeys<TCurrent, TNext>>> extends infer TDiff ? keyof TDiff extends never ? UnsetMarker : TDiff : never : TNext;
43
46
  /**
44
47
  * Next function overloads - key to automatic context and input inference
45
48
  * Matches tRPC's pattern: can modify context, input, or both
46
49
  */
47
- type MiddlewareNext<TContextOverridesIn> = {
48
- /** Continue without modification - passes through existing overrides */(): Promise<MiddlewareResult<TContextOverridesIn>>; /** Continue with modified context and/or input */
49
- <$ContextOverride>(opts: {
50
- ctx?: $ContextOverride;
51
- input?: unknown;
52
- }): Promise<MiddlewareResult<$ContextOverride>>;
53
- };
50
+ /**
51
+ * Continue middleware execution with optional ctx/input changes.
52
+ * When ctx includes the current context plus extra fields, only the delta is
53
+ * carried forward as middleware overrides.
54
+ */
55
+ type MiddlewareNext<TContext, TContextOverridesIn> = <TNextContext extends object = CurrentMiddlewareContext<TContext, TContextOverridesIn>>(opts?: {
56
+ ctx?: TNextContext;
57
+ input?: unknown;
58
+ }) => Promise<MiddlewareResult<Overwrite<TContextOverridesIn, ContextOverridesFromNext<CurrentMiddlewareContext<TContext, TContextOverridesIn>, TNextContext>>>>;
54
59
  /**
55
60
  * Middleware function signature with input access (tRPC-compatible)
56
61
  *
@@ -61,11 +66,11 @@ type MiddlewareNext<TContextOverridesIn> = {
61
66
  * @typeParam TInputOut - Parsed input type (unknown if before .input(), typed if after)
62
67
  */
63
68
  type MiddlewareFunction<TContext, TMeta, TContextOverridesIn, $ContextOverridesOut, TInputOut = unknown> = (opts: {
64
- ctx: Simplify<Overwrite<TContext, TContextOverridesIn>>;
69
+ ctx: CurrentMiddlewareContext<TContext, TContextOverridesIn>;
65
70
  meta: TMeta;
66
71
  input: TInputOut;
67
72
  getRawInput: GetRawInputFn;
68
- next: MiddlewareNext<TContextOverridesIn>;
73
+ next: MiddlewareNext<TContext, TContextOverridesIn>;
69
74
  }) => Promise<MiddlewareResult<$ContextOverridesOut>>;
70
75
  /** Stored middleware with type info erased for runtime */
71
76
  type AnyMiddleware = MiddlewareFunction<any, any, any, any, any>;
@@ -1,4 +1,4 @@
1
- import { O as CombinedDataTransformer, n as HttpClientError } from "./http-types-DqJubRPJ.js";
1
+ import { O as CombinedDataTransformer, n as HttpClientError } from "./http-types-BS63Nsug.js";
2
2
  import { FunctionArgs, FunctionReference, FunctionReturnType } from "convex/server";
3
3
 
4
4
  //#region src/crpc/http-client.d.ts
package/dist/watcher.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { A as resolveConfiguredBackend, Ct as getConvexConfig, P as resolveRunDeps, St as generateMeta, wt as logger } from "./backend-core-DA9iT-To.mjs";
2
+ import { A as resolveConfiguredBackend, Ct as generateMeta, P as resolveRunDeps, Tt as logger, wt as getConvexConfig } from "./backend-core-Rv9NorIW.mjs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitcn",
3
- "version": "0.12.15",
3
+ "version": "0.12.17",
4
4
  "description": "kitcn - React Query integration and CLI tools for Convex",
5
5
  "keywords": [
6
6
  "convex",
@@ -54,7 +54,7 @@ Only remember these non-parity deltas:
54
54
  19. On the kitcn auth client path, use `createAuthMutations(authClient)` wrappers so logout unsubscribes auth queries before sign out. Raw Convex preset keeps a smaller plain `authClient`.
55
55
  20. **NEVER** use `ctx.runQuery`/`ctx.runMutation`/`ctx.runAction` directly for module-to-module calls. Use `create<Module>Handler(ctx)` or `create<Module>Caller(ctx)` from `convex/functions/generated/<module>.runtime` instead.
56
56
  21. **`create<Module>Handler(ctx)`** — default choice for queries/mutations. Bypasses input validation, middleware, output validation → zero overhead. Query/mutation ctx only. Import from `./generated/<module>.runtime`.
57
- 22. **`create<Module>Caller(ctx)`** — use in actions and HTTP routes (where handler is unavailable). Goes through validation + middleware. Root caller exposes query+mutation procedures. In `ActionCtx`, action procedures are under `caller.actions.*`; scheduling is under `caller.schedule.now|after|at` with `caller.schedule.cancel(id)`. Import from `./generated/<module>.runtime`. Each caller/handler eagerly loads every procedure in its module (no lazy loading) — split large modules to keep bundles lean.
57
+ 22. **`create<Module>Caller(ctx)`** — use in actions and HTTP routes (where handler is unavailable). Goes through validation + middleware. Root caller exposes query+mutation procedures. In `ActionCtx`, action procedures are under `caller.actions.*`; scheduling is under `caller.schedule.now|after|at` with `caller.schedule.cancel(id)`. If your code widened `ctx` to a union like `MutationCtx | ActionCtx`, narrow it before accessing `caller.actions.*` (for example with `requireActionCtx(ctx)`). Import from `./generated/<module>.runtime`. Each caller/handler eagerly loads every procedure in its module (no lazy loading) — split large modules to keep bundles lean.
58
58
  23. API types (`Api`, `ApiInputs`, `ApiOutputs`, `Select`, `Insert`, `TableName`) import from `@convex/api` — no manual `inferApiInputs<typeof api>`.
59
59
  24. HTTP router must export as `httpRouter` (not `appRouter`) for codegen.
60
60
  25. Server wiring imports come from `convex/functions/generated/` directory: `getAuth`, `defineAuth` from `generated/auth`; `initCRPC`, `QueryCtx`, `MutationCtx`, `OrmCtx` from `generated/server`; `create<Module>Caller`, `create<Module>Handler` from `generated/<module>.runtime`. No manual `convex/lib/orm.ts`.
@@ -227,7 +227,8 @@ Builder rules that matter:
227
227
  1. Build `public`, `optional`, `auth`, and `private` procedure families once in `convex/lib/crpc.ts`.
228
228
  2. `.meta(...)` is client-visible via generated API metadata. Never put secrets there.
229
229
  3. Resolve session/user once in middleware. Do not re-fetch auth state in every procedure.
230
- 4. Keep deeper auth/runtime edge cases in `references/setup/server.md` and `references/features/auth*.md`.
230
+ 4. Shared `c.middleware()` chains preserve mutation writer types on mutation procedures. If the middleware itself performs writes, type it as mutation-only with `c.middleware<MutationCtx>(...)`.
231
+ 5. Keep deeper auth/runtime edge cases in `references/setup/server.md` and `references/features/auth*.md`.
231
232
 
232
233
  ### 3) Query + Mutation Procedure Template
233
234