kitcn 0.24.0 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/aggregate/index.d.ts +11 -1
  2. package/dist/aggregate/index.js +1 -1
  3. package/dist/auth/generated/index.d.ts +1 -1
  4. package/dist/auth/generated/index.js +1 -1
  5. package/dist/auth/http/index.d.ts +1 -1
  6. package/dist/auth/index.d.ts +4 -4
  7. package/dist/auth/index.js +10 -9
  8. package/dist/auth/nextjs/index.d.ts +2 -2
  9. package/dist/auth/nextjs/index.js +3 -3
  10. package/dist/auth/start/server/index.d.ts +1 -1
  11. package/dist/auth/start/server/index.js +1 -1
  12. package/dist/{builder-CsxVc5xC.js → builder-C6JSHkRK.js} +9 -3
  13. package/dist/{caller-factory-CWa0ELLD.js → caller-factory-Dd3H7j3V.js} +3 -3
  14. package/dist/{where-clause-compiler-DW6jy2er.d.ts → capabilities-Bem7xvGK.d.ts} +2958 -4145
  15. package/dist/cli.mjs +94 -58
  16. package/dist/{convex-plugin-D8B0oCFq.js → convex-plugin-DfOhBU9g.js} +1 -1
  17. package/dist/{create-schema-orm-B3f2Kc8O.js → create-schema-orm-Bu2JCiBS.js} +1 -1
  18. package/dist/crpc/index.d.ts +2 -2
  19. package/dist/crpc/index.js +3 -3
  20. package/dist/{customFunctions-DxEEO4Dq.js → customFunctions-ivbc6-_g.js} +2 -2
  21. package/dist/definitions-Dzk8mSTL.js +215 -0
  22. package/dist/extensions-Blzsyekm.js +55 -0
  23. package/dist/filter-expression-Dydt8wS0.js +402 -0
  24. package/dist/{generated-contract-disabled-B-nmd7Ne.d.ts → generated-contract-disabled-BEc4d98x.d.ts} +2 -2
  25. package/dist/{http-types-DXOgaerG.d.ts → http-types-90mapMP9.d.ts} +2 -2
  26. package/dist/id-CuSfWa5q.js +37 -0
  27. package/dist/{local-env-yFKub75x.mjs → local-env-Dkh4a_BK.mjs} +2244 -2113
  28. package/dist/{middleware-Br5zubu7.d.ts → middleware-CE_MC6Gi.d.ts} +1 -1
  29. package/dist/{middleware-DUd1Sj39.js → middleware-CdqNVyp8.js} +1 -1
  30. package/dist/orm/aggregate-index/index.d.ts +20 -0
  31. package/dist/orm/aggregate-index/index.js +2136 -0
  32. package/dist/orm/index.d.ts +5 -4
  33. package/dist/orm/index.js +127 -4292
  34. package/dist/orm/migrations/index.d.ts +3 -0
  35. package/dist/orm/migrations/index.js +506 -0
  36. package/dist/plugins/index.d.ts +1 -1
  37. package/dist/plugins/index.js +1 -1
  38. package/dist/{procedure-caller-DQxnLBS_.js → procedure-caller-CgLWu5F9.js} +2 -2
  39. package/dist/{procedure-name-C20pFZnk.d.ts → procedure-name-Bjw1JDIS.d.ts} +7 -4
  40. package/dist/{query-context-BzihIpnM.js → query-context-DOm5Xm3H.js} +1 -402
  41. package/dist/ratelimit/index.d.ts +2 -2
  42. package/dist/ratelimit/index.js +3 -3
  43. package/dist/rsc/index.d.ts +4 -4
  44. package/dist/rsc/index.js +4 -4
  45. package/dist/runtime-BdqTbgKh.js +1080 -0
  46. package/dist/schema-BQd2Xrfb.js +1411 -0
  47. package/dist/server/index.d.ts +4 -4
  48. package/dist/server/index.js +4 -4
  49. package/dist/{runtime-6DJxpDfb.js → table-CX2lnX7e.js} +3 -1095
  50. package/dist/{token-xlpENMVn.js → token-DcV_0fkF.js} +1 -1
  51. package/dist/{types-BHR7ZKKD.d.ts → types-In-ZZOsd.d.ts} +1 -1
  52. package/dist/{validators-C7LelqTN.js → validators-CIoUYCqO.js} +2 -1
  53. package/dist/{validators-BhsByJeg.d.ts → validators-wOIjhkfN.d.ts} +7 -1
  54. package/dist/watcher.mjs +1 -1
  55. package/dist/where-clause-compiler-Dmq4HMrK.d.ts +2089 -0
  56. package/package.json +6 -4
  57. package/skills/kitcn/SKILL.md +19 -18
  58. package/skills/kitcn/references/features/aggregates.md +21 -0
  59. package/skills/kitcn/references/features/auth-organizations.md +3 -3
  60. package/skills/kitcn/references/features/auth-polar.md +2 -1
  61. package/skills/kitcn/references/features/auth.md +8 -1
  62. package/skills/kitcn/references/setup/auth.md +52 -42
  63. package/skills/kitcn/references/setup/index.md +1 -1
  64. package/skills/kitcn/references/setup/server.md +2 -1
  65. /package/dist/{api-entry-N3nBOlI2.js → api-entry-CkDpGYVg.js} +0 -0
  66. /package/dist/{context-utils-BBUtBqjN.d.ts → context-utils-DwZ3Cam1.d.ts} +0 -0
  67. /package/dist/{create-schema-BXrKE2YY.js → create-schema-BRFjdgRr.js} +0 -0
  68. /package/dist/{error-Bvo7YEhk.js → error-CMLeCadS.js} +0 -0
  69. /package/dist/{generated-contract-disabled-BXaz7JCE.js → generated-contract-disabled-CZa0iyV0.js} +0 -0
  70. /package/dist/{meta-utils-D9K4fICl.js → meta-utils-D2lqN2Lg.js} +0 -0
  71. /package/dist/{query-context-CNo9ffvI.d.ts → query-context-DJONf8X5.d.ts} +0 -0
  72. /package/dist/{query-options-CzRV4G4N.js → query-options-DUiOj01a.js} +0 -0
  73. /package/dist/{token-B9Bjcqug.d.ts → token-kQaqFby4.d.ts} +0 -0
  74. /package/dist/{transformer-yZuBWo8v.js → transformer-D8wO-kEj.js} +0 -0
  75. /package/dist/{types-BCl8gfGy.d.ts → types-Bf3XQex5.d.ts} +0 -0
  76. /package/dist/{types-DF2cg_w0.d.ts → types-MHYXboyy.d.ts} +0 -0
  77. /package/dist/{types-CnTpHR1F.d.ts → types-eNzQmbqM.d.ts} +0 -0
  78. /package/dist/{upstream-BR6sBLg3.js → upstream-BCgGZX6q.js} +0 -0
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as createSystemFields, S as TableName, _ as getSchemaRelations, a as generateMeta, b as OrmSchemaExtensions, d as loadBabelParser, f as loadClackPrompts, g as isColorEnabled, h as highlighter, i as resolveConfiguredBackend, l as createProjectJiti, m as loadEsbuild, n as withLocalCodegenEnv, o as getConvexConfig, p as loadDotenv, r as loadCliConfig, s as logger, t as getLocalBackendEnvVars, u as CRPC_BUILDER_STUB_SOURCE, v as Columns, x as RlsPolicies, y as EnableRLS } from "./local-env-yFKub75x.mjs";
2
+ import { C as Columns, D as TableName, E as RlsPolicies, O as createSystemFields, S as getRankIndexes, T as OrmSchemaExtensions, _ as loadEsbuild, a as generateMeta, b as getAggregateIndexes, c as resolveSchemaDefaultExport, f as createProjectJiti, g as loadDotenv, h as loadClackPrompts, i as resolveConfiguredBackend, l as schemaDeclaresAggregateIndexes, m as loadBabelParser, n as withLocalCodegenEnv, o as getConvexConfig, p as CRPC_BUILDER_STUB_SOURCE, r as loadCliConfig, s as collectSchemaTables, t as getLocalBackendEnvVars, u as logger, v as highlighter, w as EnableRLS, x as getIndexes, y as isColorEnabled } from "./local-env-Dkh4a_BK.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import fs, { existsSync, readFileSync } from "node:fs";
5
5
  import path, { basename, delimiter, dirname, extname, isAbsolute, join, posix, relative, resolve } from "node:path";
