@nocobase/cli 2.1.0-alpha.27 → 2.1.0-alpha.28

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.
@@ -39,7 +39,7 @@ export default class AppLogs extends Command {
39
39
  follow: Flags.boolean({
40
40
  char: 'f',
41
41
  description: 'Keep streaming new log lines',
42
- default: true,
42
+ default: false,
43
43
  allowNo: true,
44
44
  }),
45
45
  };
@@ -65,7 +65,7 @@ export default class AppLogs extends Command {
65
65
  ].join('\n'));
66
66
  }
67
67
  const tail = String(flags.tail ?? 100);
68
- const follow = flags.follow !== false;
68
+ const follow = flags.follow === true;
69
69
  printInfo(follow
70
70
  ? `Showing logs for "${runtime.envName}" (press Ctrl+C to stop).`
71
71
  : `Showing recent logs for "${runtime.envName}".`);
@@ -10,6 +10,7 @@ import { Command, Flags } from '@oclif/core';
10
10
  import { upsertEnv } from '../../lib/auth-store.js';
11
11
  import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, startDockerContainer, stopDockerContainer, } from '../../lib/app-runtime.js';
12
12
  import { resolveConfiguredEnvPath } from '../../lib/cli-home.js';
13
+ import { deriveBuiltinDbConnection } from '../../lib/builtin-db.js';
13
14
  import { commandSucceeds, run } from '../../lib/run-npm.js';
14
15
  import { failTask, printInfo, startTask, stopTask, succeedTask, updateTask } from '../../lib/ui.js';
15
16
  const DEFAULT_DOCKER_REGISTRY = 'nocobase/nocobase';
@@ -312,9 +313,10 @@ export default class AppUpgrade extends Command {
312
313
  const storagePath = readEnvValue(runtime.env, 'storagePath');
313
314
  const appKey = readEnvValue(runtime.env, 'appKey');
314
315
  const timeZone = readEnvValue(runtime.env, 'timezone');
315
- const dbDialect = readEnvValue(runtime.env, 'dbDialect');
316
- const dbHost = readEnvValue(runtime.env, 'dbHost');
317
- const dbPort = readEnvValue(runtime.env, 'dbPort');
316
+ const builtinDbConnection = runtime.env.config.builtinDb ? deriveBuiltinDbConnection(runtime) : undefined;
317
+ const dbDialect = builtinDbConnection?.dbDialect || readEnvValue(runtime.env, 'dbDialect');
318
+ const dbHost = builtinDbConnection?.dbHost || readEnvValue(runtime.env, 'dbHost');
319
+ const dbPort = builtinDbConnection?.dbPort || readEnvValue(runtime.env, 'dbPort');
318
320
  const dbDatabase = readEnvValue(runtime.env, 'dbDatabase');
319
321
  const dbUser = readEnvValue(runtime.env, 'dbUser');
320
322
  const dbPassword = readEnvValue(runtime.env, 'dbPassword');
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
10
  import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime } from '../../lib/app-runtime.js';
11
+ import { resolveBuiltinDbConnection } from '../../lib/builtin-db.js';
11
12
  import { checkExternalDbConnection, formatDbCheckAddress, readExternalDbConnectionConfig, } from "../../lib/db-connection-check.js";
12
13
  import { commandOutput } from '../../lib/run-npm.js';
13
14
  import { validateTcpPort } from "../../lib/prompt-validators.js";
