@nocobase/cli 2.1.0-beta.44.test.3 → 2.1.0-beta.44.test.4

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.
Files changed (77) hide show
  1. package/bin/run.js +40 -3
  2. package/dist/commands/app/destroy.js +13 -6
  3. package/dist/commands/app/restart.js +11 -2
  4. package/dist/commands/app/shared.js +3 -2
  5. package/dist/commands/app/start.js +10 -2
  6. package/dist/commands/app/upgrade.js +6 -4
  7. package/dist/commands/config/delete.js +2 -0
  8. package/dist/commands/config/get.js +2 -0
  9. package/dist/commands/config/set.js +2 -0
  10. package/dist/commands/env/add.js +5 -5
  11. package/dist/commands/init.js +117 -7
  12. package/dist/commands/install.js +50 -13
  13. package/dist/commands/source/download.js +1 -1
  14. package/dist/commands/source/test.js +13 -14
  15. package/dist/locale/en-US.json +13 -5
  16. package/dist/locale/zh-CN.json +13 -5
  17. package/package.json +1 -7
  18. package/scripts/build.mjs +34 -0
  19. package/scripts/clean.mjs +9 -0
  20. package/tsconfig.json +19 -0
  21. package/dist/lib/api-client.js +0 -335
  22. package/dist/lib/api-command-compat.js +0 -641
  23. package/dist/lib/app-health.js +0 -139
  24. package/dist/lib/app-managed-resources.js +0 -321
  25. package/dist/lib/app-public-path.js +0 -80
  26. package/dist/lib/app-runtime.js +0 -189
  27. package/dist/lib/auth-store.js +0 -498
  28. package/dist/lib/backup.js +0 -171
  29. package/dist/lib/bootstrap.js +0 -409
  30. package/dist/lib/build-config.js +0 -18
  31. package/dist/lib/builtin-db.js +0 -86
  32. package/dist/lib/cli-config.js +0 -398
  33. package/dist/lib/cli-entry-error.js +0 -44
  34. package/dist/lib/cli-home.js +0 -47
  35. package/dist/lib/cli-locale.js +0 -141
  36. package/dist/lib/command-discovery.js +0 -39
  37. package/dist/lib/db-connection-check.js +0 -219
  38. package/dist/lib/docker-env-file.js +0 -60
  39. package/dist/lib/docker-image.js +0 -37
  40. package/dist/lib/docker-log-stream.js +0 -45
  41. package/dist/lib/env-auth.js +0 -960
  42. package/dist/lib/env-command-config.js +0 -45
  43. package/dist/lib/env-config.js +0 -100
  44. package/dist/lib/env-guard.js +0 -61
  45. package/dist/lib/env-paths.js +0 -101
  46. package/dist/lib/env-proxy.js +0 -1295
  47. package/dist/lib/generated-command.js +0 -203
  48. package/dist/lib/http-request.js +0 -49
  49. package/dist/lib/inquirer-theme.js +0 -17
  50. package/dist/lib/inquirer.js +0 -243
  51. package/dist/lib/managed-env-file.js +0 -98
  52. package/dist/lib/naming.js +0 -70
  53. package/dist/lib/object-utils.js +0 -76
  54. package/dist/lib/openapi.js +0 -62
  55. package/dist/lib/plugin-import.js +0 -279
  56. package/dist/lib/plugin-storage.js +0 -64
  57. package/dist/lib/post-processors.js +0 -23
  58. package/dist/lib/prompt-catalog-core.js +0 -185
  59. package/dist/lib/prompt-catalog-terminal.js +0 -375
  60. package/dist/lib/prompt-catalog.js +0 -10
  61. package/dist/lib/prompt-validators.js +0 -258
  62. package/dist/lib/prompt-web-ui.js +0 -2227
  63. package/dist/lib/resource-command.js +0 -357
  64. package/dist/lib/resource-request.js +0 -104
  65. package/dist/lib/run-npm.js +0 -393
  66. package/dist/lib/runtime-env-vars.js +0 -32
  67. package/dist/lib/runtime-generator.js +0 -498
  68. package/dist/lib/runtime-store.js +0 -56
  69. package/dist/lib/self-manager.js +0 -301
  70. package/dist/lib/session-id.js +0 -17
  71. package/dist/lib/session-integration.js +0 -703
  72. package/dist/lib/session-store.js +0 -118
  73. package/dist/lib/skills-manager.js +0 -438
  74. package/dist/lib/source-publish.js +0 -326
  75. package/dist/lib/source-registry.js +0 -188
  76. package/dist/lib/startup-update.js +0 -309
  77. package/dist/lib/ui.js +0 -159
