convex 1.48.0 → 1.49.0-alpha.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 +7 -0
- package/dist/browser.bundle.js +1 -1
- package/dist/browser.bundle.js.map +1 -1
- package/dist/cjs/bundler/context.js +7 -5
- package/dist/cjs/bundler/context.js.map +2 -2
- package/dist/cjs/bundler/fs.js +47 -6
- package/dist/cjs/bundler/fs.js.map +2 -2
- package/dist/cjs/cli/account.js +237 -0
- package/dist/cjs/cli/account.js.map +7 -0
- package/dist/cjs/cli/configure.js +15 -2
- package/dist/cjs/cli/configure.js.map +2 -2
- package/dist/cjs/cli/lib/accountManagement.js +196 -0
- package/dist/cjs/cli/lib/accountManagement.js.map +7 -0
- package/dist/cjs/cli/lib/accounts.js +334 -0
- package/dist/cjs/cli/lib/accounts.js.map +7 -0
- package/dist/cjs/cli/lib/deployKeyWarning.js +43 -0
- package/dist/cjs/cli/lib/deployKeyWarning.js.map +7 -0
- package/dist/cjs/cli/lib/deployment.js +2 -0
- package/dist/cjs/cli/lib/deployment.js.map +2 -2
- package/dist/cjs/cli/lib/deploymentSelection.js +27 -18
- package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/cjs/cli/lib/envvars.js +32 -0
- package/dist/cjs/cli/lib/envvars.js.map +2 -2
- package/dist/cjs/cli/lib/fsUtils.js +1 -1
- package/dist/cjs/cli/lib/fsUtils.js.map +2 -2
- package/dist/cjs/cli/lib/generateDocs.js +1 -1
- package/dist/cjs/cli/lib/generateDocs.js.map +1 -1
- package/dist/cjs/cli/lib/login.js +42 -4
- package/dist/cjs/cli/lib/login.js.map +3 -3
- package/dist/cjs/cli/lib/mcp/requestContext.js +5 -1
- package/dist/cjs/cli/lib/mcp/requestContext.js.map +2 -2
- package/dist/cjs/cli/lib/plugins/claudeCode.js +188 -0
- package/dist/cjs/cli/lib/plugins/claudeCode.js.map +7 -0
- package/dist/cjs/cli/lib/plugins/codex.js +167 -0
- package/dist/cjs/cli/lib/plugins/codex.js.map +7 -0
- package/dist/cjs/cli/lib/plugins/harness.js +50 -0
- package/dist/cjs/cli/lib/plugins/harness.js.map +7 -0
- package/dist/cjs/cli/lib/plugins/marketplaces.js +76 -0
- package/dist/cjs/cli/lib/plugins/marketplaces.js.map +7 -0
- package/dist/cjs/cli/lib/plugins/skills.js +98 -0
- package/dist/cjs/cli/lib/plugins/skills.js.map +7 -0
- package/dist/cjs/cli/lib/plugins/utils.js +125 -0
- package/dist/cjs/cli/lib/plugins/utils.js.map +7 -0
- package/dist/cjs/cli/lib/utils/utils.js +18 -9
- package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
- package/dist/cjs/cli/login.js +213 -114
- package/dist/cjs/cli/login.js.map +3 -3
- package/dist/cjs/cli/logout.js +113 -12
- package/dist/cjs/cli/logout.js.map +3 -3
- package/dist/cjs/cli/mcp.js +43 -10
- package/dist/cjs/cli/mcp.js.map +3 -3
- package/dist/cjs/cli/plugins.js +114 -0
- package/dist/cjs/cli/plugins.js.map +7 -0
- package/dist/cjs/cli/program.js +3 -1
- package/dist/cjs/cli/program.js.map +2 -2
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/impl/actions_impl.js.map +2 -2
- package/dist/cjs-types/bundler/context.d.ts +5 -0
- package/dist/cjs-types/bundler/context.d.ts.map +1 -1
- package/dist/cjs-types/bundler/fs.d.ts +7 -2
- package/dist/cjs-types/bundler/fs.d.ts.map +1 -1
- package/dist/cjs-types/cli/account.d.ts +6 -0
- package/dist/cjs-types/cli/account.d.ts.map +1 -0
- package/dist/cjs-types/cli/configure.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/accountManagement.d.ts +10 -0
- package/dist/cjs-types/cli/lib/accountManagement.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/accounts.d.ts +59 -0
- package/dist/cjs-types/cli/lib/accounts.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts +3 -0
- package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/deployment.d.ts +2 -0
- package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +2 -1
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/envvars.d.ts +6 -0
- package/dist/cjs-types/cli/lib/envvars.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/fsUtils.d.ts +1 -0
- package/dist/cjs-types/cli/lib/fsUtils.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/login.d.ts +3 -1
- package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +2 -2
- package/dist/cjs-types/cli/lib/plugins/claudeCode.d.ts +25 -0
- package/dist/cjs-types/cli/lib/plugins/claudeCode.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/plugins/codex.d.ts +25 -0
- package/dist/cjs-types/cli/lib/plugins/codex.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/plugins/harness.d.ts +33 -0
- package/dist/cjs-types/cli/lib/plugins/harness.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/plugins/marketplaces.d.ts +40 -0
- package/dist/cjs-types/cli/lib/plugins/marketplaces.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/plugins/skills.d.ts +18 -0
- package/dist/cjs-types/cli/lib/plugins/skills.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/plugins/utils.d.ts +21 -0
- package/dist/cjs-types/cli/lib/plugins/utils.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/utils/utils.d.ts +5 -0
- package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
- package/dist/cjs-types/cli/login.d.ts +21 -0
- package/dist/cjs-types/cli/login.d.ts.map +1 -1
- package/dist/cjs-types/cli/logout.d.ts +8 -1
- package/dist/cjs-types/cli/logout.d.ts.map +1 -1
- package/dist/cjs-types/cli/mcp.d.ts.map +1 -1
- package/dist/cjs-types/cli/plugins.d.ts +3 -0
- package/dist/cjs-types/cli/plugins.d.ts.map +1 -0
- package/dist/cjs-types/cli/program.d.ts.map +1 -1
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cjs-types/index.d.ts.map +1 -1
- package/dist/cjs-types/server/impl/actions_impl.d.ts +3 -2
- package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
- package/dist/cli.bundle.cjs +10059 -7094
- package/dist/cli.bundle.cjs.map +4 -4
- package/dist/esm/bundler/context.js +7 -5
- package/dist/esm/bundler/context.js.map +2 -2
- package/dist/esm/bundler/fs.js +47 -6
- package/dist/esm/bundler/fs.js.map +2 -2
- package/dist/esm/cli/account.js +221 -0
- package/dist/esm/cli/account.js.map +7 -0
- package/dist/esm/cli/configure.js +15 -2
- package/dist/esm/cli/configure.js.map +2 -2
- package/dist/esm/cli/lib/accountManagement.js +179 -0
- package/dist/esm/cli/lib/accountManagement.js.map +7 -0
- package/dist/esm/cli/lib/accounts.js +289 -0
- package/dist/esm/cli/lib/accounts.js.map +7 -0
- package/dist/esm/cli/lib/deployKeyWarning.js +27 -0
- package/dist/esm/cli/lib/deployKeyWarning.js.map +7 -0
- package/dist/esm/cli/lib/deployment.js +2 -2
- package/dist/esm/cli/lib/deployment.js.map +2 -2
- package/dist/esm/cli/lib/deploymentSelection.js +35 -20
- package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/esm/cli/lib/envvars.js +35 -1
- package/dist/esm/cli/lib/envvars.js.map +2 -2
- package/dist/esm/cli/lib/fsUtils.js +1 -1
- package/dist/esm/cli/lib/fsUtils.js.map +2 -2
- package/dist/esm/cli/lib/generateDocs.js +1 -1
- package/dist/esm/cli/lib/generateDocs.js.map +1 -1
- package/dist/esm/cli/lib/login.js +52 -4
- package/dist/esm/cli/lib/login.js.map +3 -3
- package/dist/esm/cli/lib/mcp/requestContext.js +5 -1
- package/dist/esm/cli/lib/mcp/requestContext.js.map +2 -2
- package/dist/esm/cli/lib/plugins/claudeCode.js +160 -0
- package/dist/esm/cli/lib/plugins/claudeCode.js.map +7 -0
- package/dist/esm/cli/lib/plugins/codex.js +140 -0
- package/dist/esm/cli/lib/plugins/codex.js.map +7 -0
- package/dist/esm/cli/lib/plugins/harness.js +17 -0
- package/dist/esm/cli/lib/plugins/harness.js.map +7 -0
- package/dist/esm/cli/lib/plugins/marketplaces.js +53 -0
- package/dist/esm/cli/lib/plugins/marketplaces.js.map +7 -0
- package/dist/esm/cli/lib/plugins/skills.js +65 -0
- package/dist/esm/cli/lib/plugins/skills.js.map +7 -0
- package/dist/esm/cli/lib/plugins/utils.js +86 -0
- package/dist/esm/cli/lib/plugins/utils.js.map +7 -0
- package/dist/esm/cli/lib/utils/utils.js +16 -9
- package/dist/esm/cli/lib/utils/utils.js.map +2 -2
- package/dist/esm/cli/login.js +225 -112
- package/dist/esm/cli/login.js.map +3 -3
- package/dist/esm/cli/logout.js +110 -13
- package/dist/esm/cli/logout.js.map +2 -2
- package/dist/esm/cli/mcp.js +34 -10
- package/dist/esm/cli/mcp.js.map +2 -2
- package/dist/esm/cli/plugins.js +99 -0
- package/dist/esm/cli/plugins.js.map +7 -0
- package/dist/esm/cli/program.js +3 -1
- package/dist/esm/cli/program.js.map +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/impl/actions_impl.js.map +2 -2
- package/dist/esm-types/bundler/context.d.ts +5 -0
- package/dist/esm-types/bundler/context.d.ts.map +1 -1
- package/dist/esm-types/bundler/fs.d.ts +7 -2
- package/dist/esm-types/bundler/fs.d.ts.map +1 -1
- package/dist/esm-types/cli/account.d.ts +6 -0
- package/dist/esm-types/cli/account.d.ts.map +1 -0
- package/dist/esm-types/cli/configure.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/accountManagement.d.ts +10 -0
- package/dist/esm-types/cli/lib/accountManagement.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/accounts.d.ts +59 -0
- package/dist/esm-types/cli/lib/accounts.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/deployKeyWarning.d.ts +3 -0
- package/dist/esm-types/cli/lib/deployKeyWarning.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/deployment.d.ts +2 -0
- package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts +2 -1
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/envvars.d.ts +6 -0
- package/dist/esm-types/cli/lib/envvars.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/fsUtils.d.ts +1 -0
- package/dist/esm-types/cli/lib/fsUtils.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/login.d.ts +3 -1
- package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +2 -2
- package/dist/esm-types/cli/lib/plugins/claudeCode.d.ts +25 -0
- package/dist/esm-types/cli/lib/plugins/claudeCode.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/plugins/codex.d.ts +25 -0
- package/dist/esm-types/cli/lib/plugins/codex.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/plugins/harness.d.ts +33 -0
- package/dist/esm-types/cli/lib/plugins/harness.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/plugins/marketplaces.d.ts +40 -0
- package/dist/esm-types/cli/lib/plugins/marketplaces.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/plugins/skills.d.ts +18 -0
- package/dist/esm-types/cli/lib/plugins/skills.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/plugins/utils.d.ts +21 -0
- package/dist/esm-types/cli/lib/plugins/utils.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/utils/utils.d.ts +5 -0
- package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
- package/dist/esm-types/cli/login.d.ts +21 -0
- package/dist/esm-types/cli/login.d.ts.map +1 -1
- package/dist/esm-types/cli/logout.d.ts +8 -1
- package/dist/esm-types/cli/logout.d.ts.map +1 -1
- package/dist/esm-types/cli/mcp.d.ts.map +1 -1
- package/dist/esm-types/cli/plugins.d.ts +3 -0
- package/dist/esm-types/cli/plugins.d.ts.map +1 -0
- package/dist/esm-types/cli/program.d.ts.map +1 -1
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/esm-types/index.d.ts.map +1 -1
- package/dist/esm-types/server/impl/actions_impl.d.ts +3 -2
- package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
- package/dist/react.bundle.js +1 -1
- package/dist/react.bundle.js.map +1 -1
- package/package.json +2 -2
- package/src/bundler/context.ts +9 -5
- package/src/bundler/fs.ts +54 -5
- package/src/cli/account.ts +320 -0
- package/src/cli/configure.ts +18 -2
- package/src/cli/lib/accountManagement.ts +262 -0
- package/src/cli/lib/accounts.ts +400 -0
- package/src/cli/lib/deployKeyWarning.ts +43 -0
- package/src/cli/lib/deployment.ts +2 -2
- package/src/cli/lib/deploymentSelection.ts +37 -18
- package/src/cli/lib/envvars.ts +43 -1
- package/src/cli/lib/fsUtils.ts +5 -2
- package/src/cli/lib/generateDocs.ts +1 -1
- package/src/cli/lib/login.ts +64 -3
- package/src/cli/lib/mcp/requestContext.ts +7 -1
- package/src/cli/lib/plugins/claudeCode.ts +201 -0
- package/src/cli/lib/plugins/codex.ts +177 -0
- package/src/cli/lib/plugins/harness.ts +49 -0
- package/src/cli/lib/plugins/marketplaces.ts +94 -0
- package/src/cli/lib/plugins/skills.ts +101 -0
- package/src/cli/lib/plugins/utils.ts +121 -0
- package/src/cli/lib/utils/utils.ts +19 -15
- package/src/cli/login.ts +293 -168
- package/src/cli/logout.ts +142 -17
- package/src/cli/mcp.ts +48 -11
- package/src/cli/plugins.ts +154 -0
- package/src/cli/program.ts +4 -0
- package/src/index.ts +1 -1
- package/src/server/impl/actions_impl.ts +3 -2
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { isDeepStrictEqual } from "util";
|
|
4
|
+
import { randomUUID } from "crypto";
|
|
5
|
+
import * as dotenv from "dotenv";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { logFinishedStep, logWarning } from "../../bundler/log.js";
|
|
8
|
+
import { globalConfigPath, readGlobalConfig } from "./utils/globalConfig.js";
|
|
9
|
+
import { ENV_VAR_FILE_PATH, rootDirectory } from "./utils/utils.js";
|
|
10
|
+
import { CONVEX_ACCOUNT_ENV_VAR } from "./envvars.js";
|
|
11
|
+
const settingsSchema = z.object({
|
|
12
|
+
defaultAccount: z.string().optional(),
|
|
13
|
+
directories: z.record(z.string()).optional(),
|
|
14
|
+
revokeReplacedTokens: z.boolean().optional()
|
|
15
|
+
}).passthrough();
|
|
16
|
+
const credentialsSchema = z.object({
|
|
17
|
+
accessToken: z.string().min(1),
|
|
18
|
+
memberId: z.string().optional(),
|
|
19
|
+
email: z.string().optional()
|
|
20
|
+
}).passthrough();
|
|
21
|
+
export async function readAccountSettings(ctx) {
|
|
22
|
+
if (!ctx.fs.exists(globalConfigPath())) return {};
|
|
23
|
+
try {
|
|
24
|
+
return settingsSchema.parse(
|
|
25
|
+
JSON.parse(ctx.fs.readUtf8File(globalConfigPath()))
|
|
26
|
+
);
|
|
27
|
+
} catch {
|
|
28
|
+
return await ctx.crash({
|
|
29
|
+
exitCode: 1,
|
|
30
|
+
errorType: "invalid filesystem data",
|
|
31
|
+
printedMessage: `Unable to read account settings from ${globalConfigPath()}. Check defaultAccount, directories, and revokeReplacedTokens.`
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function writeAccountSettings(ctx, settings) {
|
|
36
|
+
if (Object.keys(settings).length === 0) {
|
|
37
|
+
if (ctx.fs.exists(globalConfigPath())) ctx.fs.unlink(globalConfigPath());
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const temporary = `${globalConfigPath()}.${randomUUID()}.tmp`;
|
|
41
|
+
try {
|
|
42
|
+
ctx.fs.writeUtf8File(temporary, JSON.stringify(settings, null, 2), 384);
|
|
43
|
+
ctx.fs.swapTmpFile(temporary, globalConfigPath());
|
|
44
|
+
} finally {
|
|
45
|
+
if (ctx.fs.exists(temporary)) ctx.fs.unlink(temporary);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export async function updateAccountSettings(ctx, update, afterWrite) {
|
|
49
|
+
const lockPath = `${globalConfigPath()}.lock`;
|
|
50
|
+
ctx.fs.mkdir(rootDirectory(), { allowExisting: true });
|
|
51
|
+
const deadline = Date.now() + 5e3;
|
|
52
|
+
for (; ; ) {
|
|
53
|
+
try {
|
|
54
|
+
ctx.fs.mkdir(lockPath);
|
|
55
|
+
break;
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (err.code !== "EEXIST") throw err;
|
|
58
|
+
if (Date.now() >= deadline) {
|
|
59
|
+
return await ctx.crash({
|
|
60
|
+
exitCode: 1,
|
|
61
|
+
errorType: "fatal",
|
|
62
|
+
printedMessage: `Another command is updating Convex accounts. Retry after it finishes. If it was interrupted, remove ${lockPath}.`
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
let released = false;
|
|
69
|
+
const release = () => {
|
|
70
|
+
if (released) return;
|
|
71
|
+
ctx.fs.rmdir(lockPath);
|
|
72
|
+
released = true;
|
|
73
|
+
};
|
|
74
|
+
const cleanup = ctx.registerCleanup(async () => release());
|
|
75
|
+
try {
|
|
76
|
+
const settings = await readAccountSettings(ctx);
|
|
77
|
+
const result = await update(settings);
|
|
78
|
+
writeAccountSettings(ctx, settings);
|
|
79
|
+
afterWrite?.();
|
|
80
|
+
return result;
|
|
81
|
+
} finally {
|
|
82
|
+
ctx.removeCleanup(cleanup);
|
|
83
|
+
release();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function accountConfigPath(name) {
|
|
87
|
+
return path.join(
|
|
88
|
+
rootDirectory(),
|
|
89
|
+
"accounts",
|
|
90
|
+
`${encodeURIComponent(name)}.json`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
export async function validateAccountName(ctx, name) {
|
|
94
|
+
if (!/^[a-z0-9][a-z0-9_-]*$/.test(name)) {
|
|
95
|
+
await ctx.crash({
|
|
96
|
+
exitCode: 1,
|
|
97
|
+
errorType: "invalid filesystem or env vars",
|
|
98
|
+
printedMessage: "Account names must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, and underscores."
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export async function getAccountSelection(ctx, options = {}) {
|
|
103
|
+
let name = options.name;
|
|
104
|
+
let source = "--account";
|
|
105
|
+
if (name === void 0 && process.env[CONVEX_ACCOUNT_ENV_VAR] !== void 0) {
|
|
106
|
+
name = process.env[CONVEX_ACCOUNT_ENV_VAR];
|
|
107
|
+
source = `${CONVEX_ACCOUNT_ENV_VAR} environment variable`;
|
|
108
|
+
}
|
|
109
|
+
if (name === void 0) {
|
|
110
|
+
const files = options.envFile ? [options.envFile] : [ENV_VAR_FILE_PATH, ".env"];
|
|
111
|
+
for (const file of files) {
|
|
112
|
+
if (!ctx.fs.exists(file)) continue;
|
|
113
|
+
name = dotenv.parse(ctx.fs.readUtf8File(file))[CONVEX_ACCOUNT_ENV_VAR];
|
|
114
|
+
if (name !== void 0) {
|
|
115
|
+
source = `${CONVEX_ACCOUNT_ENV_VAR} in ${file}`;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (name === void 0) {
|
|
121
|
+
const config = await readAccountSettings(ctx);
|
|
122
|
+
const binding = findAccountDirectory(
|
|
123
|
+
config.directories ?? {},
|
|
124
|
+
process.cwd()
|
|
125
|
+
);
|
|
126
|
+
name = binding?.name ?? config.defaultAccount;
|
|
127
|
+
source = binding ? `directory selection for ${binding.directory}` : `default account in ${globalConfigPath()}`;
|
|
128
|
+
}
|
|
129
|
+
if (name === void 0) return null;
|
|
130
|
+
await validateAccountName(ctx, name);
|
|
131
|
+
return { name, source };
|
|
132
|
+
}
|
|
133
|
+
export async function readAccountAuth(ctx, account, allowMissing = false) {
|
|
134
|
+
const credentials = await readAccountCredentials(ctx, account, allowMissing);
|
|
135
|
+
return credentials === null ? null : {
|
|
136
|
+
kind: "accessToken",
|
|
137
|
+
accessToken: credentials.accessToken,
|
|
138
|
+
header: `Bearer ${credentials.accessToken}`,
|
|
139
|
+
account
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
export async function readAccountCredentials(ctx, account, allowMissing = false) {
|
|
143
|
+
await validateAccountName(ctx, account.name);
|
|
144
|
+
const configPath = accountConfigPath(account.name);
|
|
145
|
+
if (!ctx.fs.exists(configPath)) {
|
|
146
|
+
if (allowMissing) return null;
|
|
147
|
+
return await ctx.crash({
|
|
148
|
+
exitCode: 1,
|
|
149
|
+
errorType: "invalid filesystem data",
|
|
150
|
+
printedMessage: `Account "${account.name}" selected by ${account.source} is not logged in. Run \`npx convex login --account ${account.name}\`.`
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
return credentialsSchema.parse(JSON.parse(ctx.fs.readUtf8File(configPath)));
|
|
155
|
+
} catch {
|
|
156
|
+
return await ctx.crash({
|
|
157
|
+
exitCode: 1,
|
|
158
|
+
errorType: "invalid filesystem data",
|
|
159
|
+
printedMessage: `Unable to read credentials for account "${account.name}" from ${configPath}.`
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
export function readAccountToken(ctx, name) {
|
|
164
|
+
try {
|
|
165
|
+
const token = JSON.parse(
|
|
166
|
+
ctx.fs.readUtf8File(accountConfigPath(name))
|
|
167
|
+
).accessToken;
|
|
168
|
+
return typeof token === "string" && token.length > 0 ? token : null;
|
|
169
|
+
} catch {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function writeCredentialsFile(ctx, name, credentials) {
|
|
174
|
+
const configPath = accountConfigPath(name);
|
|
175
|
+
const directory = path.dirname(configPath);
|
|
176
|
+
ctx.fs.mkdir(directory, { allowExisting: true });
|
|
177
|
+
for (const dir of [rootDirectory(), directory]) {
|
|
178
|
+
if (!ctx.fs.lstat(dir).isDirectory()) {
|
|
179
|
+
return await ctx.crash({
|
|
180
|
+
exitCode: 1,
|
|
181
|
+
errorType: "invalid filesystem data",
|
|
182
|
+
printedMessage: `Cannot save account credentials through a symlink or non-directory: ${dir}.`
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const temporary = `${configPath}.${randomUUID()}.tmp`;
|
|
187
|
+
try {
|
|
188
|
+
ctx.fs.writeUtf8File(
|
|
189
|
+
temporary,
|
|
190
|
+
JSON.stringify(credentials, null, 2),
|
|
191
|
+
384
|
|
192
|
+
);
|
|
193
|
+
ctx.fs.swapTmpFile(temporary, configPath);
|
|
194
|
+
} finally {
|
|
195
|
+
if (ctx.fs.exists(temporary)) ctx.fs.unlink(temporary);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
export async function writeAccountCredentials(ctx, name, accessToken, metadata = {}, expected, onConflict) {
|
|
199
|
+
await validateAccountName(ctx, name);
|
|
200
|
+
await updateAccountSettings(ctx, async (settings) => {
|
|
201
|
+
if (expected !== void 0) {
|
|
202
|
+
const current = await readAccountCredentials(
|
|
203
|
+
ctx,
|
|
204
|
+
{ name, source: "login" },
|
|
205
|
+
true
|
|
206
|
+
);
|
|
207
|
+
if (!isDeepStrictEqual(current, expected)) {
|
|
208
|
+
await onConflict?.();
|
|
209
|
+
return await ctx.crash({
|
|
210
|
+
exitCode: 1,
|
|
211
|
+
errorType: "fatal",
|
|
212
|
+
printedMessage: `Account "${name}" changed during login. Retry the login.`
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
await writeCredentialsFile(ctx, name, { ...metadata, accessToken });
|
|
217
|
+
if (settings.defaultAccount === name) settings.accessToken = accessToken;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
export async function legacyAuthForFirstAccount(ctx, account) {
|
|
221
|
+
const settings = await readAccountSettings(ctx);
|
|
222
|
+
const accountsDir = path.dirname(accountConfigPath(account.name));
|
|
223
|
+
if (settings.defaultAccount !== void 0 || ctx.fs.exists(accountsDir) && ctx.fs.listDir(accountsDir).some((entry) => entry.name.endsWith(".json"))) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const config = readGlobalConfig(ctx);
|
|
227
|
+
return config === null ? null : {
|
|
228
|
+
kind: "accessToken",
|
|
229
|
+
accessToken: config.accessToken,
|
|
230
|
+
header: `Bearer ${config.accessToken}`,
|
|
231
|
+
account
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
export async function initializeDefaultAccount(ctx, account, namingLegacyAccount, select = true) {
|
|
235
|
+
const defaultAccount = await updateAccountSettings(ctx, async (settings) => {
|
|
236
|
+
if (settings.defaultAccount !== void 0) return void 0;
|
|
237
|
+
const credentials = await readAccountCredentials(ctx, account);
|
|
238
|
+
const accessToken = credentials.accessToken;
|
|
239
|
+
const legacyToken = settings.accessToken;
|
|
240
|
+
if (!select && (savedAccountNames(ctx).some((name) => name !== account.name) || !namingLegacyAccount && typeof legacyToken === "string" && legacyToken.length > 0 && legacyToken !== accessToken))
|
|
241
|
+
return void 0;
|
|
242
|
+
if (!namingLegacyAccount && typeof legacyToken === "string" && legacyToken.length > 0 && legacyToken !== accessToken) {
|
|
243
|
+
let legacyName = "default";
|
|
244
|
+
for (let suffix = 2; ctx.fs.exists(accountConfigPath(legacyName)); suffix++) {
|
|
245
|
+
legacyName = `default-${suffix}`;
|
|
246
|
+
}
|
|
247
|
+
await writeCredentialsFile(ctx, legacyName, { accessToken: legacyToken });
|
|
248
|
+
settings.defaultAccount = legacyName;
|
|
249
|
+
} else {
|
|
250
|
+
settings.defaultAccount = account.name;
|
|
251
|
+
settings.accessToken = accessToken;
|
|
252
|
+
}
|
|
253
|
+
return settings.defaultAccount;
|
|
254
|
+
});
|
|
255
|
+
if (defaultAccount !== void 0)
|
|
256
|
+
logFinishedStep(`Default account: ${defaultAccount}`);
|
|
257
|
+
}
|
|
258
|
+
export function findAccountDirectory(directories, cwd) {
|
|
259
|
+
let directory = path.resolve(cwd);
|
|
260
|
+
for (; ; ) {
|
|
261
|
+
if (Object.hasOwn(directories, directory)) {
|
|
262
|
+
return { directory, name: directories[directory] };
|
|
263
|
+
}
|
|
264
|
+
const parent = path.dirname(directory);
|
|
265
|
+
if (parent === directory) return null;
|
|
266
|
+
directory = parent;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
export function savedAccountNames(ctx) {
|
|
270
|
+
const directory = path.join(rootDirectory(), "accounts");
|
|
271
|
+
if (!ctx.fs.exists(directory)) return [];
|
|
272
|
+
return ctx.fs.listDir(directory).filter((entry) => entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -5)).sort();
|
|
273
|
+
}
|
|
274
|
+
export async function writeAccountDirectory(ctx, name) {
|
|
275
|
+
await validateAccountName(ctx, name);
|
|
276
|
+
await updateAccountSettings(ctx, (settings) => {
|
|
277
|
+
settings.directories = { ...settings.directories, [process.cwd()]: name };
|
|
278
|
+
});
|
|
279
|
+
logFinishedStep(
|
|
280
|
+
`Saved directory selection: ${name} (applies to this directory and its subdirectories).`
|
|
281
|
+
);
|
|
282
|
+
const selected = await getAccountSelection(ctx);
|
|
283
|
+
if (selected !== null && selected.name !== name) {
|
|
284
|
+
logWarning(
|
|
285
|
+
`Account "${selected.name}" selected by ${selected.source} overrides this directory selection. Remove that override to use account "${name}".`
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=accounts.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/lib/accounts.ts"],
|
|
4
|
+
"sourcesContent": ["import path from \"path\";\nimport { isDeepStrictEqual } from \"util\";\nimport { randomUUID } from \"crypto\";\nimport { TempPath } from \"../../bundler/fs.js\";\nimport * as dotenv from \"dotenv\";\nimport { z } from \"zod\";\nimport { BigBrainAuth, Context } from \"../../bundler/context.js\";\nimport { logFinishedStep, logWarning } from \"../../bundler/log.js\";\nimport { globalConfigPath, readGlobalConfig } from \"./utils/globalConfig.js\";\nimport { ENV_VAR_FILE_PATH, rootDirectory } from \"./utils/utils.js\";\n\nimport { CONVEX_ACCOUNT_ENV_VAR } from \"./envvars.js\";\n\nexport type AccountSelection = {\n name: string;\n source: string;\n};\n\nconst settingsSchema = z\n .object({\n defaultAccount: z.string().optional(),\n directories: z.record(z.string()).optional(),\n revokeReplacedTokens: z.boolean().optional(),\n })\n .passthrough();\n\nconst credentialsSchema = z\n .object({\n accessToken: z.string().min(1),\n memberId: z.string().optional(),\n email: z.string().optional(),\n })\n .passthrough();\n\nexport type AccountCredentials = z.infer<typeof credentialsSchema>;\n\nexport async function readAccountSettings(\n ctx: Context,\n): Promise<z.infer<typeof settingsSchema>> {\n if (!ctx.fs.exists(globalConfigPath())) return {};\n try {\n return settingsSchema.parse(\n JSON.parse(ctx.fs.readUtf8File(globalConfigPath())),\n );\n } catch {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Unable to read account settings from ${globalConfigPath()}. Check defaultAccount, directories, and revokeReplacedTokens.`,\n });\n }\n}\n\nfunction writeAccountSettings(ctx: Context, settings: Record<string, unknown>) {\n if (Object.keys(settings).length === 0) {\n if (ctx.fs.exists(globalConfigPath())) ctx.fs.unlink(globalConfigPath());\n return;\n }\n const temporary = `${globalConfigPath()}.${randomUUID()}.tmp` as TempPath;\n try {\n ctx.fs.writeUtf8File(temporary, JSON.stringify(settings, null, 2), 0o600);\n ctx.fs.swapTmpFile(temporary, globalConfigPath());\n } finally {\n if (ctx.fs.exists(temporary)) ctx.fs.unlink(temporary);\n }\n}\n\nexport async function updateAccountSettings<T>(\n ctx: Context,\n update: (settings: z.infer<typeof settingsSchema>) => T | Promise<T>,\n afterWrite?: () => void,\n): Promise<T> {\n const lockPath = `${globalConfigPath()}.lock`;\n ctx.fs.mkdir(rootDirectory(), { allowExisting: true });\n const deadline = Date.now() + 5000;\n for (;;) {\n try {\n ctx.fs.mkdir(lockPath);\n break;\n } catch (err: any) {\n // Only the process that creates the directory owns the update lock.\n // eslint-disable-next-line no-restricted-syntax\n if (err.code !== \"EEXIST\") throw err;\n if (Date.now() >= deadline) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Another command is updating Convex accounts. Retry after it finishes. If it was interrupted, remove ${lockPath}.`,\n });\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n let released = false;\n const release = () => {\n if (released) return;\n ctx.fs.rmdir(lockPath);\n released = true;\n };\n const cleanup = ctx.registerCleanup(async () => release());\n try {\n const settings = await readAccountSettings(ctx);\n const result = await update(settings);\n writeAccountSettings(ctx, settings);\n // Credential deletion follows persistence while sharing the lock with renewals.\n afterWrite?.();\n return result;\n } finally {\n ctx.removeCleanup(cleanup);\n release();\n }\n}\n\nexport function accountConfigPath(name: string): string {\n return path.join(\n rootDirectory(),\n \"accounts\",\n `${encodeURIComponent(name)}.json`,\n );\n}\n\nexport async function validateAccountName(\n ctx: Context,\n name: string,\n): Promise<void> {\n if (!/^[a-z0-9][a-z0-9_-]*$/.test(name)) {\n await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage:\n \"Account names must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, and underscores.\",\n });\n }\n}\n\nexport async function getAccountSelection(\n ctx: Context,\n options: { name?: string | undefined; envFile?: string | undefined } = {},\n): Promise<AccountSelection | null> {\n let name = options.name;\n let source = \"--account\";\n if (name === undefined && process.env[CONVEX_ACCOUNT_ENV_VAR] !== undefined) {\n name = process.env[CONVEX_ACCOUNT_ENV_VAR];\n source = `${CONVEX_ACCOUNT_ENV_VAR} environment variable`;\n }\n if (name === undefined) {\n const files = options.envFile\n ? [options.envFile]\n : [ENV_VAR_FILE_PATH, \".env\"];\n for (const file of files) {\n if (!ctx.fs.exists(file)) continue;\n name = dotenv.parse(ctx.fs.readUtf8File(file))[CONVEX_ACCOUNT_ENV_VAR];\n if (name !== undefined) {\n source = `${CONVEX_ACCOUNT_ENV_VAR} in ${file}`;\n break;\n }\n }\n }\n if (name === undefined) {\n const config = await readAccountSettings(ctx);\n const binding = findAccountDirectory(\n config.directories ?? {},\n process.cwd(),\n );\n name = binding?.name ?? config.defaultAccount;\n source = binding\n ? `directory selection for ${binding.directory}`\n : `default account in ${globalConfigPath()}`;\n }\n if (name === undefined) return null;\n await validateAccountName(ctx, name);\n return { name, source };\n}\n\nexport async function readAccountAuth(\n ctx: Context,\n account: AccountSelection,\n allowMissing = false,\n): Promise<Extract<BigBrainAuth, { kind: \"accessToken\" }> | null> {\n const credentials = await readAccountCredentials(ctx, account, allowMissing);\n return credentials === null\n ? null\n : {\n kind: \"accessToken\",\n accessToken: credentials.accessToken,\n header: `Bearer ${credentials.accessToken}`,\n account,\n };\n}\n\nexport async function readAccountCredentials(\n ctx: Context,\n account: AccountSelection,\n allowMissing = false,\n): Promise<AccountCredentials | null> {\n await validateAccountName(ctx, account.name);\n const configPath = accountConfigPath(account.name);\n if (!ctx.fs.exists(configPath)) {\n if (allowMissing) return null;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Account \"${account.name}\" selected by ${account.source} is not logged in. Run \\`npx convex login --account ${account.name}\\`.`,\n });\n }\n try {\n return credentialsSchema.parse(JSON.parse(ctx.fs.readUtf8File(configPath)));\n } catch {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Unable to read credentials for account \"${account.name}\" from ${configPath}.`,\n });\n }\n}\n\nexport function readAccountToken(ctx: Context, name: string): string | null {\n try {\n const token = JSON.parse(\n ctx.fs.readUtf8File(accountConfigPath(name)),\n ).accessToken;\n return typeof token === \"string\" && token.length > 0 ? token : null;\n } catch {\n return null;\n }\n}\n\nasync function writeCredentialsFile(\n ctx: Context,\n name: string,\n credentials: AccountCredentials,\n) {\n const configPath = accountConfigPath(name);\n const directory = path.dirname(configPath);\n ctx.fs.mkdir(directory, { allowExisting: true });\n for (const dir of [rootDirectory(), directory]) {\n if (!ctx.fs.lstat(dir).isDirectory()) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Cannot save account credentials through a symlink or non-directory: ${dir}.`,\n });\n }\n }\n const temporary = `${configPath}.${randomUUID()}.tmp` as TempPath;\n try {\n ctx.fs.writeUtf8File(\n temporary,\n JSON.stringify(credentials, null, 2),\n 0o600,\n );\n ctx.fs.swapTmpFile(temporary, configPath);\n } finally {\n if (ctx.fs.exists(temporary)) ctx.fs.unlink(temporary);\n }\n}\n\nexport async function writeAccountCredentials(\n ctx: Context,\n name: string,\n accessToken: string,\n metadata: Omit<AccountCredentials, \"accessToken\"> = {},\n expected?: AccountCredentials | null,\n onConflict?: () => Promise<void>,\n): Promise<void> {\n await validateAccountName(ctx, name);\n await updateAccountSettings(ctx, async (settings) => {\n if (expected !== undefined) {\n const current = await readAccountCredentials(\n ctx,\n { name, source: \"login\" },\n true,\n );\n if (!isDeepStrictEqual(current, expected)) {\n await onConflict?.();\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Account \"${name}\" changed during login. Retry the login.`,\n });\n }\n }\n await writeCredentialsFile(ctx, name, { ...metadata, accessToken });\n if (settings.defaultAccount === name) settings.accessToken = accessToken;\n });\n}\n\nexport async function legacyAuthForFirstAccount(\n ctx: Context,\n account: AccountSelection,\n): Promise<Extract<BigBrainAuth, { kind: \"accessToken\" }> | null> {\n const settings = await readAccountSettings(ctx);\n const accountsDir = path.dirname(accountConfigPath(account.name));\n if (\n settings.defaultAccount !== undefined ||\n (ctx.fs.exists(accountsDir) &&\n ctx.fs.listDir(accountsDir).some((entry) => entry.name.endsWith(\".json\")))\n ) {\n return null;\n }\n const config = readGlobalConfig(ctx);\n return config === null\n ? null\n : {\n kind: \"accessToken\",\n accessToken: config.accessToken,\n header: `Bearer ${config.accessToken}`,\n account,\n };\n}\n\nexport async function initializeDefaultAccount(\n ctx: Context,\n account: AccountSelection,\n namingLegacyAccount: boolean,\n select = true,\n) {\n const defaultAccount = await updateAccountSettings(ctx, async (settings) => {\n if (settings.defaultAccount !== undefined) return undefined;\n const credentials = await readAccountCredentials(ctx, account);\n const accessToken = credentials!.accessToken;\n const legacyToken = settings.accessToken;\n if (\n !select &&\n (savedAccountNames(ctx).some((name) => name !== account.name) ||\n (!namingLegacyAccount &&\n typeof legacyToken === \"string\" &&\n legacyToken.length > 0 &&\n legacyToken !== accessToken))\n )\n return undefined;\n if (\n !namingLegacyAccount &&\n typeof legacyToken === \"string\" &&\n legacyToken.length > 0 &&\n legacyToken !== accessToken\n ) {\n // An explicitly new login keeps the previous account as the default for\n // directories that haven't selected an account.\n let legacyName = \"default\";\n for (\n let suffix = 2;\n ctx.fs.exists(accountConfigPath(legacyName));\n suffix++\n ) {\n legacyName = `default-${suffix}`;\n }\n await writeCredentialsFile(ctx, legacyName, { accessToken: legacyToken });\n settings.defaultAccount = legacyName;\n } else {\n settings.defaultAccount = account.name;\n settings.accessToken = accessToken;\n }\n\n return settings.defaultAccount;\n });\n if (defaultAccount !== undefined)\n logFinishedStep(`Default account: ${defaultAccount}`);\n}\n\nexport function findAccountDirectory(\n directories: Record<string, string>,\n cwd: string,\n): { directory: string; name: string } | null {\n let directory = path.resolve(cwd);\n for (;;) {\n if (Object.hasOwn(directories, directory)) {\n return { directory, name: directories[directory] };\n }\n const parent = path.dirname(directory);\n if (parent === directory) return null;\n directory = parent;\n }\n}\n\nexport function savedAccountNames(ctx: Context): string[] {\n const directory = path.join(rootDirectory(), \"accounts\");\n if (!ctx.fs.exists(directory)) return [];\n return ctx.fs\n .listDir(directory)\n .filter((entry) => entry.name.endsWith(\".json\"))\n .map((entry) => entry.name.slice(0, -5))\n .sort();\n}\n\nexport async function writeAccountDirectory(ctx: Context, name: string) {\n await validateAccountName(ctx, name);\n await updateAccountSettings(ctx, (settings) => {\n settings.directories = { ...settings.directories, [process.cwd()]: name };\n });\n logFinishedStep(\n `Saved directory selection: ${name} (applies to this directory and its subdirectories).`,\n );\n const selected = await getAccountSelection(ctx);\n if (selected !== null && selected.name !== name) {\n logWarning(\n `Account \"${selected.name}\" selected by ${selected.source} overrides this directory selection. Remove that override to use account \"${name}\".`,\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { logWarning } from "../../bundler/log.js";
|
|
3
|
+
import {
|
|
4
|
+
deploymentNameFromAdminKey,
|
|
5
|
+
deploymentTypeFromAdminKey,
|
|
6
|
+
isDeploymentKey,
|
|
7
|
+
isPreviewDeployKey,
|
|
8
|
+
isProjectKey
|
|
9
|
+
} from "./deployment.js";
|
|
10
|
+
import { getDeployKeySource } from "./envvars.js";
|
|
11
|
+
import { IGNORED_DEPLOY_KEY, readDeployKeyFromEnv } from "./utils/utils.js";
|
|
12
|
+
const warnedContexts = /* @__PURE__ */ new WeakSet();
|
|
13
|
+
export function warnIfDeployKeyOverridesLogin(ctx, hasAccount) {
|
|
14
|
+
if (!hasAccount || warnedContexts.has(ctx) || process.env.CONVEX_OVERRIDE_ACCESS_TOKEN)
|
|
15
|
+
return;
|
|
16
|
+
const key = readDeployKeyFromEnv((name) => process.env[name]);
|
|
17
|
+
if (key === void 0 || key === IGNORED_DEPLOY_KEY || isPreviewDeployKey(key))
|
|
18
|
+
return;
|
|
19
|
+
const { envVarName, source } = getDeployKeySource(key);
|
|
20
|
+
const type = deploymentTypeFromAdminKey(key);
|
|
21
|
+
const target = isDeploymentKey(key) ? `${type === "prod" ? "production" : type} deployment "${deploymentNameFromAdminKey(key)}"` : isProjectKey(key) ? "the project selected by the key" : "the deployment selected by the key";
|
|
22
|
+
logWarning(
|
|
23
|
+
`WARNING: ${envVarName} in ${source} overrides your Convex account for deployment commands. They target ${target}. Remove ${envVarName} to use the selected account.`
|
|
24
|
+
);
|
|
25
|
+
warnedContexts.add(ctx);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=deployKeyWarning.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/lib/deployKeyWarning.ts"],
|
|
4
|
+
"sourcesContent": ["import { Context } from \"../../bundler/context.js\";\nimport { logWarning } from \"../../bundler/log.js\";\nimport {\n deploymentNameFromAdminKey,\n deploymentTypeFromAdminKey,\n isDeploymentKey,\n isPreviewDeployKey,\n isProjectKey,\n} from \"./deployment.js\";\nimport { getDeployKeySource } from \"./envvars.js\";\nimport { IGNORED_DEPLOY_KEY, readDeployKeyFromEnv } from \"./utils/utils.js\";\n\nconst warnedContexts = new WeakSet<Context>();\n\nexport function warnIfDeployKeyOverridesLogin(\n ctx: Context,\n hasAccount: boolean,\n) {\n if (\n !hasAccount ||\n warnedContexts.has(ctx) ||\n process.env.CONVEX_OVERRIDE_ACCESS_TOKEN\n )\n return;\n const key = readDeployKeyFromEnv((name) => process.env[name]);\n if (\n key === undefined ||\n key === IGNORED_DEPLOY_KEY ||\n isPreviewDeployKey(key)\n )\n return;\n const { envVarName, source } = getDeployKeySource(key);\n const type = deploymentTypeFromAdminKey(key);\n const target = isDeploymentKey(key)\n ? `${type === \"prod\" ? \"production\" : type} deployment \"${deploymentNameFromAdminKey(key)}\"`\n : isProjectKey(key)\n ? \"the project selected by the key\"\n : \"the deployment selected by the key\";\n logWarning(\n `WARNING: ${envVarName} in ${source} overrides your Convex account for deployment commands. They target ${target}. Remove ${envVarName} to use the selected account.`,\n );\n warnedContexts.add(ctx);\n}\n"],
|
|
5
|
+
"mappings": ";AACA,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B;AACnC,SAAS,oBAAoB,4BAA4B;AAEzD,MAAM,iBAAiB,oBAAI,QAAiB;AAErC,gBAAS,8BACd,KACA,YACA;AACA,MACE,CAAC,cACD,eAAe,IAAI,GAAG,KACtB,QAAQ,IAAI;AAEZ;AACF,QAAM,MAAM,qBAAqB,CAAC,SAAS,QAAQ,IAAI,IAAI,CAAC;AAC5D,MACE,QAAQ,UACR,QAAQ,sBACR,mBAAmB,GAAG;AAEtB;AACF,QAAM,EAAE,YAAY,OAAO,IAAI,mBAAmB,GAAG;AACrD,QAAM,OAAO,2BAA2B,GAAG;AAC3C,QAAM,SAAS,gBAAgB,GAAG,IAC9B,GAAG,SAAS,SAAS,eAAe,IAAI,gBAAgB,2BAA2B,GAAG,CAAC,MACvF,aAAa,GAAG,IACd,oCACA;AACN;AAAA,IACE,YAAY,UAAU,OAAO,MAAM,uEAAuE,MAAM,YAAY,UAAU;AAAA,EACxI;AACA,iBAAe,IAAI,GAAG;AACxB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -61,7 +61,7 @@ export async function eraseDeploymentEnvVar(ctx) {
|
|
|
61
61
|
ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);
|
|
62
62
|
return true;
|
|
63
63
|
}
|
|
64
|
-
async function gitIgnoreEnvVarFile(ctx) {
|
|
64
|
+
export async function gitIgnoreEnvVarFile(ctx) {
|
|
65
65
|
const gitIgnorePath = ".gitignore";
|
|
66
66
|
const gitIgnoreContents = ctx.fs.exists(gitIgnorePath) ? ctx.fs.readUtf8File(gitIgnorePath) : "";
|
|
67
67
|
const changedGitIgnore = changesToGitIgnore(gitIgnoreContents);
|
|
@@ -125,7 +125,7 @@ export async function deploymentNameFromAdminKeyOrCrash(ctx, adminKey) {
|
|
|
125
125
|
}
|
|
126
126
|
return deploymentName;
|
|
127
127
|
}
|
|
128
|
-
function deploymentNameFromAdminKey(adminKey) {
|
|
128
|
+
export function deploymentNameFromAdminKey(adminKey) {
|
|
129
129
|
const parts = adminKey.split("|");
|
|
130
130
|
if (parts.length === 1) {
|
|
131
131
|
return null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/lib/deployment.ts"],
|
|
4
|
-
"sourcesContent": ["import * as dotenv from \"dotenv\";\nimport { Context } from \"../../bundler/context.js\";\nimport { changedEnvVarFile, getEnvVarRegex } from \"./envvars.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n ENV_VAR_FILE_PATH,\n} from \"./utils/utils.js\";\nimport { DeploymentType } from \"./api.js\";\n\n// Given a deployment string like \"dev:tall-forest-1234\"\n// returns only the slug \"tall-forest-1234\".\n// If there's no prefix returns the original string.\nexport function stripDeploymentTypePrefix(deployment: string) {\n return deployment.split(\":\").at(-1)!;\n}\n\n// Handling legacy CONVEX_DEPLOYMENT without type prefix as well\nexport function getDeploymentTypeFromConfiguredDeployment(raw: string) {\n const typeRaw = raw.split(\":\")[0];\n const type =\n typeRaw === \"prod\" ||\n typeRaw === \"dev\" ||\n typeRaw === \"preview\" ||\n typeRaw === \"local\"\n ? typeRaw\n : null;\n return type;\n}\n\nexport function isAnonymousDeployment(deploymentName: string) {\n return deploymentName.startsWith(\"anonymous-\");\n}\n\nexport function removeAnonymousPrefix(deploymentName: string) {\n if (isAnonymousDeployment(deploymentName)) {\n return deploymentName.slice(\"anonymous-\".length);\n }\n return deploymentName;\n}\n\nexport async function writeDeploymentEnvVar(\n ctx: Context,\n deploymentType: DeploymentType,\n deployment: {\n team: string | null;\n project: string | null;\n deploymentName: string;\n },\n existingValue: string | null,\n): Promise<{ wroteToGitIgnore: boolean; changedDeploymentEnvVar: boolean }> {\n const existingFile = ctx.fs.exists(ENV_VAR_FILE_PATH)\n ? ctx.fs.readUtf8File(ENV_VAR_FILE_PATH)\n : null;\n const changedFile = changesToEnvVarFile(\n existingFile,\n deploymentType,\n deployment,\n );\n const deploymentEnvVarValue =\n deploymentType + \":\" + deployment.deploymentName;\n // The `existingValue` that reaches this function is at least sometimes is missing its prefix.\n // Until this is cleaned up consider either of these values not a change.\n // Otherwise we spam the init instructions (Welcome to Convex etc.) on every run of `npx convex dev`.\n const changedDeploymentEnvVar =\n !!changedFile &&\n existingValue !== deployment.deploymentName &&\n existingValue !== deploymentEnvVarValue;\n\n if (changedFile !== null) {\n ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);\n // Only do this if we're not reinitializing an existing setup\n return {\n wroteToGitIgnore: await gitIgnoreEnvVarFile(ctx),\n changedDeploymentEnvVar,\n };\n }\n return {\n wroteToGitIgnore: false,\n changedDeploymentEnvVar,\n };\n}\n\n// Only used in the internal --url flow\nexport async function eraseDeploymentEnvVar(ctx: Context): Promise<boolean> {\n const existingFile = ctx.fs.exists(ENV_VAR_FILE_PATH)\n ? ctx.fs.readUtf8File(ENV_VAR_FILE_PATH)\n : null;\n if (existingFile === null) {\n return false;\n }\n const config = dotenv.parse(existingFile);\n const existing = config[CONVEX_DEPLOYMENT_ENV_VAR_NAME];\n if (existing === undefined) {\n return false;\n }\n const changedFile = existingFile.replace(\n getEnvVarRegex(CONVEX_DEPLOYMENT_ENV_VAR_NAME),\n \"\",\n );\n ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);\n return true;\n}\n\
|
|
5
|
-
"mappings": ";AAAA,YAAY,YAAY;AAExB,SAAS,mBAAmB,sBAAsB;AAClD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMA,gBAAS,0BAA0B,YAAoB;AAC5D,SAAO,WAAW,MAAM,GAAG,EAAE,GAAG,EAAE;AACpC;AAGO,gBAAS,0CAA0C,KAAa;AACrE,QAAM,UAAU,IAAI,MAAM,GAAG,EAAE,CAAC;AAChC,QAAM,OACJ,YAAY,UACZ,YAAY,SACZ,YAAY,aACZ,YAAY,UACR,UACA;AACN,SAAO;AACT;AAEO,gBAAS,sBAAsB,gBAAwB;AAC5D,SAAO,eAAe,WAAW,YAAY;AAC/C;AAEO,gBAAS,sBAAsB,gBAAwB;AAC5D,MAAI,sBAAsB,cAAc,GAAG;AACzC,WAAO,eAAe,MAAM,aAAa,MAAM;AAAA,EACjD;AACA,SAAO;AACT;AAEA,sBAAsB,sBACpB,KACA,gBACA,YAKA,eAC0E;AAC1E,QAAM,eAAe,IAAI,GAAG,OAAO,iBAAiB,IAChD,IAAI,GAAG,aAAa,iBAAiB,IACrC;AACJ,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,wBACJ,iBAAiB,MAAM,WAAW;AAIpC,QAAM,0BACJ,CAAC,CAAC,eACF,kBAAkB,WAAW,kBAC7B,kBAAkB;AAEpB,MAAI,gBAAgB,MAAM;AACxB,QAAI,GAAG,cAAc,mBAAmB,WAAW;AAEnD,WAAO;AAAA,MACL,kBAAkB,MAAM,oBAAoB,GAAG;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,kBAAkB;AAAA,IAClB;AAAA,EACF;AACF;AAGA,sBAAsB,sBAAsB,KAAgC;AAC1E,QAAM,eAAe,IAAI,GAAG,OAAO,iBAAiB,IAChD,IAAI,GAAG,aAAa,iBAAiB,IACrC;AACJ,MAAI,iBAAiB,MAAM;AACzB,WAAO;AAAA,EACT;AACA,QAAM,SAAS,OAAO,MAAM,YAAY;AACxC,QAAM,WAAW,OAAO,8BAA8B;AACtD,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,cAAc,aAAa;AAAA,IAC/B,eAAe,8BAA8B;AAAA,IAC7C;AAAA,EACF;AACA,MAAI,GAAG,cAAc,mBAAmB,WAAW;AACnD,SAAO;AACT;AAEA,
|
|
4
|
+
"sourcesContent": ["import * as dotenv from \"dotenv\";\nimport { Context } from \"../../bundler/context.js\";\nimport { changedEnvVarFile, getEnvVarRegex } from \"./envvars.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n ENV_VAR_FILE_PATH,\n} from \"./utils/utils.js\";\nimport { DeploymentType } from \"./api.js\";\n\n// Given a deployment string like \"dev:tall-forest-1234\"\n// returns only the slug \"tall-forest-1234\".\n// If there's no prefix returns the original string.\nexport function stripDeploymentTypePrefix(deployment: string) {\n return deployment.split(\":\").at(-1)!;\n}\n\n// Handling legacy CONVEX_DEPLOYMENT without type prefix as well\nexport function getDeploymentTypeFromConfiguredDeployment(raw: string) {\n const typeRaw = raw.split(\":\")[0];\n const type =\n typeRaw === \"prod\" ||\n typeRaw === \"dev\" ||\n typeRaw === \"preview\" ||\n typeRaw === \"local\"\n ? typeRaw\n : null;\n return type;\n}\n\nexport function isAnonymousDeployment(deploymentName: string) {\n return deploymentName.startsWith(\"anonymous-\");\n}\n\nexport function removeAnonymousPrefix(deploymentName: string) {\n if (isAnonymousDeployment(deploymentName)) {\n return deploymentName.slice(\"anonymous-\".length);\n }\n return deploymentName;\n}\n\nexport async function writeDeploymentEnvVar(\n ctx: Context,\n deploymentType: DeploymentType,\n deployment: {\n team: string | null;\n project: string | null;\n deploymentName: string;\n },\n existingValue: string | null,\n): Promise<{ wroteToGitIgnore: boolean; changedDeploymentEnvVar: boolean }> {\n const existingFile = ctx.fs.exists(ENV_VAR_FILE_PATH)\n ? ctx.fs.readUtf8File(ENV_VAR_FILE_PATH)\n : null;\n const changedFile = changesToEnvVarFile(\n existingFile,\n deploymentType,\n deployment,\n );\n const deploymentEnvVarValue =\n deploymentType + \":\" + deployment.deploymentName;\n // The `existingValue` that reaches this function is at least sometimes is missing its prefix.\n // Until this is cleaned up consider either of these values not a change.\n // Otherwise we spam the init instructions (Welcome to Convex etc.) on every run of `npx convex dev`.\n const changedDeploymentEnvVar =\n !!changedFile &&\n existingValue !== deployment.deploymentName &&\n existingValue !== deploymentEnvVarValue;\n\n if (changedFile !== null) {\n ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);\n // Only do this if we're not reinitializing an existing setup\n return {\n wroteToGitIgnore: await gitIgnoreEnvVarFile(ctx),\n changedDeploymentEnvVar,\n };\n }\n return {\n wroteToGitIgnore: false,\n changedDeploymentEnvVar,\n };\n}\n\n// Only used in the internal --url flow\nexport async function eraseDeploymentEnvVar(ctx: Context): Promise<boolean> {\n const existingFile = ctx.fs.exists(ENV_VAR_FILE_PATH)\n ? ctx.fs.readUtf8File(ENV_VAR_FILE_PATH)\n : null;\n if (existingFile === null) {\n return false;\n }\n const config = dotenv.parse(existingFile);\n const existing = config[CONVEX_DEPLOYMENT_ENV_VAR_NAME];\n if (existing === undefined) {\n return false;\n }\n const changedFile = existingFile.replace(\n getEnvVarRegex(CONVEX_DEPLOYMENT_ENV_VAR_NAME),\n \"\",\n );\n ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);\n return true;\n}\n\nexport async function gitIgnoreEnvVarFile(ctx: Context): Promise<boolean> {\n const gitIgnorePath = \".gitignore\";\n const gitIgnoreContents = ctx.fs.exists(gitIgnorePath)\n ? ctx.fs.readUtf8File(gitIgnorePath)\n : \"\";\n const changedGitIgnore = changesToGitIgnore(gitIgnoreContents);\n if (changedGitIgnore !== null) {\n ctx.fs.writeUtf8File(gitIgnorePath, changedGitIgnore);\n return true;\n }\n return false;\n}\n\n// exported for tests\nexport function changesToEnvVarFile(\n existingFile: string | null,\n deploymentType: DeploymentType,\n {\n team,\n project,\n deploymentName,\n }: { team: string | null; project: string | null; deploymentName: string },\n): string | null {\n const deploymentValue = deploymentType + \":\" + deploymentName;\n const commentOnPreviousLine = \"# Deployment used by `npx convex dev`\";\n const commentAfterValue =\n team !== null && project !== null\n ? `team: ${team}, project: ${project}`\n : null;\n return changedEnvVarFile({\n existingFileContent: existingFile,\n envVarName: CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n envVarValue: deploymentValue,\n commentAfterValue,\n commentOnPreviousLine,\n });\n}\n\n// exported for tests\nexport function changesToGitIgnore(existingFile: string | null): string | null {\n if (existingFile === null) {\n return `${ENV_VAR_FILE_PATH}\\n`;\n }\n const gitIgnoreLines = existingFile.split(\"\\n\");\n const envVarFileIgnored = gitIgnoreLines.some((line) => {\n if (line.startsWith(\"#\")) return false;\n if (line.startsWith(\"!\")) return false;\n\n // .gitignore ignores trailing whitespace, and also we need to remove\n // the trailing `\\r` from Windows-style newline since we split on `\\n`.\n const trimmedLine = line.trimEnd();\n\n const envIgnorePatterns = [\n /^\\.env\\.local$/,\n /^\\.env\\.\\*$/,\n /^\\.env\\*$/,\n /^.*\\.local$/,\n /^\\.env\\*\\.local$/,\n ];\n\n return envIgnorePatterns.some((pattern) => pattern.test(trimmedLine));\n });\n if (!envVarFileIgnored) {\n return `${existingFile}\\n${ENV_VAR_FILE_PATH}\\n`;\n } else {\n return null;\n }\n}\n\nexport async function deploymentNameFromAdminKeyOrCrash(\n ctx: Context,\n adminKey: string,\n) {\n const deploymentName = deploymentNameFromAdminKey(adminKey);\n if (deploymentName === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Please set ${CONVEX_DEPLOY_KEY_ENV_VAR_NAME} to a new key which you can find on your Convex dashboard.`,\n });\n }\n return deploymentName;\n}\n\nexport function deploymentNameFromAdminKey(adminKey: string) {\n const parts = adminKey.split(\"|\");\n if (parts.length === 1) {\n return null;\n }\n if (isPreviewDeployKey(adminKey)) {\n // Preview deploy keys do not contain a deployment name.\n return null;\n }\n return stripDeploymentTypePrefix(parts[0]);\n}\n\n// Needed to differentiate a preview deploy key\n// from a concrete preview deployment's deploy key.\n// preview deploy key: `preview:team:project|key`\n// preview deployment's deploy key: `preview:deploymentName|key`\nexport function isPreviewDeployKey(adminKey: string) {\n const parts = adminKey.split(\"|\");\n if (parts.length === 1) {\n return false;\n }\n const [prefix] = parts;\n const prefixParts = prefix.split(\":\");\n return prefixParts[0] === \"preview\" && prefixParts.length === 3;\n}\n\nexport function isProjectKey(adminKey: string) {\n return /^project:.*\\|/.test(adminKey);\n}\n\n// \"dev deploy keys\" and \"prod deploy keys\" are deployment keys.\n// On the client these are also known as admin keys.\nexport function isDeploymentKey(adminKey: string) {\n return /^(dev|prod):.*\\|/.test(adminKey);\n}\n\n// For current keys returns prod|dev|preview,\n// for legacy keys returns \"prod\".\n// Examples:\n// \"prod:deploymentName|key\" -> \"prod\"\n// \"preview:deploymentName|key\" -> \"preview\"\n// \"dev:deploymentName|key\" -> \"dev\"\n// \"custom:deploymentName|key\" -> \"custom\"\n// \"key\" -> \"prod\"\nexport function deploymentTypeFromAdminKey(adminKey: string) {\n const parts = adminKey.split(\":\");\n if (parts.length === 1) {\n return \"prod\";\n }\n return parts.at(0)! as DeploymentType;\n}\n\nexport async function getTeamAndProjectFromPreviewAdminKey(\n ctx: Context,\n adminKey: string,\n) {\n const parts = adminKey.split(\"|\")[0].split(\":\");\n if (parts.length !== 3) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Malformed preview CONVEX_DEPLOY_KEY, get a new key from Project Settings.\",\n });\n }\n const [_preview, teamSlug, projectSlug] = parts;\n return { teamSlug, projectSlug };\n}\n\nexport type CleanupDeploymentFunc = () => Promise<void>;\nexport type DeploymentDetails = {\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n reference: string | null;\n isDefault: boolean;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -25,28 +25,36 @@ import {
|
|
|
25
25
|
targetProjectForLocalSelector
|
|
26
26
|
} from "./localDeployment/projectMismatch.js";
|
|
27
27
|
import { chalkStderr } from "chalk";
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
getBuildEnvironment,
|
|
30
|
+
loadProjectEnvironmentVariables
|
|
31
|
+
} from "./envvars.js";
|
|
29
32
|
import { readGlobalConfig } from "./utils/globalConfig.js";
|
|
33
|
+
import {
|
|
34
|
+
getAccountSelection,
|
|
35
|
+
readAccountAuth
|
|
36
|
+
} from "./accounts.js";
|
|
30
37
|
import {
|
|
31
38
|
CONVEX_DEPLOYMENT_ENV_VAR_NAME,
|
|
32
39
|
CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME,
|
|
33
40
|
CONVEX_DEPLOY_KEY_ENV_VAR_NAME,
|
|
34
41
|
CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,
|
|
35
42
|
CONVEX_SELF_HOSTED_URL_VAR_NAME,
|
|
36
|
-
ENV_VAR_FILE_PATH,
|
|
37
43
|
bigBrainAPI,
|
|
38
44
|
processDeployKeyValue,
|
|
39
45
|
readDeployKeyFromEnv,
|
|
46
|
+
readDeployKeyEnvVar,
|
|
40
47
|
typedPlatformClient
|
|
41
48
|
} from "./utils/utils.js";
|
|
42
49
|
import * as dotenv from "dotenv";
|
|
43
50
|
export async function initializeBigBrainAuth(ctx, initialArgs) {
|
|
44
51
|
if (initialArgs.url !== void 0 && initialArgs.adminKey !== void 0) {
|
|
45
52
|
ctx._updateBigBrainAuth(
|
|
46
|
-
getBigBrainAuth(ctx, {
|
|
53
|
+
await getBigBrainAuth(ctx, {
|
|
47
54
|
previewDeployKey: null,
|
|
48
55
|
projectKey: null,
|
|
49
|
-
deploymentKey: null
|
|
56
|
+
deploymentKey: null,
|
|
57
|
+
skipAccount: true
|
|
50
58
|
})
|
|
51
59
|
);
|
|
52
60
|
return;
|
|
@@ -64,29 +72,30 @@ export async function initializeBigBrainAuth(ctx, initialArgs) {
|
|
|
64
72
|
const rawDeployKey2 = readDeployKeyFromEnv((name) => config[name]);
|
|
65
73
|
const deployKey2 = await processDeployKeyValue(ctx, rawDeployKey2);
|
|
66
74
|
if (deployKey2 !== void 0) {
|
|
67
|
-
const bigBrainAuth = getBigBrainAuth(ctx, {
|
|
75
|
+
const bigBrainAuth = await getBigBrainAuth(ctx, {
|
|
68
76
|
previewDeployKey: isPreviewDeployKey(deployKey2) ? deployKey2 : null,
|
|
69
77
|
projectKey: isProjectKey(deployKey2) ? deployKey2 : null,
|
|
70
|
-
deploymentKey: isDeploymentKey(deployKey2) ? deployKey2 : null
|
|
78
|
+
deploymentKey: isDeploymentKey(deployKey2) ? deployKey2 : null,
|
|
79
|
+
envFile: initialArgs.envFile
|
|
71
80
|
});
|
|
72
81
|
ctx._updateBigBrainAuth(bigBrainAuth);
|
|
73
82
|
return;
|
|
74
83
|
}
|
|
75
84
|
ctx._updateBigBrainAuth(
|
|
76
|
-
getBigBrainAuth(ctx, {
|
|
85
|
+
await getBigBrainAuth(ctx, {
|
|
77
86
|
previewDeployKey: null,
|
|
78
87
|
projectKey: null,
|
|
79
|
-
deploymentKey: null
|
|
88
|
+
deploymentKey: null,
|
|
89
|
+
envFile: initialArgs.envFile
|
|
80
90
|
})
|
|
81
91
|
);
|
|
82
92
|
return;
|
|
83
93
|
}
|
|
84
|
-
|
|
85
|
-
dotenv.config();
|
|
94
|
+
loadProjectEnvironmentVariables();
|
|
86
95
|
const rawDeployKey = readDeployKeyFromEnv((name) => process.env[name]);
|
|
87
96
|
const deployKey = await processDeployKeyValue(ctx, rawDeployKey);
|
|
88
97
|
if (deployKey !== void 0) {
|
|
89
|
-
const bigBrainAuth = getBigBrainAuth(ctx, {
|
|
98
|
+
const bigBrainAuth = await getBigBrainAuth(ctx, {
|
|
90
99
|
previewDeployKey: isPreviewDeployKey(deployKey) ? deployKey : null,
|
|
91
100
|
projectKey: isProjectKey(deployKey) ? deployKey : null,
|
|
92
101
|
deploymentKey: isDeploymentKey(deployKey) ? deployKey : null
|
|
@@ -95,7 +104,7 @@ export async function initializeBigBrainAuth(ctx, initialArgs) {
|
|
|
95
104
|
return;
|
|
96
105
|
}
|
|
97
106
|
ctx._updateBigBrainAuth(
|
|
98
|
-
getBigBrainAuth(ctx, {
|
|
107
|
+
await getBigBrainAuth(ctx, {
|
|
99
108
|
previewDeployKey: null,
|
|
100
109
|
projectKey: null,
|
|
101
110
|
deploymentKey: null
|
|
@@ -103,7 +112,7 @@ export async function initializeBigBrainAuth(ctx, initialArgs) {
|
|
|
103
112
|
);
|
|
104
113
|
return;
|
|
105
114
|
}
|
|
106
|
-
export async function updateBigBrainAuthAfterLogin(ctx, accessToken) {
|
|
115
|
+
export async function updateBigBrainAuthAfterLogin(ctx, accessToken, account) {
|
|
107
116
|
const existingAuth = ctx.bigBrainAuth();
|
|
108
117
|
if (existingAuth !== null && existingAuth.kind === "projectKey") {
|
|
109
118
|
logVerbose(
|
|
@@ -114,18 +123,20 @@ export async function updateBigBrainAuthAfterLogin(ctx, accessToken) {
|
|
|
114
123
|
ctx._updateBigBrainAuth({
|
|
115
124
|
accessToken,
|
|
116
125
|
kind: "accessToken",
|
|
117
|
-
header: `Bearer ${accessToken}
|
|
126
|
+
header: `Bearer ${accessToken}`,
|
|
127
|
+
...account ? { account } : {}
|
|
118
128
|
});
|
|
119
129
|
}
|
|
120
130
|
export async function clearBigBrainAuth(ctx) {
|
|
121
131
|
ctx._updateBigBrainAuth(null);
|
|
122
132
|
}
|
|
123
|
-
function getBigBrainAuth(ctx, opts) {
|
|
133
|
+
async function getBigBrainAuth(ctx, opts) {
|
|
124
134
|
if (process.env.CONVEX_OVERRIDE_ACCESS_TOKEN) {
|
|
125
135
|
return {
|
|
126
136
|
accessToken: process.env.CONVEX_OVERRIDE_ACCESS_TOKEN,
|
|
127
137
|
kind: "accessToken",
|
|
128
|
-
header: `Bearer ${process.env.CONVEX_OVERRIDE_ACCESS_TOKEN}
|
|
138
|
+
header: `Bearer ${process.env.CONVEX_OVERRIDE_ACCESS_TOKEN}`,
|
|
139
|
+
account: null
|
|
129
140
|
};
|
|
130
141
|
}
|
|
131
142
|
if (opts.projectKey !== null) {
|
|
@@ -142,12 +153,17 @@ function getBigBrainAuth(ctx, opts) {
|
|
|
142
153
|
deploymentKey: opts.deploymentKey
|
|
143
154
|
};
|
|
144
155
|
}
|
|
156
|
+
const account = opts.skipAccount ? null : await getAccountSelection(ctx, { envFile: opts.envFile });
|
|
157
|
+
if (account !== null) {
|
|
158
|
+
return await readAccountAuth(ctx, account);
|
|
159
|
+
}
|
|
145
160
|
const globalConfig = readGlobalConfig(ctx);
|
|
146
161
|
if (globalConfig) {
|
|
147
162
|
return {
|
|
148
163
|
kind: "accessToken",
|
|
149
164
|
header: `Bearer ${globalConfig.accessToken}`,
|
|
150
|
-
accessToken: globalConfig.accessToken
|
|
165
|
+
accessToken: globalConfig.accessToken,
|
|
166
|
+
account: null
|
|
151
167
|
};
|
|
152
168
|
}
|
|
153
169
|
if (opts.previewDeployKey !== null) {
|
|
@@ -187,7 +203,7 @@ export async function ensureAuthCanCreateDeployment(ctx) {
|
|
|
187
203
|
)} and try again.`
|
|
188
204
|
});
|
|
189
205
|
}
|
|
190
|
-
const envVar = process.env[
|
|
206
|
+
const envVar = readDeployKeyEnvVar((name) => process.env[name])?.name ?? CONVEX_DEPLOY_KEY_ENV_VAR_NAME;
|
|
191
207
|
return await ctx.crash({
|
|
192
208
|
exitCode: 1,
|
|
193
209
|
errorType: "fatal",
|
|
@@ -357,8 +373,7 @@ async function resolveBaseDeploymentSelection(ctx, cliArgs, selectionWithinProje
|
|
|
357
373
|
}
|
|
358
374
|
return result2.metadata;
|
|
359
375
|
}
|
|
360
|
-
|
|
361
|
-
dotenv.config();
|
|
376
|
+
loadProjectEnvironmentVariables();
|
|
362
377
|
const result = await getDeploymentSelectionFromEnv(
|
|
363
378
|
ctx,
|
|
364
379
|
selectionWithinProject,
|