kitcn 0.16.1 → 0.17.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 (38) hide show
  1. package/dist/aggregate/index.d.ts +1 -1
  2. package/dist/auth/client/index.js +1 -1
  3. package/dist/auth/index.js +19 -21
  4. package/dist/auth/nextjs/index.d.ts +1 -1
  5. package/dist/auth/nextjs/index.js +4 -4
  6. package/dist/{auth-store-ssZDPa37.js → auth-store-BnGZxmnY.js} +4 -1
  7. package/dist/{backend-core-DqPydYyx.mjs → backend-core-KwJ5FZgj.mjs} +214 -169
  8. package/dist/{builder-DBgto1yn.js → builder-Dwy6D2QA.js} +261 -166
  9. package/dist/{caller-factory-NEfgD5E0.js → caller-factory-DHywSoGZ.js} +7 -5
  10. package/dist/cli.mjs +14 -7
  11. package/dist/crpc/index.js +1 -127
  12. package/dist/{middleware-Bg-PdtrI.js → middleware-qzHEHaDy.js} +1 -1
  13. package/dist/orm/index.d.ts +1 -1
  14. package/dist/orm/index.js +335 -106
  15. package/dist/plugins/index.js +1 -1
  16. package/dist/{procedure-caller-9m6NBxQu.js → procedure-caller-JB9kjYsy.js} +1 -1
  17. package/dist/{procedure-name-Cy1AxayA.d.ts → procedure-name-exVcmr_p.d.ts} +28 -3
  18. package/dist/{query-context-B47_3n97.js → query-context-C90vNlc9.js} +105 -22
  19. package/dist/query-options-C_eBSIXG.js +247 -0
  20. package/dist/ratelimit/index.d.ts +26 -6
  21. package/dist/ratelimit/index.js +427 -100
  22. package/dist/ratelimit/react/index.d.ts +14 -0
  23. package/dist/ratelimit/react/index.js +149 -16
  24. package/dist/react/index.d.ts +3 -1
  25. package/dist/react/index.js +48 -15
  26. package/dist/rsc/index.js +22 -33
  27. package/dist/server/index.d.ts +1 -1
  28. package/dist/server/index.js +3 -3
  29. package/dist/solid/index.js +19 -5
  30. package/dist/watcher.mjs +2 -2
  31. package/dist/{where-clause-compiler-C8UKgzTO.d.ts → where-clause-compiler-BRhLW1dp.d.ts} +24 -0
  32. package/package.json +1 -1
  33. package/skills/kitcn/SKILL.md +1 -0
  34. package/skills/kitcn/references/features/create-plugins.md +1 -1
  35. package/skills/kitcn/references/features/orm.md +11 -1
  36. package/skills/kitcn/references/features/ratelimit.md +105 -0
  37. package/skills/kitcn/references/setup/server.md +1 -1
  38. package/dist/query-options-C96zLANM.js +0 -121