@@ -1,189 +0,0 @@
1
- /**
2
- * This file is part of the NocoBase (R) project.
3
- * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
- * Authors: NocoBase Team.
5
- *
6
- * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
- * For more information, please refer to: https://www.nocobase.com/agreement.
8
- */
9
- import path from 'node:path';
10
- import { resolveEnvKind } from './auth-store.js';
11
- import { getEnv, loadAuthConfig } from './auth-store.js';
12
- import { DEFAULT_DOCKER_CONTAINER_PREFIX, DEFAULT_DOCKER_NETWORK, getEffectiveCliConfigValue, } from './cli-config.js';
13
- import { resolveManagedLocalEnvFilePath } from './managed-env-file.js';
14
- import { commandOutput, commandSucceeds, run, runNocoBaseCommand } from './run-npm.js';
15
- import { buildRuntimeEnvVars } from './runtime-env-vars.js';
16
- const DOCKER_APP_WORKDIR = '/app/nocobase';
17
- function sanitizeDockerResourceName(value) {
18
- const normalized = value
19
- .trim()
20
- .toLowerCase()
21
- .replace(/[^a-z0-9_.-]+/g, '-')
22
- .replace(/-+/g, '-')
23
- .replace(/^-+|-+$/g, '');
24
- return normalized || 'nocobase';
25
- }
26
- export function defaultWorkspaceName(cwd = process.cwd()) {
27
- return sanitizeDockerResourceName(`nb-${path.basename(cwd)}`);
28
- }
29
- export function defaultDockerContainerPrefix(cwd = process.cwd()) {
30
- const configured = String(DEFAULT_DOCKER_CONTAINER_PREFIX ?? '').trim();
31
- if (configured) {
32
- return sanitizeDockerResourceName(configured);
33
- }
34
- return defaultWorkspaceName(cwd);
35
- }
36
- export function defaultDockerNetworkName() {
37
- return sanitizeDockerResourceName(DEFAULT_DOCKER_NETWORK);
38
- }
39
- export function buildDockerAppContainerName(envName, containerPrefix) {
40
- const prefix = containerPrefix?.trim() || defaultDockerContainerPrefix();
41
- return sanitizeDockerResourceName(`${prefix}-${envName}-app`);
42
- }
43
- export function buildDockerDbContainerName(envName, dbDialect, containerPrefix) {
44
- const prefix = containerPrefix?.trim() || defaultDockerContainerPrefix();
45
- const dialect = dbDialect.trim() || 'postgres';
46
- return sanitizeDockerResourceName(`${prefix}-${envName}-${dialect}`);
47
- }
48
- function normalizeEnvSource(env) {
49
- const source = String(env.config.source ?? '').trim();
50
- if (source === 'docker' || source === 'npm' || source === 'git') {
51
- return source;
52
- }
53
- const kind = resolveEnvKind(env.config);
54
- if (kind === 'local') {
55
- return 'local';
56
- }
57
- return undefined;
58
- }
59
- export async function resolveManagedAppRuntime(envName) {
60
- const config = await loadAuthConfig();
61
- const env = await getEnv(envName, { config });
62
- if (!env) {
63
- return undefined;
64
- }
65
- const resolvedName = env.name || envName?.trim() || config.lastEnv || 'default';
66
- const source = normalizeEnvSource(env);
67
- const dockerNetworkName = sanitizeDockerResourceName(getEffectiveCliConfigValue(config, 'docker.network') || defaultDockerNetworkName());
68
- const dockerContainerPrefix = sanitizeDockerResourceName(getEffectiveCliConfigValue(config, 'docker.container-prefix') || defaultDockerContainerPrefix());
69
- const kind = env.kind ?? resolveEnvKind(env.config);
70
- if (kind === 'docker') {
71
- return {
72
- kind: 'docker',
73
- env,
74
- envName: resolvedName,
75
- source: 'docker',
76
- dockerNetworkName,
77
- dockerContainerPrefix,
78
- workspaceName: dockerNetworkName,
79
- containerName: buildDockerAppContainerName(resolvedName, dockerContainerPrefix),
80
- };
81
- }
82
- if (kind === 'local') {
83
- return {
84
- kind: 'local',
85
- env,
86
- envName: resolvedName,
87
- source: source === 'git' ? 'git' : source === 'npm' ? 'npm' : 'local',
88
- projectRoot: env.sourcePath,
89
- dockerNetworkName,
90
- dockerContainerPrefix,
91
- workspaceName: dockerNetworkName,
92
- };
93
- }
94
- if (kind === 'ssh') {
95
- return {
96
- kind: 'ssh',
97
- env,
98
- envName: resolvedName,
99
- source,
100
- };
101
- }
102
- return {
103
- kind: 'http',
104
- env,
105
- envName: resolvedName,
106
- source,
107
- };
108
- }
109
- export function formatMissingManagedAppEnvMessage(envName) {
110
- const requested = String(envName ?? '').trim();
111
- if (requested) {
112
- return [
113
- `Env "${requested}" is not configured in this workspace.`,
114
- `If you want to create a new NocoBase AI environment, run \`nb init --ui --env ${requested}\` first.`,
115
- ].join('\n');
116
- }
117
- return 'No NocoBase env is configured yet. Run `nb init --ui` to create one first.';
118
- }
119
- export function managedAppLifecycleEnvVars() {
120
- return {
121
- APP_ENV: 'production',
122
- NODE_ENV: 'production',
123
- };
124
- }
125
- export async function runLocalNocoBaseCommand(runtime, args, options) {
126
- const envVars = await buildRuntimeEnvVars(runtime);
127
- const appEnvPath = resolveManagedLocalEnvFilePath(runtime);
128
- await runNocoBaseCommand(args, {
129
- cwd: runtime.projectRoot,
130
- env: {
131
- ...envVars,
132
- APP_ENV_PATH: appEnvPath,
133
- ...options?.env,
134
- },
135
- stdio: options?.stdio,
136
- onStdout: options?.onStdout,
137
- onStderr: options?.onStderr,
138
- });
139
- }
140
- export async function dockerContainerExists(containerName) {
141
- return await commandSucceeds('docker', ['container', 'inspect', containerName]);
142
- }
143
- export async function dockerContainerIsRunning(containerName) {
144
- try {
145
- const output = await commandOutput('docker', ['inspect', '--format', '{{.State.Running}}', containerName], { errorName: 'docker inspect' });
146
- return output.trim() === 'true';
147
- }
148
- catch (_error) {
149
- return false;
150
- }
151
- }
152
- export async function startDockerContainer(containerName, options) {
153
- const exists = await dockerContainerExists(containerName);
154
- if (!exists) {
155
- throw new Error(`Docker app container "${containerName}" does not exist.`);
156
- }
157
- if (await dockerContainerIsRunning(containerName)) {
158
- return 'already-running';
159
- }
160
- await run('docker', ['start', containerName], {
161
- errorName: 'docker start',
162
- stdio: options?.stdio,
163
- });
164
- return 'started';
165
- }
166
- export async function stopDockerContainer(containerName, options) {
167
- const exists = await dockerContainerExists(containerName);
168
- if (!exists) {
169
- throw new Error(`Docker app container "${containerName}" does not exist.`);
170
- }
171
- if (!(await dockerContainerIsRunning(containerName))) {
172
- return 'already-stopped';
173
- }
174
- await run('docker', ['stop', containerName], {
175
- errorName: 'docker stop',
176
- stdio: options?.stdio,
177
- });
178
- return 'stopped';
179
- }
180
- export async function runDockerNocoBaseCommand(containerName, args, options) {
181
- await startDockerContainer(containerName, { stdio: options?.stdio });
182
- const dockerEnvArgs = Object.entries(options?.env ?? {}).flatMap(([key, value]) => ['-e', `${key}=${value}`]);
183
- await run('docker', ['exec', ...dockerEnvArgs, '-w', DOCKER_APP_WORKDIR, containerName, 'yarn', 'nocobase', ...args], {
184
- errorName: 'docker exec',
185
- stdio: options?.stdio,
186
- onStdout: options?.onStdout,
187
- onStderr: options?.onStderr,
188
- });
189
- }
@@ -1,498 +0,0 @@
1
- /**
2
- * This file is part of the NocoBase (R) project.
3
- * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
- * Authors: NocoBase Team.
5
- *
6
- * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
- * For more information, please refer to: https://www.nocobase.com/agreement.
8
- */
9
- import { promises as fs } from 'node:fs';
10
- import path from 'node:path';
11
- import { resolveAppPublicPath } from './app-public-path.js';
12
- import { resolveCliHomeDir, resolveConfiguredEnvPath, resolveEnvRelativePath } from './cli-home.js';
13
- import { normalizeCliLocale } from './cli-locale.js';
14
- import { inferConfiguredAppPathFromLegacyConfig, resolveConfiguredAppPath, resolveConfiguredSourcePath, resolveConfiguredStoragePath, } from './env-paths.js';
15
- import { cleanupCurrentSessionAfterEnvRemoval, resolveEffectiveCurrentEnv, setSessionCurrentEnv, } from './session-store.js';
16
- function normalizeStoredEnvKind(value) {
17
- const kind = String(value ?? '').trim();
18
- if (kind === 'remote') {
19
- return 'http';
20
- }
21
- if (kind === 'local' || kind === 'http' || kind === 'docker' || kind === 'ssh') {
22
- return kind;
23
- }
24
- return undefined;
25
- }
26
- function normalizeOptionalString(value) {
27
- const normalized = String(value ?? '').trim();
28
- return normalized || undefined;
29
- }
30
- function normalizeOptionalCliLocale(value) {
31
- const normalized = normalizeOptionalString(value);
32
- if (!normalized) {
33
- return undefined;
34
- }
35
- return normalizeCliLocale(normalized);
36
- }
37
- function normalizeOptionalCliUpdatePolicy(value) {
38
- const normalized = normalizeOptionalString(value);
39
- if (normalized === 'prompt' || normalized === 'auto' || normalized === 'off') {
40
- return normalized;
41
- }
42
- return undefined;
43
- }
44
- export function readEnvApiBaseUrl(config) {
45
- if (!config) {
46
- return undefined;
47
- }
48
- return (normalizeOptionalString(config.apiBaseUrl) ??
49
- normalizeOptionalString(config.baseUrl) ??
50
- normalizeOptionalString(config.apibaseUrl));
51
- }
52
- export function resolveEnvKind(config) {
53
- if (!config) {
54
- return undefined;
55
- }
56
- const explicitKind = normalizeStoredEnvKind(config.kind);
57
- if (explicitKind) {
58
- return explicitKind;
59
- }
60
- const source = String(config.source ?? '').trim();
61
- if (source === 'docker') {
62
- return 'docker';
63
- }
64
- if (source === 'npm' || source === 'git' || source === 'local') {
65
- return 'local';
66
- }
67
- if (String(config.appPath ?? '').trim() || String(config.appRootPath ?? '').trim()) {
68
- return 'local';
69
- }
70
- if (readEnvApiBaseUrl(config) || config.auth) {
71
- return 'http';
72
- }
73
- return undefined;
74
- }
75
- function normalizeEnvConfigEntry(entry) {
76
- if (!entry) {
77
- return entry;
78
- }
79
- const { kind: _kind, apiBaseUrl: _apiBaseUrl, baseUrl: _baseUrl, apibaseUrl: _legacyApiBaseUrl, ...rest } = entry;
80
- const normalizedKind = resolveEnvKind(entry);
81
- const apiBaseUrl = readEnvApiBaseUrl(entry);
82
- return {
83
- ...rest,
84
- ...(normalizedKind ? { kind: normalizedKind } : {}),
85
- ...(apiBaseUrl !== undefined ? { apiBaseUrl } : {}),
86
- ...(normalizeOptionalString(entry.appPublicPath) ? { appPublicPath: resolveAppPublicPath(entry.appPublicPath) } : {}),
87
- };
88
- }
89
- function normalizeAuthConfig(config) {
90
- const settings = config.settings ?? {};
91
- const locale = normalizeOptionalCliLocale(settings.locale);
92
- const updatePolicy = normalizeOptionalCliUpdatePolicy(settings.update?.policy);
93
- return {
94
- name: config.name || config.dockerResourcePrefix,
95
- settings: {
96
- ...(locale ? { locale } : {}),
97
- ...(updatePolicy ? { update: { policy: updatePolicy } } : {}),
98
- ...(settings.license?.pkgUrl ? { license: { pkgUrl: normalizeOptionalString(settings.license.pkgUrl) } } : {}),
99
- ...(settings.docker?.network || settings.docker?.containerPrefix
100
- ? {
101
- docker: {
102
- ...(settings.docker?.network ? { network: normalizeOptionalString(settings.docker.network) } : {}),
103
- ...(settings.docker?.containerPrefix
104
- ? { containerPrefix: normalizeOptionalString(settings.docker.containerPrefix) }
105
- : {}),
106
- },
107
- }
108
- : {}),
109
- ...(settings.bin?.docker || settings.bin?.caddy || settings.bin?.git || settings.bin?.nginx || settings.bin?.yarn
110
- ? {
111
- bin: {
112
- ...(settings.bin?.docker ? { docker: normalizeOptionalString(settings.bin.docker) } : {}),
113
- ...(settings.bin?.caddy ? { caddy: normalizeOptionalString(settings.bin.caddy) } : {}),
114
- ...(settings.bin?.git ? { git: normalizeOptionalString(settings.bin.git) } : {}),
115
- ...(settings.bin?.nginx ? { nginx: normalizeOptionalString(settings.bin.nginx) } : {}),
116
- ...(settings.bin?.yarn ? { yarn: normalizeOptionalString(settings.bin.yarn) } : {}),
117
- },
118
- }
119
- : {}),
120
- ...(settings.proxy?.nbCliRoot ||
121
- settings.proxy?.upstreamHost ||
122
- settings.proxy?.host
123
- ? {
124
- proxy: {
125
- ...(settings.proxy?.nbCliRoot ? { nbCliRoot: normalizeOptionalString(settings.proxy.nbCliRoot) } : {}),
126
- ...(settings.proxy?.upstreamHost || settings.proxy?.host
127
- ? {
128
- upstreamHost: normalizeOptionalString(settings.proxy?.upstreamHost ?? settings.proxy.host),
129
- }
130
- : {}),
131
- },
132
- }
133
- : {}),
134
- },
135
- lastEnv: config.lastEnv ||
136
- config.currentEnv ||
137
- 'default',
138
- envs: Object.fromEntries(Object.entries(config.envs || {}).map(([envName, entry]) => [envName, normalizeEnvConfigEntry(entry) ?? {}])),
139
- };
140
- }
141
- function getConfigFile(options = {}) {
142
- return path.join(resolveCliHomeDir(options.scope), 'config.json');
143
- }
144
- function createDefaultConfig() {
145
- return {
146
- lastEnv: 'default',
147
- envs: {},
148
- };
149
- }
150
- async function readStoredAuthConfig(filePath) {
151
- try {
152
- const content = await fs.readFile(filePath, 'utf8');
153
- const parsed = JSON.parse(content);
154
- return normalizeAuthConfig(parsed);
155
- }
156
- catch (_error) {
157
- return undefined;
158
- }
159
- }
160
- export async function loadExactAuthConfig(options = {}) {
161
- return (await readStoredAuthConfig(getConfigFile(options))) ?? createDefaultConfig();
162
- }
163
- export async function loadAuthConfig(options = {}) {
164
- return await loadExactAuthConfig(options);
165
- }
166
- export async function saveAuthConfig(config, options = {}) {
167
- const filePath = getConfigFile(options);
168
- await fs.mkdir(path.dirname(filePath), { recursive: true });
169
- await fs.writeFile(filePath, JSON.stringify(normalizeAuthConfig(config), null, 2));
170
- }
171
- export async function listEnvs(options = {}) {
172
- const config = await loadAuthConfig(options);
173
- return {
174
- lastEnv: config.lastEnv || 'default',
175
- envs: config.envs,
176
- };
177
- }
178
- export async function getCurrentEnvName(options = {}) {
179
- const config = await loadAuthConfig(options);
180
- return await resolveEffectiveCurrentEnv(Object.keys(config.envs).sort(), {
181
- scope: options.scope,
182
- lastEnv: config.lastEnv,
183
- });
184
- }
185
- export async function setCurrentEnv(envName, options = {}) {
186
- const config = await loadExactAuthConfig(options);
187
- if (!config.envs[envName]) {
188
- throw new Error(`Env "${envName}" is not configured`);
189
- }
190
- config.lastEnv = envName;
191
- await setSessionCurrentEnv(envName, options.scope);
192
- await saveAuthConfig(config, options);
193
- }
194
- export class Env {
195
- config;
196
- constructor(config = {}) {
197
- this.config = config;
198
- }
199
- get name() {
200
- return this.config.name;
201
- }
202
- get baseUrl() {
203
- return readEnvApiBaseUrl(this.config);
204
- }
205
- get apiBaseUrl() {
206
- return readEnvApiBaseUrl(this.config);
207
- }
208
- get auth() {
209
- return this.config.auth;
210
- }
211
- get authType() {
212
- return resolveConfiguredAuthType(this.config);
213
- }
214
- get runtime() {
215
- return this.config.runtime;
216
- }
217
- get kind() {
218
- return resolveEnvKind(this.config);
219
- }
220
- get appRootPath() {
221
- if (this.kind === 'ssh') {
222
- const configuredPath = String(this.config.appRootPath ?? '').trim();
223
- if (configuredPath) {
224
- return configuredPath;
225
- }
226
- }
227
- const legacyPath = resolveConfiguredEnvPath(this.config.appRootPath);
228
- if (legacyPath) {
229
- return legacyPath;
230
- }
231
- return this.kind === 'local' ? this.sourcePath : resolveEnvRelativePath('.');
232
- }
233
- get appPath() {
234
- if (this.kind === 'ssh') {
235
- const configuredPath = String(this.config.appPath ?? inferConfiguredAppPathFromLegacyConfig(this.config) ?? '').trim();
236
- if (configuredPath) {
237
- return configuredPath;
238
- }
239
- }
240
- return resolveConfiguredAppPath(this.config) ?? resolveEnvRelativePath('.');
241
- }
242
- get sourcePath() {
243
- if (this.kind === 'ssh') {
244
- const configuredPath = String(this.config.appRootPath ?? '').trim();
245
- if (configuredPath) {
246
- return configuredPath;
247
- }
248
- }
249
- return resolveConfiguredSourcePath(this.config) ?? path.join(this.appPath, 'source');
250
- }
251
- get storagePath() {
252
- if (this.kind === 'ssh') {
253
- const configuredPath = String(this.config.storagePath ?? '').trim();
254
- if (configuredPath) {
255
- return configuredPath;
256
- }
257
- }
258
- const resolvedStoragePath = resolveConfiguredStoragePath(this.config);
259
- if (resolvedStoragePath) {
260
- return resolvedStoragePath;
261
- }
262
- return this.kind === 'local' || this.kind === 'docker'
263
- ? path.join(this.appPath, 'storage')
264
- : resolveEnvRelativePath('.');
265
- }
266
- get appPort() {
267
- return this.config.appPort;
268
- }
269
- get envVars() {
270
- const out = {
271
- STORAGE_PATH: this.storagePath,
272
- };
273
- const put = (key, value) => {
274
- if (value === undefined || value === null) {
275
- return;
276
- }
277
- out[key] = String(value);
278
- };
279
- put('APP_PORT', this.appPort);
280
- put('APP_PUBLIC_PATH', this.config.appPublicPath ? resolveAppPublicPath(this.config.appPublicPath) : undefined);
281
- put('CDN_BASE_URL', this.config.cdnBaseUrl);
282
- put('APP_KEY', this.config.appKey);
283
- put('TZ', this.config.timezone);
284
- put('DB_DIALECT', this.config.dbDialect);
285
- if (!this.config.builtinDb) {
286
- put('DB_HOST', this.config.dbHost);
287
- put('DB_PORT', this.config.dbPort);
288
- }
289
- else if (String(this.config.source ?? '').trim() !== 'docker') {
290
- put('DB_PORT', this.config.dbPort);
291
- }
292
- put('DB_DATABASE', this.config.dbDatabase);
293
- put('DB_USER', this.config.dbUser);
294
- put('DB_PASSWORD', this.config.dbPassword);
295
- put('DB_SCHEMA', this.config.dbSchema);
296
- put('DB_TABLE_PREFIX', this.config.dbTablePrefix);
297
- put('DB_UNDERSCORED', this.config.dbUnderscored);
298
- return out;
299
- }
300
- }
301
- export async function getEnv(envName, options = {}) {
302
- const { config: snapshot, ...loadOptions } = options;
303
- const config = snapshot ?? (await loadAuthConfig(loadOptions));
304
- const resolved = envName?.trim() ||
305
- (await resolveEffectiveCurrentEnv(Object.keys(config.envs).sort(), {
306
- scope: loadOptions.scope,
307
- lastEnv: config.lastEnv,
308
- }));
309
- const envConfig = config.envs[resolved];
310
- if (!envConfig) {
311
- return undefined;
312
- }
313
- return new Env({ ...(normalizeEnvConfigEntry(envConfig) ?? {}), name: resolved });
314
- }
315
- function areAuthConfigsEquivalent(left, right) {
316
- if (!left && !right) {
317
- return true;
318
- }
319
- if (!left || !right || left.type !== right.type) {
320
- return false;
321
- }
322
- if (left.type === 'token' && right.type === 'token') {
323
- return left.accessToken === right.accessToken;
324
- }
325
- if (left.type === 'oauth' && right.type === 'oauth') {
326
- return (left.accessToken === right.accessToken &&
327
- left.refreshToken === right.refreshToken &&
328
- left.expiresAt === right.expiresAt &&
329
- left.scope === right.scope &&
330
- left.issuer === right.issuer &&
331
- left.clientId === right.clientId &&
332
- left.resource === right.resource);
333
- }
334
- return false;
335
- }
336
- async function writeEnv(envName, updater, options = {}) {
337
- const config = await loadExactAuthConfig(options);
338
- const previous = config.envs[envName];
339
- config.envs[envName] = updater(previous);
340
- await saveAuthConfig(config, options);
341
- }
342
- function normalizeConfiguredAuthType(value) {
343
- return value === 'basic' || value === 'token' || value === 'oauth' ? value : undefined;
344
- }
345
- export function resolveConfiguredAuthType(config) {
346
- return normalizeConfiguredAuthType(config?.authType) ?? normalizeConfiguredAuthType(config?.auth?.type);
347
- }
348
- export async function upsertEnv(envName, config, options = {}) {
349
- await writeEnv(envName, (previous) => {
350
- const { apiBaseUrl: _apiBaseUrl, baseUrl: _baseUrl, apibaseUrl: _legacyApiBaseUrl, accessToken, authType, authUsername, ...rest } = config;
351
- const nextApiBaseUrl = readEnvApiBaseUrl(config);
352
- const previousApiBaseUrl = readEnvApiBaseUrl(previous);
353
- const baseUrlChanged = previousApiBaseUrl !== nextApiBaseUrl;
354
- const previousAuthType = resolveConfiguredAuthType(previous);
355
- const requestedAuthType = normalizeConfiguredAuthType(authType);
356
- const nextAuthType = requestedAuthType ?? (accessToken ? 'token' : previousAuthType);
357
- const nextAuthUsername = nextAuthType === 'basic' ? normalizeOptionalString(authUsername) ?? previous?.authUsername : undefined;
358
- const nextAuth = accessToken
359
- ? {
360
- type: 'token',
361
- accessToken,
362
- }
363
- : nextAuthType === 'oauth' && !baseUrlChanged && previous?.auth?.type === 'oauth'
364
- ? previous.auth
365
- : undefined;
366
- const authChanged = !areAuthConfigsEquivalent(previous?.auth, nextAuth);
367
- const authTypeChanged = previousAuthType !== nextAuthType;
368
- const authUsernameChanged = previous?.authUsername !== nextAuthUsername;
369
- return {
370
- ...previous,
371
- apiBaseUrl: nextApiBaseUrl,
372
- authType: nextAuthType,
373
- authUsername: nextAuthUsername,
374
- auth: nextAuth,
375
- ...rest,
376
- runtime: baseUrlChanged || authChanged || authTypeChanged || authUsernameChanged ? undefined : previous?.runtime,
377
- };
378
- }, options);
379
- }
380
- export async function updateEnvConnection(envName, updates, options = {}) {
381
- await writeEnv(envName, (previous) => {
382
- const nextApiBaseUrl = readEnvApiBaseUrl(updates) ?? readEnvApiBaseUrl(previous);
383
- const previousApiBaseUrl = readEnvApiBaseUrl(previous);
384
- const baseUrlChanged = previousApiBaseUrl !== nextApiBaseUrl;
385
- const previousAuthType = resolveConfiguredAuthType(previous);
386
- const requestedAuthType = normalizeConfiguredAuthType(updates.authType);
387
- const nextAuthType = requestedAuthType ?? (updates.accessToken ? 'token' : previousAuthType);
388
- const nextAuthUsername = nextAuthType === 'basic' ? normalizeOptionalString(updates.authUsername) ?? previous?.authUsername : undefined;
389
- const nextAuth = updates.accessToken
390
- ? {
391
- type: 'token',
392
- accessToken: updates.accessToken,
393
- }
394
- : nextAuthType === 'oauth' && !baseUrlChanged && previous?.auth?.type === 'oauth'
395
- ? previous.auth
396
- : undefined;
397
- const authChanged = !areAuthConfigsEquivalent(previous?.auth, nextAuth);
398
- const authTypeChanged = previousAuthType !== nextAuthType;
399
- const authUsernameChanged = previous?.authUsername !== nextAuthUsername;
400
- return {
401
- ...previous,
402
- ...(nextApiBaseUrl !== undefined ? { apiBaseUrl: nextApiBaseUrl } : {}),
403
- authType: nextAuthType,
404
- authUsername: nextAuthUsername,
405
- auth: nextAuth,
406
- runtime: baseUrlChanged || authChanged || authTypeChanged || authUsernameChanged ? undefined : previous?.runtime,
407
- };
408
- }, options);
409
- }
410
- export async function replaceEnvConfig(envName, config, options = {}) {
411
- await writeEnv(envName, (previous) => {
412
- if (!previous) {
413
- throw new Error(`Env "${envName}" is not configured`);
414
- }
415
- const { apiBaseUrl: _apiBaseUrl, baseUrl: _baseUrl, apibaseUrl: _legacyApiBaseUrl, accessToken, authType, authUsername, ...rest } = config;
416
- const nextApiBaseUrl = readEnvApiBaseUrl(config);
417
- const previousApiBaseUrl = readEnvApiBaseUrl(previous);
418
- const baseUrlChanged = previousApiBaseUrl !== nextApiBaseUrl;
419
- const previousAuthType = resolveConfiguredAuthType(previous);
420
- const nextAuthType = normalizeConfiguredAuthType(authType) ?? (accessToken ? 'token' : undefined);
421
- const nextAuthUsername = nextAuthType === 'basic' ? normalizeOptionalString(authUsername) : undefined;
422
- const nextAuth = accessToken
423
- ? {
424
- type: 'token',
425
- accessToken,
426
- }
427
- : nextAuthType === 'oauth' && !baseUrlChanged && previous?.auth?.type === 'oauth'
428
- ? previous.auth
429
- : undefined;
430
- const authChanged = !areAuthConfigsEquivalent(previous?.auth, nextAuth);
431
- const authTypeChanged = previousAuthType !== nextAuthType;
432
- const authUsernameChanged = previous?.authUsername !== nextAuthUsername;
433
- return {
434
- ...rest,
435
- ...(nextApiBaseUrl !== undefined ? { apiBaseUrl: nextApiBaseUrl } : {}),
436
- ...(nextAuthType ? { authType: nextAuthType } : {}),
437
- ...(nextAuthUsername ? { authUsername: nextAuthUsername } : {}),
438
- ...(nextAuth ? { auth: nextAuth } : {}),
439
- runtime: baseUrlChanged || authChanged || authTypeChanged || authUsernameChanged ? undefined : previous?.runtime,
440
- };
441
- }, options);
442
- }
443
- export async function setEnvOauthSession(envName, auth, options = {}) {
444
- await writeEnv(envName, (previous) => ({
445
- ...previous,
446
- authType: 'oauth',
447
- auth,
448
- runtime: options.preserveRuntime ? previous?.runtime : undefined,
449
- }), options);
450
- }
451
- export async function setEnvRuntime(envName, runtime, options = {}) {
452
- const config = await loadExactAuthConfig(options);
453
- const current = config.envs[envName] ?? {};
454
- config.envs[envName] = {
455
- ...current,
456
- runtime,
457
- };
458
- await saveAuthConfig(config, options);
459
- }
460
- export async function clearEnvRootSetup(envName, options = {}) {
461
- const config = await loadExactAuthConfig(options);
462
- const current = config.envs[envName];
463
- if (!current) {
464
- return false;
465
- }
466
- const { rootUsername: _rootUsername, rootEmail: _rootEmail, rootPassword: _rootPassword, rootNickname: _rootNickname, ...rest } = current;
467
- config.envs[envName] = rest;
468
- await saveAuthConfig(config, options);
469
- return true;
470
- }
471
- export async function removeEnv(envName, options = {}) {
472
- const config = await loadExactAuthConfig(options);
473
- if (!config.envs[envName]) {
474
- throw new Error(`Env "${envName}" is not configured`);
475
- }
476
- delete config.envs[envName];
477
- if (config.lastEnv === envName) {
478
- const nextEnv = Object.keys(config.envs).sort()[0];
479
- config.lastEnv = nextEnv ?? 'default';
480
- }
481
- await saveAuthConfig(config, options);
482
- const remainingEnvNames = Object.keys(config.envs).sort();
483
- const fallbackEnv = remainingEnvNames.length
484
- ? await resolveEffectiveCurrentEnv(remainingEnvNames, {
485
- scope: options.scope,
486
- lastEnv: config.lastEnv,
487
- })
488
- : undefined;
489
- await cleanupCurrentSessionAfterEnvRemoval(envName, {
490
- scope: options.scope,
491
- fallbackEnv,
492
- });
493
- return {
494
- removed: envName,
495
- lastEnv: config.lastEnv || 'default',
496
- hasEnvs: Object.keys(config.envs).length > 0,
497
- };
498
- }