@@ -95,7 +96,14 @@ async function resolveDbCheckInput(command, flags) {
95
96
  if (!runtime) {
96
97
  command.error(formatMissingManagedAppEnvMessage(envName));
97
98
  }
98
- const dbConfig = resolveDbConfigFromFlags(flags, runtime.env.config);
99
+ const envConfig = { ...runtime.env.config };
100
+ if ((runtime.kind === 'local' || runtime.kind === 'docker') && runtime.env.config.builtinDb) {
101
+ const builtinDbConnection = await resolveBuiltinDbConnection(runtime);
102
+ envConfig.dbHost = builtinDbConnection.dbHost;
103
+ envConfig.dbPort = builtinDbConnection.dbPort;
104
+ envConfig.dbDialect = builtinDbConnection.dbDialect;
105
+ }
106
+ const dbConfig = resolveDbConfigFromFlags(flags, envConfig);
99
107
  validateDbConfigOrThrow(command, dbConfig, true);
100
108
  return {
101
109
  envName: runtime.envName,
@@ -47,7 +47,7 @@ export default class DbLogs extends Command {
47
47
  follow: Flags.boolean({
48
48
  char: 'f',
49
49
  description: 'Keep streaming new log lines',
50
- default: true,
50
+ default: false,
51
51
  allowNo: true,
52
52
  }),
53
53
  };
@@ -62,7 +62,7 @@ export default class DbLogs extends Command {
62
62
  this.error(formatUnmanagedDbLogsMessage(runtime));
63
63
  }
64
64
  const tail = String(flags.tail ?? 100);
65
- const follow = flags.follow !== false;
65
+ const follow = flags.follow === true;
66
66
  printInfo(follow
67
67
  ? `Showing built-in database logs for "${runtime.envName}" (press Ctrl+C to stop).`
68
68
  : `Showing recent built-in database logs for "${runtime.envName}".`);
@@ -6,7 +6,8 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
- import { buildDockerDbContainerName, dockerContainerExists, dockerContainerIsRunning, resolveManagedAppRuntime, } from '../../lib/app-runtime.js';
9
+ import { dockerContainerExists, dockerContainerIsRunning, resolveManagedAppRuntime, } from '../../lib/app-runtime.js';
10
+ import { resolveBuiltinDbConnection } from '../../lib/builtin-db.js';
10
11
  function formatAddress(host, port, fallbackHost) {
11
12
  const normalizedHost = String(host ?? '').trim() || String(fallbackHost ?? '').trim();
12
13
  const normalizedPort = String(port ?? '').trim();
@@ -23,14 +24,14 @@ export async function resolveDbRuntime(envName) {
23
24
  const source = runtime.kind === 'http' || runtime.kind === 'ssh' ? runtime.kind : runtime.source;
24
25
  const dbDialect = String(runtime.env.config.dbDialect ?? 'postgres').trim() || 'postgres';
25
26
  if ((runtime.kind === 'local' || runtime.kind === 'docker') && runtime.env.config.builtinDb) {
26
- const containerName = buildDockerDbContainerName(runtime.envName, dbDialect, runtime.dockerContainerPrefix || runtime.workspaceName);
27
+ const connection = await resolveBuiltinDbConnection(runtime);
27
28
  return {
28
29
  kind: 'builtin',
29
30
  envName: runtime.envName,
30
31
  source,
31
- dbDialect,
32
- containerName,
33
- address: formatAddress(runtime.env.config.dbHost, runtime.env.config.dbPort, containerName),
32
+ dbDialect: connection.dbDialect,
33
+ containerName: connection.containerName,
34
+ address: formatAddress(connection.dbHost, connection.dbPort, connection.containerName),
34
35
  appRuntime: runtime,
35
36
  };
36
37
  }
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { Args, Command, Flags } from '@oclif/core';
10
10
  import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime } from '../../lib/app-runtime.js';
11
+ import { resolveBuiltinDbConnection } from '../../lib/builtin-db.js';
11
12
  import { renderTable } from '../../lib/ui.js';
12
13
  import { appRootPath, dbStatus, runtimeStatus, storagePath } from './shared.js';
13
14
  function normalizeJsonValue(value) {
@@ -85,6 +86,9 @@ export default class EnvInfo extends Command {
85
86
  this.error(formatMissingManagedAppEnvMessage(requestedEnv));
86
87
  }
87
88
  const auth = runtime.env.auth;
89
+ const builtinDbConnection = (runtime.kind === 'local' || runtime.kind === 'docker') && runtime.env.config.builtinDb
90
+ ? await resolveBuiltinDbConnection(runtime)
91
+ : undefined;
88
92
  const appGroup = {
89
93
  appRootPath: appRootPath(runtime),
90
94
  storagePath: storagePath(runtime),
@@ -101,8 +105,8 @@ export default class EnvInfo extends Command {
101
105
  builtinDb: runtime.env.config.builtinDb,
102
106
  dbDialect: runtime.env.config.dbDialect,
103
107
  builtinDbImage: runtime.env.config.builtinDbImage,
104
- dbHost: runtime.env.config.dbHost,
105
- dbPort: runtime.env.config.dbPort,
108
+ dbHost: builtinDbConnection?.dbHost ?? runtime.env.config.dbHost,
109
+ dbPort: builtinDbConnection?.dbPort ?? runtime.env.config.dbPort,
106
110
  dbDatabase: runtime.env.config.dbDatabase,
107
111
  dbUser: runtime.env.config.dbUser,
108
112
  dbPassword: maskSecret(runtime.env.config.dbPassword, showSecrets),
@@ -13,6 +13,7 @@ import { getEnvAsync, getInstanceIdAsync, keyDecrypt } from '@nocobase/license-k
13
13
  import _ from 'lodash';
14
14
  import { checkExternalDbConnection, readExternalDbConnectionConfig, } from "../../lib/db-connection-check.js";
15
15
  import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime } from '../../lib/app-runtime.js';
16
+ import { buildRuntimeEnvVars } from '../../lib/runtime-env-vars.js';
16
17
  import { resolveLicensePkgUrlFromConfig } from '../../lib/cli-config.js';
17
18
  import { commandOutput } from '../../lib/run-npm.js';
18
19
  import { appUrl } from '../env/shared.js';
@@ -156,14 +157,15 @@ export async function withLicenseEnvVars(nextEnv, task) {
156
157
  }
157
158
  }
158
159
  async function withLicenseEnv(runtime, task) {
159
- return await withLicenseEnvVars(runtime.env.envVars, task);
160
+ return await withLicenseEnvVars(await buildRuntimeEnvVars(runtime), task);
160
161
  }
161
162
  export async function getCurrentLicenseEnv(runtime) {
162
163
  if (runtime.kind === 'docker') {
164
+ const envVars = await buildRuntimeEnvVars(runtime);
163
165
  const payload = await runDockerLicenseJsonCommand(runtime, [
164
166
  'license',
165
167
  'env',
166
- ...buildDockerLicenseDbFlagArgs(runtime.env.envVars),
168
+ ...buildDockerLicenseDbFlagArgs(envVars),
167
169
  ]);
168
170
  return payload?.env;
169
171
  }
@@ -181,10 +183,11 @@ export async function generateValidatedInstanceIdFromEnvVars(envVars) {
181
183
  return await generateInstanceIdFromEnvVars(envVars);
182
184
  }
183
185
  async function generateInstanceIdForDockerRuntime(runtime) {
186
+ const envVars = await buildRuntimeEnvVars(runtime);
184
187
  const payload = await runDockerLicenseJsonCommand(runtime, [
185
188
  'license',
186
189
  'generate-id',
187
- ...buildDockerLicenseDbFlagArgs(runtime.env.envVars),
190
+ ...buildDockerLicenseDbFlagArgs(envVars),
188
191
  ]);
189
192
  const instanceId = trimValue(payload.instanceId);
190
193
  if (!instanceId) {
@@ -197,7 +200,7 @@ export async function generateInstanceIdForRuntime(runtime) {
197
200
  return await generateInstanceIdForDockerRuntime(runtime);
198
201
  }
199
202
  if (runtime.kind === 'local') {
200
- return await generateValidatedInstanceIdFromEnvVars(runtime.env.envVars);
203
+ return await generateValidatedInstanceIdFromEnvVars(await buildRuntimeEnvVars(runtime));
201
204
  }
202
205
  throw new Error(`Env "${runtime.envName}" does not support automatic instance ID generation.`);
203
206
  }
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { mkdir, readdir } from 'node:fs/promises';
10
10
  import { dockerContainerExists, startDockerContainer } from './app-runtime.js';
11
+ import { deriveBuiltinDbConnection, resolveBuiltinDbConnection } from './builtin-db.js';
11
12
  import { resolveConfiguredEnvPath } from './cli-home.js';
12
13
  import { commandSucceeds, run } from './run-npm.js';
13
14
  import Install from '../commands/install.js';
@@ -92,9 +93,10 @@ export function buildSavedDockerRunArgs(runtime) {
92
93
  : trimValue(runtime.env.appPort);
93
94
  const appKey = trimValue(config.appKey);
94
95
  const timeZone = trimValue(config.timezone) || Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';
95
- const dbDialect = trimValue(config.dbDialect);
96
- const dbHost = trimValue(config.dbHost);
97
- const dbPort = trimValue(config.dbPort);
96
+ const builtinDbConnection = config.builtinDb ? deriveBuiltinDbConnection(runtime) : undefined;
97
+ const dbDialect = builtinDbConnection?.dbDialect || trimValue(config.dbDialect);
98
+ const dbHost = builtinDbConnection?.dbHost || trimValue(config.dbHost);
99
+ const dbPort = builtinDbConnection?.dbPort || trimValue(config.dbPort);
98
100
  const dbDatabase = trimValue(config.dbDatabase);
99
101
  const dbUser = trimValue(config.dbUser);
100
102
  const dbPassword = trimValue(config.dbPassword);
@@ -178,14 +180,16 @@ export async function ensureBuiltinDbReady(runtime, options) {
178
180
  if (!config.builtinDb) {
179
181
  return;
180
182
  }
183
+ const builtinDbConnection = await resolveBuiltinDbConnection(runtime);
181
184
  const plan = Install.buildBuiltinDbPlan({
182
185
  envName: runtime.envName,
183
186
  workspaceName: runtime.workspaceName,
187
+ dockerContainerPrefix: runtime.dockerContainerPrefix,
184
188
  storagePath: config.storagePath,
185
189
  source: runtime.source,
186
- dbDialect: config.dbDialect,
187
- dbHost: config.dbHost,
188
- dbPort: config.dbPort,
190
+ dbDialect: builtinDbConnection.dbDialect,
191
+ dbHost: builtinDbConnection.dbHost,
192
+ dbPort: builtinDbConnection.dbPort,
189
193
  dbDatabase: config.dbDatabase,
190
194
  dbUser: config.dbUser,
191
195
  dbPassword: config.dbPassword,
@@ -11,6 +11,7 @@ import { resolveEnvKind } from './auth-store.js';
11
11
  import { getEnv, loadAuthConfig } from './auth-store.js';
12
12
  import { DEFAULT_DOCKER_CONTAINER_PREFIX, DEFAULT_DOCKER_NETWORK, getEffectiveCliConfigValue, } from './cli-config.js';
13
13
  import { commandOutput, commandSucceeds, run, runNocoBaseCommand } from './run-npm.js';
14
+ import { buildRuntimeEnvVars } from './runtime-env-vars.js';
14
15
  const DOCKER_APP_WORKDIR = '/app/nocobase';
15
16
  function sanitizeDockerResourceName(value) {
16
17
  const normalized = value
@@ -115,9 +116,10 @@ export function formatMissingManagedAppEnvMessage(envName) {
115
116
  return 'No NocoBase env is configured yet. Run `nb init` to create one first.';
116
117
  }
117
118
  export async function runLocalNocoBaseCommand(runtime, args, options) {
119
+ const envVars = await buildRuntimeEnvVars(runtime);
118
120
  await runNocoBaseCommand(args, {
119
121
  cwd: runtime.projectRoot,
120
- env: runtime.env.envVars,
122
+ env: envVars,
121
123
  stdio: options?.stdio,
122
124
  });
123
125
  }
@@ -195,8 +195,13 @@ export class Env {
195
195
  put('APP_KEY', this.config.appKey);
196
196
  put('TZ', this.config.timezone);
197
197
  put('DB_DIALECT', this.config.dbDialect);
198
- put('DB_HOST', this.config.dbHost);
199
- put('DB_PORT', this.config.dbPort);
198
+ if (!this.config.builtinDb) {
199
+ put('DB_HOST', this.config.dbHost);
200
+ put('DB_PORT', this.config.dbPort);
201
+ }
202
+ else if (String(this.config.source ?? '').trim() !== 'docker') {
203
+ put('DB_PORT', this.config.dbPort);
204
+ }
200
205
  put('DB_DATABASE', this.config.dbDatabase);
201
206
  put('DB_USER', this.config.dbUser);
202
207
  put('DB_PASSWORD', this.config.dbPassword);
@@ -0,0 +1,86 @@
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 { buildDockerDbContainerName } from './app-runtime.js';
10
+ import { commandOutput } from './run-npm.js';
11
+ function trimValue(value) {
12
+ return String(value ?? '').trim();
13
+ }
14
+ export function defaultBuiltinDbPortForDialect(value) {
15
+ const dialect = trimValue(value) || 'postgres';
16
+ switch (dialect) {
17
+ case 'mysql':
18
+ case 'mariadb':
19
+ return '3306';
20
+ case 'kingbase':
21
+ return '54321';
22
+ case 'postgres':
23
+ default:
24
+ return '5432';
25
+ }
26
+ }
27
+ export function resolveBuiltinDbContainerName(runtime, dbDialect) {
28
+ const dialect = trimValue(dbDialect ?? runtime.env.config.dbDialect) || 'postgres';
29
+ return buildDockerDbContainerName(runtime.envName, dialect, runtime.dockerContainerPrefix || runtime.workspaceName);
30
+ }
31
+ export function deriveBuiltinDbConnection(runtime, overrides = {}) {
32
+ const dbDialect = trimValue(overrides.dbDialect ?? runtime.env.config.dbDialect) || 'postgres';
33
+ const containerName = resolveBuiltinDbContainerName(runtime, dbDialect);
34
+ const networkName = trimValue(runtime.dockerNetworkName || runtime.workspaceName) || undefined;
35
+ if (runtime.source === 'docker') {
36
+ return {
37
+ builtinDb: true,
38
+ dbDialect,
39
+ dbHost: containerName,
40
+ dbPort: defaultBuiltinDbPortForDialect(dbDialect),
41
+ containerName,
42
+ networkName,
43
+ };
44
+ }
45
+ const dbPort = trimValue(overrides.dbPort ?? runtime.env.config.dbPort) || defaultBuiltinDbPortForDialect(dbDialect);
46
+ return {
47
+ builtinDb: true,
48
+ dbDialect,
49
+ dbHost: '127.0.0.1',
50
+ dbPort,
51
+ containerName,
52
+ networkName,
53
+ };
54
+ }
55
+ export async function resolveBuiltinDbConnection(runtime) {
56
+ const derived = deriveBuiltinDbConnection(runtime);
57
+ if (runtime.source === 'docker') {
58
+ return derived;
59
+ }
60
+ const mappedPort = await inspectBuiltinDbPublishedPort(derived.containerName, derived.dbDialect);
61
+ if (mappedPort) {
62
+ return {
63
+ ...derived,
64
+ dbPort: mappedPort,
65
+ };
66
+ }
67
+ return derived;
68
+ }
69
+ async function inspectBuiltinDbPublishedPort(containerName, dbDialect) {
70
+ const containerPort = defaultBuiltinDbPortForDialect(dbDialect);
71
+ try {
72
+ const output = await commandOutput('docker', [
73
+ 'inspect',
74
+ '--format',
75
+ `{{with index .NetworkSettings.Ports "${containerPort}/tcp"}}{{(index . 0).HostPort}}{{end}}`,
76
+ containerName,
77
+ ], {
78
+ errorName: 'docker inspect',
79
+ });
80
+ const hostPort = trimValue(output);
81
+ return hostPort || undefined;
82
+ }
83
+ catch {
84
+ return undefined;
85
+ }
86
+ }
@@ -71,6 +71,13 @@ export function buildStoredEnvConfig(input) {
71
71
  if (input.builtinDb === false) {
72
72
  envConfig.builtinDbImage = undefined;
73
73
  }
74
+ if (input.builtinDb === true) {
75
+ delete envConfig.dbHost;
76
+ const source = trimConfigValue(input.source);
77
+ if (source === 'docker') {
78
+ delete envConfig.dbPort;
79
+ }
80
+ }
74
81
  const authType = trimConfigValue(input.authType);
75
82
  const accessToken = trimConfigValue(input.accessToken);
76
83
  if (authType === 'token' && accessToken) {
@@ -15,6 +15,8 @@
15
15
  * For more information, please refer to: https://www.nocobase.com/agreement.
16
16
  */
17
17
  import fs from 'node:fs';
18
+ import fsp from 'node:fs/promises';
19
+ import os from 'node:os';
18
20
  import path from 'node:path';
19
21
  import spawn from 'cross-spawn';
20
22
  const FORWARDED_SIGNALS = ['SIGINT', 'SIGTERM'];
@@ -178,6 +180,57 @@ export function commandOutput(name, args, options) {
178
180
  });
179
181
  });
180
182
  }
183
+ async function readCommandOutputFile(filePath) {
184
+ try {
185
+ return await fsp.readFile(filePath, 'utf8');
186
+ }
187
+ catch {
188
+ return '';
189
+ }
190
+ }
191
+ export async function commandOutputViaFile(name, args, options) {
192
+ const cwd = resolveCwd(options?.cwd);
193
+ const label = options?.errorName ?? name;
194
+ const command = resolveCommandName(name);
195
+ const captureDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'nocobase-cli-output-'));
196
+ const stdoutPath = path.join(captureDir, 'stdout.log');
197
+ const stderrPath = path.join(captureDir, 'stderr.log');
198
+ const stdoutHandle = await fsp.open(stdoutPath, 'w');
199
+ const stderrHandle = await fsp.open(stderrPath, 'w');
200
+ try {
201
+ const result = await new Promise((resolve, reject) => {
202
+ const child = spawn(command, [...args], {
203
+ cwd,
204
+ env: {
205
+ ...process.env,
206
+ ...options?.env,
207
+ },
208
+ stdio: ['ignore', stdoutHandle.fd, stderrHandle.fd],
209
+ windowsHide: process.platform === 'win32',
210
+ });
211
+ child.once('error', reject);
212
+ child.once('close', (code, signal) => {
213
+ resolve({ code, signal });
214
+ });
215
+ });
216
+ await stdoutHandle.close();
217
+ await stderrHandle.close();
218
+ const stdout = await readCommandOutputFile(stdoutPath);
219
+ const stderr = await readCommandOutputFile(stderrPath);
220
+ if (result.code === 0) {
221
+ return stdout.trim();
222
+ }
223
+ if (result.signal) {
224
+ throw new Error(`${label} exited due to signal ${result.signal}`);
225
+ }
226
+ const details = stderr.trim() || stdout.trim();
227
+ throw new Error(details ? `${label} exited with code ${result.code}: ${details}` : `${label} exited with code ${result.code}`);
228
+ }
229
+ finally {
230
+ await Promise.allSettled([stdoutHandle.close(), stderrHandle.close()]);
231
+ await fsp.rm(captureDir, { recursive: true, force: true });
232
+ }
233
+ }
181
234
  /** Run `yarn` with the given argument list, inheriting stdio (errors label as `npm` for compatibility). */
182
235
  export function runNpm(args, options) {
183
236
  return run('yarn', [...args], { ...options, errorName: 'npm' });
@@ -0,0 +1,32 @@
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 { resolveBuiltinDbConnection } from './builtin-db.js';
10
+ function put(out, key, value) {
11
+ if (value === undefined || value === null) {
12
+ return;
13
+ }
14
+ out[key] = String(value);
15
+ }
16
+ export async function buildRuntimeEnvVars(runtime) {
17
+ const config = runtime.env.config ?? {};
18
+ const out = {
19
+ ...runtime.env.envVars,
20
+ };
21
+ if (runtime.kind !== 'local' && runtime.kind !== 'docker') {
22
+ return out;
23
+ }
24
+ if (!config.builtinDb) {
25
+ return out;
26
+ }
27
+ const connection = await resolveBuiltinDbConnection(runtime);
28
+ put(out, 'DB_DIALECT', connection.dbDialect);
29
+ put(out, 'DB_HOST', connection.dbHost);
30
+ put(out, 'DB_PORT', connection.dbPort);
31
+ return out;
32
+ }
@@ -10,7 +10,7 @@ import fsp from 'node:fs/promises';
10
10
  import path from 'node:path';
11
11
  import { resolveCliHomeDir } from './cli-home.js';
12
12
  import { compareVersions } from './self-manager.js';
13
- import { commandOutput, run } from './run-npm.js';
13
+ import { commandOutput, commandOutputViaFile, run } from './run-npm.js';
14
14
  export const NOCOBASE_SKILLS_SOURCE = 'nocobase/skills';
15
15
  export const NOCOBASE_SKILLS_PACKAGE_NAME = '@nocobase/skills';
16
16
  const NOCOBASE_SKILLS_NAME_PREFIX = 'nocobase-';
@@ -57,7 +57,7 @@ async function writeManagedSkillsState(workspaceRoot, state) {
57
57
  export async function listGlobalSkills(options = {}) {
58
58
  const globalRoot = resolveSkillsRoot(options);
59
59
  await ensureSkillsWorkspaceRoot(globalRoot);
60
- const output = await (options.commandOutputFn ?? commandOutput)('npx', ['-y', 'skills', 'list', '-g', '--json'], {
60
+ const output = await (options.commandOutputFn ?? commandOutputViaFile)('npx', ['-y', 'skills', 'list', '-g', '--json'], {
61
61
  cwd: globalRoot,
62
62
  errorName: 'skills list',
63
63
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/cli",
3
- "version": "2.1.0-alpha.27",
3
+ "version": "2.1.0-alpha.28",
4
4
  "description": "NocoBase Command Line Tool",
5
5
  "type": "module",
6
6
  "main": "dist/generated/command-registry.js",
@@ -103,5 +103,5 @@
103
103
  "type": "git",
104
104
  "url": "git+https://github.com/nocobase/nocobase.git"
105
105
  },
106
- "gitHead": "a340a88d86d3ff7e06d723215b02aa3c122f4870"
106
+ "gitHead": "e38293c4a1ce4d043d2b17a3067fd4f0341a7a2d"
107
107
  }