@@ -3931,6 +3931,14 @@ async function runAnalyze(argv) {
3931
3931
 
3932
3932
  //#endregion
3933
3933
  //#region src/shared/meta-utils.ts
3934
+ /**
3935
+ * Suffix of a parse snapshot — a mirror of a Convex module that kitcn builds
3936
+ * predating in-memory evaluation could strand in a project. Codegen writes no
3937
+ * snapshot, so this exists only so readers of the Convex functions directory
3938
+ * skip a stranded file rather than parse it as a real module. Nothing deletes
3939
+ * one: kitcn cannot prove it owns a file it did not write.
3940
+ */
3941
+ const PARSE_SNAPSHOT_SUFFIX = ".kitcn-parse.ts";
3934
3942
  /** Files to exclude from meta generation */
3935
3943
  const EXCLUDED_FILES = new Set([
3936
3944
  "schema.ts",
@@ -3949,6 +3957,7 @@ const DIRECT_CODEGEN_META_CAPTURE_REGEX = /\b_crpc(?:Meta|HttpRoute)\b/;
3949
3957
  * Filters out private files/directories (prefixed with _) and config files.
3950
3958
  */
3951
3959
  function isValidConvexFile(file) {
3960
+ if (file.endsWith(PARSE_SNAPSHOT_SUFFIX)) return false;
3952
3961
  if (file.endsWith(".runtime.ts")) return false;
3953
3962
  if (file.endsWith(".test.ts")) return false;
3954
3963
  if (file.endsWith(".spec.ts")) return false;
@@ -4789,12 +4798,21 @@ export function defineMigration(
4789
4798
  }
4790
4799
  `;
4791
4800
  }
4801
+ function renderRuntimeApiTypesImport(entries, importPath) {
4802
+ const specifiers = [];
4803
+ if (entries.some((entry) => !entry.internal)) specifiers.push("api as generatedApi");
4804
+ if (entries.some((entry) => entry.internal)) specifiers.push("internal as generatedInternal");
4805
+ if (specifiers.length === 0) return "";
4806
+ if (specifiers.length === 1) return `import type { ${specifiers[0]} } from '${importPath}';\n`;
4807
+ return `import type {\n${specifiers.map((specifier) => ` ${specifier},\n`).join("")}} from '${importPath}';\n`;
4808
+ }
4792
4809
  function emitGeneratedModuleRuntimeFile(outputFile, functionsDir, moduleName, procedureEntries, runtimeExportNames) {
4793
4810
  const { callerExportName, handlerExportName } = runtimeExportNames?.get(moduleName) ?? getModuleRuntimeExportNames(moduleName);
4794
4811
  const useGeneratedApiTypes = moduleUsesOwnGeneratedRuntime(functionsDir, moduleName);
4795
4812
  const runtimeApiTypesImportPath = useGeneratedApiTypes ? getRuntimeApiTypesImportPath(outputFile, functionsDir) : null;
4796
4813
  const generatedServerImportPath = getGeneratedServerImportPath(outputFile, functionsDir);
4797
4814
  const { callerEntries, handlerEntries } = partitionRuntimeEntriesForEmission(procedureEntries);
4815
+ const runtimeApiTypesImport = runtimeApiTypesImportPath ? renderRuntimeApiTypesImport(callerEntries, runtimeApiTypesImportPath) : "";
4798
4816
  const callerRegistryLines = emitProcedureRegistryEntries(callerEntries, outputFile, functionsDir, moduleName, useGeneratedApiTypes);
4799
4817
  const callerRegistryBody = callerRegistryLines.length > 0 ? `\n${callerRegistryLines.join("\n")}\n` : "\n";
4800
4818
  const hasHandlerRegistry = handlerEntries.length > 0;
@@ -4843,11 +4861,7 @@ import {
4843
4861
  typedProcedureResolver,
4844
4862
  type GeneratedRegistryCallerForContext,${hasHandlerRegistry ? "\n type GeneratedRegistryHandlerForContext," : ""}
4845
4863
  } from 'kitcn/server';
4846
- ${runtimeApiTypesImportPath ? `import type {
4847
- api as generatedApi,
4848
- internal as generatedInternal,
4849
- } from '${runtimeApiTypesImportPath}';
4850
- ` : ""}import type { ActionCtx, MutationCtx, QueryCtx } from '${generatedServerImportPath}';
4864
+ ${runtimeApiTypesImport}import type { ActionCtx, MutationCtx, QueryCtx } from '${generatedServerImportPath}';
4851
4865
  import type { OrmTriggerContext } from 'kitcn/orm';
4852
4866
 
4853
4867
  const procedureRegistry = {${callerRegistryBody}} as const;
@@ -5048,19 +5062,17 @@ function isCRPCHttpRouter(value) {
5048
5062
  async function parseModuleRuntime(filePath, jitiInstance) {
5049
5063
  const source = fs.readFileSync(filePath, "utf8");
5050
5064
  const rewrittenSource = source.replaceAll(/from\s+(['"])kitcn\/server\1/g, `from ${JSON.stringify(normalizeImportPath(getProjectServerParserShimPath()))}`);
5051
- const importPath = rewrittenSource === source ? filePath : (() => {
5052
- const tempFilePath = `${filePath}.kitcn-parse.ts`;
5053
- fs.writeFileSync(tempFilePath, rewrittenSource, "utf8");
5054
- return tempFilePath;
5055
- })();
5056
5065
  const result = {};
5057
5066
  const httpRoutes = {};
5058
5067
  const procedures = [];
5059
5068
  const isHttp = filePath.endsWith("http.ts");
5060
- const module = await jitiInstance.import(importPath);
5069
+ const module = rewrittenSource === source ? await jitiInstance.import(filePath) : await jitiInstance.evalModule(rewrittenSource, {
5070
+ async: true,
5071
+ ext: ".ts",
5072
+ filename: filePath
5073
+ });
5061
5074
  if (!module || typeof module !== "object") {
5062
5075
  if (isHttp) logger.error(" http.ts: module is empty or not an object");
5063
- if (importPath !== filePath) fs.rmSync(importPath, { force: true });
5064
5076
  return {
5065
5077
  meta: null,
5066
5078
  httpRoutes: {},
@@ -5095,7 +5107,6 @@ async function parseModuleRuntime(filePath, jitiInstance) {
5095
5107
  };
5096
5108
  }
5097
5109
  }
5098
- if (importPath !== filePath) fs.rmSync(importPath, { force: true });
5099
5110
  return {
5100
5111
  meta: Object.keys(result).length > 0 ? result : null,
5101
5112
  httpRoutes,
@@ -6939,6 +6950,92 @@ const normalizeLockfileScaffoldPath = (value) => {
6939
6950
  return normalized;
6940
6951
  };
6941
6952
 
6953
+ //#endregion
6954
+ //#region src/cli/utils/typescript-runtime.ts
6955
+ const require$1 = createRequire(import.meta.url);
6956
+ let cachedTypeScript = null;
6957
+ const loadTypeScript = () => {
6958
+ if (cachedTypeScript) return cachedTypeScript;
6959
+ const loaded = require$1("typescript");
6960
+ const resolved = "default" in loaded && loaded.default ? loaded.default : loaded;
6961
+ cachedTypeScript = resolved;
6962
+ return resolved;
6963
+ };
6964
+ const createTypeScriptProxy = () => new Proxy({}, { get(_target, property) {
6965
+ return loadTypeScript()[property];
6966
+ } });
6967
+
6968
+ //#endregion
6969
+ //#region src/cli/registry/schema-chain.ts
6970
+ const ts$3 = createTypeScriptProxy();
6971
+ const parse$2 = (source) => ts$3.createSourceFile("schema.ts", source, ts$3.ScriptTarget.Latest, true, ts$3.ScriptKind.TS);
6972
+ const isDefineSchemaCall = (node) => {
6973
+ if (!ts$3.isCallExpression(node)) return false;
6974
+ if (ts$3.isIdentifier(node.expression)) return node.expression.text === "defineSchema";
6975
+ return ts$3.isPropertyAccessExpression(node.expression) && node.expression.name.text === "defineSchema";
6976
+ };
6977
+ const findDefineSchemaCall = (sourceFile) => {
6978
+ let found = null;
6979
+ const visit = (node) => {
6980
+ if (found) return;
6981
+ if (isDefineSchemaCall(node)) {
6982
+ found = node;
6983
+ return;
6984
+ }
6985
+ ts$3.forEachChild(node, visit);
6986
+ };
6987
+ visit(sourceFile);
6988
+ return found;
6989
+ };
6990
+ /**
6991
+ * Resolve the real `defineSchema(...)` call and the methods chained onto it.
6992
+ *
6993
+ * Locating the call through the TypeScript AST is what keeps registration out
6994
+ * of comments and string literals that merely mention `defineSchema(`.
6995
+ */
6996
+ const findDefineSchemaChain = (source) => {
6997
+ const sourceFile = parse$2(source);
6998
+ const defineSchemaCall = findDefineSchemaCall(sourceFile);
6999
+ if (!defineSchemaCall) return null;
7000
+ const calls = [];
7001
+ let current = defineSchemaCall;
7002
+ while (current.parent && ts$3.isPropertyAccessExpression(current.parent) && current.parent.expression === current && current.parent.parent && ts$3.isCallExpression(current.parent.parent) && current.parent.parent.expression === current.parent) {
7003
+ const propertyAccess = current.parent;
7004
+ const call = current.parent.parent;
7005
+ const dotToken = propertyAccess.getChildren(sourceFile).find((child) => child.kind === ts$3.SyntaxKind.DotToken);
7006
+ if (!dotToken) throw new Error("Schema chain property access is missing its dot token.");
7007
+ calls.push({
7008
+ closeParenIndex: call.end - 1,
7009
+ dotIndex: dotToken.getStart(sourceFile),
7010
+ end: call.end,
7011
+ name: propertyAccess.name.text
7012
+ });
7013
+ current = call;
7014
+ }
7015
+ return {
7016
+ calls,
7017
+ defineSchemaEnd: defineSchemaCall.end
7018
+ };
7019
+ };
7020
+ /**
7021
+ * Whether `source` really calls `name()` somewhere, ignoring comments and
7022
+ * string literals.
7023
+ */
7024
+ const hasCallExpression = (source, name) => {
7025
+ const sourceFile = parse$2(source);
7026
+ let found = false;
7027
+ const visit = (node) => {
7028
+ if (found) return;
7029
+ if (ts$3.isCallExpression(node) && ts$3.isIdentifier(node.expression) && node.expression.text === name) {
7030
+ found = true;
7031
+ return;
7032
+ }
7033
+ ts$3.forEachChild(node, visit);
7034
+ };
7035
+ visit(sourceFile);
7036
+ return found;
7037
+ };
7038
+
6942
7039
  //#endregion
6943
7040
  //#region src/cli/registry/state.ts
6944
7041
  const getPluginLockfilePath = (functionsDir) => join(functionsDir, "plugins.lock.json");
@@ -7080,7 +7177,6 @@ const READ_OPTIONAL_RUNTIME_ENV_PROPERTY_RE = /\breadOptionalRuntimeEnv\s*:/m;
7080
7177
  const READ_OPTIONAL_RUNTIME_ENV_RE = /(\s*readOptionalRuntimeEnv\s*:\s*\[)([\s\S]*?)(\]\s*,?)/m;
7081
7178
  const LEADING_WHITESPACE_RE = /^\s*/;
7082
7179
  const STRING_LITERAL_ARRAY_ENTRY_RE = /^(['"])([^'"]+)\1$/;
7083
- const WHITESPACE_RE$2 = /\s/;
7084
7180
  const findMatchingObjectBraceIndex$1 = (source, openIndex) => {
7085
7181
  let depth = 0;
7086
7182
  let quote;
@@ -7390,79 +7486,28 @@ const getPlannedFileContent = (files, absolutePath) => {
7390
7486
  const normalizedPath = normalizePath$1(relative(process.cwd(), absolutePath));
7391
7487
  return files?.find((file) => file.path === normalizedPath)?.content;
7392
7488
  };
7393
- const skipWhitespace$2 = (source, start) => {
7394
- let index = start;
7395
- while (index < source.length && WHITESPACE_RE$2.test(source[index] ?? "")) index += 1;
7396
- return index;
7397
- };
7398
- const findBalancedParenEnd$1 = (source, openParenIndex) => {
7399
- let depth = 0;
7400
- for (let index = openParenIndex; index < source.length; index += 1) {
7401
- const char = source[index];
7402
- if (char === "(") {
7403
- depth += 1;
7404
- continue;
7405
- }
7406
- if (char !== ")") continue;
7407
- depth -= 1;
7408
- if (depth === 0) return index;
7409
- }
7410
- return -1;
7411
- };
7412
7489
  const findSchemaExtensionInsertIndex = (source) => {
7413
- const defineSchemaIndex = source.indexOf("defineSchema(");
7414
- if (defineSchemaIndex < 0) return {
7490
+ const chain = findDefineSchemaChain(source);
7491
+ if (!chain) return {
7415
7492
  closeParenIndex: -1,
7416
7493
  hasExtend: false,
7417
7494
  insertIndex: -1
7418
7495
  };
7419
- const defineSchemaOpenParenIndex = source.indexOf("(", defineSchemaIndex);
7420
- if (defineSchemaOpenParenIndex < 0) return {
7496
+ const firstCall = chain.calls[0];
7497
+ if (!firstCall) return {
7421
7498
  closeParenIndex: -1,
7422
7499
  hasExtend: false,
7423
- insertIndex: -1
7500
+ insertIndex: chain.defineSchemaEnd
7424
7501
  };
7425
- const defineSchemaCloseParenIndex = findBalancedParenEnd$1(source, defineSchemaOpenParenIndex);
7426
- if (defineSchemaCloseParenIndex < 0) return {
7427
- closeParenIndex: -1,
7428
- hasExtend: false,
7429
- insertIndex: -1
7502
+ if (firstCall.name === "extend") return {
7503
+ closeParenIndex: firstCall.closeParenIndex,
7504
+ hasExtend: true,
7505
+ insertIndex: firstCall.closeParenIndex
7430
7506
  };
7431
- const cursor = defineSchemaCloseParenIndex + 1;
7432
- while (cursor < source.length) {
7433
- const nextSegmentIndex = skipWhitespace$2(source, cursor);
7434
- if (source.startsWith(".relations(", nextSegmentIndex) || source.startsWith(".triggers(", nextSegmentIndex)) return {
7435
- closeParenIndex: -1,
7436
- hasExtend: false,
7437
- insertIndex: nextSegmentIndex
7438
- };
7439
- if (!source.startsWith(".extend(", nextSegmentIndex)) return {
7440
- closeParenIndex: -1,
7441
- hasExtend: false,
7442
- insertIndex: nextSegmentIndex
7443
- };
7444
- const extendOpenParenIndex = source.indexOf("(", nextSegmentIndex);
7445
- if (extendOpenParenIndex < 0) return {
7446
- closeParenIndex: -1,
7447
- hasExtend: false,
7448
- insertIndex: -1
7449
- };
7450
- const extendCloseParenIndex = findBalancedParenEnd$1(source, extendOpenParenIndex);
7451
- if (extendCloseParenIndex < 0) return {
7452
- closeParenIndex: -1,
7453
- hasExtend: false,
7454
- insertIndex: -1
7455
- };
7456
- return {
7457
- closeParenIndex: extendCloseParenIndex,
7458
- hasExtend: true,
7459
- insertIndex: extendCloseParenIndex
7460
- };
7461
- }
7462
7507
  return {
7463
7508
  closeParenIndex: -1,
7464
7509
  hasExtend: false,
7465
- insertIndex: cursor
7510
+ insertIndex: firstCall.dotIndex
7466
7511
  };
7467
7512
  };
7468
7513
  const buildSchemaRegistrationPlanFile = (functionsDir, descriptor, roots, bootstrapFiles) => {
@@ -7473,7 +7518,7 @@ const buildSchemaRegistrationPlanFile = (functionsDir, descriptor, roots, bootst
7473
7518
  const pluginFactory = schemaRegistration.importName;
7474
7519
  const pluginImportPath = resolveRelativeImportPath(schemaPath, join(schemaRegistration.target === "lib" ? roots.libRootDir : roots.functionsRootDir, schemaRegistration.path));
7475
7520
  let source = bootstrappedSchemaSource ?? fs.readFileSync(schemaPath, "utf8");
7476
- if (!source.includes(`${pluginFactory}()`)) {
7521
+ if (!hasCallExpression(source, pluginFactory)) {
7477
7522
  if (!new RegExp(`import\\s+\\{[^}]*\\b${pluginFactory}\\b[^}]*\\}\\s+from\\s+['"]${pluginImportPath}['"];?`).test(source)) source = `import { ${pluginFactory} } from '${pluginImportPath}';\n${source}`;
7478
7523
  const extensionTarget = findSchemaExtensionInsertIndex(source);
7479
7524
  if (extensionTarget.hasExtend && extensionTarget.closeParenIndex >= 0) source = `${source.slice(0, extensionTarget.closeParenIndex)}, ${pluginFactory}()${source.slice(extensionTarget.closeParenIndex)}`;
@@ -7654,27 +7699,11 @@ const buildPluginInstallPlan = async (params) => {
7654
7699
  };
7655
7700
  };
7656
7701
 
7657
- //#endregion
7658
- //#region src/cli/utils/typescript-runtime.ts
7659
- const require$1 = createRequire(import.meta.url);
7660
- let cachedTypeScript = null;
7661
- const loadTypeScript = () => {
7662
- if (cachedTypeScript) return cachedTypeScript;
7663
- const loaded = require$1("typescript");
7664
- const resolved = "default" in loaded && loaded.default ? loaded.default : loaded;
7665
- cachedTypeScript = resolved;
7666
- return resolved;
7667
- };
7668
- const createTypeScriptProxy = () => new Proxy({}, { get(_target, property) {
7669
- return loadTypeScript()[property];
7670
- } });
7671
-
7672
7702
  //#endregion
7673
7703
  //#region src/cli/registry/schema-ownership.ts
7674
7704
  const OBJECT_ENTRY_INDENT = " ";
7675
7705
  const LEADING_INDENT_RE = /^[ \t]*/;
7676
7706
  const LEGACY_MANAGED_COMMENT_RE = /^[ \t]*\/\* kitcn-managed [^*]+ \*\/\n?/gm;
7677
- const WHITESPACE_RE$1 = /\s/;
7678
7707
  const ts$2 = createTypeScriptProxy();
7679
7708
  let printer = null;
7680
7709
  const getPrinter = () => {
@@ -7920,13 +7949,15 @@ const mergeIndexEntries = (params) => {
7920
7949
  const targetParamName = params.existingInfo.indexParamName ?? params.existingInfo.varName ?? params.desiredInfo.indexParamName;
7921
7950
  const desiredParamName = params.desiredInfo.indexParamName ?? params.desiredInfo.varName;
7922
7951
  const desiredEntries = params.desiredInfo.indexEntries;
7952
+ const unparsedThirdArgText = params.existingInfo.thirdArgText && !params.existingInfo.indexEntries ? params.existingInfo.thirdArgText : null;
7923
7953
  if (!desiredEntries || desiredEntries.length === 0) return {
7924
7954
  changed: false,
7925
7955
  entries: params.existingInfo.indexEntries?.map((entry) => entry.getText(params.existingInfo.sourceFile)),
7926
7956
  indexParamName: targetParamName,
7927
- requiresIndexArg: Boolean(params.existingInfo.thirdArgText)
7957
+ requiresIndexArg: Boolean(params.existingInfo.thirdArgText),
7958
+ verbatimIndexArgText: unparsedThirdArgText
7928
7959
  };
7929
- if (params.existingInfo.thirdArgText && !params.existingInfo.indexEntries) throw new Error(`Schema patch conflict in ${params.displayPath}: ${params.pluginKey} indexes for table "${params.tableKey}" could not be merged into the existing schema callback.`);
7960
+ if (unparsedThirdArgText) throw new Error(`Schema patch conflict in ${params.displayPath}: ${params.pluginKey} indexes for table "${params.tableKey}" could not be merged into the existing schema callback.`);
7930
7961
  const existingEntries = params.existingInfo.indexEntries ?? [];
7931
7962
  const existingMap = new Map(existingEntries.map((entry) => [getIndexIdentity(entry, params.existingInfo.sourceFile), entry]));
7932
7963
  const nextEntries = existingEntries.map((entry) => entry.getText(params.existingInfo.sourceFile));
@@ -7946,13 +7977,14 @@ const mergeIndexEntries = (params) => {
7946
7977
  changed,
7947
7978
  entries: nextEntries,
7948
7979
  indexParamName: targetParamName,
7949
- requiresIndexArg: Boolean(params.existingInfo.thirdArgText ?? nextEntries.length > 0)
7980
+ requiresIndexArg: Boolean(params.existingInfo.thirdArgText ?? nextEntries.length > 0),
7981
+ verbatimIndexArgText: null
7950
7982
  };
7951
7983
  };
7952
7984
  const renderTableStatement = (params) => {
7953
7985
  const fieldsText = renderObjectLiteral(" ", params.fieldEntries.map(ensureTrailingComma));
7954
7986
  const indexEntries = params.indexEntries ?? [];
7955
- const indexBlock = indexEntries.length > 0 ? `,\n (${params.indexParamName ?? params.varName}) => ${renderArrayLiteral(" ", indexEntries)}` : "";
7987
+ const indexBlock = params.verbatimIndexArgText ? `,\n ${params.verbatimIndexArgText}` : indexEntries.length > 0 ? `,\n (${params.indexParamName ?? params.varName}) => ${renderArrayLiteral(" ", indexEntries)}` : "";
7956
7988
  return `export const ${params.varName} = convexTable(\n ${params.tableNameText},\n ${fieldsText}${indexBlock}\n);`;
7957
7989
  };
7958
7990
  const insertDeclaration = (source, declaration) => {
@@ -7992,7 +8024,8 @@ const mergeTableDeclaration = (params) => {
7992
8024
  indexEntries: indexMerge.requiresIndexArg ? indexMerge.entries : null,
7993
8025
  indexParamName: indexMerge.indexParamName,
7994
8026
  tableNameText: existingInfo.tableNameText,
7995
- varName: existingInfo.varName
8027
+ varName: existingInfo.varName,
8028
+ verbatimIndexArgText: indexMerge.verbatimIndexArgText
7996
8029
  });
7997
8030
  return {
7998
8031
  content: replaceRange(params.source, existingInfo.statement.getStart(existingInfo.sourceFile), existingInfo.statement.end, nextStatement),
@@ -8015,43 +8048,15 @@ const updateTablesObject = (source, registrations) => {
8015
8048
  if (!changed) return source;
8016
8049
  return replaceRange(source, info.object.getStart(info.sourceFile), info.object.end, renderObjectLiteral(getIndentAt(source, info.object.getStart(info.sourceFile)), existingEntries));
8017
8050
  };
8018
- const skipWhitespace$1 = (source, start) => {
8019
- let cursor = start;
8020
- while (cursor < source.length && WHITESPACE_RE$1.test(source[cursor])) cursor += 1;
8021
- return cursor;
8022
- };
8023
- const findBalancedParenEnd = (source, openParenIndex) => {
8024
- let depth = 0;
8025
- for (let index = openParenIndex; index < source.length; index += 1) {
8026
- const char = source[index];
8027
- if (char === "(") depth += 1;
8028
- else if (char === ")") {
8029
- depth -= 1;
8030
- if (depth === 0) return index;
8031
- }
8032
- }
8033
- return -1;
8034
- };
8035
8051
  const findRelationsInsertIndex = (source) => {
8036
- const defineSchemaIndex = source.indexOf("defineSchema(");
8037
- if (defineSchemaIndex < 0) return -1;
8038
- const defineSchemaOpenParenIndex = source.indexOf("(", defineSchemaIndex);
8039
- if (defineSchemaOpenParenIndex < 0) return -1;
8040
- const defineSchemaCloseParenIndex = findBalancedParenEnd(source, defineSchemaOpenParenIndex);
8041
- if (defineSchemaCloseParenIndex < 0) return -1;
8042
- let cursor = defineSchemaCloseParenIndex + 1;
8043
- while (cursor < source.length) {
8044
- const nextSegmentIndex = skipWhitespace$1(source, cursor);
8045
- if (source.startsWith(".relations(", nextSegmentIndex)) return nextSegmentIndex;
8046
- if (source.startsWith(".triggers(", nextSegmentIndex)) return nextSegmentIndex;
8047
- if (!source.startsWith(".extend(", nextSegmentIndex)) return nextSegmentIndex;
8048
- const extendOpenParenIndex = source.indexOf("(", nextSegmentIndex);
8049
- if (extendOpenParenIndex < 0) return -1;
8050
- const extendCloseParenIndex = findBalancedParenEnd(source, extendOpenParenIndex);
8051
- if (extendCloseParenIndex < 0) return -1;
8052
- cursor = extendCloseParenIndex + 1;
8053
- }
8054
- return cursor;
8052
+ const chain = findDefineSchemaChain(source);
8053
+ if (!chain) return -1;
8054
+ let insertIndex = chain.defineSchemaEnd;
8055
+ for (const call of chain.calls) {
8056
+ if (call.name !== "extend") return call.dotIndex;
8057
+ insertIndex = call.end;
8058
+ }
8059
+ return insertIndex;
8055
8060
  };
8056
8061
  const mergeRelationProperty = (params) => {
8057
8062
  const desiredInfo = readPropertyObject(params.desiredRelation, params.tableKey);
@@ -8171,13 +8176,32 @@ const readManagedChecksumFromSource = (source, unit) => {
8171
8176
  };
8172
8177
  const mergeOrmImports = (source, importNames) => {
8173
8178
  if (importNames.length === 0) return source;
8174
- const sourceFile = parseSource(source);
8175
- const ormImport = sourceFile.statements.find((statement) => ts$2.isImportDeclaration(statement) && isStringLiteralLike(statement.moduleSpecifier) && statement.moduleSpecifier.text === "kitcn/orm");
8176
- if (!ormImport) return `${`import {\n ${[...new Set(importNames)].sort().join(",\n ")},\n} from 'kitcn/orm';\n\n`}${source}`;
8177
- if (!ormImport.importClause?.namedBindings || !ts$2.isNamedImports(ormImport.importClause.namedBindings)) return source;
8178
- const existingImports = ormImport.importClause.namedBindings.elements.map((element) => element.getText(sourceFile));
8179
- const nextImport = `import {\n ${[...new Set([...existingImports, ...importNames])].sort((a, b) => a.localeCompare(b)).join(",\n ")},\n} from 'kitcn/orm';`;
8180
- return replaceRange(source, ormImport.getStart(sourceFile), ormImport.end, nextImport);
8179
+ const requiredNames = new Set(importNames);
8180
+ const initialSourceFile = parseSource(source);
8181
+ const typeOnlyReplacements = initialSourceFile.statements.flatMap((statement) => {
8182
+ if (!ts$2.isImportDeclaration(statement) || !isStringLiteralLike(statement.moduleSpecifier) || statement.moduleSpecifier.text !== "kitcn/orm" || !statement.importClause?.isTypeOnly || !statement.importClause.namedBindings || !ts$2.isNamedImports(statement.importClause.namedBindings)) return [];
8183
+ const remainingElements = statement.importClause.namedBindings.elements.filter((element) => !requiredNames.has(element.name.text));
8184
+ if (remainingElements.length === statement.importClause.namedBindings.elements.length) return [];
8185
+ const namedBindings = remainingElements.length > 0 ? `{ ${remainingElements.map((element) => element.getText(initialSourceFile)).join(", ")} }` : null;
8186
+ const bindings = [statement.importClause.name?.text, namedBindings].filter((value) => Boolean(value));
8187
+ const replacement = bindings.length > 0 ? `import type ${bindings.join(", ")} from ${statement.moduleSpecifier.getText(initialSourceFile)};` : "";
8188
+ return [{
8189
+ end: statement.end,
8190
+ replacement,
8191
+ start: statement.getStart(initialSourceFile)
8192
+ }];
8193
+ });
8194
+ let workingSource = source;
8195
+ for (const replacement of typeOnlyReplacements.sort((a, b) => b.start - a.start)) workingSource = replaceRange(workingSource, replacement.start, replacement.end, replacement.replacement);
8196
+ const sourceFile = parseSource(workingSource);
8197
+ const ormImport = sourceFile.statements.find((statement) => ts$2.isImportDeclaration(statement) && isStringLiteralLike(statement.moduleSpecifier) && statement.moduleSpecifier.text === "kitcn/orm" && statement.importClause !== void 0 && !statement.importClause.isTypeOnly && statement.importClause.namedBindings !== void 0 && ts$2.isNamedImports(statement.importClause.namedBindings));
8198
+ if (!ormImport) return `${`import {\n ${[...new Set(importNames)].sort().join(",\n ")},\n} from 'kitcn/orm';\n\n`}${workingSource}`;
8199
+ const namedBindings = ormImport.importClause?.namedBindings;
8200
+ const specifiersByLocalName = /* @__PURE__ */ new Map();
8201
+ for (const element of namedBindings.elements) specifiersByLocalName.set(element.name.text, element.getText(sourceFile));
8202
+ for (const name of importNames) specifiersByLocalName.set(name, name);
8203
+ const nextImport = `import {\n ${[...specifiersByLocalName.values()].sort((a, b) => a.localeCompare(b)).join(",\n ")},\n} from 'kitcn/orm';`;
8204
+ return replaceRange(workingSource, ormImport.getStart(sourceFile), ormImport.end, nextImport);
8181
8205
  };
8182
8206
  const hasSchemaFragment = (source, tableKey) => {
8183
8207
  if (new RegExp(`convexTable\\(\\s*['"]${escapeRegex(tableKey)}['"]`).test(source)) return true;
@@ -8258,6 +8282,39 @@ const reconcileRootSchemaOwnership = async (params) => {
8258
8282
  };
8259
8283
  };
8260
8284
 
8285
+ //#endregion
8286
+ //#region src/cli/registry/items/ratelimit/ratelimit-crpc.ts
8287
+ const CRPC_META_RATELIMIT_RE = /ratelimit\?: string;/;
8288
+ const CRPC_RATELIMIT_BUCKET_RE = /ratelimit\?: RatelimitBucket;/;
8289
+ const CRPC_CREATE_LINE_RE = /const c = initCRPC\.create\(\);/;
8290
+ const CRPC_META_CREATE_RE = /const c = initCRPC\s*\.meta<\{\s*([\s\S]*?)\s*\}>\(\)\s*\.create\(\);/;
8291
+ const PUBLIC_MUTATION_LINE_RE = /export const publicMutation = c\.mutation(?:\.use\(ratelimit\.middleware\(\)\))?;/;
8292
+ /**
8293
+ * Wire ratelimit middleware into an existing `crpc.ts` source.
8294
+ *
8295
+ * Shared so other plugins can reproduce the ratelimit-patched baseline and
8296
+ * recognize it as managed content rather than a user edit.
8297
+ */
8298
+ const patchRatelimitCrpcSource = (input) => {
8299
+ let source = input;
8300
+ if (!source.includes("from './plugins/ratelimit/plugin'")) if (source.includes("import type { ActionCtx, MutationCtx, QueryCtx }")) source = source.replace("import type { ActionCtx, MutationCtx, QueryCtx } from '../functions/generated/server';", `import { type RatelimitBucket, ratelimit } from './plugins/ratelimit/plugin';
8301
+ import type { ActionCtx, MutationCtx, QueryCtx } from '../functions/generated/server';`);
8302
+ else source = `import { type RatelimitBucket, ratelimit } from './plugins/ratelimit/plugin';\n${source}`;
8303
+ if (CRPC_META_RATELIMIT_RE.test(source)) source = source.replace(CRPC_META_RATELIMIT_RE, "ratelimit?: RatelimitBucket;");
8304
+ if (!CRPC_RATELIMIT_BUCKET_RE.test(source)) {
8305
+ if (CRPC_META_CREATE_RE.test(source)) source = source.replace(CRPC_META_CREATE_RE, (_match, fields) => {
8306
+ return `const c = initCRPC\n .meta<{\n${[...fields.split("\n").map((line) => line.trim()).filter(Boolean), "ratelimit?: RatelimitBucket;"].map((line) => ` ${line}`).join("\n")}\n }>()\n .create();`;
8307
+ });
8308
+ else if (CRPC_CREATE_LINE_RE.test(source)) source = source.replace(CRPC_CREATE_LINE_RE, `const c = initCRPC
8309
+ .meta<{
8310
+ ratelimit?: RatelimitBucket;
8311
+ }>()
8312
+ .create();`);
8313
+ }
8314
+ if (PUBLIC_MUTATION_LINE_RE.test(source)) source = source.replace(PUBLIC_MUTATION_LINE_RE, "export const publicMutation = c.mutation.use(ratelimit.middleware());");
8315
+ return source;
8316
+ };
8317
+
8261
8318
  //#endregion
8262
8319
  //#region src/cli/registry/items/auth/auth.template.ts
8263
8320
  const AUTH_TEMPLATE = `import { convex } from 'kitcn/auth';
@@ -10358,7 +10415,7 @@ function buildAuthCrpcRegistrationPlanFile(params) {
10358
10415
  kind: "scaffold",
10359
10416
  filePath: crpcPath,
10360
10417
  content: renderAuthCrpcTemplate({ withRatelimit: source.includes("from './plugins/ratelimit/plugin'") || source.includes("RatelimitBucket") || source.includes("ratelimit.middleware()") }),
10361
- managedBaselineContent: baselineCrpcSource,
10418
+ managedBaselineContent: [baselineCrpcSource, patchRatelimitCrpcSource(baselineCrpcSource)],
10362
10419
  createReason: "Create crpc.ts with auth-aware procedures.",
10363
10420
  updateReason: "Register auth-aware procedures in crpc.ts.",
10364
10421
  skipReason: "Auth-aware procedures are already registered in crpc.ts."
@@ -10398,6 +10455,7 @@ app.use(
10398
10455
  filePath: httpPath,
10399
10456
  content: source,
10400
10457
  managedBaselineContent: baselineHttpSource,
10458
+ requiresExplicitOverwrite: false,
10401
10459
  createReason: "Create http.ts with auth middleware.",
10402
10460
  updateReason: "Register auth middleware in http.ts.",
10403
10461
  skipReason: "Auth middleware is already registered in http.ts."
@@ -10555,6 +10613,7 @@ export default http;
10555
10613
  kind: "scaffold",
10556
10614
  filePath: httpPath,
10557
10615
  content: source,
10616
+ requiresExplicitOverwrite: false,
10558
10617
  createReason: "Create Convex http.ts with auth routes.",
10559
10618
  updateReason: "Register auth routes in Convex http.ts.",
10560
10619
  skipReason: "Convex http.ts already registers auth routes."
@@ -10592,6 +10651,7 @@ function buildAuthConvexNextProviderPlanFile(params) {
10592
10651
  kind: "scaffold",
10593
10652
  filePath: providerPath,
10594
10653
  content: source,
10654
+ requiresExplicitOverwrite: false,
10595
10655
  createReason: "Create auth-aware Convex client provider.",
10596
10656
  updateReason: "Update Convex client provider with auth.",
10597
10657
  skipReason: "Convex client provider already includes auth."
@@ -10616,6 +10676,7 @@ function buildAuthConvexStartProviderPlanFile(params) {
10616
10676
  kind: "scaffold",
10617
10677
  filePath: providerPath,
10618
10678
  content: patchAuthConvexProviderSource(fs.readFileSync(providerPath, "utf8")),
10679
+ requiresExplicitOverwrite: false,
10619
10680
  createReason: "Create auth-aware Start provider.",
10620
10681
  updateReason: "Update Start provider with auth.",
10621
10682
  skipReason: "Start provider already includes auth."
@@ -10634,6 +10695,7 @@ function buildAuthConvexReactEntryPlanFile(params) {
10634
10695
  kind: "scaffold",
10635
10696
  filePath: entryPath,
10636
10697
  content: source,
10698
+ requiresExplicitOverwrite: false,
10637
10699
  createReason: "Create auth-aware client entry.",
10638
10700
  updateReason: "Update client entry with auth.",
10639
10701
  skipReason: "Client entry already includes auth."
@@ -10897,11 +10959,6 @@ export function ratelimitExtension() {
10897
10959
 
10898
10960
  //#endregion
10899
10961
  //#region src/cli/registry/items/ratelimit/ratelimit-item.ts
10900
- const CRPC_META_RATELIMIT_RE = /ratelimit\?: string;/;
10901
- const CRPC_RATELIMIT_BUCKET_RE = /ratelimit\?: RatelimitBucket;/;
10902
- const CRPC_CREATE_LINE_RE = /const c = initCRPC\.create\(\);/;
10903
- const CRPC_META_CREATE_RE = /const c = initCRPC\s*\.meta<\{\s*([\s\S]*?)\s*\}>\(\)\s*\.create\(\);/;
10904
- const PUBLIC_MUTATION_LINE_RE = /export const publicMutation = c\.mutation(?:\.use\(ratelimit\.middleware\(\)\))?;/;
10905
10962
  const RATELIMIT_FILES = [createRegistryFile({
10906
10963
  id: "ratelimit-schema",
10907
10964
  path: "schema.ts",
@@ -10922,27 +10979,12 @@ function buildRatelimitCrpcRegistrationPlanFile(params) {
10922
10979
  functionsDir: params.functionsDir,
10923
10980
  crpcFilePath: crpcPath
10924
10981
  });
10925
- let source = fs.existsSync(crpcPath) ? fs.readFileSync(crpcPath, "utf8") : baselineCrpcSource;
10926
- if (!source.includes("from './plugins/ratelimit/plugin'")) if (source.includes("import type { ActionCtx, MutationCtx, QueryCtx }")) source = source.replace("import type { ActionCtx, MutationCtx, QueryCtx } from '../functions/generated/server';", `import { type RatelimitBucket, ratelimit } from './plugins/ratelimit/plugin';
10927
- import type { ActionCtx, MutationCtx, QueryCtx } from '../functions/generated/server';`);
10928
- else source = `import { type RatelimitBucket, ratelimit } from './plugins/ratelimit/plugin';\n${source}`;
10929
- if (CRPC_META_RATELIMIT_RE.test(source)) source = source.replace(CRPC_META_RATELIMIT_RE, "ratelimit?: RatelimitBucket;");
10930
- if (!CRPC_RATELIMIT_BUCKET_RE.test(source)) {
10931
- if (CRPC_META_CREATE_RE.test(source)) source = source.replace(CRPC_META_CREATE_RE, (_match, fields) => {
10932
- return `const c = initCRPC\n .meta<{\n${[...fields.split("\n").map((line) => line.trim()).filter(Boolean), "ratelimit?: RatelimitBucket;"].map((line) => ` ${line}`).join("\n")}\n }>()\n .create();`;
10933
- });
10934
- else if (CRPC_CREATE_LINE_RE.test(source)) source = source.replace(CRPC_CREATE_LINE_RE, `const c = initCRPC
10935
- .meta<{
10936
- ratelimit?: RatelimitBucket;
10937
- }>()
10938
- .create();`);
10939
- }
10940
- if (PUBLIC_MUTATION_LINE_RE.test(source)) source = source.replace(PUBLIC_MUTATION_LINE_RE, "export const publicMutation = c.mutation.use(ratelimit.middleware());");
10941
10982
  return createPlanFile({
10942
10983
  kind: "scaffold",
10943
10984
  filePath: crpcPath,
10944
- content: source,
10985
+ content: patchRatelimitCrpcSource(fs.existsSync(crpcPath) ? fs.readFileSync(crpcPath, "utf8") : baselineCrpcSource),
10945
10986
  managedBaselineContent: baselineCrpcSource,
10987
+ requiresExplicitOverwrite: false,
10946
10988
  createReason: "Create crpc.ts with ratelimit middleware.",
10947
10989
  updateReason: "Register ratelimit middleware in crpc.ts.",
10948
10990
  skipReason: "Ratelimit middleware is already registered in crpc.ts."
@@ -12263,6 +12305,7 @@ function buildResendHttpRegistrationPlanFile(params) {
12263
12305
  filePath: httpPath,
12264
12306
  content: source,
12265
12307
  managedBaselineContent: baselineHttpSource,
12308
+ requiresExplicitOverwrite: false,
12266
12309
  createReason: "Create http.ts with resend webhook route.",
12267
12310
  updateReason: "Register resend webhook in http.ts.",
12268
12311
  skipReason: "Resend webhook is already registered in http.ts."
@@ -15541,7 +15584,8 @@ async function runScaffoldCommandFlow(params) {
15541
15584
  cwd: scaffoldProjectDir,
15542
15585
  created: applyResult.created,
15543
15586
  updated: applyResult.updated,
15544
- skipped: applyResult.skipped,
15587
+ skipped: [...applyResult.skipped, ...applyResult.refused],
15588
+ refused: applyResult.refused,
15545
15589
  usedShadcn: params.template !== void 0 && params.template !== "expo",
15546
15590
  template: params.template ?? null,
15547
15591
  codegen: codegenResult.codegen,
@@ -15673,8 +15717,9 @@ async function applyPluginInstallPlanFiles(files, options) {
15673
15717
  const result = {
15674
15718
  created: [],
15675
15719
  manualActions: [],
15676
- updated: [],
15677
- skipped: []
15720
+ refused: [],
15721
+ skipped: [],
15722
+ updated: []
15678
15723
  };
15679
15724
  for (const file of files) {
15680
15725
  if (file.manualActions?.length) result.manualActions.push(...file.manualActions);
@@ -15690,7 +15735,7 @@ async function applyPluginInstallPlanFiles(files, options) {
15690
15735
  continue;
15691
15736
  }
15692
15737
  const managedBaselines = Array.isArray(file.managedBaselineContent) ? file.managedBaselineContent : typeof file.managedBaselineContent === "string" ? [file.managedBaselineContent] : [];
15693
- const requiresExplicitOverwrite = file.requiresExplicitOverwrite ?? (file.kind === "config" || file.kind === "scaffold" && file.templateId !== void 0 || file.kind === "env" && file.templateId !== LOCAL_CONVEX_ENV_TEMPLATE_ID && file.templateId !== KITCN_ENV_HELPER_TEMPLATE_ID);
15738
+ const requiresExplicitOverwrite = file.requiresExplicitOverwrite ?? (file.kind === "config" || file.kind === "scaffold" || file.kind === "env" && file.templateId !== LOCAL_CONVEX_ENV_TEMPLATE_ID && file.templateId !== KITCN_ENV_HELPER_TEMPLATE_ID);
15694
15739
  const existingContent = file.existingContent;
15695
15740
  const matchesManagedBaseline = typeof existingContent === "string" && managedBaselines.some((managedBaselineContent) => isContentEquivalent({
15696
15741
  filePath: file.path,
@@ -15700,7 +15745,7 @@ async function applyPluginInstallPlanFiles(files, options) {
15700
15745
  let shouldOverwrite = options.overwrite || !requiresExplicitOverwrite || matchesManagedBaseline;
15701
15746
  if (!shouldOverwrite && !options.yes && options.promptAdapter.isInteractive()) shouldOverwrite = await options.promptAdapter.confirm(`Overwrite ${file.path}?`);
15702
15747
  if (!shouldOverwrite) {
15703
- result.skipped.push(file.path);
15748
+ result.refused.push(file.path);
15704
15749
  continue;
15705
15750
  }
15706
15751
  fs.mkdirSync(dirname(absolutePath), { recursive: true });
@@ -16970,4 +17015,4 @@ function isEntryPoint(entry, filename) {
16970
17015
  }
16971
17016
 
16972
17017
  //#endregion
16973
- export { promptForScaffoldTemplateSelection as $, resolveCodegenTrimSegments as A, highlighter as At, runConfiguredCodegen as B, isEntryPoint as C, formatDependencyInstallCommand as Ct, parseInitCommandArgs as D, generateMeta as Dt, parseBackendRunJson as E, stripConvexCommandNoise as Et, resolveRunDeps as F, runMigrationFlow as G, runDevSchemaBackfillIfNeeded as H, runAfterScaffoldScript as I, withWorkingDirectory as J, trackProcess as K, runAggregateBackfillFlow as L, resolveDocTopic as M, resolveInitProjectDir as N, readPackageVersions as O, getConvexConfig as Ot, resolveMigrationConfig as P, promptForPluginSelection as Q, runAggregatePruneFlow as R, isConvexDevPreRunConflictFlag as S, detectPackageManager as St, parseArgs as T, serializeEnvValue as Tt, runInitCommandFlow as U, runConvexInitIfNeeded as V, runMigrationCreate as W, collectPluginScaffoldTemplates as X, createSpinner as Y, filterScaffoldTemplatePathMap as Z, formatInfoOutput as _, applyPlanningDependencyInstall as _t, cleanup as a, getPluginCatalogEntry as at, getDevAggregateBackfillStatePath as b, resolveSupportedDependencyWarnings as bt, createCommandEnv as c, buildPluginInstallPlan as ct, extractBackfillCliOptions as d, collectInstalledPluginKeys as dt, resolveAddTemplateDefaults as et, extractConcaveRunTargetArgs as f, getPluginLockfilePath as ft, formatDocsOutput as g, applyDependencyHintsInstall as gt, extractResetCliOptions as h, resolveSchemaInstalledPlugins as ht, buildInitializationPlan as i, resolveTemplatesByIdOrThrow as it, resolveConfiguredBackend as j, resolveBackfillConfig as k, logger as kt, ensureConvexGitignoreEntry as l, resolvePluginScaffoldRoots as lt, extractMigrationDownOptions as m, readPluginLockfile as mt, applyPluginInstallPlanFiles as n, resolvePresetScaffoldTemplates as nt, createBackendAdapter as o, getSupportedPluginKeys as ot, extractMigrationCliOptions as p, getSchemaFilePath as pt, withLocalCodegenEnv as q, assertNoRemovedDevPreRunFlag as r, resolveTemplateSelectionSource as rt, createBackendCommandEnv as s, isSupportedPluginKey as st, applyDependencyInstallPlan as t, resolvePluginPreset as tt, extractBackendRunTargetArgs as u, assertSchemaFileExists as ut, getAggregateBackfillDeploymentKey as v, applyPluginDependencyInstall as vt, isInitialized as w, resolveAuthEnvState as wt, hasRemoteConvexDeploymentEnv as x, resolveProjectScaffoldContext as xt, getConvexDeploymentCommandEnv as y, inspectPluginDependencyInstall as yt, runBackendFunction as z };
17018
+ export { promptForScaffoldTemplateSelection as $, resolveCodegenTrimSegments as A, PARSE_SNAPSHOT_SUFFIX as At, runConfiguredCodegen as B, isEntryPoint as C, formatDependencyInstallCommand as Ct, parseInitCommandArgs as D, generateMeta as Dt, parseBackendRunJson as E, stripConvexCommandNoise as Et, resolveRunDeps as F, runMigrationFlow as G, runDevSchemaBackfillIfNeeded as H, runAfterScaffoldScript as I, withWorkingDirectory as J, trackProcess as K, runAggregateBackfillFlow as L, resolveDocTopic as M, resolveInitProjectDir as N, readPackageVersions as O, getConvexConfig as Ot, resolveMigrationConfig as P, promptForPluginSelection as Q, runAggregatePruneFlow as R, isConvexDevPreRunConflictFlag as S, detectPackageManager as St, parseArgs as T, serializeEnvValue as Tt, runInitCommandFlow as U, runConvexInitIfNeeded as V, runMigrationCreate as W, collectPluginScaffoldTemplates as X, createSpinner as Y, filterScaffoldTemplatePathMap as Z, formatInfoOutput as _, applyPlanningDependencyInstall as _t, cleanup as a, getPluginCatalogEntry as at, getDevAggregateBackfillStatePath as b, resolveSupportedDependencyWarnings as bt, createCommandEnv as c, buildPluginInstallPlan as ct, extractBackfillCliOptions as d, collectInstalledPluginKeys as dt, resolveAddTemplateDefaults as et, extractConcaveRunTargetArgs as f, getPluginLockfilePath as ft, formatDocsOutput as g, applyDependencyHintsInstall as gt, extractResetCliOptions as h, resolveSchemaInstalledPlugins as ht, buildInitializationPlan as i, resolveTemplatesByIdOrThrow as it, resolveConfiguredBackend as j, highlighter as jt, resolveBackfillConfig as k, logger as kt, ensureConvexGitignoreEntry as l, resolvePluginScaffoldRoots as lt, extractMigrationDownOptions as m, readPluginLockfile as mt, applyPluginInstallPlanFiles as n, resolvePresetScaffoldTemplates as nt, createBackendAdapter as o, getSupportedPluginKeys as ot, extractMigrationCliOptions as p, getSchemaFilePath as pt, withLocalCodegenEnv as q, assertNoRemovedDevPreRunFlag as r, resolveTemplateSelectionSource as rt, createBackendCommandEnv as s, isSupportedPluginKey as st, applyDependencyInstallPlan as t, resolvePluginPreset as tt, extractBackendRunTargetArgs as u, assertSchemaFileExists as ut, getAggregateBackfillDeploymentKey as v, applyPluginDependencyInstall as vt, isInitialized as w, resolveAuthEnvState as wt, hasRemoteConvexDeploymentEnv as x, resolveProjectScaffoldContext as xt, getConvexDeploymentCommandEnv as y, inspectPluginDependencyInstall as yt, runBackendFunction as z };