@@ -12,21 +12,6 @@ import { diffWords, structuredPatch } from "diff";
12
12
  import { parseEnv } from "node:util";
13
13
  import { createServer } from "node:http";
14
14
 
15
- //#region src/orm/index-utils.ts
16
- function getIndexes(table) {
17
- const indexes = table.getIndexes?.();
18
- return Array.isArray(indexes) ? indexes : [];
19
- }
20
- function getAggregateIndexes(table) {
21
- const indexes = table.getAggregateIndexes?.();
22
- return Array.isArray(indexes) ? indexes : [];
23
- }
24
- function getRankIndexes(table) {
25
- const indexes = table.getRankIndexes?.();
26
- return Array.isArray(indexes) ? indexes : [];
27
- }
28
-
29
- //#endregion
30
15
  //#region src/orm/mutation-utils.ts
31
16
  const UTF8_ENCODER = new TextEncoder();
32
17
  function getTableName(table) {
@@ -2144,8 +2129,11 @@ const EXACT_VERSION_RE = /^(\d+)\.(\d+)\.\d+$/;
2144
2129
  const VERSION_IN_SPEC_RE = /(\d+)\.(\d+)(?:\.\d+)?/;
2145
2130
  const PLAIN_VERSION_SPEC_RE = /^[\^~]?v?\d+\.\d+(?:\.\d+)?$/;
2146
2131
  const UPPER_BOUND_RE = /(?:^|\s)<={0,1}\s*v?(\d+)\.(\d+)(?:\.\d+)?/g;
2132
+ const LOWER_BOUND_RE = /(?:^|\s)>={0,1}\s*v?(\d+)\.(\d+)(?:\.\d+)?/g;
2147
2133
  const SUPPORTED_CONCAVE_CLI_VERSION = "0.0.1-alpha.14";
2148
- const SUPPORTED_CONVEX_VERSION = "1.42.3";
2134
+ const SUPPORTED_CONVEX_VERSION = "1.44.0";
2135
+ const SUPPORTED_CONVEX_MIN_VERSION = "1.42";
2136
+ const SUPPORTED_CONVEX_MIN_TYPE_VERSION = "1.42.3";
2149
2137
  const SUPPORTED_BETTER_AUTH_VERSION = "1.6.18";
2150
2138
  const SUPPORTED_BETTER_AUTH_MIN_VERSION = "1.6.11";
2151
2139
  const SUPPORTED_HONO_VERSION = "4.12.9";
@@ -2155,16 +2143,16 @@ const SUPPORTED_ZOD_VERSION = "4.3.6";
2155
2143
  const KITCN_INSTALL_SPEC_ENV = "KITCN_INSTALL_SPEC";
2156
2144
  const KITCN_RESEND_INSTALL_SPEC_ENV = "KITCN_RESEND_INSTALL_SPEC";
2157
2145
  let ownVersion;
2158
- function getMinimumVersionRange(version) {
2159
- const match = EXACT_VERSION_RE.exec(version);
2160
- if (!match) throw new Error(`Unsupported exact version "${version}". Expected x.y.z format.`);
2161
- return `>=${match[1]}.${match[2]}`;
2162
- }
2163
2146
  function getMinorVersionPeerRange(minimumVersion, supportedVersion) {
2164
2147
  const match = EXACT_VERSION_RE.exec(supportedVersion);
2165
2148
  if (!match) throw new Error(`Unsupported exact version "${supportedVersion}". Expected x.y.z format.`);
2166
2149
  return `>=${minimumVersion} <${match[1]}.${Number(match[2]) + 1}.0`;
2167
2150
  }
2151
+ function getNextMinorVersion(version) {
2152
+ const match = EXACT_VERSION_RE.exec(version);
2153
+ if (!match) throw new Error(`Unsupported exact version "${version}". Expected x.y.z format.`);
2154
+ return `${match[1]}.${Number(match[2]) + 1}.0`;
2155
+ }
2168
2156
  function getPackageNameFromInstallSpec(spec) {
2169
2157
  const normalized = spec.trim();
2170
2158
  if (normalized.length === 0) throw new Error("Install spec must be non-empty.");
@@ -2216,8 +2204,11 @@ function resolveScaffoldInstallSpec(env = process.env) {
2216
2204
  const SUPPORTED_DEPENDENCY_VERSIONS = {
2217
2205
  convex: {
2218
2206
  exact: SUPPORTED_CONVEX_VERSION,
2207
+ minimumType: SUPPORTED_CONVEX_MIN_TYPE_VERSION,
2219
2208
  range: `^${SUPPORTED_CONVEX_VERSION}`,
2220
- minimum: getMinimumVersionRange(SUPPORTED_CONVEX_VERSION)
2209
+ minimum: `>=${SUPPORTED_CONVEX_MIN_VERSION}`,
2210
+ maximumExclusive: getNextMinorVersion(SUPPORTED_CONVEX_VERSION),
2211
+ peer: getMinorVersionPeerRange(SUPPORTED_CONVEX_MIN_VERSION, SUPPORTED_CONVEX_VERSION)
2221
2212
  },
2222
2213
  betterAuth: {
2223
2214
  exact: SUPPORTED_BETTER_AUTH_VERSION,
@@ -2276,20 +2267,31 @@ function compareMajorMinor(aMajor, aMinor, bMajor, bMinor) {
2276
2267
  if (aMajor !== bMajor) return aMajor - bMajor;
2277
2268
  return aMinor - bMinor;
2278
2269
  }
2279
- function isConcreteVersionSpecBelowMinimum(spec, minimum) {
2270
+ function isConcreteVersionSpecOutsideRange(spec, minimum, maximumExclusive) {
2280
2271
  const specMatch = VERSION_IN_SPEC_RE.exec(spec);
2281
2272
  const minimumMatch = VERSION_IN_SPEC_RE.exec(minimum);
2282
- if (!specMatch || !minimumMatch) return false;
2283
- return compareMajorMinor(Number(specMatch[1]), Number(specMatch[2]), Number(minimumMatch[1]), Number(minimumMatch[2])) < 0;
2273
+ const maximumMatch = VERSION_IN_SPEC_RE.exec(maximumExclusive);
2274
+ if (!specMatch || !minimumMatch || !maximumMatch) return false;
2275
+ const specMajor = Number(specMatch[1]);
2276
+ const specMinor = Number(specMatch[2]);
2277
+ const minimumMajor = Number(minimumMatch[1]);
2278
+ const minimumMinor = Number(minimumMatch[2]);
2279
+ const maximumMajor = Number(maximumMatch[1]);
2280
+ const maximumMinor = Number(maximumMatch[2]);
2281
+ return compareMajorMinor(specMajor, specMinor, minimumMajor, minimumMinor) < 0 || compareMajorMinor(specMajor, specMinor, maximumMajor, maximumMinor) >= 0;
2284
2282
  }
2285
- function isDeclaredVersionSpecBelowMinimum(spec, minimum) {
2283
+ function isDeclaredVersionSpecOutsideRange(spec, minimum, maximumExclusive) {
2286
2284
  const normalized = spec.trim();
2287
- if (PLAIN_VERSION_SPEC_RE.test(normalized)) return isConcreteVersionSpecBelowMinimum(normalized, minimum);
2285
+ if (PLAIN_VERSION_SPEC_RE.test(normalized)) return isConcreteVersionSpecOutsideRange(normalized, minimum, maximumExclusive);
2288
2286
  const minimumMatch = VERSION_IN_SPEC_RE.exec(minimum);
2289
- if (!minimumMatch) return false;
2287
+ const maximumMatch = VERSION_IN_SPEC_RE.exec(maximumExclusive);
2288
+ if (!minimumMatch || !maximumMatch) return false;
2290
2289
  const minimumMajor = Number(minimumMatch[1]);
2291
2290
  const minimumMinor = Number(minimumMatch[2]);
2291
+ const maximumMajor = Number(maximumMatch[1]);
2292
+ const maximumMinor = Number(maximumMatch[2]);
2292
2293
  for (const match of normalized.matchAll(UPPER_BOUND_RE)) if (compareMajorMinor(Number(match[1]), Number(match[2]), minimumMajor, minimumMinor) <= 0) return true;
2294
+ for (const match of normalized.matchAll(LOWER_BOUND_RE)) if (compareMajorMinor(Number(match[1]), Number(match[2]), maximumMajor, maximumMinor) >= 0) return true;
2293
2295
  return false;
2294
2296
  }
2295
2297
  function resolveSupportedDependencyWarnings(cwd = process.cwd()) {
@@ -2297,18 +2299,18 @@ function resolveSupportedDependencyWarnings(cwd = process.cwd()) {
2297
2299
  if (!packageJsonPath) return [];
2298
2300
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
2299
2301
  const installedConvexVersion = readInstalledDependencyVersion(packageJsonPath, "convex");
2300
- if (installedConvexVersion && isConcreteVersionSpecBelowMinimum(installedConvexVersion, SUPPORTED_DEPENDENCY_VERSIONS.convex.minimum)) return [{
2302
+ if (installedConvexVersion && isConcreteVersionSpecOutsideRange(installedConvexVersion, SUPPORTED_DEPENDENCY_VERSIONS.convex.minimum, SUPPORTED_DEPENDENCY_VERSIONS.convex.maximumExclusive)) return [{
2301
2303
  packageName: "convex",
2302
2304
  current: installedConvexVersion,
2303
- minimum: SUPPORTED_DEPENDENCY_VERSIONS.convex.minimum,
2305
+ supported: SUPPORTED_DEPENDENCY_VERSIONS.convex.peer,
2304
2306
  installSpec: PINNED_CONVEX_INSTALL_SPEC
2305
2307
  }];
2306
2308
  const convexVersion = readDependencyVersion(packageJson, "convex");
2307
- if (!convexVersion || !isDeclaredVersionSpecBelowMinimum(convexVersion, SUPPORTED_DEPENDENCY_VERSIONS.convex.minimum)) return [];
2309
+ if (!convexVersion || !isDeclaredVersionSpecOutsideRange(convexVersion, SUPPORTED_DEPENDENCY_VERSIONS.convex.minimum, SUPPORTED_DEPENDENCY_VERSIONS.convex.maximumExclusive)) return [];
2308
2310
  return [{
2309
2311
  packageName: "convex",
2310
2312
  current: convexVersion,
2311
- minimum: SUPPORTED_DEPENDENCY_VERSIONS.convex.minimum,
2313
+ supported: SUPPORTED_DEPENDENCY_VERSIONS.convex.peer,
2312
2314
  installSpec: PINNED_CONVEX_INSTALL_SPEC
2313
2315
  }];
2314
2316
  }
@@ -12047,6 +12049,10 @@ function normalizeStringList(values) {
12047
12049
  if (!Array.isArray(values)) return [];
12048
12050
  return [...new Set(values.filter((value) => typeof value === "string"))].sort();
12049
12051
  }
12052
+ function normalizeOrderedStringList(values) {
12053
+ if (!Array.isArray(values)) return [];
12054
+ return [...new Set(values.filter((value) => typeof value === "string"))];
12055
+ }
12050
12056
  function readOptionalCliFlagValue(args, flag) {
12051
12057
  for (let i = 0; i < args.length; i += 1) {
12052
12058
  const arg = args[i];
@@ -12062,24 +12068,6 @@ function readOptionalCliFlagValue(args, flag) {
12062
12068
  }
12063
12069
  }
12064
12070
  }
12065
- function resolveSchemaDefaultExport(schemaModule) {
12066
- const schemaValue = schemaModule.default !== void 0 ? schemaModule.default : schemaModule;
12067
- if (!schemaValue || typeof schemaValue !== "object") return null;
12068
- return schemaValue;
12069
- }
12070
- function collectSchemaTables(schemaValue) {
12071
- const allTables = /* @__PURE__ */ new Set();
12072
- const relations = getSchemaRelations(schemaValue);
12073
- if (relations && typeof relations === "object" && !Array.isArray(relations)) for (const relationConfig of Object.values(relations)) {
12074
- const table = relationConfig?.table;
12075
- if (table) allTables.add(table);
12076
- }
12077
- const tables = schemaValue.tables;
12078
- if (tables && typeof tables === "object" && !Array.isArray(tables)) {
12079
- for (const table of Object.values(tables)) if (table) allTables.add(table);
12080
- }
12081
- return [...allTables];
12082
- }
12083
12071
  function buildAggregateFingerprintPayload(tables) {
12084
12072
  return tables.map((table) => getTableConfig(table)).map((tableConfig) => ({
12085
12073
  tableName: tableConfig.name,
@@ -12091,18 +12079,60 @@ function buildAggregateFingerprintPayload(tables) {
12091
12079
  avgFields: normalizeStringList(index.avgFields),
12092
12080
  minFields: normalizeStringList(index.minFields),
12093
12081
  maxFields: normalizeStringList(index.maxFields)
12082
+ })).sort((a, b) => a.name.localeCompare(b.name)),
12083
+ rankIndexes: tableConfig.rankIndexes.map((index) => ({
12084
+ name: index.name,
12085
+ partitionFields: normalizeOrderedStringList(index.partitionFields),
12086
+ orderFields: (index.orderFields ?? []).map((field) => `${field.field}:${field.direction}`),
12087
+ sumField: index.sumField ?? ""
12094
12088
  })).sort((a, b) => a.name.localeCompare(b.name))
12095
12089
  })).sort((a, b) => a.tableName.localeCompare(b.tableName));
12096
12090
  }
12097
- async function computeAggregateIndexFingerprint(functionsDir) {
12091
+ async function loadBackendSchemaValue(functionsDir) {
12098
12092
  const schemaPath = join(functionsDir, "schema.ts");
12099
12093
  if (!fs.existsSync(schemaPath)) return null;
12100
12094
  const schemaModule = await createProjectJiti().import(schemaPath);
12101
12095
  if (!schemaModule || typeof schemaModule !== "object") return null;
12102
- const schemaValue = resolveSchemaDefaultExport(schemaModule);
12096
+ return resolveSchemaDefaultExport(schemaModule);
12097
+ }
12098
+ /**
12099
+ * Whether the deployed ORM can serve the aggregate procedures at all.
12100
+ *
12101
+ * `kitcn codegen` registers `aggregateCapability()` only for schemas that
12102
+ * declare an `aggregateIndex`/`rankIndex`, so calling `aggregateBackfill`
12103
+ * against a schema without one is a guaranteed error rather than a no-op.
12104
+ *
12105
+ * No schema file means no ORM and no aggregate procedures to call. A schema
12106
+ * that exists but fails to load is treated as using them, so a real backfill
12107
+ * is never skipped over a transient load error.
12108
+ */
12109
+ async function backendUsesAggregateIndexes() {
12110
+ try {
12111
+ const { functionsDir } = getConvexConfig();
12112
+ const schemaValue = await loadBackendSchemaValue(functionsDir);
12113
+ if (!schemaValue) return false;
12114
+ return schemaDeclaresAggregateIndexes(schemaValue);
12115
+ } catch {
12116
+ return true;
12117
+ }
12118
+ }
12119
+ /**
12120
+ * Whether the deployed ORM registered `migrationCapability()`. Codegen keys
12121
+ * that off the generated manifest, so the flows key off the same file.
12122
+ */
12123
+ function backendUsesMigrations() {
12124
+ try {
12125
+ const { functionsDir } = getConvexConfig();
12126
+ return fs.existsSync(join(functionsDir, "migrations", "manifest.ts"));
12127
+ } catch {
12128
+ return true;
12129
+ }
12130
+ }
12131
+ async function computeAggregateIndexFingerprint(functionsDir) {
12132
+ const schemaValue = await loadBackendSchemaValue(functionsDir);
12103
12133
  if (!schemaValue) return null;
12104
12134
  const tables = collectSchemaTables(schemaValue);
12105
- if (tables.length === 0) return null;
12135
+ if (tables.length === 0 || !schemaDeclaresAggregateIndexes(schemaValue)) return null;
12106
12136
  const payload = buildAggregateFingerprintPayload(tables);
12107
12137
  return createHash("sha256").update(JSON.stringify(payload)).digest("hex");
12108
12138
  }
@@ -13000,7 +13030,8 @@ async function runAggregateBackfillFlow(params) {
13000
13030
  const { execaFn, backendAdapter, backfillConfig, mode, targetArgs, env, signal, context } = params;
13001
13031
  if (signal?.aborted) return 0;
13002
13032
  if (backfillConfig.enabled === "off") return 0;
13003
- const kickoff = await runBackendFunction(execaFn, backendAdapter, "generated/server:aggregateBackfill", {
13033
+ if (!await backendUsesAggregateIndexes()) return 0;
13034
+ const kickoff = await runBackendFunction(execaFn, backendAdapter, "generated/aggregate:aggregateBackfill", {
13004
13035
  mode,
13005
13036
  batchSize: backfillConfig.batchSize
13006
13037
  }, targetArgs, {
@@ -13033,7 +13064,7 @@ async function runAggregateBackfillFlow(params) {
13033
13064
  const deadline = Date.now() + backfillConfig.timeoutMs;
13034
13065
  let lastProgress = "";
13035
13066
  while (!signal?.aborted) {
13036
- const statusResult = await runBackendFunction(execaFn, backendAdapter, "generated/server:aggregateBackfillStatus", {}, targetArgs, {
13067
+ const statusResult = await runBackendFunction(execaFn, backendAdapter, "generated/aggregate:aggregateBackfillStatus", {}, targetArgs, {
13037
13068
  echoOutput: false,
13038
13069
  env
13039
13070
  });
@@ -13067,7 +13098,7 @@ async function runAggregateBackfillFlow(params) {
13067
13098
  }
13068
13099
  async function runAggregatePruneFlow(params) {
13069
13100
  const { execaFn, backendAdapter, targetArgs, env } = params;
13070
- const result = await runBackendFunction(execaFn, backendAdapter, "generated/server:aggregateBackfill", { mode: "prune" }, targetArgs, {
13101
+ const result = await runBackendFunction(execaFn, backendAdapter, "generated/aggregate:aggregateBackfill", { mode: "prune" }, targetArgs, {
13071
13102
  echoOutput: false,
13072
13103
  env
13073
13104
  });
@@ -13178,6 +13209,7 @@ export const migration = defineMigration({
13178
13209
  async function runMigrationFlow(params) {
13179
13210
  const { execaFn, backendAdapter, migrationConfig, targetArgs, env, signal, context, direction, steps, to } = params;
13180
13211
  if (signal?.aborted || migrationConfig.enabled === "off") return 0;
13212
+ if (!backendUsesMigrations()) return 0;
13181
13213
  const kickoff = await runBackendFunction(execaFn, backendAdapter, "generated/server:migrationRun", {
13182
13214
  direction,
13183
13215
  batchSize: migrationConfig.batchSize,
@@ -15394,6 +15426,10 @@ const handleMigrateCommand = async (argv, deps = {}) => {
15394
15426
  to
15395
15427
  });
15396
15428
  }
15429
+ if (!backendUsesMigrations()) {
15430
+ logger.info("No migrations manifest. Run `kitcn migrate create <name>` to add one.");
15431
+ return 0;
15432
+ }
15397
15433
  if (migrateArgs.subcommand === "status") return (await runBackendFunction(execaFn, backendAdapter, "generated/server:migrationStatus", {}, targetArgs, { env: commandEnv })).exitCode;
15398
15434
  let runId;
15399
15435
  const cancelArgs = [];
@@ -15771,7 +15807,7 @@ function warnSupportedDependencyIssues(command) {
15771
15807
  const packageManager = detectPackageManager(process.cwd());
15772
15808
  for (const warning of resolveSupportedDependencyWarnings()) {
15773
15809
  const installCommand = formatDependencyInstallCommand(packageManager, [warning.installSpec]);
15774
- logger.warn(`⚠️ kitcn expects ${warning.packageName} ${warning.minimum}; found ${warning.current}. Run \`${installCommand}\` when you can.`);
15810
+ logger.warn(`⚠️ kitcn expects ${warning.packageName} ${warning.supported}; found ${warning.current}. Run \`${installCommand}\` when you can.`);
15775
15811
  }
15776
15812
  }
15777
15813
  const handlePassthroughCommand = async (argv, deps) => {
@@ -1,4 +1,4 @@
1
- import { r as omit } from "./upstream-BR6sBLg3.js";
1
+ import { r as omit } from "./upstream-BCgGZX6q.js";
2
2
  import { createAuthEndpoint, createAuthMiddleware, sessionMiddleware } from "better-auth/api";
3
3
  import { bearer } from "better-auth/plugins/bearer";
4
4
  import { jwt } from "better-auth/plugins/jwt";
@@ -1,4 +1,4 @@
1
- import { augmentBetterAuthTables, indexFields } from "./create-schema-BXrKE2YY.js";
1
+ import { augmentBetterAuthTables, indexFields } from "./create-schema-BRFjdgRr.js";
2
2
 
3
3
  //#region src/auth/create-schema-orm.ts
4
4
  const specialFields = (tables) => Object.fromEntries(Object.entries(tables).map(([key, table]) => {
@@ -1,5 +1,5 @@
1
- import { B as dateWireCodec, F as DATE_CODEC_TAG, G as identityTransformer, H as defaultCRPCTransformer, I as DataTransformer, L as DataTransformerOptions, P as CombinedDataTransformer, R as WireCodec, U as encodeWire, V as decodeWire, W as getTransformer, a as HttpErrorCode, c as HttpQueryKey, d as HttpRouteMap, f as InferHttpInput, g as isHttpClientError, h as buildHttpQueryPrefixKey, i as HttpClientFromRouter, l as HttpQueryPrefixKey, m as buildHttpQueryKey, n as HttpClient, o as HttpMutationKey, p as InferHttpOutput, r as HttpClientError, s as HttpProcedureCall, t as HTTP_DEFAULT_STALE_TIME, u as HttpRouteInfo, z as createTaggedTransformer } from "../http-types-DXOgaerG.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-BHR7ZKKD.js";
1
+ import { B as dateWireCodec, F as DATE_CODEC_TAG, G as identityTransformer, H as defaultCRPCTransformer, I as DataTransformer, L as DataTransformerOptions, P as CombinedDataTransformer, R as WireCodec, U as encodeWire, V as decodeWire, W as getTransformer, a as HttpErrorCode, c as HttpQueryKey, d as HttpRouteMap, f as InferHttpInput, g as isHttpClientError, h as buildHttpQueryPrefixKey, i as HttpClientFromRouter, l as HttpQueryPrefixKey, m as buildHttpQueryKey, n as HttpClient, o as HttpMutationKey, p as InferHttpOutput, r as HttpClientError, s as HttpProcedureCall, t as HTTP_DEFAULT_STALE_TIME, u as HttpRouteInfo, z as createTaggedTransformer } from "../http-types-90mapMP9.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-In-ZZOsd.js";
3
3
  import { FunctionArgs, FunctionReference } from "convex/server";
4
4
 
5
5
  //#region src/crpc/auth-error.d.ts
@@ -1,6 +1,6 @@
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-yZuBWo8v.js";
3
- import { a as buildSearchParams, c as HTTP_DEFAULT_STALE_TIME, d as buildHttpQueryPrefixKey, f as isHttpClientError, i as RESERVED_KEYS, l as HttpClientError, n as convexInfiniteQueryOptions, o as executeHttpRequest, r as convexQuery, s as replaceUrlParam, t as convexAction, u as buildHttpQueryKey } from "../query-options-CzRV4G4N.js";
1
+ import { a as isCRPCErrorCode, i as isCRPCError, n as defaultIsUnauthorized, r as isCRPCClientError, t as CRPCClientError } from "../error-CMLeCadS.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-D8wO-kEj.js";
3
+ import { a as buildSearchParams, c as HTTP_DEFAULT_STALE_TIME, d as buildHttpQueryPrefixKey, f as isHttpClientError, i as RESERVED_KEYS, l as HttpClientError, n as convexInfiniteQueryOptions, o as executeHttpRequest, r as convexQuery, s as replaceUrlParam, t as convexAction, u as buildHttpQueryKey } from "../query-options-DUiOj01a.js";
4
4
 
5
5
  //#region src/crpc/auth-error.ts
6
6
  /**
@@ -1,5 +1,5 @@
1
- import { i as pick, r as omit } from "./upstream-BR6sBLg3.js";
2
- import { t as addFieldsToValidator } from "./validators-C7LelqTN.js";
1
+ import { i as pick, r as omit } from "./upstream-BCgGZX6q.js";
2
+ import { t as addFieldsToValidator } from "./validators-CIoUYCqO.js";
3
3
 
4
4
  //#region src/internal/upstream/server/customFunctions.ts
5
5
  /**
@@ -0,0 +1,215 @@
1
+ import { A as integer, C as index, I as ConvexColumnBuilder, L as entityKind, M as custom, O as text, t as convexTable } from "./table-CX2lnX7e.js";
2
+ import { t as defineSchemaExtension } from "./extensions-Blzsyekm.js";
3
+ import { v } from "convex/values";
4
+
5
+ //#region src/orm/builders/boolean.ts
6
+ /**
7
+ * Boolean column builder class
8
+ * Compiles to v.boolean() or v.optional(v.boolean())
9
+ */
10
+ var ConvexBooleanBuilder = class extends ConvexColumnBuilder {
11
+ static [entityKind] = "ConvexBooleanBuilder";
12
+ constructor(name) {
13
+ super(name, "boolean", "ConvexBoolean");
14
+ }
15
+ /**
16
+ * Expose Convex validator for schema integration
17
+ */
18
+ get convexValidator() {
19
+ if (this.config.notNull) return v.boolean();
20
+ return v.optional(v.union(v.null(), v.boolean()));
21
+ }
22
+ /**
23
+ * Compile to Convex validator
24
+ * .notNull() → v.boolean()
25
+ * nullable → v.optional(v.boolean())
26
+ */
27
+ build() {
28
+ return this.convexValidator;
29
+ }
30
+ };
31
+ function boolean(name) {
32
+ return new ConvexBooleanBuilder(name ?? "");
33
+ }
34
+
35
+ //#endregion
36
+ //#region src/orm/migrations/schema.ts
37
+ const MIGRATION_STATE_TABLE = "migration_state";
38
+ const MIGRATION_RUN_TABLE = "migration_run";
39
+ const migrationStateTable = convexTable(MIGRATION_STATE_TABLE, {
40
+ migrationId: text().notNull(),
41
+ checksum: text().notNull(),
42
+ applied: boolean().notNull(),
43
+ status: text().notNull(),
44
+ direction: text(),
45
+ runId: text(),
46
+ cursor: text(),
47
+ processed: integer().notNull(),
48
+ startedAt: integer(),
49
+ updatedAt: integer().notNull(),
50
+ completedAt: integer(),
51
+ lastError: text(),
52
+ writeMode: text().notNull()
53
+ }, (t) => [index("by_migration_id").on(t.migrationId), index("by_status").on(t.status)]);
54
+ const migrationRunTable = convexTable(MIGRATION_RUN_TABLE, {
55
+ runId: text().notNull(),
56
+ direction: text().notNull(),
57
+ status: text().notNull(),
58
+ dryRun: boolean().notNull(),
59
+ allowDrift: boolean().notNull(),
60
+ migrationIds: custom(v.array(v.string())).notNull(),
61
+ currentIndex: integer().notNull(),
62
+ startedAt: integer().notNull(),
63
+ updatedAt: integer().notNull(),
64
+ completedAt: integer(),
65
+ cancelRequested: boolean().notNull(),
66
+ lastError: text()
67
+ }, (t) => [index("by_run_id").on(t.runId), index("by_status").on(t.status)]);
68
+ const migrationStorageTables = {
69
+ [MIGRATION_STATE_TABLE]: migrationStateTable,
70
+ [MIGRATION_RUN_TABLE]: migrationRunTable
71
+ };
72
+ const MIGRATION_STORAGE_TABLE_NAMES = new Set([MIGRATION_STATE_TABLE, MIGRATION_RUN_TABLE]);
73
+ function migrationExtension() {
74
+ return defineSchemaExtension("migration", migrationStorageTables);
75
+ }
76
+ function injectMigrationStorageTables(schema) {
77
+ const merged = { ...schema };
78
+ for (const [tableName, tableDef] of Object.entries(migrationStorageTables)) {
79
+ if (tableName in schema && schema[tableName] !== tableDef) throw new Error(`defineSchema cannot inject internal table '${tableName}' because the name is already in use.`);
80
+ merged[tableName] = tableDef;
81
+ }
82
+ return merged;
83
+ }
84
+
85
+ //#endregion
86
+ //#region src/orm/migrations/definitions.ts
87
+ const MIGRATION_ID_RE = /^[a-zA-Z0-9_:-]+$/;
88
+ const FUNCTION_SOURCE_WHITESPACE_RE = /\s+/g;
89
+ const FUNCTION_SOURCE_PUNCTUATION_SPACE_RE = /\s*([{}();,:])\s*/g;
90
+ function defineMigration(migration) {
91
+ validateMigrationId(migration.id);
92
+ validateMigrationStep("up", migration.up);
93
+ if (migration.down) validateMigrationStep("down", migration.down);
94
+ return migration;
95
+ }
96
+ function defineMigrationSet(migrations) {
97
+ const normalized = [...migrations].map((migration) => {
98
+ const defined = defineMigration(migration);
99
+ return {
100
+ ...defined,
101
+ checksum: defined.checksum ?? computeMigrationChecksum(defined)
102
+ };
103
+ });
104
+ normalized.sort((a, b) => a.id.localeCompare(b.id));
105
+ const byId = {};
106
+ for (const migration of normalized) {
107
+ if (byId[migration.id]) throw new Error(`defineMigrationSet received duplicate migration id '${migration.id}'.`);
108
+ byId[migration.id] = migration;
109
+ }
110
+ return {
111
+ migrations: normalized,
112
+ ids: normalized.map((migration) => migration.id),
113
+ byId
114
+ };
115
+ }
116
+ function detectMigrationDrift(params) {
117
+ const { migrationSet, appliedState } = params;
118
+ const issues = [];
119
+ for (const [migrationId, state] of Object.entries(appliedState)) {
120
+ if (!state.applied) continue;
121
+ const migration = migrationSet.byId[migrationId];
122
+ if (!migration) {
123
+ issues.push({
124
+ kind: "missing_from_manifest",
125
+ migrationId,
126
+ message: `Applied migration '${migrationId}' is missing from the current migration manifest.`
127
+ });
128
+ continue;
129
+ }
130
+ if (state.checksum && state.checksum !== migration.checksum) issues.push({
131
+ kind: "checksum_mismatch",
132
+ migrationId,
133
+ expectedChecksum: migration.checksum,
134
+ actualChecksum: state.checksum,
135
+ message: `Applied migration '${migrationId}' checksum drift detected.`
136
+ });
137
+ }
138
+ return issues;
139
+ }
140
+ function buildMigrationPlan(params) {
141
+ const { direction, migrationSet, appliedState, steps, to } = params;
142
+ if (direction === "up") return {
143
+ direction,
144
+ migrations: migrationSet.migrations.filter((migration) => !appliedState[migration.id]?.applied)
145
+ };
146
+ if (steps !== void 0 && to !== void 0) throw new Error("Use either down steps or down to, not both.");
147
+ const appliedInOrder = migrationSet.migrations.filter((migration) => appliedState[migration.id]?.applied);
148
+ const ensureDownSteps = (selected) => {
149
+ const missingDown = selected.find((migration) => !migration.down);
150
+ if (missingDown) throw new Error(`Cannot execute down migration for '${missingDown.id}': missing down migration handler.`);
151
+ return selected;
152
+ };
153
+ if (to) {
154
+ const targetIndex = migrationSet.ids.indexOf(to);
155
+ if (targetIndex === -1) throw new Error(`Unknown migration id '${to}' for down --to.`);
156
+ return {
157
+ direction,
158
+ migrations: ensureDownSteps(appliedInOrder.filter((migration) => {
159
+ return migrationSet.ids.indexOf(migration.id) > targetIndex;
160
+ })).reverse()
161
+ };
162
+ }
163
+ const resolvedSteps = steps ?? 1;
164
+ if (!Number.isInteger(resolvedSteps) || resolvedSteps < 1) throw new Error("Down steps must be a positive integer.");
165
+ return {
166
+ direction,
167
+ migrations: ensureDownSteps(appliedInOrder.slice(-resolvedSteps).reverse())
168
+ };
169
+ }
170
+ function validateMigrationId(id) {
171
+ if (!id || typeof id !== "string") throw new Error("Migration id must be a non-empty string.");
172
+ if (!MIGRATION_ID_RE.test(id)) throw new Error(`Migration id '${id}' is invalid. Use alphanumeric characters, '_' ':' or '-'.`);
173
+ }
174
+ function validateMigrationStep(direction, step) {
175
+ if (!step || typeof step !== "object") throw new Error(`Migration ${direction} step must be an object.`);
176
+ if (!step.table || typeof step.table !== "string") throw new Error(`Migration ${direction} step.table must be a string.`);
177
+ if (typeof step.migrateOne !== "function") throw new Error(`Migration ${direction} step.migrateOne must be a function.`);
178
+ if (step.batchSize !== void 0 && (!Number.isInteger(step.batchSize) || step.batchSize < 1)) throw new Error(`Migration ${direction} step.batchSize must be a positive integer.`);
179
+ if (step.writeMode !== void 0 && step.writeMode !== "safe_bypass" && step.writeMode !== "normal") throw new Error(`Migration ${direction} step.writeMode must be 'safe_bypass' or 'normal'.`);
180
+ }
181
+ function computeMigrationChecksum(migration) {
182
+ return simpleStableHash(JSON.stringify({
183
+ id: migration.id,
184
+ name: migration.name ?? null,
185
+ description: migration.description ?? null,
186
+ up: serializeStep(migration.up),
187
+ down: migration.down ? serializeStep(migration.down) : null
188
+ }));
189
+ }
190
+ function serializeStep(step) {
191
+ return {
192
+ table: step.table,
193
+ batchSize: step.batchSize ?? null,
194
+ writeMode: step.writeMode ?? "safe_bypass",
195
+ source: normalizeFunctionSource(step.migrateOne)
196
+ };
197
+ }
198
+ function normalizeFunctionSource(fn) {
199
+ return fn.toString().replace(FUNCTION_SOURCE_WHITESPACE_RE, " ").replace(FUNCTION_SOURCE_PUNCTUATION_SPACE_RE, "$1").trim();
200
+ }
201
+ function simpleStableHash(value) {
202
+ let hashA = 2166136261;
203
+ let hashB = 16777619;
204
+ for (let i = 0; i < value.length; i += 1) {
205
+ const code = value.charCodeAt(i);
206
+ hashA ^= code;
207
+ hashA = Math.imul(hashA, 16777619);
208
+ hashB ^= code + i;
209
+ hashB = Math.imul(hashB, 2246822507);
210
+ }
211
+ return `m_${(hashA >>> 0).toString(16).padStart(8, "0")}${(hashB >>> 0).toString(16).padStart(8, "0")}`;
212
+ }
213
+
214
+ //#endregion
215
+ export { MIGRATION_RUN_TABLE as a, injectMigrationStorageTables as c, boolean as d, detectMigrationDrift as i, migrationExtension as l, defineMigration as n, MIGRATION_STATE_TABLE as o, defineMigrationSet as r, MIGRATION_STORAGE_TABLE_NAMES as s, buildMigrationPlan as t, migrationStorageTables as u };
@@ -0,0 +1,55 @@
1
+ import { d as OrmSchemaExtensionTriggers, l as OrmSchemaExtensionRelations } from "./table-CX2lnX7e.js";
2
+
3
+ //#region src/orm/extensions.ts
4
+ function defineChainMethod(target, key, value) {
5
+ Object.defineProperty(target, key, {
6
+ value,
7
+ enumerable: false,
8
+ configurable: true
9
+ });
10
+ }
11
+ function createSchemaExtensionChain(state, capabilities) {
12
+ const extension = {
13
+ key: state.key,
14
+ tables: state.tables
15
+ };
16
+ Object.defineProperty(extension, OrmSchemaExtensionRelations, {
17
+ value: state.relations,
18
+ enumerable: false,
19
+ configurable: true
20
+ });
21
+ Object.defineProperty(extension, OrmSchemaExtensionTriggers, {
22
+ value: state.triggers,
23
+ enumerable: false,
24
+ configurable: true
25
+ });
26
+ if (capabilities.canRelations) defineChainMethod(extension, "relations", (relations) => createSchemaExtensionChain({
27
+ ...state,
28
+ relations
29
+ }, {
30
+ canRelations: false,
31
+ canTriggers: true
32
+ }));
33
+ if (capabilities.canTriggers) defineChainMethod(extension, "triggers", (triggers) => createSchemaExtensionChain({
34
+ ...state,
35
+ triggers
36
+ }, {
37
+ canRelations: false,
38
+ canTriggers: false
39
+ }));
40
+ return extension;
41
+ }
42
+ function defineSchemaExtension(key, tables) {
43
+ return createSchemaExtensionChain({
44
+ key,
45
+ tables,
46
+ relations: void 0,
47
+ triggers: void 0
48
+ }, {
49
+ canRelations: true,
50
+ canTriggers: true
51
+ });
52
+ }
53
+
54
+ //#endregion
55
+ export { defineSchemaExtension as t };