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,20 +1,21 @@
|
|
|
1
1
|
import { Context } from "../../../bundler/context.js";
|
|
2
2
|
import {
|
|
3
3
|
dashboardOutDir,
|
|
4
|
-
|
|
4
|
+
loadProjectDashboardConfig,
|
|
5
5
|
loadUuidForAnonymousUser,
|
|
6
|
-
|
|
6
|
+
saveProjectDashboardConfig,
|
|
7
7
|
} from "./filePaths.js";
|
|
8
8
|
import { choosePorts } from "./utils.js";
|
|
9
9
|
import { startServer } from "./serve.js";
|
|
10
|
-
import { listExistingAnonymousDeployments } from "./anonymous.js";
|
|
11
10
|
import { localDeploymentUrl, selfHostedEventTag } from "./run.js";
|
|
12
11
|
import serveHandler from "serve-handler";
|
|
13
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
ensureBackendBinaryDownloaded,
|
|
14
|
+
ensureDashboardDownloaded,
|
|
15
|
+
} from "./download.js";
|
|
14
16
|
import { bigBrainAPIMaybeThrows } from "../utils/utils.js";
|
|
15
17
|
|
|
16
18
|
export const DEFAULT_LOCAL_DASHBOARD_PORT = 6790;
|
|
17
|
-
export const DEFAULT_LOCAL_DASHBOARD_API_PORT = 6791;
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* This runs the `dashboard-self-hosted` app locally.
|
|
@@ -22,32 +23,59 @@ export const DEFAULT_LOCAL_DASHBOARD_API_PORT = 6791;
|
|
|
22
23
|
* uses `dashboard.convex.dev`, and some of the code below is written
|
|
23
24
|
* assuming this is only used for `anonymous`.
|
|
24
25
|
*/
|
|
25
|
-
export async function handleDashboard(
|
|
26
|
+
export async function handleDashboard(
|
|
27
|
+
ctx: Context,
|
|
28
|
+
deployment: { name: string; cloudPort: number; adminKey: string },
|
|
29
|
+
options: {
|
|
30
|
+
/** The backend version to use if the user overrides the default version with the --local-backend-version flag */
|
|
31
|
+
backendVersion: string | undefined;
|
|
32
|
+
},
|
|
33
|
+
) {
|
|
34
|
+
// We call `ensureBackendBinaryDownloaded` here to get the version,
|
|
35
|
+
// but `handleAnonymousDeployment` has already downloaded it.
|
|
36
|
+
const { version } = await ensureBackendBinaryDownloaded(
|
|
37
|
+
ctx,
|
|
38
|
+
options.backendVersion === undefined
|
|
39
|
+
? { kind: "latest" }
|
|
40
|
+
: { kind: "version", version: options.backendVersion },
|
|
41
|
+
);
|
|
26
42
|
const anonymousId = loadUuidForAnonymousUser(ctx) ?? undefined;
|
|
27
|
-
const isRunning = await checkIfDashboardIsRunning(ctx);
|
|
28
|
-
if (isRunning) {
|
|
29
|
-
// It's possible this is running with a different version, but
|
|
30
|
-
// let's not worry about that for now.
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
43
|
await ensureDashboardDownloaded(ctx, version);
|
|
34
|
-
const [dashboardPort
|
|
35
|
-
count:
|
|
44
|
+
const [dashboardPort] = await choosePorts(ctx, {
|
|
45
|
+
count: 1,
|
|
36
46
|
startPort: DEFAULT_LOCAL_DASHBOARD_PORT,
|
|
37
47
|
requestedPorts: [null, null],
|
|
38
48
|
});
|
|
39
|
-
|
|
49
|
+
saveProjectDashboardConfig(ctx, deployment.name, {
|
|
40
50
|
port: dashboardPort,
|
|
41
|
-
apiPort,
|
|
42
|
-
version,
|
|
43
51
|
});
|
|
44
52
|
|
|
45
53
|
let hasReportedSelfHostedEvent = false;
|
|
46
54
|
|
|
55
|
+
const serverOptions = { cors: false } as const;
|
|
47
56
|
const { cleanupHandle } = await startServer(
|
|
48
57
|
ctx,
|
|
49
58
|
dashboardPort,
|
|
50
59
|
async (request, response) => {
|
|
60
|
+
const pathname = new URL(
|
|
61
|
+
request.url ?? "/",
|
|
62
|
+
// We only want to extract the pathname so the base doesn’t matter
|
|
63
|
+
"http://localhost",
|
|
64
|
+
).pathname;
|
|
65
|
+
|
|
66
|
+
if (pathname === "/api/current_deployment") {
|
|
67
|
+
serverOptions satisfies { cors: false };
|
|
68
|
+
response.setHeader("Content-Type", "application/json");
|
|
69
|
+
response.end(
|
|
70
|
+
JSON.stringify({
|
|
71
|
+
name: deployment.name,
|
|
72
|
+
url: localDeploymentUrl(deployment.cloudPort),
|
|
73
|
+
adminKey: deployment.adminKey,
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
51
79
|
if (!hasReportedSelfHostedEvent) {
|
|
52
80
|
hasReportedSelfHostedEvent = true;
|
|
53
81
|
void reportSelfHostedEvent(ctx, {
|
|
@@ -60,9 +88,8 @@ export async function handleDashboard(ctx: Context, version: string) {
|
|
|
60
88
|
public: dashboardOutDir(),
|
|
61
89
|
});
|
|
62
90
|
},
|
|
63
|
-
|
|
91
|
+
serverOptions,
|
|
64
92
|
);
|
|
65
|
-
await startServingListDeploymentsApi(ctx, apiPort);
|
|
66
93
|
return {
|
|
67
94
|
dashboardPort,
|
|
68
95
|
cleanupHandle,
|
|
@@ -100,70 +127,11 @@ async function reportSelfHostedEvent(
|
|
|
100
127
|
}
|
|
101
128
|
}
|
|
102
129
|
|
|
103
|
-
/**
|
|
104
|
-
* This serves a really basic API that just returns a JSON blob with the deployments
|
|
105
|
-
* and their credentials.
|
|
106
|
-
* The locally running dashboard can hit this API.
|
|
107
|
-
*/
|
|
108
|
-
async function startServingListDeploymentsApi(ctx: Context, port: number) {
|
|
109
|
-
await startServer(
|
|
110
|
-
ctx,
|
|
111
|
-
port,
|
|
112
|
-
async (request, response) => {
|
|
113
|
-
const deployments = await listExistingAnonymousDeployments(ctx);
|
|
114
|
-
const deploymentsJson = deployments.map((d) => ({
|
|
115
|
-
name: d.deploymentName,
|
|
116
|
-
url: localDeploymentUrl(d.config.ports.cloud),
|
|
117
|
-
adminKey: d.config.adminKey,
|
|
118
|
-
}));
|
|
119
|
-
response.setHeader("Content-Type", "application/json");
|
|
120
|
-
response.end(JSON.stringify({ deployments: deploymentsJson }));
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
cors: true,
|
|
124
|
-
},
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export async function checkIfDashboardIsRunning(ctx: Context) {
|
|
129
|
-
const dashboardConfig = loadDashboardConfig(ctx);
|
|
130
|
-
if (dashboardConfig === null) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
// We're checking if the mini API server is running and has a response that
|
|
134
|
-
// looks like a list of deployments, since it's easier than checking the
|
|
135
|
-
// dashboard UI + won't trigger the event for the developer opening the dashboard.
|
|
136
|
-
let resp: Response;
|
|
137
|
-
try {
|
|
138
|
-
resp = await fetch(`http://127.0.0.1:${dashboardConfig.apiPort}`);
|
|
139
|
-
} catch {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
if (!resp.ok) {
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
let data: { deployments: { name: string; url: string; adminKey: string }[] };
|
|
146
|
-
try {
|
|
147
|
-
data = await resp.json();
|
|
148
|
-
} catch {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
return Array.isArray(data.deployments);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
130
|
export function dashboardUrl(ctx: Context, deploymentName: string) {
|
|
155
|
-
const dashboardConfig =
|
|
131
|
+
const dashboardConfig = loadProjectDashboardConfig(ctx, deploymentName);
|
|
156
132
|
if (dashboardConfig === null) {
|
|
157
133
|
return null;
|
|
158
134
|
}
|
|
159
135
|
|
|
160
|
-
|
|
161
|
-
if (dashboardConfig.apiPort !== DEFAULT_LOCAL_DASHBOARD_API_PORT) {
|
|
162
|
-
queryParams.set("a", dashboardConfig.apiPort.toString());
|
|
163
|
-
}
|
|
164
|
-
queryParams.set("d", deploymentName);
|
|
165
|
-
const queryString = queryParams.toString();
|
|
166
|
-
const url = new URL(`http://127.0.0.1:${dashboardConfig.port}`);
|
|
167
|
-
url.search = queryString;
|
|
168
|
-
return url.href;
|
|
136
|
+
return `http://127.0.0.1:${dashboardConfig.port}/`;
|
|
169
137
|
}
|
|
@@ -15,7 +15,8 @@ import {
|
|
|
15
15
|
versionedBinaryDir,
|
|
16
16
|
dashboardOutDir,
|
|
17
17
|
resetDashboardDir,
|
|
18
|
-
|
|
18
|
+
loadGlobalDashboardConfig,
|
|
19
|
+
saveGlobalDashboardConfig,
|
|
19
20
|
executableName,
|
|
20
21
|
} from "./filePaths.js";
|
|
21
22
|
import child_process from "child_process";
|
|
@@ -79,11 +80,38 @@ async function _ensureBackendBinaryDownloaded(
|
|
|
79
80
|
return { version, binaryPath };
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
let cachedLatestVersion: string | null = null;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Finds the latest version of the Convex local backend through
|
|
87
|
+
* version.convex.dev, caching the resolved version for the lifetime of the
|
|
88
|
+
* process so repeated lookups hit the network at most once.
|
|
89
|
+
*
|
|
90
|
+
* Wraps {@link _findLatestVersionWithBinary}. Only successful (non-null)
|
|
91
|
+
* results are cached, so a failed `requireSuccess: false` lookup can be retried
|
|
92
|
+
* by a later call.
|
|
93
|
+
*/
|
|
94
|
+
export async function findLatestVersionWithBinary<
|
|
95
|
+
RequireSuccess extends boolean,
|
|
96
|
+
>(
|
|
97
|
+
ctx: Context,
|
|
98
|
+
requireSuccess: RequireSuccess,
|
|
99
|
+
): Promise<RequireSuccess extends true ? string : string | null> {
|
|
100
|
+
if (cachedLatestVersion !== null) {
|
|
101
|
+
return cachedLatestVersion;
|
|
102
|
+
}
|
|
103
|
+
const result = await _findLatestVersionWithBinary(ctx, requireSuccess);
|
|
104
|
+
if (result !== null) {
|
|
105
|
+
cachedLatestVersion = result;
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
82
110
|
/**
|
|
83
111
|
* Finds the latest version of the Convex local backend
|
|
84
112
|
* through version.convex.dev
|
|
85
113
|
*/
|
|
86
|
-
export async function
|
|
114
|
+
export async function _findLatestVersionWithBinary<
|
|
87
115
|
RequireSuccess extends boolean,
|
|
88
116
|
>(
|
|
89
117
|
ctx: Context,
|
|
@@ -298,12 +326,15 @@ async function downloadZipFile(
|
|
|
298
326
|
}
|
|
299
327
|
|
|
300
328
|
export async function ensureDashboardDownloaded(ctx: Context, version: string) {
|
|
301
|
-
const config =
|
|
329
|
+
const config = loadGlobalDashboardConfig(ctx);
|
|
302
330
|
if (config !== null && config.version === version) {
|
|
303
331
|
return;
|
|
304
332
|
}
|
|
305
333
|
await resetDashboardDir(ctx);
|
|
306
334
|
await _ensureDashboardDownloaded(ctx, version);
|
|
335
|
+
// Record which version is now in `dashboardOutDir()`
|
|
336
|
+
// so we can skip the download next time.
|
|
337
|
+
saveGlobalDashboardConfig(ctx, { version });
|
|
307
338
|
}
|
|
308
339
|
async function _ensureDashboardDownloaded(ctx: Context, version: string) {
|
|
309
340
|
const zipLocation = dashboardZip();
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
0.0.2
|
|
7
7
|
convex-local-backend[.exe]
|
|
8
8
|
dashboard
|
|
9
|
-
config.json
|
|
9
|
+
config.json // `GlobalDashboardConfig`
|
|
10
10
|
out
|
|
11
11
|
// if present, output files from building the self-hosted dashboard which can
|
|
12
12
|
// be served using `npx serve`
|
|
@@ -24,6 +24,10 @@ Legacy (home directory) - used for backward compatibility if data already exists
|
|
|
24
24
|
- For "local" deployments: ~/.convex/convex-backend-state/local-{team}-{project}/
|
|
25
25
|
- For "anonymous" deployments: ~/.convex/anonymous-convex-backend-state/{anonymous-deployment-name}/
|
|
26
26
|
|
|
27
|
+
For anonymous deployments, the locally running dashboard's `{ port }`
|
|
28
|
+
is stored as `dashboard.json` next to that deployment's `config.json` (see
|
|
29
|
+
`ProjectDashboardConfig`), wherever the deployment lives.
|
|
30
|
+
|
|
27
31
|
|
|
28
32
|
~/.convex
|
|
29
33
|
convex-backend-state
|
|
@@ -331,12 +335,19 @@ export function dashboardOutDir() {
|
|
|
331
335
|
return path.join(dashboardDir(), "out");
|
|
332
336
|
}
|
|
333
337
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
338
|
+
/**
|
|
339
|
+
* Global dashboard config in ~/.cache/convex/dashboard/config.json.
|
|
340
|
+
*/
|
|
341
|
+
export type GlobalDashboardConfig = {
|
|
337
342
|
version: string;
|
|
343
|
+
|
|
344
|
+
// Previous versions of the Convex CLI would also store
|
|
345
|
+
// fields here for ports. They are now in ProjectDashboardConfig.
|
|
338
346
|
};
|
|
339
|
-
|
|
347
|
+
|
|
348
|
+
export function loadGlobalDashboardConfig(
|
|
349
|
+
ctx: Context,
|
|
350
|
+
): GlobalDashboardConfig | null {
|
|
340
351
|
const configFile = path.join(dashboardDir(), "config.json");
|
|
341
352
|
if (!ctx.fs.exists(configFile)) {
|
|
342
353
|
return null;
|
|
@@ -350,7 +361,10 @@ export function loadDashboardConfig(ctx: Context) {
|
|
|
350
361
|
}
|
|
351
362
|
}
|
|
352
363
|
|
|
353
|
-
export function
|
|
364
|
+
export function saveGlobalDashboardConfig(
|
|
365
|
+
ctx: Context,
|
|
366
|
+
config: GlobalDashboardConfig,
|
|
367
|
+
) {
|
|
354
368
|
const configFile = path.join(dashboardDir(), "config.json");
|
|
355
369
|
if (!ctx.fs.exists(dashboardDir())) {
|
|
356
370
|
ctx.fs.mkdir(dashboardDir(), { recursive: true });
|
|
@@ -358,6 +372,52 @@ export function saveDashboardConfig(ctx: Context, config: DashboardConfig) {
|
|
|
358
372
|
ctx.fs.writeUtf8File(configFile, JSON.stringify(config));
|
|
359
373
|
}
|
|
360
374
|
|
|
375
|
+
/**
|
|
376
|
+
* Project-scoped dashboard config (for anonymous dev) in
|
|
377
|
+
* project/.convex/local/default/dashboard.json
|
|
378
|
+
* (or legacyDeploymentStateDir/dashboard.json)
|
|
379
|
+
*/
|
|
380
|
+
export type ProjectDashboardConfig = {
|
|
381
|
+
port: number;
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
function dashboardConfigPath(ctx: Context, deploymentName: string) {
|
|
385
|
+
return path.join(
|
|
386
|
+
deploymentStateDir(ctx, "anonymous", deploymentName),
|
|
387
|
+
"dashboard.json",
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export function loadProjectDashboardConfig(
|
|
392
|
+
ctx: Context,
|
|
393
|
+
deploymentName: string,
|
|
394
|
+
): ProjectDashboardConfig | null {
|
|
395
|
+
const configFile = dashboardConfigPath(ctx, deploymentName);
|
|
396
|
+
if (!ctx.fs.exists(configFile)) {
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
const content = ctx.fs.readUtf8File(configFile);
|
|
400
|
+
try {
|
|
401
|
+
return JSON.parse(content);
|
|
402
|
+
} catch (e) {
|
|
403
|
+
logVerbose(`Failed to parse project dashboard config: ${e as any}`);
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export function saveProjectDashboardConfig(
|
|
409
|
+
ctx: Context,
|
|
410
|
+
deploymentName: string,
|
|
411
|
+
config: ProjectDashboardConfig,
|
|
412
|
+
) {
|
|
413
|
+
const configPath = dashboardConfigPath(ctx, deploymentName);
|
|
414
|
+
const directoryPath = path.dirname(configPath);
|
|
415
|
+
if (!ctx.fs.exists(directoryPath)) {
|
|
416
|
+
ctx.fs.mkdir(directoryPath, { recursive: true });
|
|
417
|
+
}
|
|
418
|
+
ctx.fs.writeUtf8File(configPath, JSON.stringify(config));
|
|
419
|
+
}
|
|
420
|
+
|
|
361
421
|
export function loadUuidForAnonymousUser(ctx: Context) {
|
|
362
422
|
const configFile = path.join(
|
|
363
423
|
rootDeploymentStateDir("anonymous"),
|
|
@@ -19,38 +19,24 @@ import {
|
|
|
19
19
|
loadProjectLocalConfig,
|
|
20
20
|
legacyDeploymentStateDir,
|
|
21
21
|
rootDeploymentStateDir,
|
|
22
|
-
saveDeploymentConfig,
|
|
23
22
|
} from "./filePaths.js";
|
|
24
23
|
import {
|
|
25
|
-
ensureBackendRunning,
|
|
26
24
|
ensureBackendStopped,
|
|
27
25
|
localDeploymentUrl,
|
|
28
|
-
runLocalBackend,
|
|
29
26
|
withRunningBackend,
|
|
30
27
|
} from "./run.js";
|
|
31
|
-
import {
|
|
32
|
-
import { OnDeploymentActivityFunc } from "../deployment.js";
|
|
33
|
-
import { promptSearch } from "../utils/prompts.js";
|
|
28
|
+
import { handlePotentialUpgradeAndStart } from "./upgrade.js";
|
|
34
29
|
import { LocalDeploymentError, printLocalDeploymentOnError } from "./errors.js";
|
|
35
30
|
import {
|
|
36
31
|
chooseLocalBackendPorts,
|
|
37
32
|
printLocalDeploymentWelcomeMessage,
|
|
38
|
-
isOffline,
|
|
39
|
-
LOCAL_BACKEND_INSTANCE_SECRET,
|
|
40
33
|
} from "./utils.js";
|
|
41
34
|
import { ensureBackendBinaryDownloaded } from "./download.js";
|
|
42
35
|
import { defaultEnvBackend } from "../defaultEnv.js";
|
|
43
36
|
import { deploymentEnvBackend, EnvVar } from "../env.js";
|
|
44
37
|
import { getProjectDetails } from "../deploymentSelection.js";
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
deploymentName: string;
|
|
48
|
-
deploymentUrl: string;
|
|
49
|
-
adminKey: string;
|
|
50
|
-
reference: string | null;
|
|
51
|
-
isDefault: boolean;
|
|
52
|
-
onActivity: OnDeploymentActivityFunc;
|
|
53
|
-
};
|
|
38
|
+
import { DeploymentDetails } from "../deployment.js";
|
|
39
|
+
import { LEGACY_LOCAL_BACKEND_INSTANCE_SECRET } from "./secrets.js";
|
|
54
40
|
|
|
55
41
|
export async function handleLocalDeployment(
|
|
56
42
|
ctx: Context,
|
|
@@ -65,10 +51,6 @@ export async function handleLocalDeployment(
|
|
|
65
51
|
forceUpgrade: boolean;
|
|
66
52
|
},
|
|
67
53
|
): Promise<DeploymentDetails> {
|
|
68
|
-
if (await isOffline()) {
|
|
69
|
-
return handleOffline(ctx, options);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
54
|
const existingDeploymentForProject = await getExistingDeployment(ctx, {
|
|
73
55
|
projectSlug: options.projectSlug,
|
|
74
56
|
teamSlug: options.teamSlug,
|
|
@@ -110,38 +92,34 @@ export async function handleLocalDeployment(
|
|
|
110
92
|
requestedPorts: options.ports,
|
|
111
93
|
suggestedPorts: existingDeploymentForProject?.config.ports,
|
|
112
94
|
});
|
|
113
|
-
const { deploymentName,
|
|
95
|
+
const { deploymentName, projectId } = await bigBrainStart(ctx, {
|
|
114
96
|
port: cloudPort,
|
|
115
97
|
projectSlug: options.projectSlug,
|
|
116
98
|
teamSlug: options.teamSlug,
|
|
117
99
|
instanceName: existingDeploymentForProject?.deploymentName ?? null,
|
|
118
100
|
});
|
|
119
|
-
const onActivity = async (isOffline: boolean, _wasOffline: boolean) => {
|
|
120
|
-
await ensureBackendRunning(ctx, {
|
|
121
|
-
cloudPort,
|
|
122
|
-
deploymentName,
|
|
123
|
-
maxTimeSecs: 5,
|
|
124
|
-
});
|
|
125
|
-
if (isOffline) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
await bigBrainRecordActivity(ctx, {
|
|
129
|
-
instanceName: deploymentName,
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
101
|
|
|
133
|
-
const { cleanupHandle } = await
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
102
|
+
const { cleanupHandle, adminKey } = await handlePotentialUpgradeAndStart(
|
|
103
|
+
ctx,
|
|
104
|
+
{
|
|
105
|
+
deploymentKind: "local",
|
|
106
|
+
deploymentName,
|
|
107
|
+
oldVersion: existingDeploymentForProject?.config.backendVersion ?? null,
|
|
108
|
+
newBinaryPath: binaryPath,
|
|
109
|
+
newVersion: version,
|
|
110
|
+
ports: { cloud: cloudPort, site: sitePort },
|
|
111
|
+
existingCredentials: existingDeploymentForProject?.config
|
|
112
|
+
? {
|
|
113
|
+
adminKey: existingDeploymentForProject?.config.adminKey,
|
|
114
|
+
instanceSecret:
|
|
115
|
+
existingDeploymentForProject?.config.instanceSecret ??
|
|
116
|
+
LEGACY_LOCAL_BACKEND_INSTANCE_SECRET,
|
|
117
|
+
}
|
|
118
|
+
: null,
|
|
119
|
+
forceUpgrade: options.forceUpgrade,
|
|
120
|
+
cloudProjectId: projectId,
|
|
121
|
+
},
|
|
122
|
+
);
|
|
145
123
|
|
|
146
124
|
if (isFirstTime) {
|
|
147
125
|
await importDefaultEnvVars(ctx, {
|
|
@@ -156,22 +134,32 @@ export async function handleLocalDeployment(
|
|
|
156
134
|
// Periodically report activity to BigBrain every 60 seconds.
|
|
157
135
|
// Uses self-scheduling setTimeout to avoid overlapping requests.
|
|
158
136
|
let activityTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
159
|
-
|
|
137
|
+
let activityPingStopped = false;
|
|
138
|
+
async function activityPing() {
|
|
139
|
+
if (activityPingStopped) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
await bigBrainRecordActivity(ctx, {
|
|
144
|
+
instanceName: deploymentName,
|
|
145
|
+
adminKey,
|
|
146
|
+
});
|
|
147
|
+
} catch {
|
|
148
|
+
// Best-effort: don't crash on failed pings
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (activityPingStopped) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
160
154
|
activityTimeout = setTimeout(async () => {
|
|
161
|
-
|
|
162
|
-
await bigBrainRecordActivity(ctx, {
|
|
163
|
-
instanceName: deploymentName,
|
|
164
|
-
});
|
|
165
|
-
} catch {
|
|
166
|
-
// Best-effort: don't crash on failed pings
|
|
167
|
-
}
|
|
168
|
-
scheduleActivityPing();
|
|
155
|
+
void activityPing();
|
|
169
156
|
}, 60_000);
|
|
170
|
-
}
|
|
171
|
-
|
|
157
|
+
}
|
|
158
|
+
void activityPing();
|
|
172
159
|
|
|
173
160
|
const cleanupFunc = ctx.removeCleanup(cleanupHandle);
|
|
174
161
|
ctx.registerCleanup(async (exitCode, err) => {
|
|
162
|
+
activityPingStopped = true;
|
|
175
163
|
if (activityTimeout !== null) {
|
|
176
164
|
clearTimeout(activityTimeout);
|
|
177
165
|
}
|
|
@@ -190,7 +178,6 @@ export async function handleLocalDeployment(
|
|
|
190
178
|
deploymentUrl: localDeploymentUrl(cloudPort),
|
|
191
179
|
reference: null,
|
|
192
180
|
isDefault: false,
|
|
193
|
-
onActivity,
|
|
194
181
|
};
|
|
195
182
|
}
|
|
196
183
|
|
|
@@ -218,64 +205,6 @@ export async function loadLocalDeploymentCredentials(
|
|
|
218
205
|
};
|
|
219
206
|
}
|
|
220
207
|
|
|
221
|
-
async function handleOffline(
|
|
222
|
-
ctx: Context,
|
|
223
|
-
options: {
|
|
224
|
-
teamSlug: string;
|
|
225
|
-
projectSlug: string;
|
|
226
|
-
ports: { cloud: number | undefined; site: number | undefined };
|
|
227
|
-
},
|
|
228
|
-
): Promise<DeploymentDetails> {
|
|
229
|
-
const { deploymentName, config } =
|
|
230
|
-
await chooseFromExistingLocalDeployments(ctx);
|
|
231
|
-
const { binaryPath } = await ensureBackendBinaryDownloaded(ctx, {
|
|
232
|
-
kind: "version",
|
|
233
|
-
version: config.backendVersion,
|
|
234
|
-
});
|
|
235
|
-
const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {
|
|
236
|
-
requestedPorts: options.ports,
|
|
237
|
-
// FIXME: This doesn’t try to reuse the ports already assigned in the config.
|
|
238
|
-
// Please update this if we ever support offline mode (currently this is dead code).
|
|
239
|
-
});
|
|
240
|
-
saveDeploymentConfig(ctx, "local", deploymentName, config);
|
|
241
|
-
await runLocalBackend(ctx, {
|
|
242
|
-
binaryPath,
|
|
243
|
-
ports: { cloud: cloudPort, site: sitePort },
|
|
244
|
-
deploymentName,
|
|
245
|
-
deploymentKind: "local",
|
|
246
|
-
instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,
|
|
247
|
-
isLatestVersion: false,
|
|
248
|
-
});
|
|
249
|
-
return {
|
|
250
|
-
adminKey: config.adminKey,
|
|
251
|
-
deploymentName,
|
|
252
|
-
deploymentUrl: localDeploymentUrl(cloudPort),
|
|
253
|
-
reference: null,
|
|
254
|
-
isDefault: false,
|
|
255
|
-
onActivity: async (isOffline: boolean, wasOffline: boolean) => {
|
|
256
|
-
await ensureBackendRunning(ctx, {
|
|
257
|
-
cloudPort,
|
|
258
|
-
deploymentName,
|
|
259
|
-
maxTimeSecs: 5,
|
|
260
|
-
});
|
|
261
|
-
if (isOffline) {
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
if (wasOffline) {
|
|
265
|
-
await bigBrainStart(ctx, {
|
|
266
|
-
port: cloudPort,
|
|
267
|
-
projectSlug: options.projectSlug,
|
|
268
|
-
teamSlug: options.teamSlug,
|
|
269
|
-
instanceName: deploymentName,
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
await bigBrainRecordActivity(ctx, {
|
|
273
|
-
instanceName: deploymentName,
|
|
274
|
-
});
|
|
275
|
-
},
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
|
|
279
208
|
async function getExistingDeployment(
|
|
280
209
|
ctx: Context,
|
|
281
210
|
options: {
|
|
@@ -341,73 +270,6 @@ async function getLegacyLocalDeployments(ctx: Context): Promise<
|
|
|
341
270
|
});
|
|
342
271
|
}
|
|
343
272
|
|
|
344
|
-
/**
|
|
345
|
-
* Get all local deployments from both project-local and legacy locations.
|
|
346
|
-
*/
|
|
347
|
-
async function getLocalDeployments(ctx: Context): Promise<
|
|
348
|
-
Array<{
|
|
349
|
-
deploymentName: string;
|
|
350
|
-
config: LocalDeploymentConfig;
|
|
351
|
-
}>
|
|
352
|
-
> {
|
|
353
|
-
const deployments: Array<{
|
|
354
|
-
deploymentName: string;
|
|
355
|
-
config: LocalDeploymentConfig;
|
|
356
|
-
}> = [];
|
|
357
|
-
|
|
358
|
-
// Check project-local storage
|
|
359
|
-
const projectLocal = loadProjectLocalConfig(ctx);
|
|
360
|
-
if (
|
|
361
|
-
projectLocal !== null &&
|
|
362
|
-
projectLocal.deploymentName.startsWith("local-")
|
|
363
|
-
) {
|
|
364
|
-
deployments.push(projectLocal);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Also include legacy deployments (but avoid duplicates)
|
|
368
|
-
const legacyDeployments = await getLegacyLocalDeployments(ctx);
|
|
369
|
-
for (const legacy of legacyDeployments) {
|
|
370
|
-
if (!deployments.some((d) => d.deploymentName === legacy.deploymentName)) {
|
|
371
|
-
deployments.push(legacy);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return deployments;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
async function chooseFromExistingLocalDeployments(ctx: Context): Promise<{
|
|
379
|
-
deploymentName: string;
|
|
380
|
-
config: LocalDeploymentConfig;
|
|
381
|
-
}> {
|
|
382
|
-
const localDeployments = await getLocalDeployments(ctx);
|
|
383
|
-
|
|
384
|
-
if (localDeployments.length === 0) {
|
|
385
|
-
return ctx.crash({
|
|
386
|
-
exitCode: 1,
|
|
387
|
-
errorType: "fatal",
|
|
388
|
-
printedMessage:
|
|
389
|
-
"No local deployments found. Please run `npx convex dev` while online first.",
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// Auto-select if there's only one deployment
|
|
394
|
-
if (localDeployments.length === 1) {
|
|
395
|
-
logVerbose(
|
|
396
|
-
`Auto-selecting the only local deployment: ${localDeployments[0].deploymentName}`,
|
|
397
|
-
);
|
|
398
|
-
return localDeployments[0];
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// Multiple deployments (legacy) - prompt user to choose
|
|
402
|
-
return promptSearch(ctx, {
|
|
403
|
-
message: "Choose from an existing local deployment:",
|
|
404
|
-
choices: localDeployments.map((d) => ({
|
|
405
|
-
name: d.deploymentName,
|
|
406
|
-
value: d,
|
|
407
|
-
})),
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
|
|
411
273
|
/** Copies the default dev env vars from big brain the first time the local dev backend is started */
|
|
412
274
|
export async function importDefaultEnvVars(
|
|
413
275
|
ctx: Context,
|