kitcn 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aggregate/index.d.ts +1 -1
- package/dist/auth/client/index.js +1 -1
- package/dist/auth/index.js +19 -21
- package/dist/auth/nextjs/index.d.ts +1 -1
- package/dist/auth/nextjs/index.js +4 -4
- package/dist/{auth-store-ssZDPa37.js → auth-store-BnGZxmnY.js} +4 -1
- package/dist/{backend-core-DqPydYyx.mjs → backend-core-BsKP1LVg.mjs} +204 -164
- package/dist/{builder-DBgto1yn.js → builder-f4F_NRvK.js} +245 -153
- package/dist/{caller-factory-NEfgD5E0.js → caller-factory-DHywSoGZ.js} +7 -5
- package/dist/cli.mjs +14 -7
- package/dist/crpc/index.js +1 -127
- package/dist/{middleware-Bg-PdtrI.js → middleware-Cgrv2jIu.js} +1 -1
- package/dist/orm/index.d.ts +1 -1
- package/dist/orm/index.js +486 -121
- package/dist/plugins/index.js +1 -1
- package/dist/{procedure-caller-9m6NBxQu.js → procedure-caller-Rj6z3ai7.js} +1 -1
- package/dist/{procedure-name-Cy1AxayA.d.ts → procedure-name-Bo5KMcqc.d.ts} +15 -3
- package/dist/{query-context-ydn9kb6P.js → query-context-C90vNlc9.js} +131 -30
- package/dist/query-options-C_eBSIXG.js +247 -0
- package/dist/ratelimit/index.d.ts +26 -6
- package/dist/ratelimit/index.js +427 -100
- package/dist/ratelimit/react/index.d.ts +14 -0
- package/dist/ratelimit/react/index.js +149 -16
- package/dist/react/index.d.ts +3 -1
- package/dist/react/index.js +48 -15
- package/dist/rsc/index.js +22 -33
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +3 -3
- package/dist/solid/index.js +19 -5
- package/dist/watcher.mjs +2 -2
- package/dist/{where-clause-compiler-WF9UcrAB.d.ts → where-clause-compiler-BRhLW1dp.d.ts} +51 -0
- package/package.json +1 -1
- package/skills/kitcn/SKILL.md +1 -0
- package/skills/kitcn/references/features/create-plugins.md +1 -1
- package/skills/kitcn/references/features/orm.md +11 -1
- package/skills/kitcn/references/features/ratelimit.md +105 -0
- package/skills/kitcn/references/setup/server.md +1 -1
- 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;
|
|
@@ -5048,19 +5057,17 @@ function isCRPCHttpRouter(value) {
|
|
|
5048
5057
|
async function parseModuleRuntime(filePath, jitiInstance) {
|
|
5049
5058
|
const source = fs.readFileSync(filePath, "utf8");
|
|
5050
5059
|
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
5060
|
const result = {};
|
|
5057
5061
|
const httpRoutes = {};
|
|
5058
5062
|
const procedures = [];
|
|
5059
5063
|
const isHttp = filePath.endsWith("http.ts");
|
|
5060
|
-
const module = await jitiInstance.import(
|
|
5064
|
+
const module = rewrittenSource === source ? await jitiInstance.import(filePath) : await jitiInstance.evalModule(rewrittenSource, {
|
|
5065
|
+
async: true,
|
|
5066
|
+
ext: ".ts",
|
|
5067
|
+
filename: filePath
|
|
5068
|
+
});
|
|
5061
5069
|
if (!module || typeof module !== "object") {
|
|
5062
5070
|
if (isHttp) logger.error(" http.ts: module is empty or not an object");
|
|
5063
|
-
if (importPath !== filePath) fs.rmSync(importPath, { force: true });
|
|
5064
5071
|
return {
|
|
5065
5072
|
meta: null,
|
|
5066
5073
|
httpRoutes: {},
|
|
@@ -5095,7 +5102,6 @@ async function parseModuleRuntime(filePath, jitiInstance) {
|
|
|
5095
5102
|
};
|
|
5096
5103
|
}
|
|
5097
5104
|
}
|
|
5098
|
-
if (importPath !== filePath) fs.rmSync(importPath, { force: true });
|
|
5099
5105
|
return {
|
|
5100
5106
|
meta: Object.keys(result).length > 0 ? result : null,
|
|
5101
5107
|
httpRoutes,
|
|
@@ -6939,6 +6945,92 @@ const normalizeLockfileScaffoldPath = (value) => {
|
|
|
6939
6945
|
return normalized;
|
|
6940
6946
|
};
|
|
6941
6947
|
|
|
6948
|
+
//#endregion
|
|
6949
|
+
//#region src/cli/utils/typescript-runtime.ts
|
|
6950
|
+
const require$1 = createRequire(import.meta.url);
|
|
6951
|
+
let cachedTypeScript = null;
|
|
6952
|
+
const loadTypeScript = () => {
|
|
6953
|
+
if (cachedTypeScript) return cachedTypeScript;
|
|
6954
|
+
const loaded = require$1("typescript");
|
|
6955
|
+
const resolved = "default" in loaded && loaded.default ? loaded.default : loaded;
|
|
6956
|
+
cachedTypeScript = resolved;
|
|
6957
|
+
return resolved;
|
|
6958
|
+
};
|
|
6959
|
+
const createTypeScriptProxy = () => new Proxy({}, { get(_target, property) {
|
|
6960
|
+
return loadTypeScript()[property];
|
|
6961
|
+
} });
|
|
6962
|
+
|
|
6963
|
+
//#endregion
|
|
6964
|
+
//#region src/cli/registry/schema-chain.ts
|
|
6965
|
+
const ts$3 = createTypeScriptProxy();
|
|
6966
|
+
const parse$2 = (source) => ts$3.createSourceFile("schema.ts", source, ts$3.ScriptTarget.Latest, true, ts$3.ScriptKind.TS);
|
|
6967
|
+
const isDefineSchemaCall = (node) => {
|
|
6968
|
+
if (!ts$3.isCallExpression(node)) return false;
|
|
6969
|
+
if (ts$3.isIdentifier(node.expression)) return node.expression.text === "defineSchema";
|
|
6970
|
+
return ts$3.isPropertyAccessExpression(node.expression) && node.expression.name.text === "defineSchema";
|
|
6971
|
+
};
|
|
6972
|
+
const findDefineSchemaCall = (sourceFile) => {
|
|
6973
|
+
let found = null;
|
|
6974
|
+
const visit = (node) => {
|
|
6975
|
+
if (found) return;
|
|
6976
|
+
if (isDefineSchemaCall(node)) {
|
|
6977
|
+
found = node;
|
|
6978
|
+
return;
|
|
6979
|
+
}
|
|
6980
|
+
ts$3.forEachChild(node, visit);
|
|
6981
|
+
};
|
|
6982
|
+
visit(sourceFile);
|
|
6983
|
+
return found;
|
|
6984
|
+
};
|
|
6985
|
+
/**
|
|
6986
|
+
* Resolve the real `defineSchema(...)` call and the methods chained onto it.
|
|
6987
|
+
*
|
|
6988
|
+
* Locating the call through the TypeScript AST is what keeps registration out
|
|
6989
|
+
* of comments and string literals that merely mention `defineSchema(`.
|
|
6990
|
+
*/
|
|
6991
|
+
const findDefineSchemaChain = (source) => {
|
|
6992
|
+
const sourceFile = parse$2(source);
|
|
6993
|
+
const defineSchemaCall = findDefineSchemaCall(sourceFile);
|
|
6994
|
+
if (!defineSchemaCall) return null;
|
|
6995
|
+
const calls = [];
|
|
6996
|
+
let current = defineSchemaCall;
|
|
6997
|
+
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) {
|
|
6998
|
+
const propertyAccess = current.parent;
|
|
6999
|
+
const call = current.parent.parent;
|
|
7000
|
+
const dotToken = propertyAccess.getChildren(sourceFile).find((child) => child.kind === ts$3.SyntaxKind.DotToken);
|
|
7001
|
+
if (!dotToken) throw new Error("Schema chain property access is missing its dot token.");
|
|
7002
|
+
calls.push({
|
|
7003
|
+
closeParenIndex: call.end - 1,
|
|
7004
|
+
dotIndex: dotToken.getStart(sourceFile),
|
|
7005
|
+
end: call.end,
|
|
7006
|
+
name: propertyAccess.name.text
|
|
7007
|
+
});
|
|
7008
|
+
current = call;
|
|
7009
|
+
}
|
|
7010
|
+
return {
|
|
7011
|
+
calls,
|
|
7012
|
+
defineSchemaEnd: defineSchemaCall.end
|
|
7013
|
+
};
|
|
7014
|
+
};
|
|
7015
|
+
/**
|
|
7016
|
+
* Whether `source` really calls `name()` somewhere, ignoring comments and
|
|
7017
|
+
* string literals.
|
|
7018
|
+
*/
|
|
7019
|
+
const hasCallExpression = (source, name) => {
|
|
7020
|
+
const sourceFile = parse$2(source);
|
|
7021
|
+
let found = false;
|
|
7022
|
+
const visit = (node) => {
|
|
7023
|
+
if (found) return;
|
|
7024
|
+
if (ts$3.isCallExpression(node) && ts$3.isIdentifier(node.expression) && node.expression.text === name) {
|
|
7025
|
+
found = true;
|
|
7026
|
+
return;
|
|
7027
|
+
}
|
|
7028
|
+
ts$3.forEachChild(node, visit);
|
|
7029
|
+
};
|
|
7030
|
+
visit(sourceFile);
|
|
7031
|
+
return found;
|
|
7032
|
+
};
|
|
7033
|
+
|
|
6942
7034
|
//#endregion
|
|
6943
7035
|
//#region src/cli/registry/state.ts
|
|
6944
7036
|
const getPluginLockfilePath = (functionsDir) => join(functionsDir, "plugins.lock.json");
|
|
@@ -7080,7 +7172,6 @@ const READ_OPTIONAL_RUNTIME_ENV_PROPERTY_RE = /\breadOptionalRuntimeEnv\s*:/m;
|
|
|
7080
7172
|
const READ_OPTIONAL_RUNTIME_ENV_RE = /(\s*readOptionalRuntimeEnv\s*:\s*\[)([\s\S]*?)(\]\s*,?)/m;
|
|
7081
7173
|
const LEADING_WHITESPACE_RE = /^\s*/;
|
|
7082
7174
|
const STRING_LITERAL_ARRAY_ENTRY_RE = /^(['"])([^'"]+)\1$/;
|
|
7083
|
-
const WHITESPACE_RE$2 = /\s/;
|
|
7084
7175
|
const findMatchingObjectBraceIndex$1 = (source, openIndex) => {
|
|
7085
7176
|
let depth = 0;
|
|
7086
7177
|
let quote;
|
|
@@ -7390,79 +7481,28 @@ const getPlannedFileContent = (files, absolutePath) => {
|
|
|
7390
7481
|
const normalizedPath = normalizePath$1(relative(process.cwd(), absolutePath));
|
|
7391
7482
|
return files?.find((file) => file.path === normalizedPath)?.content;
|
|
7392
7483
|
};
|
|
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
7484
|
const findSchemaExtensionInsertIndex = (source) => {
|
|
7413
|
-
const
|
|
7414
|
-
if (
|
|
7485
|
+
const chain = findDefineSchemaChain(source);
|
|
7486
|
+
if (!chain) return {
|
|
7415
7487
|
closeParenIndex: -1,
|
|
7416
7488
|
hasExtend: false,
|
|
7417
7489
|
insertIndex: -1
|
|
7418
7490
|
};
|
|
7419
|
-
const
|
|
7420
|
-
if (
|
|
7491
|
+
const firstCall = chain.calls[0];
|
|
7492
|
+
if (!firstCall) return {
|
|
7421
7493
|
closeParenIndex: -1,
|
|
7422
7494
|
hasExtend: false,
|
|
7423
|
-
insertIndex:
|
|
7495
|
+
insertIndex: chain.defineSchemaEnd
|
|
7424
7496
|
};
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
insertIndex: -1
|
|
7497
|
+
if (firstCall.name === "extend") return {
|
|
7498
|
+
closeParenIndex: firstCall.closeParenIndex,
|
|
7499
|
+
hasExtend: true,
|
|
7500
|
+
insertIndex: firstCall.closeParenIndex
|
|
7430
7501
|
};
|
|
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
7502
|
return {
|
|
7463
7503
|
closeParenIndex: -1,
|
|
7464
7504
|
hasExtend: false,
|
|
7465
|
-
insertIndex:
|
|
7505
|
+
insertIndex: firstCall.dotIndex
|
|
7466
7506
|
};
|
|
7467
7507
|
};
|
|
7468
7508
|
const buildSchemaRegistrationPlanFile = (functionsDir, descriptor, roots, bootstrapFiles) => {
|
|
@@ -7473,7 +7513,7 @@ const buildSchemaRegistrationPlanFile = (functionsDir, descriptor, roots, bootst
|
|
|
7473
7513
|
const pluginFactory = schemaRegistration.importName;
|
|
7474
7514
|
const pluginImportPath = resolveRelativeImportPath(schemaPath, join(schemaRegistration.target === "lib" ? roots.libRootDir : roots.functionsRootDir, schemaRegistration.path));
|
|
7475
7515
|
let source = bootstrappedSchemaSource ?? fs.readFileSync(schemaPath, "utf8");
|
|
7476
|
-
if (!source
|
|
7516
|
+
if (!hasCallExpression(source, pluginFactory)) {
|
|
7477
7517
|
if (!new RegExp(`import\\s+\\{[^}]*\\b${pluginFactory}\\b[^}]*\\}\\s+from\\s+['"]${pluginImportPath}['"];?`).test(source)) source = `import { ${pluginFactory} } from '${pluginImportPath}';\n${source}`;
|
|
7478
7518
|
const extensionTarget = findSchemaExtensionInsertIndex(source);
|
|
7479
7519
|
if (extensionTarget.hasExtend && extensionTarget.closeParenIndex >= 0) source = `${source.slice(0, extensionTarget.closeParenIndex)}, ${pluginFactory}()${source.slice(extensionTarget.closeParenIndex)}`;
|
|
@@ -7654,27 +7694,11 @@ const buildPluginInstallPlan = async (params) => {
|
|
|
7654
7694
|
};
|
|
7655
7695
|
};
|
|
7656
7696
|
|
|
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
7697
|
//#endregion
|
|
7673
7698
|
//#region src/cli/registry/schema-ownership.ts
|
|
7674
7699
|
const OBJECT_ENTRY_INDENT = " ";
|
|
7675
7700
|
const LEADING_INDENT_RE = /^[ \t]*/;
|
|
7676
7701
|
const LEGACY_MANAGED_COMMENT_RE = /^[ \t]*\/\* kitcn-managed [^*]+ \*\/\n?/gm;
|
|
7677
|
-
const WHITESPACE_RE$1 = /\s/;
|
|
7678
7702
|
const ts$2 = createTypeScriptProxy();
|
|
7679
7703
|
let printer = null;
|
|
7680
7704
|
const getPrinter = () => {
|
|
@@ -7920,13 +7944,15 @@ const mergeIndexEntries = (params) => {
|
|
|
7920
7944
|
const targetParamName = params.existingInfo.indexParamName ?? params.existingInfo.varName ?? params.desiredInfo.indexParamName;
|
|
7921
7945
|
const desiredParamName = params.desiredInfo.indexParamName ?? params.desiredInfo.varName;
|
|
7922
7946
|
const desiredEntries = params.desiredInfo.indexEntries;
|
|
7947
|
+
const unparsedThirdArgText = params.existingInfo.thirdArgText && !params.existingInfo.indexEntries ? params.existingInfo.thirdArgText : null;
|
|
7923
7948
|
if (!desiredEntries || desiredEntries.length === 0) return {
|
|
7924
7949
|
changed: false,
|
|
7925
7950
|
entries: params.existingInfo.indexEntries?.map((entry) => entry.getText(params.existingInfo.sourceFile)),
|
|
7926
7951
|
indexParamName: targetParamName,
|
|
7927
|
-
requiresIndexArg: Boolean(params.existingInfo.thirdArgText)
|
|
7952
|
+
requiresIndexArg: Boolean(params.existingInfo.thirdArgText),
|
|
7953
|
+
verbatimIndexArgText: unparsedThirdArgText
|
|
7928
7954
|
};
|
|
7929
|
-
if (
|
|
7955
|
+
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
7956
|
const existingEntries = params.existingInfo.indexEntries ?? [];
|
|
7931
7957
|
const existingMap = new Map(existingEntries.map((entry) => [getIndexIdentity(entry, params.existingInfo.sourceFile), entry]));
|
|
7932
7958
|
const nextEntries = existingEntries.map((entry) => entry.getText(params.existingInfo.sourceFile));
|
|
@@ -7946,13 +7972,14 @@ const mergeIndexEntries = (params) => {
|
|
|
7946
7972
|
changed,
|
|
7947
7973
|
entries: nextEntries,
|
|
7948
7974
|
indexParamName: targetParamName,
|
|
7949
|
-
requiresIndexArg: Boolean(params.existingInfo.thirdArgText ?? nextEntries.length > 0)
|
|
7975
|
+
requiresIndexArg: Boolean(params.existingInfo.thirdArgText ?? nextEntries.length > 0),
|
|
7976
|
+
verbatimIndexArgText: null
|
|
7950
7977
|
};
|
|
7951
7978
|
};
|
|
7952
7979
|
const renderTableStatement = (params) => {
|
|
7953
7980
|
const fieldsText = renderObjectLiteral(" ", params.fieldEntries.map(ensureTrailingComma));
|
|
7954
7981
|
const indexEntries = params.indexEntries ?? [];
|
|
7955
|
-
const indexBlock = indexEntries.length > 0 ? `,\n (${params.indexParamName ?? params.varName}) => ${renderArrayLiteral(" ", indexEntries)}` : "";
|
|
7982
|
+
const indexBlock = params.verbatimIndexArgText ? `,\n ${params.verbatimIndexArgText}` : indexEntries.length > 0 ? `,\n (${params.indexParamName ?? params.varName}) => ${renderArrayLiteral(" ", indexEntries)}` : "";
|
|
7956
7983
|
return `export const ${params.varName} = convexTable(\n ${params.tableNameText},\n ${fieldsText}${indexBlock}\n);`;
|
|
7957
7984
|
};
|
|
7958
7985
|
const insertDeclaration = (source, declaration) => {
|
|
@@ -7992,7 +8019,8 @@ const mergeTableDeclaration = (params) => {
|
|
|
7992
8019
|
indexEntries: indexMerge.requiresIndexArg ? indexMerge.entries : null,
|
|
7993
8020
|
indexParamName: indexMerge.indexParamName,
|
|
7994
8021
|
tableNameText: existingInfo.tableNameText,
|
|
7995
|
-
varName: existingInfo.varName
|
|
8022
|
+
varName: existingInfo.varName,
|
|
8023
|
+
verbatimIndexArgText: indexMerge.verbatimIndexArgText
|
|
7996
8024
|
});
|
|
7997
8025
|
return {
|
|
7998
8026
|
content: replaceRange(params.source, existingInfo.statement.getStart(existingInfo.sourceFile), existingInfo.statement.end, nextStatement),
|
|
@@ -8015,43 +8043,15 @@ const updateTablesObject = (source, registrations) => {
|
|
|
8015
8043
|
if (!changed) return source;
|
|
8016
8044
|
return replaceRange(source, info.object.getStart(info.sourceFile), info.object.end, renderObjectLiteral(getIndentAt(source, info.object.getStart(info.sourceFile)), existingEntries));
|
|
8017
8045
|
};
|
|
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
8046
|
const findRelationsInsertIndex = (source) => {
|
|
8036
|
-
const
|
|
8037
|
-
if (
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
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;
|
|
8047
|
+
const chain = findDefineSchemaChain(source);
|
|
8048
|
+
if (!chain) return -1;
|
|
8049
|
+
let insertIndex = chain.defineSchemaEnd;
|
|
8050
|
+
for (const call of chain.calls) {
|
|
8051
|
+
if (call.name !== "extend") return call.dotIndex;
|
|
8052
|
+
insertIndex = call.end;
|
|
8053
|
+
}
|
|
8054
|
+
return insertIndex;
|
|
8055
8055
|
};
|
|
8056
8056
|
const mergeRelationProperty = (params) => {
|
|
8057
8057
|
const desiredInfo = readPropertyObject(params.desiredRelation, params.tableKey);
|
|
@@ -8171,13 +8171,32 @@ const readManagedChecksumFromSource = (source, unit) => {
|
|
|
8171
8171
|
};
|
|
8172
8172
|
const mergeOrmImports = (source, importNames) => {
|
|
8173
8173
|
if (importNames.length === 0) return source;
|
|
8174
|
-
const
|
|
8175
|
-
const
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8174
|
+
const requiredNames = new Set(importNames);
|
|
8175
|
+
const initialSourceFile = parseSource(source);
|
|
8176
|
+
const typeOnlyReplacements = initialSourceFile.statements.flatMap((statement) => {
|
|
8177
|
+
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 [];
|
|
8178
|
+
const remainingElements = statement.importClause.namedBindings.elements.filter((element) => !requiredNames.has(element.name.text));
|
|
8179
|
+
if (remainingElements.length === statement.importClause.namedBindings.elements.length) return [];
|
|
8180
|
+
const namedBindings = remainingElements.length > 0 ? `{ ${remainingElements.map((element) => element.getText(initialSourceFile)).join(", ")} }` : null;
|
|
8181
|
+
const bindings = [statement.importClause.name?.text, namedBindings].filter((value) => Boolean(value));
|
|
8182
|
+
const replacement = bindings.length > 0 ? `import type ${bindings.join(", ")} from ${statement.moduleSpecifier.getText(initialSourceFile)};` : "";
|
|
8183
|
+
return [{
|
|
8184
|
+
end: statement.end,
|
|
8185
|
+
replacement,
|
|
8186
|
+
start: statement.getStart(initialSourceFile)
|
|
8187
|
+
}];
|
|
8188
|
+
});
|
|
8189
|
+
let workingSource = source;
|
|
8190
|
+
for (const replacement of typeOnlyReplacements.sort((a, b) => b.start - a.start)) workingSource = replaceRange(workingSource, replacement.start, replacement.end, replacement.replacement);
|
|
8191
|
+
const sourceFile = parseSource(workingSource);
|
|
8192
|
+
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));
|
|
8193
|
+
if (!ormImport) return `${`import {\n ${[...new Set(importNames)].sort().join(",\n ")},\n} from 'kitcn/orm';\n\n`}${workingSource}`;
|
|
8194
|
+
const namedBindings = ormImport.importClause?.namedBindings;
|
|
8195
|
+
const specifiersByLocalName = /* @__PURE__ */ new Map();
|
|
8196
|
+
for (const element of namedBindings.elements) specifiersByLocalName.set(element.name.text, element.getText(sourceFile));
|
|
8197
|
+
for (const name of importNames) specifiersByLocalName.set(name, name);
|
|
8198
|
+
const nextImport = `import {\n ${[...specifiersByLocalName.values()].sort((a, b) => a.localeCompare(b)).join(",\n ")},\n} from 'kitcn/orm';`;
|
|
8199
|
+
return replaceRange(workingSource, ormImport.getStart(sourceFile), ormImport.end, nextImport);
|
|
8181
8200
|
};
|
|
8182
8201
|
const hasSchemaFragment = (source, tableKey) => {
|
|
8183
8202
|
if (new RegExp(`convexTable\\(\\s*['"]${escapeRegex(tableKey)}['"]`).test(source)) return true;
|
|
@@ -8258,6 +8277,39 @@ const reconcileRootSchemaOwnership = async (params) => {
|
|
|
8258
8277
|
};
|
|
8259
8278
|
};
|
|
8260
8279
|
|
|
8280
|
+
//#endregion
|
|
8281
|
+
//#region src/cli/registry/items/ratelimit/ratelimit-crpc.ts
|
|
8282
|
+
const CRPC_META_RATELIMIT_RE = /ratelimit\?: string;/;
|
|
8283
|
+
const CRPC_RATELIMIT_BUCKET_RE = /ratelimit\?: RatelimitBucket;/;
|
|
8284
|
+
const CRPC_CREATE_LINE_RE = /const c = initCRPC\.create\(\);/;
|
|
8285
|
+
const CRPC_META_CREATE_RE = /const c = initCRPC\s*\.meta<\{\s*([\s\S]*?)\s*\}>\(\)\s*\.create\(\);/;
|
|
8286
|
+
const PUBLIC_MUTATION_LINE_RE = /export const publicMutation = c\.mutation(?:\.use\(ratelimit\.middleware\(\)\))?;/;
|
|
8287
|
+
/**
|
|
8288
|
+
* Wire ratelimit middleware into an existing `crpc.ts` source.
|
|
8289
|
+
*
|
|
8290
|
+
* Shared so other plugins can reproduce the ratelimit-patched baseline and
|
|
8291
|
+
* recognize it as managed content rather than a user edit.
|
|
8292
|
+
*/
|
|
8293
|
+
const patchRatelimitCrpcSource = (input) => {
|
|
8294
|
+
let source = input;
|
|
8295
|
+
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';
|
|
8296
|
+
import type { ActionCtx, MutationCtx, QueryCtx } from '../functions/generated/server';`);
|
|
8297
|
+
else source = `import { type RatelimitBucket, ratelimit } from './plugins/ratelimit/plugin';\n${source}`;
|
|
8298
|
+
if (CRPC_META_RATELIMIT_RE.test(source)) source = source.replace(CRPC_META_RATELIMIT_RE, "ratelimit?: RatelimitBucket;");
|
|
8299
|
+
if (!CRPC_RATELIMIT_BUCKET_RE.test(source)) {
|
|
8300
|
+
if (CRPC_META_CREATE_RE.test(source)) source = source.replace(CRPC_META_CREATE_RE, (_match, fields) => {
|
|
8301
|
+
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();`;
|
|
8302
|
+
});
|
|
8303
|
+
else if (CRPC_CREATE_LINE_RE.test(source)) source = source.replace(CRPC_CREATE_LINE_RE, `const c = initCRPC
|
|
8304
|
+
.meta<{
|
|
8305
|
+
ratelimit?: RatelimitBucket;
|
|
8306
|
+
}>()
|
|
8307
|
+
.create();`);
|
|
8308
|
+
}
|
|
8309
|
+
if (PUBLIC_MUTATION_LINE_RE.test(source)) source = source.replace(PUBLIC_MUTATION_LINE_RE, "export const publicMutation = c.mutation.use(ratelimit.middleware());");
|
|
8310
|
+
return source;
|
|
8311
|
+
};
|
|
8312
|
+
|
|
8261
8313
|
//#endregion
|
|
8262
8314
|
//#region src/cli/registry/items/auth/auth.template.ts
|
|
8263
8315
|
const AUTH_TEMPLATE = `import { convex } from 'kitcn/auth';
|
|
@@ -10358,7 +10410,7 @@ function buildAuthCrpcRegistrationPlanFile(params) {
|
|
|
10358
10410
|
kind: "scaffold",
|
|
10359
10411
|
filePath: crpcPath,
|
|
10360
10412
|
content: renderAuthCrpcTemplate({ withRatelimit: source.includes("from './plugins/ratelimit/plugin'") || source.includes("RatelimitBucket") || source.includes("ratelimit.middleware()") }),
|
|
10361
|
-
managedBaselineContent: baselineCrpcSource,
|
|
10413
|
+
managedBaselineContent: [baselineCrpcSource, patchRatelimitCrpcSource(baselineCrpcSource)],
|
|
10362
10414
|
createReason: "Create crpc.ts with auth-aware procedures.",
|
|
10363
10415
|
updateReason: "Register auth-aware procedures in crpc.ts.",
|
|
10364
10416
|
skipReason: "Auth-aware procedures are already registered in crpc.ts."
|
|
@@ -10398,6 +10450,7 @@ app.use(
|
|
|
10398
10450
|
filePath: httpPath,
|
|
10399
10451
|
content: source,
|
|
10400
10452
|
managedBaselineContent: baselineHttpSource,
|
|
10453
|
+
requiresExplicitOverwrite: false,
|
|
10401
10454
|
createReason: "Create http.ts with auth middleware.",
|
|
10402
10455
|
updateReason: "Register auth middleware in http.ts.",
|
|
10403
10456
|
skipReason: "Auth middleware is already registered in http.ts."
|
|
@@ -10555,6 +10608,7 @@ export default http;
|
|
|
10555
10608
|
kind: "scaffold",
|
|
10556
10609
|
filePath: httpPath,
|
|
10557
10610
|
content: source,
|
|
10611
|
+
requiresExplicitOverwrite: false,
|
|
10558
10612
|
createReason: "Create Convex http.ts with auth routes.",
|
|
10559
10613
|
updateReason: "Register auth routes in Convex http.ts.",
|
|
10560
10614
|
skipReason: "Convex http.ts already registers auth routes."
|
|
@@ -10592,6 +10646,7 @@ function buildAuthConvexNextProviderPlanFile(params) {
|
|
|
10592
10646
|
kind: "scaffold",
|
|
10593
10647
|
filePath: providerPath,
|
|
10594
10648
|
content: source,
|
|
10649
|
+
requiresExplicitOverwrite: false,
|
|
10595
10650
|
createReason: "Create auth-aware Convex client provider.",
|
|
10596
10651
|
updateReason: "Update Convex client provider with auth.",
|
|
10597
10652
|
skipReason: "Convex client provider already includes auth."
|
|
@@ -10616,6 +10671,7 @@ function buildAuthConvexStartProviderPlanFile(params) {
|
|
|
10616
10671
|
kind: "scaffold",
|
|
10617
10672
|
filePath: providerPath,
|
|
10618
10673
|
content: patchAuthConvexProviderSource(fs.readFileSync(providerPath, "utf8")),
|
|
10674
|
+
requiresExplicitOverwrite: false,
|
|
10619
10675
|
createReason: "Create auth-aware Start provider.",
|
|
10620
10676
|
updateReason: "Update Start provider with auth.",
|
|
10621
10677
|
skipReason: "Start provider already includes auth."
|
|
@@ -10634,6 +10690,7 @@ function buildAuthConvexReactEntryPlanFile(params) {
|
|
|
10634
10690
|
kind: "scaffold",
|
|
10635
10691
|
filePath: entryPath,
|
|
10636
10692
|
content: source,
|
|
10693
|
+
requiresExplicitOverwrite: false,
|
|
10637
10694
|
createReason: "Create auth-aware client entry.",
|
|
10638
10695
|
updateReason: "Update client entry with auth.",
|
|
10639
10696
|
skipReason: "Client entry already includes auth."
|
|
@@ -10897,11 +10954,6 @@ export function ratelimitExtension() {
|
|
|
10897
10954
|
|
|
10898
10955
|
//#endregion
|
|
10899
10956
|
//#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
10957
|
const RATELIMIT_FILES = [createRegistryFile({
|
|
10906
10958
|
id: "ratelimit-schema",
|
|
10907
10959
|
path: "schema.ts",
|
|
@@ -10922,27 +10974,12 @@ function buildRatelimitCrpcRegistrationPlanFile(params) {
|
|
|
10922
10974
|
functionsDir: params.functionsDir,
|
|
10923
10975
|
crpcFilePath: crpcPath
|
|
10924
10976
|
});
|
|
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
10977
|
return createPlanFile({
|
|
10942
10978
|
kind: "scaffold",
|
|
10943
10979
|
filePath: crpcPath,
|
|
10944
|
-
content:
|
|
10980
|
+
content: patchRatelimitCrpcSource(fs.existsSync(crpcPath) ? fs.readFileSync(crpcPath, "utf8") : baselineCrpcSource),
|
|
10945
10981
|
managedBaselineContent: baselineCrpcSource,
|
|
10982
|
+
requiresExplicitOverwrite: false,
|
|
10946
10983
|
createReason: "Create crpc.ts with ratelimit middleware.",
|
|
10947
10984
|
updateReason: "Register ratelimit middleware in crpc.ts.",
|
|
10948
10985
|
skipReason: "Ratelimit middleware is already registered in crpc.ts."
|
|
@@ -12263,6 +12300,7 @@ function buildResendHttpRegistrationPlanFile(params) {
|
|
|
12263
12300
|
filePath: httpPath,
|
|
12264
12301
|
content: source,
|
|
12265
12302
|
managedBaselineContent: baselineHttpSource,
|
|
12303
|
+
requiresExplicitOverwrite: false,
|
|
12266
12304
|
createReason: "Create http.ts with resend webhook route.",
|
|
12267
12305
|
updateReason: "Register resend webhook in http.ts.",
|
|
12268
12306
|
skipReason: "Resend webhook is already registered in http.ts."
|
|
@@ -15541,7 +15579,8 @@ async function runScaffoldCommandFlow(params) {
|
|
|
15541
15579
|
cwd: scaffoldProjectDir,
|
|
15542
15580
|
created: applyResult.created,
|
|
15543
15581
|
updated: applyResult.updated,
|
|
15544
|
-
skipped: applyResult.skipped,
|
|
15582
|
+
skipped: [...applyResult.skipped, ...applyResult.refused],
|
|
15583
|
+
refused: applyResult.refused,
|
|
15545
15584
|
usedShadcn: params.template !== void 0 && params.template !== "expo",
|
|
15546
15585
|
template: params.template ?? null,
|
|
15547
15586
|
codegen: codegenResult.codegen,
|
|
@@ -15673,8 +15712,9 @@ async function applyPluginInstallPlanFiles(files, options) {
|
|
|
15673
15712
|
const result = {
|
|
15674
15713
|
created: [],
|
|
15675
15714
|
manualActions: [],
|
|
15676
|
-
|
|
15677
|
-
skipped: []
|
|
15715
|
+
refused: [],
|
|
15716
|
+
skipped: [],
|
|
15717
|
+
updated: []
|
|
15678
15718
|
};
|
|
15679
15719
|
for (const file of files) {
|
|
15680
15720
|
if (file.manualActions?.length) result.manualActions.push(...file.manualActions);
|
|
@@ -15690,7 +15730,7 @@ async function applyPluginInstallPlanFiles(files, options) {
|
|
|
15690
15730
|
continue;
|
|
15691
15731
|
}
|
|
15692
15732
|
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"
|
|
15733
|
+
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
15734
|
const existingContent = file.existingContent;
|
|
15695
15735
|
const matchesManagedBaseline = typeof existingContent === "string" && managedBaselines.some((managedBaselineContent) => isContentEquivalent({
|
|
15696
15736
|
filePath: file.path,
|
|
@@ -15700,7 +15740,7 @@ async function applyPluginInstallPlanFiles(files, options) {
|
|
|
15700
15740
|
let shouldOverwrite = options.overwrite || !requiresExplicitOverwrite || matchesManagedBaseline;
|
|
15701
15741
|
if (!shouldOverwrite && !options.yes && options.promptAdapter.isInteractive()) shouldOverwrite = await options.promptAdapter.confirm(`Overwrite ${file.path}?`);
|
|
15702
15742
|
if (!shouldOverwrite) {
|
|
15703
|
-
result.
|
|
15743
|
+
result.refused.push(file.path);
|
|
15704
15744
|
continue;
|
|
15705
15745
|
}
|
|
15706
15746
|
fs.mkdirSync(dirname(absolutePath), { recursive: true });
|
|
@@ -16970,4 +17010,4 @@ function isEntryPoint(entry, filename) {
|
|
|
16970
17010
|
}
|
|
16971
17011
|
|
|
16972
17012
|
//#endregion
|
|
16973
|
-
export { promptForScaffoldTemplateSelection as $, resolveCodegenTrimSegments as A,
|
|
17013
|
+
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 };
|