@motherbase/cli 0.2.6 → 0.2.8
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/LICENSE +21 -21
- package/README.md +248 -247
- package/bin/.motherbase/config.json +5 -0
- package/bin/motherbase.js +10 -10
- package/package.json +1 -1
- package/src/api.js +39 -16
- package/src/commands/_util.js +106 -106
- package/src/commands/backups.js +16 -16
- package/src/commands/branches.js +113 -113
- package/src/commands/completion.js +90 -90
- package/src/commands/config.js +47 -47
- package/src/commands/cron.js +65 -65
- package/src/commands/db.js +103 -103
- package/src/commands/domains.js +124 -124
- package/src/commands/gen.js +178 -172
- package/src/commands/import.js +55 -55
- package/src/commands/index.js +85 -85
- package/src/commands/inspect.js +178 -178
- package/src/commands/keys.js +72 -72
- package/src/commands/link.js +35 -35
- package/src/commands/local.js +100 -23
- package/src/commands/login.js +9 -3
- package/src/commands/logout.js +16 -16
- package/src/commands/mcp.js +61 -61
- package/src/commands/migrate.js +0 -5
- package/src/commands/migration.js +1 -1
- package/src/commands/network.js +83 -83
- package/src/commands/orgs.js +40 -40
- package/src/commands/postgres-config.js +113 -113
- package/src/commands/projects.js +131 -130
- package/src/commands/queues.js +133 -133
- package/src/commands/realtime.js +35 -35
- package/src/commands/rls.js +176 -176
- package/src/commands/secrets.js +66 -66
- package/src/commands/signing.js +130 -130
- package/src/commands/snippets.js +44 -44
- package/src/commands/status.js +42 -42
- package/src/commands/storage.js +261 -261
- package/src/commands/test.js +9 -9
- package/src/commands/unlink.js +15 -15
- package/src/commands/vault.js +82 -82
- package/src/commands/webhooks.js +62 -62
- package/src/commands/whoami.js +20 -20
- package/src/commands/wrappers.js +150 -150
- package/src/config.js +98 -98
- package/src/context.js +106 -106
- package/src/edge-templates.js +194 -194
- package/src/format.js +92 -92
- package/src/inspect/csv.js +22 -22
- package/src/inspect/queries.js +562 -562
- package/src/mcp/platform-tools.js +233 -233
- package/src/mcp/protocol.js +152 -152
- package/src/mcp/storage-tools.js +93 -93
- package/src/mcp/tools.js +478 -478
- package/src/migration/commands.js +2 -2
- package/src/migration/files.js +13 -0
- package/src/prompt.js +91 -91
- package/src/storage/remote.js +62 -62
- package/src/ui.js +111 -111
package/src/config.js
CHANGED
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Config persistence. Two files:
|
|
4
|
-
// Global creds : ~/.motherbase/config.json (contains tokens; written 0o600)
|
|
5
|
-
// { "consoles": { "<url>": { "token": "...", "email": "..." } }, "current": "<url>" }
|
|
6
|
-
// Project link : ./.motherbase/config.json (versionable, non-secret)
|
|
7
|
-
// { "consoleUrl": "<url>", "projectId": "abc", "projectName": "my-app" }
|
|
8
|
-
|
|
9
|
-
const fs = require('fs');
|
|
10
|
-
const os = require('os');
|
|
11
|
-
const path = require('path');
|
|
12
|
-
|
|
13
|
-
const GLOBAL_DIR = path.join(os.homedir(), '.motherbase');
|
|
14
|
-
const GLOBAL_FILE = path.join(GLOBAL_DIR, 'config.json');
|
|
15
|
-
const LINK_DIRNAME = '.motherbase';
|
|
16
|
-
const LINK_BASENAME = 'config.json';
|
|
17
|
-
|
|
18
|
-
function normalizeUrl(url) {
|
|
19
|
-
return String(url || '').replace(/\/+$/, '');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function readJson(file) {
|
|
23
|
-
try {
|
|
24
|
-
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
25
|
-
} catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// ── Global credentials ───────────────────────────────────────────────────────
|
|
31
|
-
|
|
32
|
-
function readGlobal() {
|
|
33
|
-
return readJson(GLOBAL_FILE) || { consoles: {}, current: null };
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function writeGlobal(cfg) {
|
|
37
|
-
fs.mkdirSync(GLOBAL_DIR, { recursive: true });
|
|
38
|
-
fs.writeFileSync(GLOBAL_FILE, JSON.stringify(cfg, null, 2) + '\n', { mode: 0o600 });
|
|
39
|
-
// Best-effort tighten perms even if the file already existed with looser mode.
|
|
40
|
-
try { fs.chmodSync(GLOBAL_FILE, 0o600); } catch { /* windows / noop */ }
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function saveConsoleToken(url, token, email) {
|
|
44
|
-
const u = normalizeUrl(url);
|
|
45
|
-
const cfg = readGlobal();
|
|
46
|
-
cfg.consoles = cfg.consoles || {};
|
|
47
|
-
cfg.consoles[u] = { ...(cfg.consoles[u] || {}), token, email };
|
|
48
|
-
cfg.current = u;
|
|
49
|
-
writeGlobal(cfg);
|
|
50
|
-
return u;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function clearConsoleToken(url) {
|
|
54
|
-
const cfg = readGlobal();
|
|
55
|
-
const u = normalizeUrl(url);
|
|
56
|
-
if (cfg.consoles && cfg.consoles[u]) delete cfg.consoles[u];
|
|
57
|
-
if (cfg.current === u) cfg.current = null;
|
|
58
|
-
writeGlobal(cfg);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function consoleEntry(url) {
|
|
62
|
-
const cfg = readGlobal();
|
|
63
|
-
return (cfg.consoles && cfg.consoles[normalizeUrl(url)]) || null;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// ── Per-project link ─────────────────────────────────────────────────────────
|
|
67
|
-
|
|
68
|
-
function linkPath(cwd) {
|
|
69
|
-
return path.join(cwd || process.cwd(), LINK_DIRNAME, LINK_BASENAME);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function readLink(cwd) {
|
|
73
|
-
return readJson(linkPath(cwd));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function writeLink(cwd, data) {
|
|
77
|
-
const dir = path.join(cwd || process.cwd(), LINK_DIRNAME);
|
|
78
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
79
|
-
fs.writeFileSync(linkPath(cwd), JSON.stringify(data, null, 2) + '\n');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function removeLink(cwd) {
|
|
83
|
-
try { fs.unlinkSync(linkPath(cwd)); return true; } catch { return false; }
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
module.exports = {
|
|
87
|
-
GLOBAL_FILE,
|
|
88
|
-
normalizeUrl,
|
|
89
|
-
readGlobal,
|
|
90
|
-
writeGlobal,
|
|
91
|
-
saveConsoleToken,
|
|
92
|
-
clearConsoleToken,
|
|
93
|
-
consoleEntry,
|
|
94
|
-
readLink,
|
|
95
|
-
writeLink,
|
|
96
|
-
removeLink,
|
|
97
|
-
linkPath,
|
|
98
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Config persistence. Two files:
|
|
4
|
+
// Global creds : ~/.motherbase/config.json (contains tokens; written 0o600)
|
|
5
|
+
// { "consoles": { "<url>": { "token": "...", "email": "..." } }, "current": "<url>" }
|
|
6
|
+
// Project link : ./.motherbase/config.json (versionable, non-secret)
|
|
7
|
+
// { "consoleUrl": "<url>", "projectId": "abc", "projectName": "my-app" }
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
const GLOBAL_DIR = path.join(os.homedir(), '.motherbase');
|
|
14
|
+
const GLOBAL_FILE = path.join(GLOBAL_DIR, 'config.json');
|
|
15
|
+
const LINK_DIRNAME = '.motherbase';
|
|
16
|
+
const LINK_BASENAME = 'config.json';
|
|
17
|
+
|
|
18
|
+
function normalizeUrl(url) {
|
|
19
|
+
return String(url || '').replace(/\/+$/, '');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function readJson(file) {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ── Global credentials ───────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
function readGlobal() {
|
|
33
|
+
return readJson(GLOBAL_FILE) || { consoles: {}, current: null };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function writeGlobal(cfg) {
|
|
37
|
+
fs.mkdirSync(GLOBAL_DIR, { recursive: true });
|
|
38
|
+
fs.writeFileSync(GLOBAL_FILE, JSON.stringify(cfg, null, 2) + '\n', { mode: 0o600 });
|
|
39
|
+
// Best-effort tighten perms even if the file already existed with looser mode.
|
|
40
|
+
try { fs.chmodSync(GLOBAL_FILE, 0o600); } catch { /* windows / noop */ }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function saveConsoleToken(url, token, email) {
|
|
44
|
+
const u = normalizeUrl(url);
|
|
45
|
+
const cfg = readGlobal();
|
|
46
|
+
cfg.consoles = cfg.consoles || {};
|
|
47
|
+
cfg.consoles[u] = { ...(cfg.consoles[u] || {}), token, email };
|
|
48
|
+
cfg.current = u;
|
|
49
|
+
writeGlobal(cfg);
|
|
50
|
+
return u;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function clearConsoleToken(url) {
|
|
54
|
+
const cfg = readGlobal();
|
|
55
|
+
const u = normalizeUrl(url);
|
|
56
|
+
if (cfg.consoles && cfg.consoles[u]) delete cfg.consoles[u];
|
|
57
|
+
if (cfg.current === u) cfg.current = null;
|
|
58
|
+
writeGlobal(cfg);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function consoleEntry(url) {
|
|
62
|
+
const cfg = readGlobal();
|
|
63
|
+
return (cfg.consoles && cfg.consoles[normalizeUrl(url)]) || null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ── Per-project link ─────────────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
function linkPath(cwd) {
|
|
69
|
+
return path.join(cwd || process.cwd(), LINK_DIRNAME, LINK_BASENAME);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function readLink(cwd) {
|
|
73
|
+
return readJson(linkPath(cwd));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function writeLink(cwd, data) {
|
|
77
|
+
const dir = path.join(cwd || process.cwd(), LINK_DIRNAME);
|
|
78
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
79
|
+
fs.writeFileSync(linkPath(cwd), JSON.stringify(data, null, 2) + '\n');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function removeLink(cwd) {
|
|
83
|
+
try { fs.unlinkSync(linkPath(cwd)); return true; } catch { return false; }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
module.exports = {
|
|
87
|
+
GLOBAL_FILE,
|
|
88
|
+
normalizeUrl,
|
|
89
|
+
readGlobal,
|
|
90
|
+
writeGlobal,
|
|
91
|
+
saveConsoleToken,
|
|
92
|
+
clearConsoleToken,
|
|
93
|
+
consoleEntry,
|
|
94
|
+
readLink,
|
|
95
|
+
writeLink,
|
|
96
|
+
removeLink,
|
|
97
|
+
linkPath,
|
|
98
|
+
};
|
package/src/context.js
CHANGED
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Resolve the runtime context: which console, which token, which project, and
|
|
4
|
-
// whether we talk through the Console proxy ('console' mode) or straight at a
|
|
5
|
-
// single project API ('direct' mode). Precedence everywhere: flags > env > config.
|
|
6
|
-
//
|
|
7
|
-
// Resolution is LAZY: building a context never throws, so commands that need no
|
|
8
|
-
// project (login, local docker, init) work with zero configuration. The
|
|
9
|
-
// require*() helpers throw a clear, actionable error only when a value is
|
|
10
|
-
// actually needed and missing.
|
|
11
|
-
|
|
12
|
-
const config = require('./config');
|
|
13
|
-
|
|
14
|
-
class CliError extends Error {
|
|
15
|
-
constructor(message) {
|
|
16
|
-
super(message);
|
|
17
|
-
this.name = 'CliError';
|
|
18
|
-
this.isCliError = true;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function firstDefined(...vals) {
|
|
23
|
-
for (const v of vals) if (v !== undefined && v !== null && v !== '') return v;
|
|
24
|
-
return undefined;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function createContext(flags = {}, env = process.env, cwd = process.cwd()) {
|
|
28
|
-
const link = config.readLink(cwd) || {};
|
|
29
|
-
const global = config.readGlobal();
|
|
30
|
-
|
|
31
|
-
const consoleUrl = firstDefined(
|
|
32
|
-
flags.url,
|
|
33
|
-
env.MOTHERBASE_CONSOLE_URL,
|
|
34
|
-
link.consoleUrl,
|
|
35
|
-
global.current,
|
|
36
|
-
);
|
|
37
|
-
const normConsoleUrl = consoleUrl ? config.normalizeUrl(consoleUrl) : undefined;
|
|
38
|
-
|
|
39
|
-
// The link file is committed to the repo, so a URL that came only from it is
|
|
40
|
-
// not trusted with a token the user supplied for some other console.
|
|
41
|
-
const urlFromLinkOnly = !firstDefined(flags.url, env.MOTHERBASE_CONSOLE_URL) && Boolean(link.consoleUrl);
|
|
42
|
-
|
|
43
|
-
const token = firstDefined(
|
|
44
|
-
urlFromLinkOnly ? undefined : flags.token,
|
|
45
|
-
urlFromLinkOnly ? undefined : env.MOTHERBASE_TOKEN,
|
|
46
|
-
normConsoleUrl ? (config.consoleEntry(normConsoleUrl) || {}).token : undefined,
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const projectId = firstDefined(flags.project, env.MOTHERBASE_PROJECT, link.projectId);
|
|
50
|
-
const projectName = firstDefined(link.projectName, projectId);
|
|
51
|
-
|
|
52
|
-
// Direct project mode: an admin JWT pointed straight at one project API. Only
|
|
53
|
-
// used as a fallback when there is no console link/flags to route through.
|
|
54
|
-
const directUrl = env.MOTHERBASE_URL ? config.normalizeUrl(env.MOTHERBASE_URL) : undefined;
|
|
55
|
-
const directToken = env.MOTHERBASE_ADMIN_TOKEN;
|
|
56
|
-
const hasConsole = Boolean(normConsoleUrl && token);
|
|
57
|
-
const hasProjectLink = Boolean(projectId);
|
|
58
|
-
const preferDirect = Boolean(directUrl && directToken) && !(hasConsole && hasProjectLink);
|
|
59
|
-
const mode = preferDirect ? 'direct' : 'console';
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
flags,
|
|
63
|
-
env,
|
|
64
|
-
cwd,
|
|
65
|
-
mode,
|
|
66
|
-
consoleUrl: normConsoleUrl,
|
|
67
|
-
token,
|
|
68
|
-
projectId,
|
|
69
|
-
projectName,
|
|
70
|
-
directUrl,
|
|
71
|
-
directToken,
|
|
72
|
-
linkedConsoleUrl: link.consoleUrl,
|
|
73
|
-
accountEmail: normConsoleUrl ? (config.consoleEntry(normConsoleUrl) || {}).email : undefined,
|
|
74
|
-
|
|
75
|
-
// Console (account / multi-project) requests need URL + session token.
|
|
76
|
-
requireConsole() {
|
|
77
|
-
if (!this.consoleUrl) {
|
|
78
|
-
throw new CliError('No console URL. Run `motherbase login --url <consoleUrl>` or set MOTHERBASE_CONSOLE_URL.');
|
|
79
|
-
}
|
|
80
|
-
if (!this.token) {
|
|
81
|
-
throw new CliError('Not logged in. Run `motherbase login` or set MOTHERBASE_TOKEN.');
|
|
82
|
-
}
|
|
83
|
-
return { consoleUrl: this.consoleUrl, token: this.token };
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
// Admin/resource requests: resolve either the console proxy path or a direct
|
|
87
|
-
// project API, whichever the context selected.
|
|
88
|
-
requireProject() {
|
|
89
|
-
if (this.mode === 'direct') {
|
|
90
|
-
return { mode: 'direct', baseUrl: this.directUrl, token: this.directToken };
|
|
91
|
-
}
|
|
92
|
-
this.requireConsole();
|
|
93
|
-
if (!this.projectId) {
|
|
94
|
-
throw new CliError('No project linked. Run `motherbase link` or set MOTHERBASE_PROJECT (or use direct mode via MOTHERBASE_URL + MOTHERBASE_ADMIN_TOKEN).');
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
mode: 'console',
|
|
98
|
-
consoleUrl: this.consoleUrl,
|
|
99
|
-
token: this.token,
|
|
100
|
-
projectId: this.projectId,
|
|
101
|
-
};
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
module.exports = { createContext, CliError };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Resolve the runtime context: which console, which token, which project, and
|
|
4
|
+
// whether we talk through the Console proxy ('console' mode) or straight at a
|
|
5
|
+
// single project API ('direct' mode). Precedence everywhere: flags > env > config.
|
|
6
|
+
//
|
|
7
|
+
// Resolution is LAZY: building a context never throws, so commands that need no
|
|
8
|
+
// project (login, local docker, init) work with zero configuration. The
|
|
9
|
+
// require*() helpers throw a clear, actionable error only when a value is
|
|
10
|
+
// actually needed and missing.
|
|
11
|
+
|
|
12
|
+
const config = require('./config');
|
|
13
|
+
|
|
14
|
+
class CliError extends Error {
|
|
15
|
+
constructor(message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = 'CliError';
|
|
18
|
+
this.isCliError = true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function firstDefined(...vals) {
|
|
23
|
+
for (const v of vals) if (v !== undefined && v !== null && v !== '') return v;
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function createContext(flags = {}, env = process.env, cwd = process.cwd()) {
|
|
28
|
+
const link = config.readLink(cwd) || {};
|
|
29
|
+
const global = config.readGlobal();
|
|
30
|
+
|
|
31
|
+
const consoleUrl = firstDefined(
|
|
32
|
+
flags.url,
|
|
33
|
+
env.MOTHERBASE_CONSOLE_URL,
|
|
34
|
+
link.consoleUrl,
|
|
35
|
+
global.current,
|
|
36
|
+
);
|
|
37
|
+
const normConsoleUrl = consoleUrl ? config.normalizeUrl(consoleUrl) : undefined;
|
|
38
|
+
|
|
39
|
+
// The link file is committed to the repo, so a URL that came only from it is
|
|
40
|
+
// not trusted with a token the user supplied for some other console.
|
|
41
|
+
const urlFromLinkOnly = !firstDefined(flags.url, env.MOTHERBASE_CONSOLE_URL) && Boolean(link.consoleUrl);
|
|
42
|
+
|
|
43
|
+
const token = firstDefined(
|
|
44
|
+
urlFromLinkOnly ? undefined : flags.token,
|
|
45
|
+
urlFromLinkOnly ? undefined : env.MOTHERBASE_TOKEN,
|
|
46
|
+
normConsoleUrl ? (config.consoleEntry(normConsoleUrl) || {}).token : undefined,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const projectId = firstDefined(flags.project, env.MOTHERBASE_PROJECT, link.projectId);
|
|
50
|
+
const projectName = firstDefined(link.projectName, projectId);
|
|
51
|
+
|
|
52
|
+
// Direct project mode: an admin JWT pointed straight at one project API. Only
|
|
53
|
+
// used as a fallback when there is no console link/flags to route through.
|
|
54
|
+
const directUrl = env.MOTHERBASE_URL ? config.normalizeUrl(env.MOTHERBASE_URL) : undefined;
|
|
55
|
+
const directToken = env.MOTHERBASE_ADMIN_TOKEN;
|
|
56
|
+
const hasConsole = Boolean(normConsoleUrl && token);
|
|
57
|
+
const hasProjectLink = Boolean(projectId);
|
|
58
|
+
const preferDirect = Boolean(directUrl && directToken) && !(hasConsole && hasProjectLink);
|
|
59
|
+
const mode = preferDirect ? 'direct' : 'console';
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
flags,
|
|
63
|
+
env,
|
|
64
|
+
cwd,
|
|
65
|
+
mode,
|
|
66
|
+
consoleUrl: normConsoleUrl,
|
|
67
|
+
token,
|
|
68
|
+
projectId,
|
|
69
|
+
projectName,
|
|
70
|
+
directUrl,
|
|
71
|
+
directToken,
|
|
72
|
+
linkedConsoleUrl: link.consoleUrl,
|
|
73
|
+
accountEmail: normConsoleUrl ? (config.consoleEntry(normConsoleUrl) || {}).email : undefined,
|
|
74
|
+
|
|
75
|
+
// Console (account / multi-project) requests need URL + session token.
|
|
76
|
+
requireConsole() {
|
|
77
|
+
if (!this.consoleUrl) {
|
|
78
|
+
throw new CliError('No console URL. Run `motherbase login --url <consoleUrl>` or set MOTHERBASE_CONSOLE_URL.');
|
|
79
|
+
}
|
|
80
|
+
if (!this.token) {
|
|
81
|
+
throw new CliError('Not logged in. Run `motherbase login` or set MOTHERBASE_TOKEN.');
|
|
82
|
+
}
|
|
83
|
+
return { consoleUrl: this.consoleUrl, token: this.token };
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// Admin/resource requests: resolve either the console proxy path or a direct
|
|
87
|
+
// project API, whichever the context selected.
|
|
88
|
+
requireProject() {
|
|
89
|
+
if (this.mode === 'direct') {
|
|
90
|
+
return { mode: 'direct', baseUrl: this.directUrl, token: this.directToken };
|
|
91
|
+
}
|
|
92
|
+
this.requireConsole();
|
|
93
|
+
if (!this.projectId) {
|
|
94
|
+
throw new CliError('No project linked. Run `motherbase link` or set MOTHERBASE_PROJECT (or use direct mode via MOTHERBASE_URL + MOTHERBASE_ADMIN_TOKEN).');
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
mode: 'console',
|
|
98
|
+
consoleUrl: this.consoleUrl,
|
|
99
|
+
token: this.token,
|
|
100
|
+
projectId: this.projectId,
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = { createContext, CliError };
|