convex 1.40.0 → 1.41.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/CHANGELOG.md +11 -0
- package/dist/browser.bundle.js +1 -1
- package/dist/browser.bundle.js.map +1 -1
- package/dist/cjs/cli/aiFiles.js +2 -2
- package/dist/cjs/cli/aiFiles.js.map +1 -1
- package/dist/cjs/cli/configure.js +1 -4
- package/dist/cjs/cli/configure.js.map +2 -2
- package/dist/cjs/cli/convexExport.js +3 -3
- package/dist/cjs/cli/convexExport.js.map +1 -1
- package/dist/cjs/cli/convexImport.js +2 -2
- package/dist/cjs/cli/convexImport.js.map +1 -1
- package/dist/cjs/cli/dashboard.js +19 -6
- package/dist/cjs/cli/dashboard.js.map +3 -3
- package/dist/cjs/cli/data.js +2 -2
- package/dist/cjs/cli/data.js.map +1 -1
- package/dist/cjs/cli/deploy.js +5 -5
- package/dist/cjs/cli/deploy.js.map +2 -2
- package/dist/cjs/cli/deploymentCreate.js +11 -5
- package/dist/cjs/cli/deploymentCreate.js.map +2 -2
- package/dist/cjs/cli/deploymentSelect.js +5 -5
- package/dist/cjs/cli/deploymentSelect.js.map +1 -1
- package/dist/cjs/cli/deploymentTokenCreate.js +5 -13
- package/dist/cjs/cli/deploymentTokenCreate.js.map +2 -2
- package/dist/cjs/cli/deploymentTokenDelete.js +4 -11
- package/dist/cjs/cli/deploymentTokenDelete.js.map +2 -2
- package/dist/cjs/cli/dev.js +6 -5
- package/dist/cjs/cli/dev.js.map +2 -2
- package/dist/cjs/cli/env.js +16 -16
- package/dist/cjs/cli/env.js.map +2 -2
- package/dist/cjs/cli/envDefault.js +10 -10
- package/dist/cjs/cli/envDefault.js.map +1 -1
- package/dist/cjs/cli/insights.js +3 -3
- package/dist/cjs/cli/insights.js.map +1 -1
- package/dist/cjs/cli/lib/aiFiles/skills.js +2 -2
- package/dist/cjs/cli/lib/aiFiles/skills.js.map +2 -2
- package/dist/cjs/cli/lib/command.js +1 -1
- package/dist/cjs/cli/lib/command.js.map +1 -1
- package/dist/cjs/cli/lib/deployment.js.map +1 -1
- package/dist/cjs/cli/lib/deploymentSelection.js +39 -0
- package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/cjs/cli/lib/dev.js +31 -0
- package/dist/cjs/cli/lib/dev.js.map +2 -2
- package/dist/cjs/cli/lib/generateDocs.js +256 -0
- package/dist/cjs/cli/lib/generateDocs.js.map +7 -0
- package/dist/cjs/cli/lib/localDeployment/anonymous.js +24 -49
- package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +3 -3
- package/dist/cjs/cli/lib/localDeployment/bigBrain.js +0 -9
- package/dist/cjs/cli/lib/localDeployment/bigBrain.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/dashboard.js +30 -68
- package/dist/cjs/cli/lib/localDeployment/dashboard.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/download.js +14 -1
- package/dist/cjs/cli/lib/localDeployment/download.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/filePaths.js +33 -4
- package/dist/cjs/cli/lib/localDeployment/filePaths.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/localDeployment.js +37 -126
- package/dist/cjs/cli/lib/localDeployment/localDeployment.js.map +3 -3
- package/dist/cjs/cli/lib/localDeployment/secrets.js +91 -0
- package/dist/cjs/cli/lib/localDeployment/secrets.js.map +7 -0
- package/dist/cjs/cli/lib/localDeployment/upgrade.js +43 -28
- package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +3 -3
- package/dist/cjs/cli/lib/localDeployment/utils.js +0 -19
- package/dist/cjs/cli/lib/localDeployment/utils.js.map +3 -3
- package/dist/cjs/cli/lib/runTestFunction.js +3 -3
- package/dist/cjs/cli/lib/runTestFunction.js.map +1 -1
- package/dist/cjs/cli/run.js +5 -5
- package/dist/cjs/cli/run.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/impl/registration_impl.js +0 -1
- package/dist/cjs/server/impl/registration_impl.js.map +2 -2
- package/dist/cjs/server/index.js.map +2 -2
- package/dist/cjs/server/meta.js.map +1 -1
- package/dist/cjs/server/registration.js.map +1 -1
- package/dist/cjs-types/cli/configure.d.ts +3 -2
- package/dist/cjs-types/cli/configure.d.ts.map +1 -1
- package/dist/cjs-types/cli/dashboard.d.ts.map +1 -1
- package/dist/cjs-types/cli/deploymentCreate.d.ts.map +1 -1
- package/dist/cjs-types/cli/deploymentTokenCreate.d.ts.map +1 -1
- package/dist/cjs-types/cli/deploymentTokenDelete.d.ts.map +1 -1
- package/dist/cjs-types/cli/dev.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployApi/definitionConfig.d.ts +4 -4
- package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +16 -16
- package/dist/cjs-types/cli/lib/deployment.d.ts +0 -2
- package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +7 -0
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/dev.d.ts +2 -1
- package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/generateDocs.d.ts +20 -0
- package/dist/cjs-types/cli/lib/generateDocs.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/generateDocs.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/generateDocs.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/bigBrain.d.ts +2 -4
- package/dist/cjs-types/cli/lib/localDeployment/bigBrain.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts +9 -4
- package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/download.d.ts +11 -1
- package/dist/cjs-types/cli/lib/localDeployment/download.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/filePaths.d.ts +16 -5
- package/dist/cjs-types/cli/lib/localDeployment/filePaths.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts +1 -9
- package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/secrets.d.ts +31 -0
- package/dist/cjs-types/cli/lib/localDeployment/secrets.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts +6 -3
- package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +0 -2
- package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/versionApi.d.ts +2 -2
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
- package/dist/cjs-types/server/index.d.ts +1 -1
- package/dist/cjs-types/server/index.d.ts.map +1 -1
- package/dist/cjs-types/server/meta.d.ts +16 -0
- package/dist/cjs-types/server/meta.d.ts.map +1 -1
- package/dist/cjs-types/server/registration.d.ts +11 -5
- package/dist/cjs-types/server/registration.d.ts.map +1 -1
- package/dist/cli.bundle.cjs +66405 -67923
- package/dist/cli.bundle.cjs.map +4 -4
- package/dist/esm/cli/aiFiles.js +2 -2
- package/dist/esm/cli/aiFiles.js.map +1 -1
- package/dist/esm/cli/configure.js +1 -4
- package/dist/esm/cli/configure.js.map +2 -2
- package/dist/esm/cli/convexExport.js +3 -3
- package/dist/esm/cli/convexExport.js.map +1 -1
- package/dist/esm/cli/convexImport.js +2 -2
- package/dist/esm/cli/convexImport.js.map +1 -1
- package/dist/esm/cli/dashboard.js +16 -3
- package/dist/esm/cli/dashboard.js.map +2 -2
- package/dist/esm/cli/data.js +2 -2
- package/dist/esm/cli/data.js.map +1 -1
- package/dist/esm/cli/deploy.js +5 -5
- package/dist/esm/cli/deploy.js.map +2 -2
- package/dist/esm/cli/deploymentCreate.js +13 -9
- package/dist/esm/cli/deploymentCreate.js.map +2 -2
- package/dist/esm/cli/deploymentSelect.js +5 -5
- package/dist/esm/cli/deploymentSelect.js.map +1 -1
- package/dist/esm/cli/deploymentTokenCreate.js +9 -15
- package/dist/esm/cli/deploymentTokenCreate.js.map +2 -2
- package/dist/esm/cli/deploymentTokenDelete.js +8 -16
- package/dist/esm/cli/deploymentTokenDelete.js.map +2 -2
- package/dist/esm/cli/dev.js +6 -5
- package/dist/esm/cli/dev.js.map +2 -2
- package/dist/esm/cli/env.js +16 -16
- package/dist/esm/cli/env.js.map +2 -2
- package/dist/esm/cli/envDefault.js +10 -10
- package/dist/esm/cli/envDefault.js.map +1 -1
- package/dist/esm/cli/insights.js +3 -3
- package/dist/esm/cli/insights.js.map +1 -1
- package/dist/esm/cli/lib/aiFiles/skills.js +2 -2
- package/dist/esm/cli/lib/aiFiles/skills.js.map +2 -2
- package/dist/esm/cli/lib/command.js +1 -1
- package/dist/esm/cli/lib/command.js.map +1 -1
- package/dist/esm/cli/lib/deployment.js.map +1 -1
- package/dist/esm/cli/lib/deploymentSelection.js +38 -0
- package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/esm/cli/lib/dev.js +31 -0
- package/dist/esm/cli/lib/dev.js.map +2 -2
- package/dist/esm/cli/lib/generateDocs.js +233 -0
- package/dist/esm/cli/lib/generateDocs.js.map +7 -0
- package/dist/esm/cli/lib/localDeployment/anonymous.js +30 -61
- package/dist/esm/cli/lib/localDeployment/anonymous.js.map +3 -3
- package/dist/esm/cli/lib/localDeployment/bigBrain.js +0 -8
- package/dist/esm/cli/lib/localDeployment/bigBrain.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/dashboard.js +36 -69
- package/dist/esm/cli/lib/localDeployment/dashboard.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/download.js +15 -2
- package/dist/esm/cli/lib/localDeployment/download.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/filePaths.js +29 -2
- package/dist/esm/cli/lib/localDeployment/filePaths.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/localDeployment.js +40 -134
- package/dist/esm/cli/lib/localDeployment/localDeployment.js.map +3 -3
- package/dist/esm/cli/lib/localDeployment/secrets.js +57 -0
- package/dist/esm/cli/lib/localDeployment/secrets.js.map +7 -0
- package/dist/esm/cli/lib/localDeployment/upgrade.js +45 -28
- package/dist/esm/cli/lib/localDeployment/upgrade.js.map +3 -3
- package/dist/esm/cli/lib/localDeployment/utils.js +0 -7
- package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
- package/dist/esm/cli/lib/runTestFunction.js +3 -3
- package/dist/esm/cli/lib/runTestFunction.js.map +1 -1
- package/dist/esm/cli/run.js +5 -5
- package/dist/esm/cli/run.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/impl/registration_impl.js +0 -1
- package/dist/esm/server/impl/registration_impl.js.map +2 -2
- package/dist/esm/server/index.js.map +2 -2
- package/dist/esm-types/cli/configure.d.ts +3 -2
- package/dist/esm-types/cli/configure.d.ts.map +1 -1
- package/dist/esm-types/cli/dashboard.d.ts.map +1 -1
- package/dist/esm-types/cli/deploymentCreate.d.ts.map +1 -1
- package/dist/esm-types/cli/deploymentTokenCreate.d.ts.map +1 -1
- package/dist/esm-types/cli/deploymentTokenDelete.d.ts.map +1 -1
- package/dist/esm-types/cli/dev.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployApi/definitionConfig.d.ts +4 -4
- package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +16 -16
- package/dist/esm-types/cli/lib/deployment.d.ts +0 -2
- package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts +7 -0
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/dev.d.ts +2 -1
- package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/generateDocs.d.ts +20 -0
- package/dist/esm-types/cli/lib/generateDocs.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/generateDocs.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/generateDocs.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts +1 -1
- package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/bigBrain.d.ts +2 -4
- package/dist/esm-types/cli/lib/localDeployment/bigBrain.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts +9 -4
- package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/download.d.ts +11 -1
- package/dist/esm-types/cli/lib/localDeployment/download.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/filePaths.d.ts +16 -5
- package/dist/esm-types/cli/lib/localDeployment/filePaths.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts +1 -9
- package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/secrets.d.ts +31 -0
- package/dist/esm-types/cli/lib/localDeployment/secrets.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts +6 -3
- package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +0 -2
- package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/versionApi.d.ts +2 -2
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
- package/dist/esm-types/server/index.d.ts +1 -1
- package/dist/esm-types/server/index.d.ts.map +1 -1
- package/dist/esm-types/server/meta.d.ts +16 -0
- package/dist/esm-types/server/meta.d.ts.map +1 -1
- package/dist/esm-types/server/registration.d.ts +11 -5
- package/dist/esm-types/server/registration.d.ts.map +1 -1
- package/dist/react.bundle.js +1 -1
- package/dist/react.bundle.js.map +1 -1
- package/package.json +4 -2
- package/src/browser/sync/request_manager.test.ts +2 -2
- package/src/cli/aiFiles.ts +2 -2
- package/src/cli/configure.ts +4 -6
- package/src/cli/convexExport.ts +3 -3
- package/src/cli/convexImport.ts +2 -2
- package/src/cli/dashboard.ts +29 -3
- package/src/cli/data.ts +2 -2
- package/src/cli/deploy.ts +5 -5
- package/src/cli/deploymentCreate.test.ts +151 -24
- package/src/cli/deploymentCreate.ts +21 -11
- package/src/cli/deploymentSelect.ts +5 -5
- package/src/cli/deploymentSelection.test.ts +0 -3
- package/src/cli/deploymentToken.test.ts +34 -23
- package/src/cli/deploymentTokenCreate.ts +9 -21
- package/src/cli/deploymentTokenDelete.ts +8 -23
- package/src/cli/dev.ts +5 -4
- package/src/cli/env.ts +16 -16
- package/src/cli/envDefault.ts +10 -10
- package/src/cli/insights.ts +3 -3
- package/src/cli/lib/aiFiles/integration.test.ts +2 -0
- package/src/cli/lib/aiFiles/skills.ts +3 -3
- package/src/cli/lib/command.ts +2 -2
- package/src/cli/lib/deployment.ts +0 -5
- package/src/cli/lib/deploymentSelection.ts +67 -0
- package/src/cli/lib/dev.ts +39 -0
- package/src/cli/lib/generateDocs.test.ts +326 -0
- package/src/cli/lib/generateDocs.ts +393 -0
- package/src/cli/lib/localDeployment/anonymous.ts +48 -72
- package/src/cli/lib/localDeployment/bigBrain.ts +7 -15
- package/src/cli/lib/localDeployment/dashboard.ts +48 -80
- package/src/cli/lib/localDeployment/download.ts +34 -3
- package/src/cli/lib/localDeployment/filePaths.ts +66 -6
- package/src/cli/lib/localDeployment/localDeployment.ts +46 -184
- package/src/cli/lib/localDeployment/run.test.ts +6 -6
- package/src/cli/lib/localDeployment/secrets.test.ts +53 -0
- package/src/cli/lib/localDeployment/secrets.ts +93 -0
- package/src/cli/lib/localDeployment/tests/keygenFailure.mjs +9 -0
- package/src/cli/lib/localDeployment/tests/keygenSuccess.mjs +31 -0
- package/src/cli/lib/localDeployment/upgrade.ts +52 -38
- package/src/cli/lib/localDeployment/utils.ts +0 -10
- package/src/cli/lib/runTestFunction.ts +3 -3
- package/src/cli/run.ts +5 -5
- package/src/index.ts +1 -1
- package/src/server/impl/registration_impl.ts +0 -2
- package/src/server/index.ts +1 -0
- package/src/server/meta.ts +17 -0
- package/src/server/registration.test.ts +2 -35
- package/src/server/registration.ts +10 -19
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/localDeployment/filePaths.ts"],
|
|
4
|
-
"sourcesContent": ["/*\n~/.cache/convex\n binaries\n 0.0.1\n convex-local-backend[.exe] // convex-local-backend.exe on windows\n 0.0.2\n convex-local-backend[.exe]\n dashboard\n config.json\n out\n // if present, output files from building the self-hosted dashboard which can\n // be served using `npx serve`\n index.html\n\n\nDeployment state storage locations:\n\nNew default (project-local): .convex/local/default/\n - Used for both \"local\" (linked to Convex project) and \"anonymous\" deployments\n - One deployment per project/worktree/clone\n - This allows worktrees/clones to have isolated storage without conflicts\n\nLegacy (home directory) - used for backward compatibility if data already exists:\n - For \"local\" deployments: ~/.convex/convex-backend-state/local-{team}-{project}/\n - For \"anonymous\" deployments: ~/.convex/anonymous-convex-backend-state/{anonymous-deployment-name}/\n\n\n~/.convex\n convex-backend-state\n local-my_team-chess\n config.json // contains `LocalDeploymentConfig`\n convex_local_storage\n convex_local_backend.sqlite3\n local-my_team-whisper\n config.json\n convex_local_storage\n convex_local_backend.sqlite3\n anonymous-convex-backend-state\n config.json // contains { uuid: <uuid> }, used to identify the anonymous user\n anonymous-chess\n config.json\n convex_local_storage\n convex_local_backend.sqlite3\n*/\n\nimport path from \"path\";\nimport { cacheDir, rootDirectory } from \"../utils/utils.js\";\nimport { Context } from \"../../../bundler/context.js\";\nimport { logVerbose } from \"../../../bundler/log.js\";\nimport { recursivelyDelete } from \"../fsUtils.js\";\nimport crypto from \"crypto\";\n\n/**\n * Ensure the `.convex/.gitignore` file exists with the right content.\n * This prevents local deployment state from being committed to git.\n */\nexport function ensureDotConvexGitignore(\n ctx: Context,\n projectDir?: string,\n): void {\n const baseDir = projectDir ?? process.cwd();\n const dotConvexDir = path.join(baseDir, \".convex\");\n const gitignorePath = path.join(dotConvexDir, \".gitignore\");\n\n // Only create if .convex directory exists but .gitignore doesn't\n if (ctx.fs.exists(dotConvexDir) && !ctx.fs.exists(gitignorePath)) {\n ctx.fs.writeUtf8File(gitignorePath, \"/*\\n\");\n logVerbose(`Created .convex/.gitignore to ignore local/`);\n }\n}\n\n// Naming is hard, but \"local\" refers to deployments linked to a Convex project\n// and \"anonymous\" refers to deployments that are not linked to a Convex project\n// (but in both cases they are running locally).\nexport type LocalDeploymentKind = \"local\" | \"anonymous\";\n\nexport function rootDeploymentStateDir(kind: LocalDeploymentKind) {\n return path.join(\n rootDirectory(),\n kind === \"local\"\n ? \"convex-backend-state\"\n : \"anonymous-convex-backend-state\",\n );\n}\n\n/**\n * Get the project-local state directory for a deployment.\n * Always returns `.convex/local/default/` - one deployment per project.\n */\nexport function projectLocalStateDir(projectDir?: string): string {\n const baseDir = projectDir ?? process.cwd();\n return path.join(baseDir, \".convex\", \"local\", \"default\");\n}\n\n/**\n * Get the legacy home directory state path for a deployment.\n */\nexport function legacyDeploymentStateDir(\n deploymentKind: LocalDeploymentKind,\n deploymentName: string,\n): string {\n return path.join(rootDeploymentStateDir(deploymentKind), deploymentName);\n}\n\n/**\n * Get the state directory for a deployment.\n *\n * Priority order:\n * 1. Project-local directory if it has data (config.json exists)\n * 2. Legacy home directory if it exists (backward compatibility)\n * 3. Project-local directory for new deployments\n *\n * This ensures that when project-local storage is in use, it takes precedence\n * over any legacy directories that might exist with the same deployment name.\n */\nexport function deploymentStateDir(\n ctx: Context,\n deploymentKind: LocalDeploymentKind,\n deploymentName: string,\n projectDir?: string,\n): string {\n // Check if project-local has data - if so, use it\n // This takes precedence over legacy to support switching deployment types\n // within the same project directory\n const localDir = projectLocalStateDir(projectDir);\n const localConfigFile = path.join(localDir, \"config.json\");\n if (ctx.fs.exists(localConfigFile)) {\n logVerbose(\n `Using project-local state for deployment ${deploymentName}: ${localDir}`,\n );\n return localDir;\n }\n\n // Check if legacy data exists in home directory\n const legacyDir = legacyDeploymentStateDir(deploymentKind, deploymentName);\n if (ctx.fs.exists(legacyDir) && ctx.fs.stat(legacyDir).isDirectory()) {\n logVerbose(\n `Using legacy home directory state for deployment ${deploymentName}: ${legacyDir}`,\n );\n return legacyDir;\n }\n\n // Default to project-local for new deployments\n logVerbose(\n `Using project-local state for new deployment ${deploymentName}: ${localDir}`,\n );\n return localDir;\n}\n\n/**\n * Get the state directory for a deployment without checking for legacy data.\n * This always returns the project-local path.\n */\nexport function deploymentStateDirUnchecked(projectDir?: string): string {\n return projectLocalStateDir(projectDir);\n}\n\nexport type LocalDeploymentConfig = {\n ports: {\n cloud: number;\n site: number;\n };\n backendVersion: string;\n adminKey: string;\n // If not present, use the default instance secret for local backends\n instanceSecret?: string;\n // The deployment name (e.g., \"local-my_team-my_project\" or \"anonymous-chess\")\n // This is stored in the config for project-local storage where the directory\n // name is always \"default\" rather than the deployment name.\n deploymentName?: string;\n // Numeric id of the cloud project this local deployment is registered under.\n // Used to detect when the cloud project has changed since the last time it\n // was used (e.g. through `npx convex deployment select`).\n cloudProjectId: number | undefined;\n};\n\n/**\n * Load deployment config from a specific directory.\n * This is used when we already know the directory path.\n */\nexport function loadDeploymentConfigFromDir(\n ctx: Context,\n dir: string,\n): LocalDeploymentConfig | null {\n const configFile = path.join(dir, \"config.json\");\n if (!ctx.fs.exists(configFile)) {\n return null;\n }\n const content = ctx.fs.readUtf8File(configFile);\n try {\n return JSON.parse(content);\n } catch (e) {\n logVerbose(\n `Failed to parse local deployment config at ${dir}: ${e as any}`,\n );\n return null;\n }\n}\n\n/**\n * Load the project-local deployment config.\n * This returns the config from `.convex/local/default/` if it exists.\n * Returns both the config and the deployment name stored in it.\n */\nexport function loadProjectLocalConfig(\n ctx: Context,\n projectDir?: string,\n): { deploymentName: string; config: LocalDeploymentConfig } | null {\n const localDir = projectLocalStateDir(projectDir);\n const config = loadDeploymentConfigFromDir(ctx, localDir);\n if (config !== null && config.deploymentName) {\n logVerbose(\n `Found project-local deployment config for ${config.deploymentName}`,\n );\n return { deploymentName: config.deploymentName, config };\n }\n return null;\n}\n\n/**\n * Load deployment config for a deployment.\n *\n * Priority order (matching deploymentStateDir):\n * 1. Project-local directory if it has a matching config\n * 2. Legacy home directory\n */\nexport function loadDeploymentConfig(\n ctx: Context,\n deploymentKind: LocalDeploymentKind,\n deploymentName: string,\n projectDir?: string,\n): LocalDeploymentConfig | null {\n // Check project-local location first - matches deploymentStateDir priority\n const localDir = projectLocalStateDir(projectDir);\n const localConfig = loadDeploymentConfigFromDir(ctx, localDir);\n if (localConfig !== null) {\n // Only use if config matches the requested deployment name\n // (project-local can hold different deployments at different times)\n if (\n !localConfig.deploymentName ||\n localConfig.deploymentName === deploymentName\n ) {\n logVerbose(\n `Found deployment config in project-local location for ${deploymentName}`,\n );\n return localConfig;\n }\n logVerbose(\n `Project-local config is for ${localConfig.deploymentName}, not ${deploymentName}`,\n );\n }\n\n // Check legacy location\n const legacyDir = legacyDeploymentStateDir(deploymentKind, deploymentName);\n const legacyConfig = loadDeploymentConfigFromDir(ctx, legacyDir);\n if (legacyConfig !== null) {\n logVerbose(\n `Found deployment config in legacy location for ${deploymentName}`,\n );\n return legacyConfig;\n }\n\n return null;\n}\n\n/**\n * Save deployment config.\n *\n * If data already exists in the legacy home directory, continue using that\n * location. Otherwise, use the project-local directory. The deployment name\n * is always stored in the config for project-local storage.\n */\nexport function saveDeploymentConfig(\n ctx: Context,\n deploymentKind: LocalDeploymentKind,\n deploymentName: string,\n config: LocalDeploymentConfig,\n projectDir?: string,\n) {\n const dir = deploymentStateDir(\n ctx,\n deploymentKind,\n deploymentName,\n projectDir,\n );\n const configFile = path.join(dir, \"config.json\");\n if (!ctx.fs.exists(dir)) {\n ctx.fs.mkdir(dir, { recursive: true });\n }\n // Ensure .gitignore exists to prevent local state from being committed\n ensureDotConvexGitignore(ctx, projectDir);\n // Always include the deployment name in the config for project-local storage\n const configWithName = { ...config, deploymentName };\n ctx.fs.writeUtf8File(configFile, JSON.stringify(configWithName));\n}\n\nexport function binariesDir() {\n return path.join(cacheDir(), \"binaries\");\n}\n\nexport function dashboardZip() {\n return path.join(dashboardDir(), \"dashboard.zip\");\n}\n\nexport function versionedBinaryDir(version: string) {\n return path.join(binariesDir(), version);\n}\n\nexport function executablePath(version: string) {\n return path.join(versionedBinaryDir(version), executableName());\n}\n\nexport function executableName() {\n const ext = process.platform === \"win32\" ? \".exe\" : \"\";\n return `convex-local-backend${ext}`;\n}\n\nexport function dashboardDir() {\n return path.join(cacheDir(), \"dashboard\");\n}\n\nexport async function resetDashboardDir(ctx: Context) {\n const dir = dashboardDir();\n if (ctx.fs.exists(dir)) {\n await recursivelyDelete(ctx, dir);\n }\n ctx.fs.mkdir(dir, { recursive: true });\n}\n\nexport function dashboardOutDir() {\n return path.join(dashboardDir(), \"out\");\n}\n\nexport type DashboardConfig = {\n port: number;\n apiPort: number;\n version: string;\n};\nexport function loadDashboardConfig(ctx: Context) {\n const configFile = path.join(dashboardDir(), \"config.json\");\n if (!ctx.fs.exists(configFile)) {\n return null;\n }\n const content = ctx.fs.readUtf8File(configFile);\n try {\n return JSON.parse(content);\n } catch (e) {\n logVerbose(`Failed to parse dashboard config: ${e as any}`);\n return null;\n }\n}\n\nexport function saveDashboardConfig(ctx: Context, config: DashboardConfig) {\n const configFile = path.join(dashboardDir(), \"config.json\");\n if (!ctx.fs.exists(dashboardDir())) {\n ctx.fs.mkdir(dashboardDir(), { recursive: true });\n }\n ctx.fs.writeUtf8File(configFile, JSON.stringify(config));\n}\n\nexport function loadUuidForAnonymousUser(ctx: Context) {\n const configFile = path.join(\n rootDeploymentStateDir(\"anonymous\"),\n \"config.json\",\n );\n if (!ctx.fs.exists(configFile)) {\n return null;\n }\n const content = ctx.fs.readUtf8File(configFile);\n try {\n const config = JSON.parse(content);\n return config.uuid ?? null;\n } catch (e) {\n logVerbose(`Failed to parse uuid for anonymous user: ${e as any}`);\n return null;\n }\n}\n\nexport function ensureUuidForAnonymousUser(ctx: Context) {\n const uuid = loadUuidForAnonymousUser(ctx);\n if (uuid) {\n return uuid;\n }\n const newUuid = crypto.randomUUID();\n const anonymousDir = rootDeploymentStateDir(\"anonymous\");\n if (!ctx.fs.exists(anonymousDir)) {\n ctx.fs.mkdir(anonymousDir, { recursive: true });\n }\n ctx.fs.writeUtf8File(\n path.join(anonymousDir, \"config.json\"),\n JSON.stringify({ uuid: newUuid }),\n );\n return newUuid;\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["/*\n~/.cache/convex\n binaries\n 0.0.1\n convex-local-backend[.exe] // convex-local-backend.exe on windows\n 0.0.2\n convex-local-backend[.exe]\n dashboard\n config.json // `GlobalDashboardConfig`\n out\n // if present, output files from building the self-hosted dashboard which can\n // be served using `npx serve`\n index.html\n\n\nDeployment state storage locations:\n\nNew default (project-local): .convex/local/default/\n - Used for both \"local\" (linked to Convex project) and \"anonymous\" deployments\n - One deployment per project/worktree/clone\n - This allows worktrees/clones to have isolated storage without conflicts\n\nLegacy (home directory) - used for backward compatibility if data already exists:\n - For \"local\" deployments: ~/.convex/convex-backend-state/local-{team}-{project}/\n - For \"anonymous\" deployments: ~/.convex/anonymous-convex-backend-state/{anonymous-deployment-name}/\n\nFor anonymous deployments, the locally running dashboard's `{ port }`\nis stored as `dashboard.json` next to that deployment's `config.json` (see\n`ProjectDashboardConfig`), wherever the deployment lives.\n\n\n~/.convex\n convex-backend-state\n local-my_team-chess\n config.json // contains `LocalDeploymentConfig`\n convex_local_storage\n convex_local_backend.sqlite3\n local-my_team-whisper\n config.json\n convex_local_storage\n convex_local_backend.sqlite3\n anonymous-convex-backend-state\n config.json // contains { uuid: <uuid> }, used to identify the anonymous user\n anonymous-chess\n config.json\n convex_local_storage\n convex_local_backend.sqlite3\n*/\n\nimport path from \"path\";\nimport { cacheDir, rootDirectory } from \"../utils/utils.js\";\nimport { Context } from \"../../../bundler/context.js\";\nimport { logVerbose } from \"../../../bundler/log.js\";\nimport { recursivelyDelete } from \"../fsUtils.js\";\nimport crypto from \"crypto\";\n\n/**\n * Ensure the `.convex/.gitignore` file exists with the right content.\n * This prevents local deployment state from being committed to git.\n */\nexport function ensureDotConvexGitignore(\n ctx: Context,\n projectDir?: string,\n): void {\n const baseDir = projectDir ?? process.cwd();\n const dotConvexDir = path.join(baseDir, \".convex\");\n const gitignorePath = path.join(dotConvexDir, \".gitignore\");\n\n // Only create if .convex directory exists but .gitignore doesn't\n if (ctx.fs.exists(dotConvexDir) && !ctx.fs.exists(gitignorePath)) {\n ctx.fs.writeUtf8File(gitignorePath, \"/*\\n\");\n logVerbose(`Created .convex/.gitignore to ignore local/`);\n }\n}\n\n// Naming is hard, but \"local\" refers to deployments linked to a Convex project\n// and \"anonymous\" refers to deployments that are not linked to a Convex project\n// (but in both cases they are running locally).\nexport type LocalDeploymentKind = \"local\" | \"anonymous\";\n\nexport function rootDeploymentStateDir(kind: LocalDeploymentKind) {\n return path.join(\n rootDirectory(),\n kind === \"local\"\n ? \"convex-backend-state\"\n : \"anonymous-convex-backend-state\",\n );\n}\n\n/**\n * Get the project-local state directory for a deployment.\n * Always returns `.convex/local/default/` - one deployment per project.\n */\nexport function projectLocalStateDir(projectDir?: string): string {\n const baseDir = projectDir ?? process.cwd();\n return path.join(baseDir, \".convex\", \"local\", \"default\");\n}\n\n/**\n * Get the legacy home directory state path for a deployment.\n */\nexport function legacyDeploymentStateDir(\n deploymentKind: LocalDeploymentKind,\n deploymentName: string,\n): string {\n return path.join(rootDeploymentStateDir(deploymentKind), deploymentName);\n}\n\n/**\n * Get the state directory for a deployment.\n *\n * Priority order:\n * 1. Project-local directory if it has data (config.json exists)\n * 2. Legacy home directory if it exists (backward compatibility)\n * 3. Project-local directory for new deployments\n *\n * This ensures that when project-local storage is in use, it takes precedence\n * over any legacy directories that might exist with the same deployment name.\n */\nexport function deploymentStateDir(\n ctx: Context,\n deploymentKind: LocalDeploymentKind,\n deploymentName: string,\n projectDir?: string,\n): string {\n // Check if project-local has data - if so, use it\n // This takes precedence over legacy to support switching deployment types\n // within the same project directory\n const localDir = projectLocalStateDir(projectDir);\n const localConfigFile = path.join(localDir, \"config.json\");\n if (ctx.fs.exists(localConfigFile)) {\n logVerbose(\n `Using project-local state for deployment ${deploymentName}: ${localDir}`,\n );\n return localDir;\n }\n\n // Check if legacy data exists in home directory\n const legacyDir = legacyDeploymentStateDir(deploymentKind, deploymentName);\n if (ctx.fs.exists(legacyDir) && ctx.fs.stat(legacyDir).isDirectory()) {\n logVerbose(\n `Using legacy home directory state for deployment ${deploymentName}: ${legacyDir}`,\n );\n return legacyDir;\n }\n\n // Default to project-local for new deployments\n logVerbose(\n `Using project-local state for new deployment ${deploymentName}: ${localDir}`,\n );\n return localDir;\n}\n\n/**\n * Get the state directory for a deployment without checking for legacy data.\n * This always returns the project-local path.\n */\nexport function deploymentStateDirUnchecked(projectDir?: string): string {\n return projectLocalStateDir(projectDir);\n}\n\nexport type LocalDeploymentConfig = {\n ports: {\n cloud: number;\n site: number;\n };\n backendVersion: string;\n adminKey: string;\n // If not present, use the default instance secret for local backends\n instanceSecret?: string;\n // The deployment name (e.g., \"local-my_team-my_project\" or \"anonymous-chess\")\n // This is stored in the config for project-local storage where the directory\n // name is always \"default\" rather than the deployment name.\n deploymentName?: string;\n // Numeric id of the cloud project this local deployment is registered under.\n // Used to detect when the cloud project has changed since the last time it\n // was used (e.g. through `npx convex deployment select`).\n cloudProjectId: number | undefined;\n};\n\n/**\n * Load deployment config from a specific directory.\n * This is used when we already know the directory path.\n */\nexport function loadDeploymentConfigFromDir(\n ctx: Context,\n dir: string,\n): LocalDeploymentConfig | null {\n const configFile = path.join(dir, \"config.json\");\n if (!ctx.fs.exists(configFile)) {\n return null;\n }\n const content = ctx.fs.readUtf8File(configFile);\n try {\n return JSON.parse(content);\n } catch (e) {\n logVerbose(\n `Failed to parse local deployment config at ${dir}: ${e as any}`,\n );\n return null;\n }\n}\n\n/**\n * Load the project-local deployment config.\n * This returns the config from `.convex/local/default/` if it exists.\n * Returns both the config and the deployment name stored in it.\n */\nexport function loadProjectLocalConfig(\n ctx: Context,\n projectDir?: string,\n): { deploymentName: string; config: LocalDeploymentConfig } | null {\n const localDir = projectLocalStateDir(projectDir);\n const config = loadDeploymentConfigFromDir(ctx, localDir);\n if (config !== null && config.deploymentName) {\n logVerbose(\n `Found project-local deployment config for ${config.deploymentName}`,\n );\n return { deploymentName: config.deploymentName, config };\n }\n return null;\n}\n\n/**\n * Load deployment config for a deployment.\n *\n * Priority order (matching deploymentStateDir):\n * 1. Project-local directory if it has a matching config\n * 2. Legacy home directory\n */\nexport function loadDeploymentConfig(\n ctx: Context,\n deploymentKind: LocalDeploymentKind,\n deploymentName: string,\n projectDir?: string,\n): LocalDeploymentConfig | null {\n // Check project-local location first - matches deploymentStateDir priority\n const localDir = projectLocalStateDir(projectDir);\n const localConfig = loadDeploymentConfigFromDir(ctx, localDir);\n if (localConfig !== null) {\n // Only use if config matches the requested deployment name\n // (project-local can hold different deployments at different times)\n if (\n !localConfig.deploymentName ||\n localConfig.deploymentName === deploymentName\n ) {\n logVerbose(\n `Found deployment config in project-local location for ${deploymentName}`,\n );\n return localConfig;\n }\n logVerbose(\n `Project-local config is for ${localConfig.deploymentName}, not ${deploymentName}`,\n );\n }\n\n // Check legacy location\n const legacyDir = legacyDeploymentStateDir(deploymentKind, deploymentName);\n const legacyConfig = loadDeploymentConfigFromDir(ctx, legacyDir);\n if (legacyConfig !== null) {\n logVerbose(\n `Found deployment config in legacy location for ${deploymentName}`,\n );\n return legacyConfig;\n }\n\n return null;\n}\n\n/**\n * Save deployment config.\n *\n * If data already exists in the legacy home directory, continue using that\n * location. Otherwise, use the project-local directory. The deployment name\n * is always stored in the config for project-local storage.\n */\nexport function saveDeploymentConfig(\n ctx: Context,\n deploymentKind: LocalDeploymentKind,\n deploymentName: string,\n config: LocalDeploymentConfig,\n projectDir?: string,\n) {\n const dir = deploymentStateDir(\n ctx,\n deploymentKind,\n deploymentName,\n projectDir,\n );\n const configFile = path.join(dir, \"config.json\");\n if (!ctx.fs.exists(dir)) {\n ctx.fs.mkdir(dir, { recursive: true });\n }\n // Ensure .gitignore exists to prevent local state from being committed\n ensureDotConvexGitignore(ctx, projectDir);\n // Always include the deployment name in the config for project-local storage\n const configWithName = { ...config, deploymentName };\n ctx.fs.writeUtf8File(configFile, JSON.stringify(configWithName));\n}\n\nexport function binariesDir() {\n return path.join(cacheDir(), \"binaries\");\n}\n\nexport function dashboardZip() {\n return path.join(dashboardDir(), \"dashboard.zip\");\n}\n\nexport function versionedBinaryDir(version: string) {\n return path.join(binariesDir(), version);\n}\n\nexport function executablePath(version: string) {\n return path.join(versionedBinaryDir(version), executableName());\n}\n\nexport function executableName() {\n const ext = process.platform === \"win32\" ? \".exe\" : \"\";\n return `convex-local-backend${ext}`;\n}\n\nexport function dashboardDir() {\n return path.join(cacheDir(), \"dashboard\");\n}\n\nexport async function resetDashboardDir(ctx: Context) {\n const dir = dashboardDir();\n if (ctx.fs.exists(dir)) {\n await recursivelyDelete(ctx, dir);\n }\n ctx.fs.mkdir(dir, { recursive: true });\n}\n\nexport function dashboardOutDir() {\n return path.join(dashboardDir(), \"out\");\n}\n\n/**\n * Global dashboard config in ~/.cache/convex/dashboard/config.json.\n */\nexport type GlobalDashboardConfig = {\n version: string;\n\n // Previous versions of the Convex CLI would also store\n // fields here for ports. They are now in ProjectDashboardConfig.\n};\n\nexport function loadGlobalDashboardConfig(\n ctx: Context,\n): GlobalDashboardConfig | null {\n const configFile = path.join(dashboardDir(), \"config.json\");\n if (!ctx.fs.exists(configFile)) {\n return null;\n }\n const content = ctx.fs.readUtf8File(configFile);\n try {\n return JSON.parse(content);\n } catch (e) {\n logVerbose(`Failed to parse dashboard config: ${e as any}`);\n return null;\n }\n}\n\nexport function saveGlobalDashboardConfig(\n ctx: Context,\n config: GlobalDashboardConfig,\n) {\n const configFile = path.join(dashboardDir(), \"config.json\");\n if (!ctx.fs.exists(dashboardDir())) {\n ctx.fs.mkdir(dashboardDir(), { recursive: true });\n }\n ctx.fs.writeUtf8File(configFile, JSON.stringify(config));\n}\n\n/**\n * Project-scoped dashboard config (for anonymous dev) in\n * project/.convex/local/default/dashboard.json\n * (or legacyDeploymentStateDir/dashboard.json)\n */\nexport type ProjectDashboardConfig = {\n port: number;\n};\n\nfunction dashboardConfigPath(ctx: Context, deploymentName: string) {\n return path.join(\n deploymentStateDir(ctx, \"anonymous\", deploymentName),\n \"dashboard.json\",\n );\n}\n\nexport function loadProjectDashboardConfig(\n ctx: Context,\n deploymentName: string,\n): ProjectDashboardConfig | null {\n const configFile = dashboardConfigPath(ctx, deploymentName);\n if (!ctx.fs.exists(configFile)) {\n return null;\n }\n const content = ctx.fs.readUtf8File(configFile);\n try {\n return JSON.parse(content);\n } catch (e) {\n logVerbose(`Failed to parse project dashboard config: ${e as any}`);\n return null;\n }\n}\n\nexport function saveProjectDashboardConfig(\n ctx: Context,\n deploymentName: string,\n config: ProjectDashboardConfig,\n) {\n const configPath = dashboardConfigPath(ctx, deploymentName);\n const directoryPath = path.dirname(configPath);\n if (!ctx.fs.exists(directoryPath)) {\n ctx.fs.mkdir(directoryPath, { recursive: true });\n }\n ctx.fs.writeUtf8File(configPath, JSON.stringify(config));\n}\n\nexport function loadUuidForAnonymousUser(ctx: Context) {\n const configFile = path.join(\n rootDeploymentStateDir(\"anonymous\"),\n \"config.json\",\n );\n if (!ctx.fs.exists(configFile)) {\n return null;\n }\n const content = ctx.fs.readUtf8File(configFile);\n try {\n const config = JSON.parse(content);\n return config.uuid ?? null;\n } catch (e) {\n logVerbose(`Failed to parse uuid for anonymous user: ${e as any}`);\n return null;\n }\n}\n\nexport function ensureUuidForAnonymousUser(ctx: Context) {\n const uuid = loadUuidForAnonymousUser(ctx);\n if (uuid) {\n return uuid;\n }\n const newUuid = crypto.randomUUID();\n const anonymousDir = rootDeploymentStateDir(\"anonymous\");\n if (!ctx.fs.exists(anonymousDir)) {\n ctx.fs.mkdir(anonymousDir, { recursive: true });\n }\n ctx.fs.writeUtf8File(\n path.join(anonymousDir, \"config.json\"),\n JSON.stringify({ uuid: newUuid }),\n );\n return newUuid;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -17,33 +17,25 @@ import {
|
|
|
17
17
|
loadDeploymentConfigFromDir,
|
|
18
18
|
loadProjectLocalConfig,
|
|
19
19
|
legacyDeploymentStateDir,
|
|
20
|
-
rootDeploymentStateDir
|
|
21
|
-
saveDeploymentConfig
|
|
20
|
+
rootDeploymentStateDir
|
|
22
21
|
} from "./filePaths.js";
|
|
23
22
|
import {
|
|
24
|
-
ensureBackendRunning,
|
|
25
23
|
ensureBackendStopped,
|
|
26
24
|
localDeploymentUrl,
|
|
27
|
-
runLocalBackend,
|
|
28
25
|
withRunningBackend
|
|
29
26
|
} from "./run.js";
|
|
30
|
-
import {
|
|
31
|
-
import { promptSearch } from "../utils/prompts.js";
|
|
27
|
+
import { handlePotentialUpgradeAndStart } from "./upgrade.js";
|
|
32
28
|
import { LocalDeploymentError, printLocalDeploymentOnError } from "./errors.js";
|
|
33
29
|
import {
|
|
34
30
|
chooseLocalBackendPorts,
|
|
35
|
-
printLocalDeploymentWelcomeMessage
|
|
36
|
-
isOffline,
|
|
37
|
-
LOCAL_BACKEND_INSTANCE_SECRET
|
|
31
|
+
printLocalDeploymentWelcomeMessage
|
|
38
32
|
} from "./utils.js";
|
|
39
33
|
import { ensureBackendBinaryDownloaded } from "./download.js";
|
|
40
34
|
import { defaultEnvBackend } from "../defaultEnv.js";
|
|
41
35
|
import { deploymentEnvBackend } from "../env.js";
|
|
42
36
|
import { getProjectDetails } from "../deploymentSelection.js";
|
|
37
|
+
import { LEGACY_LOCAL_BACKEND_INSTANCE_SECRET } from "./secrets.js";
|
|
43
38
|
export async function handleLocalDeployment(ctx, options) {
|
|
44
|
-
if (await isOffline()) {
|
|
45
|
-
return handleOffline(ctx, options);
|
|
46
|
-
}
|
|
47
39
|
const existingDeploymentForProject = await getExistingDeployment(ctx, {
|
|
48
40
|
projectSlug: options.projectSlug,
|
|
49
41
|
teamSlug: options.teamSlug
|
|
@@ -79,37 +71,29 @@ export async function handleLocalDeployment(ctx, options) {
|
|
|
79
71
|
requestedPorts: options.ports,
|
|
80
72
|
suggestedPorts: existingDeploymentForProject?.config.ports
|
|
81
73
|
});
|
|
82
|
-
const { deploymentName,
|
|
74
|
+
const { deploymentName, projectId } = await bigBrainStart(ctx, {
|
|
83
75
|
port: cloudPort,
|
|
84
76
|
projectSlug: options.projectSlug,
|
|
85
77
|
teamSlug: options.teamSlug,
|
|
86
78
|
instanceName: existingDeploymentForProject?.deploymentName ?? null
|
|
87
79
|
});
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
80
|
+
const { cleanupHandle, adminKey } = await handlePotentialUpgradeAndStart(
|
|
81
|
+
ctx,
|
|
82
|
+
{
|
|
83
|
+
deploymentKind: "local",
|
|
91
84
|
deploymentName,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
85
|
+
oldVersion: existingDeploymentForProject?.config.backendVersion ?? null,
|
|
86
|
+
newBinaryPath: binaryPath,
|
|
87
|
+
newVersion: version,
|
|
88
|
+
ports: { cloud: cloudPort, site: sitePort },
|
|
89
|
+
existingCredentials: existingDeploymentForProject?.config ? {
|
|
90
|
+
adminKey: existingDeploymentForProject?.config.adminKey,
|
|
91
|
+
instanceSecret: existingDeploymentForProject?.config.instanceSecret ?? LEGACY_LOCAL_BACKEND_INSTANCE_SECRET
|
|
92
|
+
} : null,
|
|
93
|
+
forceUpgrade: options.forceUpgrade,
|
|
94
|
+
cloudProjectId: projectId
|
|
96
95
|
}
|
|
97
|
-
|
|
98
|
-
instanceName: deploymentName
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
const { cleanupHandle } = await handlePotentialUpgrade(ctx, {
|
|
102
|
-
deploymentKind: "local",
|
|
103
|
-
deploymentName,
|
|
104
|
-
oldVersion: existingDeploymentForProject?.config.backendVersion ?? null,
|
|
105
|
-
newBinaryPath: binaryPath,
|
|
106
|
-
newVersion: version,
|
|
107
|
-
ports: { cloud: cloudPort, site: sitePort },
|
|
108
|
-
adminKey,
|
|
109
|
-
instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,
|
|
110
|
-
forceUpgrade: options.forceUpgrade,
|
|
111
|
-
cloudProjectId: projectId
|
|
112
|
-
});
|
|
96
|
+
);
|
|
113
97
|
if (isFirstTime) {
|
|
114
98
|
await importDefaultEnvVars(ctx, {
|
|
115
99
|
teamSlug: options.teamSlug,
|
|
@@ -120,20 +104,29 @@ export async function handleLocalDeployment(ctx, options) {
|
|
|
120
104
|
});
|
|
121
105
|
}
|
|
122
106
|
let activityTimeout = null;
|
|
123
|
-
|
|
107
|
+
let activityPingStopped = false;
|
|
108
|
+
async function activityPing() {
|
|
109
|
+
if (activityPingStopped) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
await bigBrainRecordActivity(ctx, {
|
|
114
|
+
instanceName: deploymentName,
|
|
115
|
+
adminKey
|
|
116
|
+
});
|
|
117
|
+
} catch {
|
|
118
|
+
}
|
|
119
|
+
if (activityPingStopped) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
124
122
|
activityTimeout = setTimeout(async () => {
|
|
125
|
-
|
|
126
|
-
await bigBrainRecordActivity(ctx, {
|
|
127
|
-
instanceName: deploymentName
|
|
128
|
-
});
|
|
129
|
-
} catch {
|
|
130
|
-
}
|
|
131
|
-
scheduleActivityPing();
|
|
123
|
+
void activityPing();
|
|
132
124
|
}, 6e4);
|
|
133
|
-
}
|
|
134
|
-
|
|
125
|
+
}
|
|
126
|
+
void activityPing();
|
|
135
127
|
const cleanupFunc = ctx.removeCleanup(cleanupHandle);
|
|
136
128
|
ctx.registerCleanup(async (exitCode, err) => {
|
|
129
|
+
activityPingStopped = true;
|
|
137
130
|
if (activityTimeout !== null) {
|
|
138
131
|
clearTimeout(activityTimeout);
|
|
139
132
|
}
|
|
@@ -150,8 +143,7 @@ export async function handleLocalDeployment(ctx, options) {
|
|
|
150
143
|
deploymentName,
|
|
151
144
|
deploymentUrl: localDeploymentUrl(cloudPort),
|
|
152
145
|
reference: null,
|
|
153
|
-
isDefault: false
|
|
154
|
-
onActivity
|
|
146
|
+
isDefault: false
|
|
155
147
|
};
|
|
156
148
|
}
|
|
157
149
|
export async function loadLocalDeploymentCredentials(ctx, deploymentName) {
|
|
@@ -169,55 +161,6 @@ export async function loadLocalDeploymentCredentials(ctx, deploymentName) {
|
|
|
169
161
|
adminKey: config.adminKey
|
|
170
162
|
};
|
|
171
163
|
}
|
|
172
|
-
async function handleOffline(ctx, options) {
|
|
173
|
-
const { deploymentName, config } = await chooseFromExistingLocalDeployments(ctx);
|
|
174
|
-
const { binaryPath } = await ensureBackendBinaryDownloaded(ctx, {
|
|
175
|
-
kind: "version",
|
|
176
|
-
version: config.backendVersion
|
|
177
|
-
});
|
|
178
|
-
const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {
|
|
179
|
-
requestedPorts: options.ports
|
|
180
|
-
// FIXME: This doesn’t try to reuse the ports already assigned in the config.
|
|
181
|
-
// Please update this if we ever support offline mode (currently this is dead code).
|
|
182
|
-
});
|
|
183
|
-
saveDeploymentConfig(ctx, "local", deploymentName, config);
|
|
184
|
-
await runLocalBackend(ctx, {
|
|
185
|
-
binaryPath,
|
|
186
|
-
ports: { cloud: cloudPort, site: sitePort },
|
|
187
|
-
deploymentName,
|
|
188
|
-
deploymentKind: "local",
|
|
189
|
-
instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,
|
|
190
|
-
isLatestVersion: false
|
|
191
|
-
});
|
|
192
|
-
return {
|
|
193
|
-
adminKey: config.adminKey,
|
|
194
|
-
deploymentName,
|
|
195
|
-
deploymentUrl: localDeploymentUrl(cloudPort),
|
|
196
|
-
reference: null,
|
|
197
|
-
isDefault: false,
|
|
198
|
-
onActivity: async (isOffline2, wasOffline) => {
|
|
199
|
-
await ensureBackendRunning(ctx, {
|
|
200
|
-
cloudPort,
|
|
201
|
-
deploymentName,
|
|
202
|
-
maxTimeSecs: 5
|
|
203
|
-
});
|
|
204
|
-
if (isOffline2) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
if (wasOffline) {
|
|
208
|
-
await bigBrainStart(ctx, {
|
|
209
|
-
port: cloudPort,
|
|
210
|
-
projectSlug: options.projectSlug,
|
|
211
|
-
teamSlug: options.teamSlug,
|
|
212
|
-
instanceName: deploymentName
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
await bigBrainRecordActivity(ctx, {
|
|
216
|
-
instanceName: deploymentName
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
164
|
async function getExistingDeployment(ctx, options) {
|
|
222
165
|
const { projectSlug, teamSlug } = options;
|
|
223
166
|
const projectLocal = loadProjectLocalConfig(ctx);
|
|
@@ -258,43 +201,6 @@ async function getLegacyLocalDeployments(ctx) {
|
|
|
258
201
|
return [];
|
|
259
202
|
});
|
|
260
203
|
}
|
|
261
|
-
async function getLocalDeployments(ctx) {
|
|
262
|
-
const deployments = [];
|
|
263
|
-
const projectLocal = loadProjectLocalConfig(ctx);
|
|
264
|
-
if (projectLocal !== null && projectLocal.deploymentName.startsWith("local-")) {
|
|
265
|
-
deployments.push(projectLocal);
|
|
266
|
-
}
|
|
267
|
-
const legacyDeployments = await getLegacyLocalDeployments(ctx);
|
|
268
|
-
for (const legacy of legacyDeployments) {
|
|
269
|
-
if (!deployments.some((d) => d.deploymentName === legacy.deploymentName)) {
|
|
270
|
-
deployments.push(legacy);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
return deployments;
|
|
274
|
-
}
|
|
275
|
-
async function chooseFromExistingLocalDeployments(ctx) {
|
|
276
|
-
const localDeployments = await getLocalDeployments(ctx);
|
|
277
|
-
if (localDeployments.length === 0) {
|
|
278
|
-
return ctx.crash({
|
|
279
|
-
exitCode: 1,
|
|
280
|
-
errorType: "fatal",
|
|
281
|
-
printedMessage: "No local deployments found. Please run `npx convex dev` while online first."
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
if (localDeployments.length === 1) {
|
|
285
|
-
logVerbose(
|
|
286
|
-
`Auto-selecting the only local deployment: ${localDeployments[0].deploymentName}`
|
|
287
|
-
);
|
|
288
|
-
return localDeployments[0];
|
|
289
|
-
}
|
|
290
|
-
return promptSearch(ctx, {
|
|
291
|
-
message: "Choose from an existing local deployment:",
|
|
292
|
-
choices: localDeployments.map((d) => ({
|
|
293
|
-
name: d.deploymentName,
|
|
294
|
-
value: d
|
|
295
|
-
}))
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
204
|
export async function importDefaultEnvVars(ctx, {
|
|
299
205
|
teamSlug,
|
|
300
206
|
projectSlug,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/localDeployment/localDeployment.ts"],
|
|
4
|
-
"sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport {\n logFinishedStep,\n logVerbose,\n logWarning,\n showSpinner,\n stopSpinner,\n} from \"../../../bundler/log.js\";\nimport { logAndHandleFetchError, ThrowingFetchError } from \"../utils/utils.js\";\nimport {\n bigBrainPause,\n bigBrainRecordActivity,\n bigBrainStart,\n} from \"./bigBrain.js\";\nimport {\n LocalDeploymentConfig,\n loadDeploymentConfig,\n loadDeploymentConfigFromDir,\n loadProjectLocalConfig,\n legacyDeploymentStateDir,\n rootDeploymentStateDir,\n saveDeploymentConfig,\n} from \"./filePaths.js\";\nimport {\n ensureBackendRunning,\n ensureBackendStopped,\n localDeploymentUrl,\n runLocalBackend,\n withRunningBackend,\n} from \"./run.js\";\nimport { handlePotentialUpgrade } from \"./upgrade.js\";\nimport { OnDeploymentActivityFunc } from \"../deployment.js\";\nimport { promptSearch } from \"../utils/prompts.js\";\nimport { LocalDeploymentError, printLocalDeploymentOnError } from \"./errors.js\";\nimport {\n chooseLocalBackendPorts,\n printLocalDeploymentWelcomeMessage,\n isOffline,\n LOCAL_BACKEND_INSTANCE_SECRET,\n} from \"./utils.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nimport { defaultEnvBackend } from \"../defaultEnv.js\";\nimport { deploymentEnvBackend, EnvVar } from \"../env.js\";\nimport { getProjectDetails } from \"../deploymentSelection.js\";\n\nexport type DeploymentDetails = {\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n reference: string | null;\n isDefault: boolean;\n onActivity: OnDeploymentActivityFunc;\n};\n\nexport async function handleLocalDeployment(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n ports: {\n cloud: number | undefined;\n site: number | undefined;\n };\n backendVersion?: string | undefined;\n forceUpgrade: boolean;\n },\n): Promise<DeploymentDetails> {\n if (await isOffline()) {\n return handleOffline(ctx, options);\n }\n\n const existingDeploymentForProject = await getExistingDeployment(ctx, {\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n });\n const isFirstTime = existingDeploymentForProject === null;\n if (isFirstTime) {\n printLocalDeploymentWelcomeMessage();\n }\n ctx.registerCleanup(async (_exitCode, err) => {\n if (err instanceof LocalDeploymentError) {\n printLocalDeploymentOnError();\n }\n });\n if (existingDeploymentForProject !== null) {\n logVerbose(`Found existing deployment for project ${options.projectSlug}`);\n // If it's still running for some reason, exit and tell the user to kill it.\n // It's fine if a different backend is running on these ports though since we'll\n // pick new ones.\n await ensureBackendStopped(ctx, {\n ports: {\n cloud: existingDeploymentForProject.config.ports.cloud,\n },\n maxTimeSecs: 5,\n deploymentName: existingDeploymentForProject.deploymentName,\n allowOtherDeployments: true,\n });\n }\n\n const { binaryPath, version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? {\n kind: \"latest\",\n allowedVersion: existingDeploymentForProject?.config.backendVersion,\n }\n : { kind: \"version\", version: options.backendVersion },\n );\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {\n requestedPorts: options.ports,\n suggestedPorts: existingDeploymentForProject?.config.ports,\n });\n const { deploymentName, adminKey, projectId } = await bigBrainStart(ctx, {\n port: cloudPort,\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n instanceName: existingDeploymentForProject?.deploymentName ?? null,\n });\n const onActivity = async (isOffline: boolean, _wasOffline: boolean) => {\n await ensureBackendRunning(ctx, {\n cloudPort,\n deploymentName,\n maxTimeSecs: 5,\n });\n if (isOffline) {\n return;\n }\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n };\n\n const { cleanupHandle } = await handlePotentialUpgrade(ctx, {\n deploymentKind: \"local\",\n deploymentName,\n oldVersion: existingDeploymentForProject?.config.backendVersion ?? null,\n newBinaryPath: binaryPath,\n newVersion: version,\n ports: { cloud: cloudPort, site: sitePort },\n adminKey,\n instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,\n forceUpgrade: options.forceUpgrade,\n cloudProjectId: projectId,\n });\n\n if (isFirstTime) {\n await importDefaultEnvVars(ctx, {\n teamSlug: options.teamSlug,\n projectSlug: options.projectSlug,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n adminKey,\n });\n }\n\n // Periodically report activity to BigBrain every 60 seconds.\n // Uses self-scheduling setTimeout to avoid overlapping requests.\n let activityTimeout: ReturnType<typeof setTimeout> | null = null;\n const scheduleActivityPing = () => {\n activityTimeout = setTimeout(async () => {\n try {\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n } catch {\n // Best-effort: don't crash on failed pings\n }\n scheduleActivityPing();\n }, 60_000);\n };\n scheduleActivityPing();\n\n const cleanupFunc = ctx.removeCleanup(cleanupHandle);\n ctx.registerCleanup(async (exitCode, err) => {\n if (activityTimeout !== null) {\n clearTimeout(activityTimeout);\n }\n if (cleanupFunc !== null) {\n await cleanupFunc(exitCode, err);\n }\n await bigBrainPause(ctx, {\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n });\n });\n\n return {\n adminKey,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n reference: null,\n isDefault: false,\n onActivity,\n };\n}\n\nexport async function loadLocalDeploymentCredentials(\n ctx: Context,\n deploymentName: string,\n): Promise<{\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n}> {\n const config = loadDeploymentConfig(ctx, \"local\", deploymentName);\n if (config === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Failed to load deployment config - try running `npx convex dev --configure`\",\n });\n }\n return {\n deploymentName,\n deploymentUrl: localDeploymentUrl(config.ports.cloud),\n adminKey: config.adminKey,\n };\n}\n\nasync function handleOffline(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n ports: { cloud: number | undefined; site: number | undefined };\n },\n): Promise<DeploymentDetails> {\n const { deploymentName, config } =\n await chooseFromExistingLocalDeployments(ctx);\n const { binaryPath } = await ensureBackendBinaryDownloaded(ctx, {\n kind: \"version\",\n version: config.backendVersion,\n });\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {\n requestedPorts: options.ports,\n // FIXME: This doesn\u2019t try to reuse the ports already assigned in the config.\n // Please update this if we ever support offline mode (currently this is dead code).\n });\n saveDeploymentConfig(ctx, \"local\", deploymentName, config);\n await runLocalBackend(ctx, {\n binaryPath,\n ports: { cloud: cloudPort, site: sitePort },\n deploymentName,\n deploymentKind: \"local\",\n instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,\n isLatestVersion: false,\n });\n return {\n adminKey: config.adminKey,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n reference: null,\n isDefault: false,\n onActivity: async (isOffline: boolean, wasOffline: boolean) => {\n await ensureBackendRunning(ctx, {\n cloudPort,\n deploymentName,\n maxTimeSecs: 5,\n });\n if (isOffline) {\n return;\n }\n if (wasOffline) {\n await bigBrainStart(ctx, {\n port: cloudPort,\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n instanceName: deploymentName,\n });\n }\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n },\n };\n}\n\nasync function getExistingDeployment(\n ctx: Context,\n options: {\n projectSlug: string;\n teamSlug: string;\n },\n): Promise<{ deploymentName: string; config: LocalDeploymentConfig } | null> {\n const { projectSlug, teamSlug } = options;\n\n // Check project-local storage first - this is the new default location\n const projectLocal = loadProjectLocalConfig(ctx);\n if (projectLocal !== null) {\n // Verify this deployment is for the expected project (matches the naming pattern)\n const expectedPrefix = `local-${teamSlug.replace(/-/g, \"_\")}-${projectSlug.replace(/-/g, \"_\")}`;\n if (projectLocal.deploymentName.startsWith(expectedPrefix)) {\n return projectLocal;\n }\n logVerbose(\n `Project-local deployment ${projectLocal.deploymentName} doesn't match expected prefix ${expectedPrefix}`,\n );\n }\n\n // Fall back to checking legacy home directory\n const prefix = `local-${teamSlug.replace(/-/g, \"_\")}-${projectSlug.replace(/-/g, \"_\")}`;\n const legacyDeployments = await getLegacyLocalDeployments(ctx);\n const existingDeploymentForProject = legacyDeployments.find((d) =>\n d.deploymentName.startsWith(prefix),\n );\n if (existingDeploymentForProject === undefined) {\n return null;\n }\n return {\n deploymentName: existingDeploymentForProject.deploymentName,\n config: existingDeploymentForProject.config,\n };\n}\n\n/**\n * Get local deployments from the legacy home directory location.\n * This is used for backward compatibility and for listing deployments in offline mode.\n */\nasync function getLegacyLocalDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const dir = rootDeploymentStateDir(\"local\");\n if (!ctx.fs.exists(dir)) {\n return [];\n }\n const deploymentNames = ctx.fs\n .listDir(dir)\n .map((d) => d.name)\n .filter((d) => d.startsWith(\"local-\"));\n return deploymentNames.flatMap((deploymentName) => {\n const legacyDir = legacyDeploymentStateDir(\"local\", deploymentName);\n const config = loadDeploymentConfigFromDir(ctx, legacyDir);\n if (config !== null) {\n return [{ deploymentName, config }];\n }\n return [];\n });\n}\n\n/**\n * Get all local deployments from both project-local and legacy locations.\n */\nasync function getLocalDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const deployments: Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }> = [];\n\n // Check project-local storage\n const projectLocal = loadProjectLocalConfig(ctx);\n if (\n projectLocal !== null &&\n projectLocal.deploymentName.startsWith(\"local-\")\n ) {\n deployments.push(projectLocal);\n }\n\n // Also include legacy deployments (but avoid duplicates)\n const legacyDeployments = await getLegacyLocalDeployments(ctx);\n for (const legacy of legacyDeployments) {\n if (!deployments.some((d) => d.deploymentName === legacy.deploymentName)) {\n deployments.push(legacy);\n }\n }\n\n return deployments;\n}\n\nasync function chooseFromExistingLocalDeployments(ctx: Context): Promise<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n}> {\n const localDeployments = await getLocalDeployments(ctx);\n\n if (localDeployments.length === 0) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"No local deployments found. Please run `npx convex dev` while online first.\",\n });\n }\n\n // Auto-select if there's only one deployment\n if (localDeployments.length === 1) {\n logVerbose(\n `Auto-selecting the only local deployment: ${localDeployments[0].deploymentName}`,\n );\n return localDeployments[0];\n }\n\n // Multiple deployments (legacy) - prompt user to choose\n return promptSearch(ctx, {\n message: \"Choose from an existing local deployment:\",\n choices: localDeployments.map((d) => ({\n name: d.deploymentName,\n value: d,\n })),\n });\n}\n\n/** Copies the default dev env vars from big brain the first time the local dev backend is started */\nexport async function importDefaultEnvVars(\n ctx: Context,\n {\n teamSlug,\n projectSlug,\n deploymentName,\n deploymentUrl,\n adminKey,\n }: {\n teamSlug: string;\n projectSlug: string;\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n },\n) {\n showSpinner(\"Importing default env vars...\");\n\n const project = await getProjectDetails(ctx, {\n kind: \"teamAndProjectSlugs\",\n teamSlug,\n projectSlug,\n });\n let defaults: EnvVar[];\n try {\n defaults = await defaultEnvBackend(ctx, project.id, \"dev\").list();\n } catch (err) {\n if (err instanceof ThrowingFetchError && err.response.status === 403) {\n stopSpinner();\n logWarning(\n `Skipping default env var import: ${err.serverErrorData?.message ?? err.message}`,\n );\n return;\n }\n return await logAndHandleFetchError(ctx, err);\n }\n if (defaults.length === 0) {\n logFinishedStep(\"No default env vars to import.\");\n return;\n }\n\n const deployment = {\n deploymentUrl,\n deploymentFields: {\n deploymentName,\n deploymentType: \"local\" as const,\n projectSlug,\n teamSlug,\n reference: null,\n isDefault: false,\n },\n };\n\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n await deploymentEnvBackend(ctx, { deploymentUrl, adminKey }).update(\n defaults.map((v) => ({ name: v.name, value: v.value })),\n );\n logFinishedStep(\n `Imported ${defaults.length} environment ${defaults.length === 1 ? \"variable\" : \"variables\"} from default environment variables: ${defaults.map((v) => v.name).join(\", \")}`,\n );\n },\n });\n}\n"],
|
|
5
|
-
"mappings": ";AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB,0BAA0B;AAC3D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,
|
|
6
|
-
"names": [
|
|
4
|
+
"sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport {\n logFinishedStep,\n logVerbose,\n logWarning,\n showSpinner,\n stopSpinner,\n} from \"../../../bundler/log.js\";\nimport { logAndHandleFetchError, ThrowingFetchError } from \"../utils/utils.js\";\nimport {\n bigBrainPause,\n bigBrainRecordActivity,\n bigBrainStart,\n} from \"./bigBrain.js\";\nimport {\n LocalDeploymentConfig,\n loadDeploymentConfig,\n loadDeploymentConfigFromDir,\n loadProjectLocalConfig,\n legacyDeploymentStateDir,\n rootDeploymentStateDir,\n} from \"./filePaths.js\";\nimport {\n ensureBackendStopped,\n localDeploymentUrl,\n withRunningBackend,\n} from \"./run.js\";\nimport { handlePotentialUpgradeAndStart } from \"./upgrade.js\";\nimport { LocalDeploymentError, printLocalDeploymentOnError } from \"./errors.js\";\nimport {\n chooseLocalBackendPorts,\n printLocalDeploymentWelcomeMessage,\n} from \"./utils.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nimport { defaultEnvBackend } from \"../defaultEnv.js\";\nimport { deploymentEnvBackend, EnvVar } from \"../env.js\";\nimport { getProjectDetails } from \"../deploymentSelection.js\";\nimport { DeploymentDetails } from \"../deployment.js\";\nimport { LEGACY_LOCAL_BACKEND_INSTANCE_SECRET } from \"./secrets.js\";\n\nexport async function handleLocalDeployment(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n ports: {\n cloud: number | undefined;\n site: number | undefined;\n };\n backendVersion?: string | undefined;\n forceUpgrade: boolean;\n },\n): Promise<DeploymentDetails> {\n const existingDeploymentForProject = await getExistingDeployment(ctx, {\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n });\n const isFirstTime = existingDeploymentForProject === null;\n if (isFirstTime) {\n printLocalDeploymentWelcomeMessage();\n }\n ctx.registerCleanup(async (_exitCode, err) => {\n if (err instanceof LocalDeploymentError) {\n printLocalDeploymentOnError();\n }\n });\n if (existingDeploymentForProject !== null) {\n logVerbose(`Found existing deployment for project ${options.projectSlug}`);\n // If it's still running for some reason, exit and tell the user to kill it.\n // It's fine if a different backend is running on these ports though since we'll\n // pick new ones.\n await ensureBackendStopped(ctx, {\n ports: {\n cloud: existingDeploymentForProject.config.ports.cloud,\n },\n maxTimeSecs: 5,\n deploymentName: existingDeploymentForProject.deploymentName,\n allowOtherDeployments: true,\n });\n }\n\n const { binaryPath, version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? {\n kind: \"latest\",\n allowedVersion: existingDeploymentForProject?.config.backendVersion,\n }\n : { kind: \"version\", version: options.backendVersion },\n );\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {\n requestedPorts: options.ports,\n suggestedPorts: existingDeploymentForProject?.config.ports,\n });\n const { deploymentName, projectId } = await bigBrainStart(ctx, {\n port: cloudPort,\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n instanceName: existingDeploymentForProject?.deploymentName ?? null,\n });\n\n const { cleanupHandle, adminKey } = await handlePotentialUpgradeAndStart(\n ctx,\n {\n deploymentKind: \"local\",\n deploymentName,\n oldVersion: existingDeploymentForProject?.config.backendVersion ?? null,\n newBinaryPath: binaryPath,\n newVersion: version,\n ports: { cloud: cloudPort, site: sitePort },\n existingCredentials: existingDeploymentForProject?.config\n ? {\n adminKey: existingDeploymentForProject?.config.adminKey,\n instanceSecret:\n existingDeploymentForProject?.config.instanceSecret ??\n LEGACY_LOCAL_BACKEND_INSTANCE_SECRET,\n }\n : null,\n forceUpgrade: options.forceUpgrade,\n cloudProjectId: projectId,\n },\n );\n\n if (isFirstTime) {\n await importDefaultEnvVars(ctx, {\n teamSlug: options.teamSlug,\n projectSlug: options.projectSlug,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n adminKey,\n });\n }\n\n // Periodically report activity to BigBrain every 60 seconds.\n // Uses self-scheduling setTimeout to avoid overlapping requests.\n let activityTimeout: ReturnType<typeof setTimeout> | null = null;\n let activityPingStopped = false;\n async function activityPing() {\n if (activityPingStopped) {\n return;\n }\n try {\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n adminKey,\n });\n } catch {\n // Best-effort: don't crash on failed pings\n }\n\n if (activityPingStopped) {\n return;\n }\n activityTimeout = setTimeout(async () => {\n void activityPing();\n }, 60_000);\n }\n void activityPing();\n\n const cleanupFunc = ctx.removeCleanup(cleanupHandle);\n ctx.registerCleanup(async (exitCode, err) => {\n activityPingStopped = true;\n if (activityTimeout !== null) {\n clearTimeout(activityTimeout);\n }\n if (cleanupFunc !== null) {\n await cleanupFunc(exitCode, err);\n }\n await bigBrainPause(ctx, {\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n });\n });\n\n return {\n adminKey,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n reference: null,\n isDefault: false,\n };\n}\n\nexport async function loadLocalDeploymentCredentials(\n ctx: Context,\n deploymentName: string,\n): Promise<{\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n}> {\n const config = loadDeploymentConfig(ctx, \"local\", deploymentName);\n if (config === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Failed to load deployment config - try running `npx convex dev --configure`\",\n });\n }\n return {\n deploymentName,\n deploymentUrl: localDeploymentUrl(config.ports.cloud),\n adminKey: config.adminKey,\n };\n}\n\nasync function getExistingDeployment(\n ctx: Context,\n options: {\n projectSlug: string;\n teamSlug: string;\n },\n): Promise<{ deploymentName: string; config: LocalDeploymentConfig } | null> {\n const { projectSlug, teamSlug } = options;\n\n // Check project-local storage first - this is the new default location\n const projectLocal = loadProjectLocalConfig(ctx);\n if (projectLocal !== null) {\n // Verify this deployment is for the expected project (matches the naming pattern)\n const expectedPrefix = `local-${teamSlug.replace(/-/g, \"_\")}-${projectSlug.replace(/-/g, \"_\")}`;\n if (projectLocal.deploymentName.startsWith(expectedPrefix)) {\n return projectLocal;\n }\n logVerbose(\n `Project-local deployment ${projectLocal.deploymentName} doesn't match expected prefix ${expectedPrefix}`,\n );\n }\n\n // Fall back to checking legacy home directory\n const prefix = `local-${teamSlug.replace(/-/g, \"_\")}-${projectSlug.replace(/-/g, \"_\")}`;\n const legacyDeployments = await getLegacyLocalDeployments(ctx);\n const existingDeploymentForProject = legacyDeployments.find((d) =>\n d.deploymentName.startsWith(prefix),\n );\n if (existingDeploymentForProject === undefined) {\n return null;\n }\n return {\n deploymentName: existingDeploymentForProject.deploymentName,\n config: existingDeploymentForProject.config,\n };\n}\n\n/**\n * Get local deployments from the legacy home directory location.\n * This is used for backward compatibility and for listing deployments in offline mode.\n */\nasync function getLegacyLocalDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const dir = rootDeploymentStateDir(\"local\");\n if (!ctx.fs.exists(dir)) {\n return [];\n }\n const deploymentNames = ctx.fs\n .listDir(dir)\n .map((d) => d.name)\n .filter((d) => d.startsWith(\"local-\"));\n return deploymentNames.flatMap((deploymentName) => {\n const legacyDir = legacyDeploymentStateDir(\"local\", deploymentName);\n const config = loadDeploymentConfigFromDir(ctx, legacyDir);\n if (config !== null) {\n return [{ deploymentName, config }];\n }\n return [];\n });\n}\n\n/** Copies the default dev env vars from big brain the first time the local dev backend is started */\nexport async function importDefaultEnvVars(\n ctx: Context,\n {\n teamSlug,\n projectSlug,\n deploymentName,\n deploymentUrl,\n adminKey,\n }: {\n teamSlug: string;\n projectSlug: string;\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n },\n) {\n showSpinner(\"Importing default env vars...\");\n\n const project = await getProjectDetails(ctx, {\n kind: \"teamAndProjectSlugs\",\n teamSlug,\n projectSlug,\n });\n let defaults: EnvVar[];\n try {\n defaults = await defaultEnvBackend(ctx, project.id, \"dev\").list();\n } catch (err) {\n if (err instanceof ThrowingFetchError && err.response.status === 403) {\n stopSpinner();\n logWarning(\n `Skipping default env var import: ${err.serverErrorData?.message ?? err.message}`,\n );\n return;\n }\n return await logAndHandleFetchError(ctx, err);\n }\n if (defaults.length === 0) {\n logFinishedStep(\"No default env vars to import.\");\n return;\n }\n\n const deployment = {\n deploymentUrl,\n deploymentFields: {\n deploymentName,\n deploymentType: \"local\" as const,\n projectSlug,\n teamSlug,\n reference: null,\n isDefault: false,\n },\n };\n\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n await deploymentEnvBackend(ctx, { deploymentUrl, adminKey }).update(\n defaults.map((v) => ({ name: v.name, value: v.value })),\n );\n logFinishedStep(\n `Imported ${defaults.length} environment ${defaults.length === 1 ? \"variable\" : \"variables\"} from default environment variables: ${defaults.map((v) => v.name).join(\", \")}`,\n );\n },\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { logVerbose } from "../../../bundler/log.js";
|
|
3
|
+
import { ensureBackendBinaryDownloaded } from "./download.js";
|
|
4
|
+
import { LocalDeploymentError } from "./errors.js";
|
|
5
|
+
import { execFile } from "child_process";
|
|
6
|
+
import { promisify } from "util";
|
|
7
|
+
import crypto from "crypto";
|
|
8
|
+
export const LEGACY_LOCAL_BACKEND_INSTANCE_SECRET = "4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974";
|
|
9
|
+
export async function generateLocalDevSecrets(ctx, {
|
|
10
|
+
deploymentName,
|
|
11
|
+
latestBinaryPath
|
|
12
|
+
}) {
|
|
13
|
+
logVerbose("Generating local dev secrets");
|
|
14
|
+
const instanceSecret = generateInstanceSecret();
|
|
15
|
+
let stdout;
|
|
16
|
+
try {
|
|
17
|
+
({ stdout } = await promisify(execFile)(latestBinaryPath, [
|
|
18
|
+
"keygen",
|
|
19
|
+
"admin-key",
|
|
20
|
+
"--instance-name",
|
|
21
|
+
deploymentName,
|
|
22
|
+
"--instance-secret",
|
|
23
|
+
instanceSecret
|
|
24
|
+
]));
|
|
25
|
+
} catch (e) {
|
|
26
|
+
const err = e;
|
|
27
|
+
const detail = err.stderr ? err.stderr : err.message;
|
|
28
|
+
const message = `Failed to generate admin key:
|
|
29
|
+
${detail}`;
|
|
30
|
+
return ctx.crash({
|
|
31
|
+
exitCode: 1,
|
|
32
|
+
errorType: "fatal",
|
|
33
|
+
printedMessage: message,
|
|
34
|
+
errForSentry: new LocalDeploymentError(message)
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const adminKey = stdout.trim();
|
|
38
|
+
return {
|
|
39
|
+
instanceSecret,
|
|
40
|
+
adminKey
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function generateInstanceSecret() {
|
|
44
|
+
return crypto.randomBytes(32).toString("hex");
|
|
45
|
+
}
|
|
46
|
+
export async function generateLocalDevSecretsWithLatestBinary(ctx, {
|
|
47
|
+
deploymentName
|
|
48
|
+
}) {
|
|
49
|
+
const { binaryPath: latestBinaryPath } = await ensureBackendBinaryDownloaded(
|
|
50
|
+
ctx,
|
|
51
|
+
{
|
|
52
|
+
kind: "latest"
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
return generateLocalDevSecrets(ctx, { deploymentName, latestBinaryPath });
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/localDeployment/secrets.ts"],
|
|
4
|
+
"sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { logVerbose } from \"../../../bundler/log.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nimport { LocalDeploymentError } from \"./errors.js\";\nimport { execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport crypto from \"crypto\";\n\nexport const LEGACY_LOCAL_BACKEND_INSTANCE_SECRET =\n \"4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974\";\n\n/**\n * Generates an instance secret and an admin key for a new (or just upgraded) local deployment.\n */\nexport async function generateLocalDevSecrets(\n ctx: Context,\n {\n deploymentName,\n latestBinaryPath,\n }: {\n deploymentName: string;\n /**\n * A path to the local backend binary.\n *\n * This must always be the latest version of the local binary that has been published,\n * in order to make sure the `keygen admin-key` command is available. If you need to call\n * this without having access to the latest binary, use `generateLocalDevSecretsWithLatestBinary`\n * which will download the latest version when necessary.\n */\n latestBinaryPath: string;\n },\n): Promise<{\n instanceSecret: string;\n adminKey: string;\n}> {\n logVerbose(\"Generating local dev secrets\");\n\n const instanceSecret = generateInstanceSecret();\n\n let stdout: string;\n try {\n ({ stdout } = await promisify(execFile)(latestBinaryPath, [\n \"keygen\",\n \"admin-key\",\n \"--instance-name\",\n deploymentName,\n \"--instance-secret\",\n instanceSecret,\n ]));\n } catch (e) {\n const err = e as { stderr?: string; message: string };\n const detail = err.stderr ? err.stderr : err.message;\n const message = `Failed to generate admin key:\\n${detail}`;\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: new LocalDeploymentError(message),\n });\n }\n\n const adminKey = stdout.trim();\n\n return {\n instanceSecret,\n adminKey,\n };\n}\n\nfunction generateInstanceSecret(): string {\n return crypto.randomBytes(32).toString(\"hex\");\n}\n\n/**\n * Similar to generateLocalDevSecrets, but can be called when we\u2019re not confident\n * we have a binary that supports `keygen admin-key`\n */\nexport async function generateLocalDevSecretsWithLatestBinary(\n ctx: Context,\n {\n deploymentName,\n }: {\n deploymentName: string;\n },\n) {\n const { binaryPath: latestBinaryPath } = await ensureBackendBinaryDownloaded(\n ctx,\n {\n kind: \"latest\",\n },\n );\n return generateLocalDevSecrets(ctx, { deploymentName, latestBinaryPath });\n}\n"],
|
|
5
|
+
"mappings": ";AACA,SAAS,kBAAkB;AAC3B,SAAS,qCAAqC;AAC9C,SAAS,4BAA4B;AACrC,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,OAAO,YAAY;AAEZ,aAAM,uCACX;AAKF,sBAAsB,wBACpB,KACA;AAAA,EACE;AAAA,EACA;AACF,GAeC;AACD,aAAW,8BAA8B;AAEzC,QAAM,iBAAiB,uBAAuB;AAE9C,MAAI;AACJ,MAAI;AACF,KAAC,EAAE,OAAO,IAAI,MAAM,UAAU,QAAQ,EAAE,kBAAkB;AAAA,MACxD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,GAAG;AACV,UAAM,MAAM;AACZ,UAAM,SAAS,IAAI,SAAS,IAAI,SAAS,IAAI;AAC7C,UAAM,UAAU;AAAA,EAAkC,MAAM;AACxD,WAAO,IAAI,MAAM;AAAA,MACf,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,cAAc,IAAI,qBAAqB,OAAO;AAAA,IAChD,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,OAAO,KAAK;AAE7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,yBAAiC;AACxC,SAAO,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAC9C;AAMA,sBAAsB,wCACpB,KACA;AAAA,EACE;AACF,GAGA;AACA,QAAM,EAAE,YAAY,iBAAiB,IAAI,MAAM;AAAA,IAC7C;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO,wBAAwB,KAAK,EAAE,gBAAgB,iBAAiB,CAAC;AAC1E;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|