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
|
import { vi, test, expect, describe, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import { oneoffContext } from "../../../bundler/context.js";
|
|
3
3
|
import { logFailure } from "../../../bundler/log.js";
|
|
4
|
-
import {
|
|
4
|
+
import { _findLatestVersionWithBinary } from "./download.js";
|
|
5
5
|
import { stripVTControlCharacters } from "util";
|
|
6
6
|
import { version as npmVersion } from "../../version.js";
|
|
7
7
|
|
|
@@ -23,7 +23,7 @@ async function setupContext() {
|
|
|
23
23
|
return ctx;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
describe("
|
|
26
|
+
describe("_findLatestVersionWithBinary", () => {
|
|
27
27
|
beforeEach(() => {
|
|
28
28
|
vi.spyOn(process.stderr, "write").mockImplementation(() => true);
|
|
29
29
|
});
|
|
@@ -47,7 +47,7 @@ describe("findLatestVersionWithBinary", () => {
|
|
|
47
47
|
} as Response),
|
|
48
48
|
);
|
|
49
49
|
|
|
50
|
-
const version = await
|
|
50
|
+
const version = await _findLatestVersionWithBinary(ctx, true);
|
|
51
51
|
|
|
52
52
|
expect(version).toBe("precompiled-2026-02-10-4ef979b");
|
|
53
53
|
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
|
@@ -69,7 +69,7 @@ describe("findLatestVersionWithBinary", () => {
|
|
|
69
69
|
} as Response),
|
|
70
70
|
);
|
|
71
71
|
|
|
72
|
-
await expect(
|
|
72
|
+
await expect(_findLatestVersionWithBinary(ctx, true)).rejects.toThrow();
|
|
73
73
|
|
|
74
74
|
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
|
75
75
|
expect(stderrOutput()).toContain("version.convex.dev returned 500");
|
|
@@ -84,7 +84,7 @@ describe("findLatestVersionWithBinary", () => {
|
|
|
84
84
|
} as Response),
|
|
85
85
|
);
|
|
86
86
|
|
|
87
|
-
await expect(
|
|
87
|
+
await expect(_findLatestVersionWithBinary(ctx, true)).rejects.toThrow();
|
|
88
88
|
|
|
89
89
|
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
|
90
90
|
expect(stderrOutput()).toContain("Invalid response missing version field");
|
|
@@ -96,7 +96,7 @@ describe("findLatestVersionWithBinary", () => {
|
|
|
96
96
|
.spyOn(global, "fetch")
|
|
97
97
|
.mockImplementation(() => Promise.reject(new Error("Network error")));
|
|
98
98
|
|
|
99
|
-
await expect(
|
|
99
|
+
await expect(_findLatestVersionWithBinary(ctx, true)).rejects.toThrow();
|
|
100
100
|
|
|
101
101
|
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
|
102
102
|
expect(stderrOutput()).toContain("Failed to fetch latest backend version");
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { test, expect, describe, vi } from "vitest";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { Context } from "../../../bundler/context.js";
|
|
5
|
+
import { generateLocalDevSecrets } from "./secrets.js";
|
|
6
|
+
|
|
7
|
+
// We test that `generateLocalDevSecrets` can correctly generate admin
|
|
8
|
+
// keys from the CLI by using fake binaries that return mock values
|
|
9
|
+
const fixturesDir = path.join(
|
|
10
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
11
|
+
"tests",
|
|
12
|
+
);
|
|
13
|
+
const successBinary = path.join(fixturesDir, "keygenSuccess.mjs");
|
|
14
|
+
const failureBinary = path.join(fixturesDir, "keygenFailure.mjs");
|
|
15
|
+
|
|
16
|
+
function mockContext(): Context {
|
|
17
|
+
return {
|
|
18
|
+
crash: vi.fn((args: { printedMessage: string | null }) => {
|
|
19
|
+
throw new Error(args.printedMessage ?? "crash");
|
|
20
|
+
}),
|
|
21
|
+
} as unknown as Context;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe("generateLocalDevSecrets", () => {
|
|
25
|
+
test("returns an instance secret and admin key from the binary", async () => {
|
|
26
|
+
const ctx = mockContext();
|
|
27
|
+
|
|
28
|
+
const { instanceSecret, adminKey } = await generateLocalDevSecrets(ctx, {
|
|
29
|
+
deploymentName: "my-deployment",
|
|
30
|
+
latestBinaryPath: successBinary,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// The fixture echoes back the instance name as the first part of the key.
|
|
34
|
+
expect(adminKey).toBe("my-deployment|mock_admin_key");
|
|
35
|
+
// The instance secret is 32 random bytes, hex-encoded.
|
|
36
|
+
expect(instanceSecret).toMatch(/^[0-9a-f]{64}$/);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("crashes when the binary fails", async () => {
|
|
40
|
+
const ctx = mockContext();
|
|
41
|
+
|
|
42
|
+
await expect(
|
|
43
|
+
generateLocalDevSecrets(ctx, {
|
|
44
|
+
deploymentName: "my-deployment",
|
|
45
|
+
latestBinaryPath: failureBinary,
|
|
46
|
+
}),
|
|
47
|
+
).rejects.toThrow();
|
|
48
|
+
|
|
49
|
+
expect(vi.mocked(ctx.crash).mock.calls[0][0].printedMessage).toContain(
|
|
50
|
+
"Failed to generate admin key",
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Context } from "../../../bundler/context.js";
|
|
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
|
+
|
|
9
|
+
export const LEGACY_LOCAL_BACKEND_INSTANCE_SECRET =
|
|
10
|
+
"4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Generates an instance secret and an admin key for a new (or just upgraded) local deployment.
|
|
14
|
+
*/
|
|
15
|
+
export async function generateLocalDevSecrets(
|
|
16
|
+
ctx: Context,
|
|
17
|
+
{
|
|
18
|
+
deploymentName,
|
|
19
|
+
latestBinaryPath,
|
|
20
|
+
}: {
|
|
21
|
+
deploymentName: string;
|
|
22
|
+
/**
|
|
23
|
+
* A path to the local backend binary.
|
|
24
|
+
*
|
|
25
|
+
* This must always be the latest version of the local binary that has been published,
|
|
26
|
+
* in order to make sure the `keygen admin-key` command is available. If you need to call
|
|
27
|
+
* this without having access to the latest binary, use `generateLocalDevSecretsWithLatestBinary`
|
|
28
|
+
* which will download the latest version when necessary.
|
|
29
|
+
*/
|
|
30
|
+
latestBinaryPath: string;
|
|
31
|
+
},
|
|
32
|
+
): Promise<{
|
|
33
|
+
instanceSecret: string;
|
|
34
|
+
adminKey: string;
|
|
35
|
+
}> {
|
|
36
|
+
logVerbose("Generating local dev secrets");
|
|
37
|
+
|
|
38
|
+
const instanceSecret = generateInstanceSecret();
|
|
39
|
+
|
|
40
|
+
let stdout: string;
|
|
41
|
+
try {
|
|
42
|
+
({ stdout } = await promisify(execFile)(latestBinaryPath, [
|
|
43
|
+
"keygen",
|
|
44
|
+
"admin-key",
|
|
45
|
+
"--instance-name",
|
|
46
|
+
deploymentName,
|
|
47
|
+
"--instance-secret",
|
|
48
|
+
instanceSecret,
|
|
49
|
+
]));
|
|
50
|
+
} catch (e) {
|
|
51
|
+
const err = e as { stderr?: string; message: string };
|
|
52
|
+
const detail = err.stderr ? err.stderr : err.message;
|
|
53
|
+
const message = `Failed to generate admin key:\n${detail}`;
|
|
54
|
+
return ctx.crash({
|
|
55
|
+
exitCode: 1,
|
|
56
|
+
errorType: "fatal",
|
|
57
|
+
printedMessage: message,
|
|
58
|
+
errForSentry: new LocalDeploymentError(message),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const adminKey = stdout.trim();
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
instanceSecret,
|
|
66
|
+
adminKey,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function generateInstanceSecret(): string {
|
|
71
|
+
return crypto.randomBytes(32).toString("hex");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Similar to generateLocalDevSecrets, but can be called when we’re not confident
|
|
76
|
+
* we have a binary that supports `keygen admin-key`
|
|
77
|
+
*/
|
|
78
|
+
export async function generateLocalDevSecretsWithLatestBinary(
|
|
79
|
+
ctx: Context,
|
|
80
|
+
{
|
|
81
|
+
deploymentName,
|
|
82
|
+
}: {
|
|
83
|
+
deploymentName: string;
|
|
84
|
+
},
|
|
85
|
+
) {
|
|
86
|
+
const { binaryPath: latestBinaryPath } = await ensureBackendBinaryDownloaded(
|
|
87
|
+
ctx,
|
|
88
|
+
{
|
|
89
|
+
kind: "latest",
|
|
90
|
+
},
|
|
91
|
+
);
|
|
92
|
+
return generateLocalDevSecrets(ctx, { deploymentName, latestBinaryPath });
|
|
93
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test fixture standing in for a backend binary that fails to generate an admin
|
|
4
|
+
// key. Writes an error message to stderr and exits with a nonzero code.
|
|
5
|
+
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
|
|
8
|
+
process.stderr.write("could not generate admin key: something went wrong\n");
|
|
9
|
+
process.exit(1);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test fixture standing in for the backend binary's `keygen admin-key` command.
|
|
4
|
+
// Parses the expected arguments and prints a fake admin key in the format
|
|
5
|
+
// `instance_name|admin_key` to stdout.
|
|
6
|
+
|
|
7
|
+
import process from "node:process";
|
|
8
|
+
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
|
|
11
|
+
function getFlag(name) {
|
|
12
|
+
const index = args.indexOf(name);
|
|
13
|
+
return index === -1 ? undefined : args[index + 1];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (args[0] !== "keygen" || args[1] !== "admin-key") {
|
|
17
|
+
process.stderr.write(
|
|
18
|
+
`Unexpected subcommand: ${args.slice(0, 2).join(" ")}\n`,
|
|
19
|
+
);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const instanceName = getFlag("--instance-name");
|
|
24
|
+
const instanceSecret = getFlag("--instance-secret");
|
|
25
|
+
|
|
26
|
+
if (instanceName === undefined || instanceSecret === undefined) {
|
|
27
|
+
process.stderr.write("Missing --instance-name or --instance-secret\n");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
process.stdout.write(`${instanceName}|mock_admin_key\n`);
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
LocalDeploymentConfig,
|
|
11
11
|
LocalDeploymentKind,
|
|
12
12
|
deploymentStateDir,
|
|
13
|
-
loadDeploymentConfig,
|
|
14
13
|
saveDeploymentConfig,
|
|
15
14
|
} from "./filePaths.js";
|
|
16
15
|
import {
|
|
@@ -32,7 +31,12 @@ import { promptOptions, promptYesNo } from "../utils/prompts.js";
|
|
|
32
31
|
import { recursivelyDelete } from "../fsUtils.js";
|
|
33
32
|
import { LocalDeploymentError } from "./errors.js";
|
|
34
33
|
import { ensureBackendBinaryDownloaded } from "./download.js";
|
|
35
|
-
|
|
34
|
+
import {
|
|
35
|
+
generateLocalDevSecretsWithLatestBinary,
|
|
36
|
+
LEGACY_LOCAL_BACKEND_INSTANCE_SECRET,
|
|
37
|
+
} from "./secrets.js";
|
|
38
|
+
|
|
39
|
+
export async function handlePotentialUpgradeAndStart(
|
|
36
40
|
ctx: Context,
|
|
37
41
|
args: {
|
|
38
42
|
deploymentKind: LocalDeploymentKind;
|
|
@@ -44,17 +48,31 @@ export async function handlePotentialUpgrade(
|
|
|
44
48
|
cloud: number;
|
|
45
49
|
site: number;
|
|
46
50
|
};
|
|
47
|
-
adminKey: string;
|
|
48
|
-
instanceSecret: string;
|
|
51
|
+
existingCredentials: { adminKey: string; instanceSecret: string } | null;
|
|
49
52
|
forceUpgrade: boolean;
|
|
50
53
|
cloudProjectId: number | undefined;
|
|
51
54
|
},
|
|
52
|
-
): Promise<{ cleanupHandle: string }> {
|
|
55
|
+
): Promise<{ cleanupHandle: string; adminKey: string }> {
|
|
56
|
+
const { adminKey, instanceSecret } =
|
|
57
|
+
args.existingCredentials === null ||
|
|
58
|
+
args.existingCredentials.instanceSecret ===
|
|
59
|
+
LEGACY_LOCAL_BACKEND_INSTANCE_SECRET
|
|
60
|
+
? // Using `generateLocalDevSecretsFromLatestBinary` instead of `generateLocalDevSecrets`
|
|
61
|
+
// here, because `newBinaryPath` can be a binary that doesn’t support
|
|
62
|
+
// the `keygen admin-key` subcommand (when the --local-backend-version flag is provided to the CLI)
|
|
63
|
+
//
|
|
64
|
+
// In most cases (the user is not using the flag), we have already downloaded the latest binary
|
|
65
|
+
// shortly before in handleLocalDeployment/handleAnonymousDeployment, so this doesn’t cause an
|
|
66
|
+
// extra download (even if the user chooses later not to upgrade their deployment)
|
|
67
|
+
await generateLocalDevSecretsWithLatestBinary(ctx, {
|
|
68
|
+
deploymentName: args.deploymentName,
|
|
69
|
+
})
|
|
70
|
+
: args.existingCredentials;
|
|
53
71
|
const newConfig: LocalDeploymentConfig = {
|
|
54
72
|
ports: args.ports,
|
|
55
73
|
backendVersion: args.newVersion,
|
|
56
|
-
adminKey
|
|
57
|
-
instanceSecret
|
|
74
|
+
adminKey,
|
|
75
|
+
instanceSecret,
|
|
58
76
|
cloudProjectId: args.cloudProjectId,
|
|
59
77
|
};
|
|
60
78
|
if (args.oldVersion === null || args.oldVersion === args.newVersion) {
|
|
@@ -65,14 +83,15 @@ export async function handlePotentialUpgrade(
|
|
|
65
83
|
args.deploymentName,
|
|
66
84
|
newConfig,
|
|
67
85
|
);
|
|
68
|
-
|
|
86
|
+
const { cleanupHandle } = await runLocalBackend(ctx, {
|
|
69
87
|
binaryPath: args.newBinaryPath,
|
|
70
88
|
deploymentKind: args.deploymentKind,
|
|
71
89
|
deploymentName: args.deploymentName,
|
|
72
90
|
ports: args.ports,
|
|
73
|
-
instanceSecret
|
|
91
|
+
instanceSecret,
|
|
74
92
|
isLatestVersion: true,
|
|
75
93
|
});
|
|
94
|
+
return { cleanupHandle, adminKey };
|
|
76
95
|
}
|
|
77
96
|
logVerbose(
|
|
78
97
|
`Considering upgrade from ${args.oldVersion} to ${args.newVersion}`,
|
|
@@ -97,14 +116,15 @@ export async function handlePotentialUpgrade(
|
|
|
97
116
|
...newConfig,
|
|
98
117
|
backendVersion: args.oldVersion,
|
|
99
118
|
});
|
|
100
|
-
|
|
119
|
+
const { cleanupHandle } = await runLocalBackend(ctx, {
|
|
101
120
|
binaryPath: oldBinaryPath,
|
|
102
121
|
ports: args.ports,
|
|
103
122
|
deploymentKind: args.deploymentKind,
|
|
104
123
|
deploymentName: args.deploymentName,
|
|
105
|
-
instanceSecret
|
|
124
|
+
instanceSecret,
|
|
106
125
|
isLatestVersion: false,
|
|
107
126
|
});
|
|
127
|
+
return { cleanupHandle, adminKey };
|
|
108
128
|
}
|
|
109
129
|
const choice =
|
|
110
130
|
args.forceUpgrade || !process.stdin.isTTY
|
|
@@ -130,31 +150,28 @@ export async function handlePotentialUpgrade(
|
|
|
130
150
|
args.deploymentName,
|
|
131
151
|
newConfig,
|
|
132
152
|
);
|
|
133
|
-
|
|
153
|
+
const { cleanupHandle } = await runLocalBackend(ctx, {
|
|
134
154
|
binaryPath: args.newBinaryPath,
|
|
135
155
|
deploymentKind: args.deploymentKind,
|
|
136
156
|
deploymentName: args.deploymentName,
|
|
137
157
|
ports: args.ports,
|
|
138
|
-
instanceSecret
|
|
158
|
+
instanceSecret,
|
|
139
159
|
isLatestVersion: true,
|
|
140
160
|
});
|
|
161
|
+
return { cleanupHandle, adminKey };
|
|
141
162
|
}
|
|
142
|
-
const
|
|
143
|
-
const oldAdminKey =
|
|
144
|
-
loadDeploymentConfig(ctx, args.deploymentKind, args.deploymentName)
|
|
145
|
-
?.adminKey ?? args.adminKey;
|
|
146
|
-
return handleUpgrade(ctx, {
|
|
163
|
+
const { cleanupHandle } = await handleUpgrade(ctx, {
|
|
147
164
|
deploymentKind: args.deploymentKind,
|
|
148
165
|
deploymentName: args.deploymentName,
|
|
149
166
|
oldVersion: args.oldVersion!,
|
|
150
167
|
newBinaryPath: args.newBinaryPath,
|
|
151
168
|
newVersion: args.newVersion,
|
|
152
169
|
ports: args.ports,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
instanceSecret: args.instanceSecret,
|
|
170
|
+
adminKey,
|
|
171
|
+
instanceSecret,
|
|
156
172
|
cloudProjectId: args.cloudProjectId,
|
|
157
173
|
});
|
|
174
|
+
return { cleanupHandle, adminKey };
|
|
158
175
|
}
|
|
159
176
|
|
|
160
177
|
async function handleUpgrade(
|
|
@@ -169,15 +186,12 @@ async function handleUpgrade(
|
|
|
169
186
|
cloud: number;
|
|
170
187
|
site: number;
|
|
171
188
|
};
|
|
172
|
-
// In most of the cases the admin key is the same for the old and new version.
|
|
173
|
-
// This is helpful when we start generating new admin key formats that might
|
|
174
|
-
// be incompatible with older backend versions.
|
|
175
|
-
oldAdminKey: string;
|
|
176
|
-
newAdminKey: string;
|
|
177
189
|
instanceSecret: string;
|
|
190
|
+
adminKey: string;
|
|
178
191
|
cloudProjectId: number | undefined;
|
|
179
192
|
},
|
|
180
193
|
): Promise<{ cleanupHandle: string }> {
|
|
194
|
+
const { adminKey } = args;
|
|
181
195
|
const { binaryPath: oldBinaryPath } = await ensureBackendBinaryDownloaded(
|
|
182
196
|
ctx,
|
|
183
197
|
{
|
|
@@ -200,7 +214,7 @@ async function handleUpgrade(
|
|
|
200
214
|
const deploymentUrl = localDeploymentUrl(args.ports.cloud);
|
|
201
215
|
const envs = (await runSystemQuery(ctx, {
|
|
202
216
|
deploymentUrl,
|
|
203
|
-
adminKey
|
|
217
|
+
adminKey,
|
|
204
218
|
functionName: "_system/cli/queryEnvironmentVariables",
|
|
205
219
|
componentPath: undefined,
|
|
206
220
|
args: {},
|
|
@@ -217,13 +231,13 @@ async function handleUpgrade(
|
|
|
217
231
|
if (ctx.fs.exists(exportPath)) {
|
|
218
232
|
ctx.fs.unlink(exportPath);
|
|
219
233
|
}
|
|
220
|
-
const
|
|
234
|
+
const snapshotExportState = await startSnapshotExport(ctx, {
|
|
221
235
|
deploymentUrl,
|
|
222
|
-
adminKey
|
|
236
|
+
adminKey,
|
|
223
237
|
includeStorage: true,
|
|
224
238
|
inputPath: exportPath,
|
|
225
239
|
});
|
|
226
|
-
if (
|
|
240
|
+
if (snapshotExportState.state !== "completed") {
|
|
227
241
|
return ctx.crash({
|
|
228
242
|
exitCode: 1,
|
|
229
243
|
errorType: "fatal",
|
|
@@ -231,9 +245,9 @@ async function handleUpgrade(
|
|
|
231
245
|
});
|
|
232
246
|
}
|
|
233
247
|
await downloadSnapshotExport(ctx, {
|
|
234
|
-
snapshotExportTs:
|
|
248
|
+
snapshotExportTs: snapshotExportState.start_ts,
|
|
235
249
|
inputPath: exportPath,
|
|
236
|
-
adminKey
|
|
250
|
+
adminKey,
|
|
237
251
|
deploymentUrl,
|
|
238
252
|
});
|
|
239
253
|
|
|
@@ -264,7 +278,7 @@ async function handleUpgrade(
|
|
|
264
278
|
if (envs.length > 0) {
|
|
265
279
|
const fetch = deploymentFetch(ctx, {
|
|
266
280
|
deploymentUrl,
|
|
267
|
-
adminKey
|
|
281
|
+
adminKey,
|
|
268
282
|
});
|
|
269
283
|
try {
|
|
270
284
|
await fetch("/api/update_environment_variables", {
|
|
@@ -280,7 +294,7 @@ async function handleUpgrade(
|
|
|
280
294
|
logVerbose("Doing a snapshot import");
|
|
281
295
|
const importId = await uploadForImport(ctx, {
|
|
282
296
|
deploymentUrl,
|
|
283
|
-
adminKey
|
|
297
|
+
adminKey,
|
|
284
298
|
filePath: exportPath,
|
|
285
299
|
importArgs: { format: "zip", mode: "replace", tableName: undefined },
|
|
286
300
|
onImportFailed: async (e) => {
|
|
@@ -291,7 +305,7 @@ async function handleUpgrade(
|
|
|
291
305
|
let status = await waitForStableImportState(ctx, {
|
|
292
306
|
importId,
|
|
293
307
|
deploymentUrl,
|
|
294
|
-
adminKey
|
|
308
|
+
adminKey,
|
|
295
309
|
onProgress: () => {
|
|
296
310
|
// do nothing for now
|
|
297
311
|
return 0;
|
|
@@ -309,7 +323,7 @@ async function handleUpgrade(
|
|
|
309
323
|
|
|
310
324
|
await confirmImport(ctx, {
|
|
311
325
|
importId,
|
|
312
|
-
adminKey
|
|
326
|
+
adminKey,
|
|
313
327
|
deploymentUrl,
|
|
314
328
|
onError: async (e) => {
|
|
315
329
|
logFailure(`Failed to confirm import: ${e}`);
|
|
@@ -319,7 +333,7 @@ async function handleUpgrade(
|
|
|
319
333
|
status = await waitForStableImportState(ctx, {
|
|
320
334
|
importId,
|
|
321
335
|
deploymentUrl,
|
|
322
|
-
adminKey
|
|
336
|
+
adminKey,
|
|
323
337
|
onProgress: () => {
|
|
324
338
|
// do nothing for now
|
|
325
339
|
return 0;
|
|
@@ -340,7 +354,7 @@ async function handleUpgrade(
|
|
|
340
354
|
saveDeploymentConfig(ctx, args.deploymentKind, args.deploymentName, {
|
|
341
355
|
ports: args.ports,
|
|
342
356
|
backendVersion: args.newVersion,
|
|
343
|
-
adminKey
|
|
357
|
+
adminKey,
|
|
344
358
|
instanceSecret: args.instanceSecret,
|
|
345
359
|
cloudProjectId: args.cloudProjectId,
|
|
346
360
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Context } from "../../../bundler/context.js";
|
|
2
2
|
import { logMessage } from "../../../bundler/log.js";
|
|
3
3
|
import { detect } from "detect-port";
|
|
4
|
-
import crypto from "crypto";
|
|
5
4
|
import { chalkStderr } from "chalk";
|
|
6
5
|
|
|
7
6
|
export async function choosePorts(
|
|
@@ -80,11 +79,6 @@ export async function chooseLocalBackendPorts(
|
|
|
80
79
|
return { cloudPort, sitePort };
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
export async function isOffline(): Promise<boolean> {
|
|
84
|
-
// TODO(ENG-7080) -- implement this for real
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
82
|
export function printLocalDeploymentWelcomeMessage() {
|
|
89
83
|
logMessage(
|
|
90
84
|
chalkStderr.cyan("You're trying out the beta local deployment feature!"),
|
|
@@ -96,9 +90,5 @@ export function printLocalDeploymentWelcomeMessage() {
|
|
|
96
90
|
);
|
|
97
91
|
}
|
|
98
92
|
|
|
99
|
-
export function generateInstanceSecret(): string {
|
|
100
|
-
return crypto.randomBytes(32).toString("hex");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
93
|
export const LOCAL_BACKEND_INSTANCE_SECRET =
|
|
104
94
|
"4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974";
|
|
@@ -15,9 +15,9 @@ export const INLINE_QUERY_DESCRIPTION = [
|
|
|
15
15
|
"Use `--component` to target a mounted component.",
|
|
16
16
|
"",
|
|
17
17
|
"To format the query:",
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
18
|
+
'• Simple expressions are returned automatically, for example: `await ctx.db.query("messages").take(5)`.',
|
|
19
|
+
'• For multi-statement queries, use an explicit return, for example: `const firstMessage = await ctx.db.query("messages").first(); console.log(firstMessage?._id); return firstMessage;`.',
|
|
20
|
+
'• For full control, pass a module source that exports a default query, for example: `export default query({ handler: async (ctx) => { return await ctx.db.query("messages").take(10); } })`.',
|
|
21
21
|
].join("\n");
|
|
22
22
|
|
|
23
23
|
export type RunTestFunctionQuerySuccess = {
|
package/src/cli/run.ts
CHANGED
|
@@ -31,11 +31,11 @@ export const run = new Command("run")
|
|
|
31
31
|
[
|
|
32
32
|
"Run a function or evaluate an inline readonly query on your deployment.",
|
|
33
33
|
"",
|
|
34
|
-
'
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
34
|
+
'• Run a function with JSON arguments: `npx convex run messages:send \'{"body": "hello", "author": "me"}\'`',
|
|
35
|
+
"• Run a function on prod: `npx convex run messages:list --prod`",
|
|
36
|
+
"• Live-update a query's result: `npx convex run messages:list --watch`",
|
|
37
|
+
"• Push local code before running: `npx convex run messages:send '{}' --push`",
|
|
38
|
+
"• Evaluate an inline readonly query: `npx convex run --inline-query 'await ctx.db.query(\"messages\").take(5)'`",
|
|
39
39
|
"",
|
|
40
40
|
"Arguments are specified as a JSON object. By default, this runs on your dev deployment.",
|
|
41
41
|
].join("\n"),
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "1.
|
|
1
|
+
export const version = "1.41.0";
|
|
@@ -62,8 +62,6 @@ async function invokeMutation<
|
|
|
62
62
|
|
|
63
63
|
runQuery: (reference: any, args?: any, options?: any) =>
|
|
64
64
|
runUdf("query", reference, args, options?.transactionLimits),
|
|
65
|
-
runSnapshotQuery: (reference: any, args?: any, options?: any) =>
|
|
66
|
-
runUdf("snapshotQuery", reference, args, options?.transactionLimits),
|
|
67
65
|
runMutation: (reference: any, args?: any, options?: any) =>
|
|
68
66
|
runUdf("mutation", reference, args, options?.transactionLimits),
|
|
69
67
|
};
|
package/src/server/index.ts
CHANGED
package/src/server/meta.ts
CHANGED
|
@@ -28,6 +28,23 @@ export type TransactionMetrics = {
|
|
|
28
28
|
scheduledFunctionArgsBytes: TransactionMetric;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Custom limits for a nested transaction. Each field specifies the absolute
|
|
33
|
+
* maximum allowed for the nested function call. Values are capped at the
|
|
34
|
+
* global transaction limits, so they can only lower limits, never raise them.
|
|
35
|
+
*
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
export interface TransactionLimits {
|
|
39
|
+
bytesRead?: number;
|
|
40
|
+
bytesWritten?: number;
|
|
41
|
+
databaseQueries?: number;
|
|
42
|
+
documentsRead?: number;
|
|
43
|
+
documentsWritten?: number;
|
|
44
|
+
functionsScheduled?: number;
|
|
45
|
+
scheduledFunctionArgsBytes?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
/**
|
|
32
49
|
* Metadata about the currently executing Convex function.
|
|
33
50
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
2
|
import { test, describe, expect } from "vitest";
|
|
3
|
-
import { assert,
|
|
3
|
+
import { assert, Equals } from "../test/type_testing.js";
|
|
4
4
|
import { v } from "../values/validator.js";
|
|
5
5
|
import {
|
|
6
6
|
ActionBuilder,
|
|
@@ -11,14 +11,7 @@ import {
|
|
|
11
11
|
mutationGeneric,
|
|
12
12
|
queryGeneric,
|
|
13
13
|
} from "./index.js";
|
|
14
|
-
import {
|
|
15
|
-
EmptyObject,
|
|
16
|
-
GenericActionCtx,
|
|
17
|
-
GenericMutationCtx,
|
|
18
|
-
GenericQueryCtx,
|
|
19
|
-
MutationBuilder,
|
|
20
|
-
} from "./registration.js";
|
|
21
|
-
import { GenericDataModel } from "./data_model.js";
|
|
14
|
+
import { EmptyObject, MutationBuilder } from "./registration.js";
|
|
22
15
|
|
|
23
16
|
describe("argument inference", () => {
|
|
24
17
|
// Test with mutation, but all the wrappers work the same way.
|
|
@@ -570,29 +563,3 @@ describe("argument and return value validators can be objects or validators", ()
|
|
|
570
563
|
expect(JSON.parse(returnString)).toEqual(expectedReturnsExport);
|
|
571
564
|
});
|
|
572
565
|
});
|
|
573
|
-
|
|
574
|
-
describe("runSnapshotQuery availability", () => {
|
|
575
|
-
test("available on mutation ctx", () => {
|
|
576
|
-
assert<
|
|
577
|
-
"runSnapshotQuery" extends keyof GenericMutationCtx<GenericDataModel>
|
|
578
|
-
? true
|
|
579
|
-
: false
|
|
580
|
-
>();
|
|
581
|
-
});
|
|
582
|
-
|
|
583
|
-
test("not available on query ctx", () => {
|
|
584
|
-
assertFalse<
|
|
585
|
-
"runSnapshotQuery" extends keyof GenericQueryCtx<GenericDataModel>
|
|
586
|
-
? true
|
|
587
|
-
: false
|
|
588
|
-
>();
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
test("not available on action ctx", () => {
|
|
592
|
-
assertFalse<
|
|
593
|
-
"runSnapshotQuery" extends keyof GenericActionCtx<GenericDataModel>
|
|
594
|
-
? true
|
|
595
|
-
: false
|
|
596
|
-
>();
|
|
597
|
-
});
|
|
598
|
-
});
|