@nocobase/cli 2.1.0-alpha.27 → 2.1.0-alpha.29
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/dist/commands/app/down.js +10 -3
- package/dist/commands/app/logs.js +2 -2
- package/dist/commands/app/start.js +2 -1
- package/dist/commands/app/stop.js +2 -1
- package/dist/commands/app/upgrade.js +7 -4
- package/dist/commands/db/check.js +9 -1
- package/dist/commands/db/logs.js +2 -2
- package/dist/commands/db/shared.js +6 -5
- package/dist/commands/db/start.js +2 -1
- package/dist/commands/db/stop.js +2 -1
- package/dist/commands/env/info.js +6 -2
- package/dist/commands/license/activate.js +4 -1
- package/dist/commands/license/generate-id.js +1 -0
- package/dist/commands/license/id.js +4 -0
- package/dist/commands/license/plugins/clean.js +4 -1
- package/dist/commands/license/plugins/sync.js +12 -10
- package/dist/commands/license/shared.js +7 -4
- package/dist/commands/plugin/disable.js +2 -0
- package/dist/commands/plugin/enable.js +2 -0
- package/dist/commands/source/dev.js +2 -1
- package/dist/lib/app-managed-resources.js +10 -6
- package/dist/lib/app-runtime.js +3 -1
- package/dist/lib/auth-store.js +7 -2
- package/dist/lib/bootstrap.js +0 -4
- package/dist/lib/builtin-db.js +86 -0
- package/dist/lib/env-config.js +7 -0
- package/dist/lib/run-npm.js +53 -0
- package/dist/lib/runtime-env-vars.js +32 -0
- package/dist/lib/skills-manager.js +2 -2
- package/dist/lib/ui.js +3 -0
- package/package.json +2 -2
|
@@ -97,15 +97,21 @@ function builtinDbContainerName(runtime) {
|
|
|
97
97
|
function managedDockerNetworkName(runtime) {
|
|
98
98
|
return runtime.dockerNetworkName?.trim() || runtime.workspaceName?.trim() || undefined;
|
|
99
99
|
}
|
|
100
|
-
async function confirmDownAll(envName, yes) {
|
|
100
|
+
async function confirmDownAll(envName, yes, options) {
|
|
101
101
|
if (yes) {
|
|
102
102
|
return true;
|
|
103
103
|
}
|
|
104
|
+
const usedCurrentEnv = options?.explicitEnv === false;
|
|
104
105
|
if (!isInteractiveTerminal()) {
|
|
106
|
+
if (usedCurrentEnv) {
|
|
107
|
+
throw new Error(`\`nb app down --all\` is using the current env "${envName}". Re-run with --env ${envName} --yes to delete everything for that env in non-interactive mode.`);
|
|
108
|
+
}
|
|
105
109
|
throw new Error(`\`nb app down --all\` needs confirmation. Re-run with --yes to delete everything for "${envName}" in non-interactive mode.`);
|
|
106
110
|
}
|
|
107
111
|
const answer = await p.confirm({
|
|
108
|
-
message:
|
|
112
|
+
message: usedCurrentEnv
|
|
113
|
+
? `Delete everything for current env "${envName}"? This removes the app, managed containers, storage data, and the saved CLI env config.`
|
|
114
|
+
: `Delete everything for "${envName}"? This removes the app, managed containers, storage data, and the saved CLI env config.`,
|
|
109
115
|
active: 'yes',
|
|
110
116
|
inactive: 'no',
|
|
111
117
|
initialValue: false,
|
|
@@ -152,6 +158,7 @@ export default class AppDown extends Command {
|
|
|
152
158
|
async run() {
|
|
153
159
|
const { flags } = await this.parse(AppDown);
|
|
154
160
|
const requestedEnv = flags.env?.trim() || undefined;
|
|
161
|
+
const explicitEnv = Boolean(requestedEnv);
|
|
155
162
|
const removeData = Boolean(flags.all);
|
|
156
163
|
const removeEnvConfig = Boolean(flags.all);
|
|
157
164
|
const runtime = await resolveManagedAppRuntime(requestedEnv);
|
|
@@ -175,7 +182,7 @@ export default class AppDown extends Command {
|
|
|
175
182
|
if (flags.all) {
|
|
176
183
|
let confirmed = false;
|
|
177
184
|
try {
|
|
178
|
-
confirmed = await confirmDownAll(runtime.envName, flags.yes);
|
|
185
|
+
confirmed = await confirmDownAll(runtime.envName, flags.yes, { explicitEnv });
|
|
179
186
|
}
|
|
180
187
|
catch (error) {
|
|
181
188
|
this.error(error instanceof Error ? error.message : String(error));
|
|
@@ -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:
|
|
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
|
|
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,7 +10,7 @@ import { Command, Flags } from '@oclif/core';
|
|
|
10
10
|
import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, startDockerContainer, } from '../../lib/app-runtime.js';
|
|
11
11
|
import { AppHealthCheckError, formatAppUrl, isAppReady, resolveManagedAppApiBaseUrl, waitForAppReady, } from '../../lib/app-health.js';
|
|
12
12
|
import { ensureBuiltinDbReady, ensureSavedLocalSource, recreateSavedDockerApp, } from '../../lib/app-managed-resources.js';
|
|
13
|
-
import { failTask, printInfo, startTask, succeedTask } from '../../lib/ui.js';
|
|
13
|
+
import { announceTargetEnv, failTask, printInfo, startTask, succeedTask } from '../../lib/ui.js';
|
|
14
14
|
function argvHasToken(argv, tokens) {
|
|
15
15
|
return tokens.some((token) => argv.includes(token));
|
|
16
16
|
}
|
|
@@ -107,6 +107,7 @@ export default class AppStart extends Command {
|
|
|
107
107
|
'Use a local or Docker env if you need CLI-managed start and stop right now.',
|
|
108
108
|
].join('\n'));
|
|
109
109
|
}
|
|
110
|
+
announceTargetEnv(runtime.envName);
|
|
110
111
|
if (runtime.kind === 'docker') {
|
|
111
112
|
const unsupportedFlags = [
|
|
112
113
|
flags.quickstart ? '--quickstart' : undefined,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Command, Flags } from '@oclif/core';
|
|
10
10
|
import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, stopDockerContainer, } from '../../lib/app-runtime.js';
|
|
11
|
-
import { failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
11
|
+
import { announceTargetEnv, failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
12
12
|
function formatStopFailure(envName, message) {
|
|
13
13
|
if (/does not exist/i.test(message)) {
|
|
14
14
|
return [
|
|
@@ -65,6 +65,7 @@ export default class AppStop extends Command {
|
|
|
65
65
|
'Use a local or Docker env if you need CLI-managed stop right now.',
|
|
66
66
|
].join('\n'));
|
|
67
67
|
}
|
|
68
|
+
announceTargetEnv(runtime.envName);
|
|
68
69
|
if (runtime.kind === 'docker') {
|
|
69
70
|
startTask(`Stopping NocoBase for "${runtime.envName}"...`);
|
|
70
71
|
try {
|
|
@@ -10,8 +10,9 @@ 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
|
-
import { failTask, printInfo, startTask, stopTask, succeedTask, updateTask } from '../../lib/ui.js';
|
|
15
|
+
import { announceTargetEnv, failTask, printInfo, startTask, stopTask, succeedTask, updateTask } from '../../lib/ui.js';
|
|
15
16
|
const DEFAULT_DOCKER_REGISTRY = 'nocobase/nocobase';
|
|
16
17
|
const DOCKER_APP_STORAGE_DESTINATION = '/app/nocobase/storage';
|
|
17
18
|
const APP_HEALTH_CHECK_INTERVAL_MS = 2_000;
|
|
@@ -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
|
|
316
|
-
const
|
|
317
|
-
const
|
|
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');
|
|
@@ -561,6 +563,7 @@ export default class AppUpgrade extends Command {
|
|
|
561
563
|
'Use a local or Docker env if you need CLI-managed upgrades right now.',
|
|
562
564
|
].join('\n'));
|
|
563
565
|
}
|
|
566
|
+
announceTargetEnv(runtime.envName);
|
|
564
567
|
try {
|
|
565
568
|
const resolvedVersion = AppUpgrade.resolveUpgradeVersion(runtime, parsed);
|
|
566
569
|
const runCommand = this.config.runCommand.bind(this.config);
|
|
@@ -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
|
|
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,
|
package/dist/commands/db/logs.js
CHANGED
|
@@ -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:
|
|
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
|
|
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 {
|
|
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
|
|
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(
|
|
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,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Command, Flags } from '@oclif/core';
|
|
10
10
|
import { formatMissingManagedAppEnvMessage, startDockerContainer, } from '../../lib/app-runtime.js';
|
|
11
|
-
import { failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
11
|
+
import { announceTargetEnv, failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
12
12
|
import { formatUnmanagedDbMessage, resolveDbRuntime } from './shared.js';
|
|
13
13
|
function formatDbStartFailure(envName, message) {
|
|
14
14
|
if (/does not exist/i.test(message)) {
|
|
@@ -52,6 +52,7 @@ export default class DbStart extends Command {
|
|
|
52
52
|
if (runtime.kind !== 'builtin') {
|
|
53
53
|
this.error(formatUnmanagedDbMessage('start', runtime));
|
|
54
54
|
}
|
|
55
|
+
announceTargetEnv(runtime.envName);
|
|
55
56
|
startTask(`Starting the built-in database for "${runtime.envName}"...`);
|
|
56
57
|
try {
|
|
57
58
|
const state = await startDockerContainer(runtime.containerName, {
|
package/dist/commands/db/stop.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Command, Flags } from '@oclif/core';
|
|
10
10
|
import { formatMissingManagedAppEnvMessage, stopDockerContainer, } from '../../lib/app-runtime.js';
|
|
11
|
-
import { failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
11
|
+
import { announceTargetEnv, failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
12
12
|
import { formatUnmanagedDbMessage, resolveDbRuntime } from './shared.js';
|
|
13
13
|
function formatDbStopFailure(envName, message) {
|
|
14
14
|
if (/does not exist/i.test(message)) {
|
|
@@ -52,6 +52,7 @@ export default class DbStop extends Command {
|
|
|
52
52
|
if (runtime.kind !== 'builtin') {
|
|
53
53
|
this.error(formatUnmanagedDbMessage('stop', runtime));
|
|
54
54
|
}
|
|
55
|
+
announceTargetEnv(runtime.envName);
|
|
55
56
|
startTask(`Stopping the built-in database for "${runtime.envName}"...`);
|
|
56
57
|
try {
|
|
57
58
|
const state = await stopDockerContainer(runtime.containerName, {
|
|
@@ -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),
|
|
@@ -10,7 +10,7 @@ import * as p from '@clack/prompts';
|
|
|
10
10
|
import { Command, Flags } from '@oclif/core';
|
|
11
11
|
import { readFile } from 'node:fs/promises';
|
|
12
12
|
import { ensureInstanceId, licenseEnvFlag, licenseJsonFlag, licensePkgUrlFlag, redactLicenseKey, requireLicenseRuntime, resolveLicenseKeyFile, resolveLicenseServiceUrl, saveLicenseKey, sanitizeLicenseOutput, validateLicenseKey, } from './shared.js';
|
|
13
|
-
import { isInteractiveTerminal } from '../../lib/ui.js';
|
|
13
|
+
import { announceTargetEnv, isInteractiveTerminal } from '../../lib/ui.js';
|
|
14
14
|
import { appUrl } from '../env/shared.js';
|
|
15
15
|
function resolveOnlineInputValue(value) {
|
|
16
16
|
return String(value ?? '').trim();
|
|
@@ -210,6 +210,9 @@ export default class LicenseActivate extends Command {
|
|
|
210
210
|
async run() {
|
|
211
211
|
const { flags } = await this.parse(LicenseActivate);
|
|
212
212
|
const runtime = await requireLicenseRuntime(flags.env);
|
|
213
|
+
if (!flags.json) {
|
|
214
|
+
announceTargetEnv(runtime.envName);
|
|
215
|
+
}
|
|
213
216
|
let key = String(flags.key ?? '').trim();
|
|
214
217
|
let keyFile = String(flags['key-file'] ?? '').trim();
|
|
215
218
|
let online = Boolean(flags.online);
|
|
@@ -21,6 +21,7 @@ function formatMissingFieldsMessage(missing) {
|
|
|
21
21
|
].join('\n');
|
|
22
22
|
}
|
|
23
23
|
export default class LicenseGenerateId extends Command {
|
|
24
|
+
static hidden = true;
|
|
24
25
|
static summary = 'Generate a commercial license instance ID from explicit database settings';
|
|
25
26
|
static description = 'Generate the commercial licensing instance ID from explicit `--db-*` flags. This command only prints the generated ID and does not save it.';
|
|
26
27
|
static examples = [
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Command, Flags } from '@oclif/core';
|
|
10
10
|
import { generateAndSaveInstanceId, licenseEnvFlag, licenseJsonFlag, readSavedInstanceId, requireLicenseRuntime, resolveInstanceIdFile, } from './shared.js';
|
|
11
|
+
import { announceTargetEnv } from '../../lib/ui.js';
|
|
11
12
|
export default class LicenseId extends Command {
|
|
12
13
|
static summary = 'Show the instance ID for the selected env';
|
|
13
14
|
static description = 'Show the commercial licensing instance ID for the selected env, generating and saving it if needed.';
|
|
@@ -28,6 +29,9 @@ export default class LicenseId extends Command {
|
|
|
28
29
|
async run() {
|
|
29
30
|
const { flags } = await this.parse(LicenseId);
|
|
30
31
|
const runtime = await requireLicenseRuntime(flags.env);
|
|
32
|
+
if (!flags.json) {
|
|
33
|
+
announceTargetEnv(runtime.envName);
|
|
34
|
+
}
|
|
31
35
|
const savedBefore = await readSavedInstanceId(runtime);
|
|
32
36
|
const shouldGenerate = Boolean(flags.force) || !savedBefore;
|
|
33
37
|
const instanceId = shouldGenerate
|
|
@@ -11,6 +11,7 @@ import pc from 'picocolors';
|
|
|
11
11
|
import { licenseEnvFlag, licenseJsonFlag, licensePkgUrlFlag, requireLicenseRuntime } from '../shared.js';
|
|
12
12
|
import { cleanLicensedPlugins } from './shared.js';
|
|
13
13
|
import { resolvePluginStoragePath } from '../../../lib/plugin-storage.js';
|
|
14
|
+
import { announceTargetEnv } from '../../../lib/ui.js';
|
|
14
15
|
function formatActionLabel(action) {
|
|
15
16
|
switch (action) {
|
|
16
17
|
case 'removed':
|
|
@@ -38,7 +39,6 @@ export default class LicensePluginsClean extends Command {
|
|
|
38
39
|
default: false,
|
|
39
40
|
}),
|
|
40
41
|
verbose: Flags.boolean({
|
|
41
|
-
char: 'V',
|
|
42
42
|
description: 'Show detailed per-plugin clean logs',
|
|
43
43
|
default: false,
|
|
44
44
|
}),
|
|
@@ -46,6 +46,9 @@ export default class LicensePluginsClean extends Command {
|
|
|
46
46
|
async run() {
|
|
47
47
|
const { flags } = await this.parse(LicensePluginsClean);
|
|
48
48
|
const runtime = await requireLicenseRuntime(flags.env);
|
|
49
|
+
if (!flags.json) {
|
|
50
|
+
announceTargetEnv(runtime.envName);
|
|
51
|
+
}
|
|
49
52
|
const shouldStreamLogs = !flags.json && Boolean(flags.verbose);
|
|
50
53
|
const pluginStoragePath = resolvePluginStoragePath(runtime.env.storagePath);
|
|
51
54
|
if (!flags.json) {
|
|
@@ -14,11 +14,10 @@ import { licenseEnvFlag, licenseJsonFlag, licensePkgUrlFlag, requireLicenseRunti
|
|
|
14
14
|
import { syncLicensedPlugins } from './shared.js';
|
|
15
15
|
import { resolvePluginStoragePath } from '../../../lib/plugin-storage.js';
|
|
16
16
|
import { commandOutput } from '../../../lib/run-npm.js';
|
|
17
|
-
import { startTask, stopTask, succeedTask, updateTask } from '../../../lib/ui.js';
|
|
17
|
+
import { announceTargetEnv, startTask, stopTask, succeedTask, updateTask } from '../../../lib/ui.js';
|
|
18
18
|
const SYNC_LOADING_DELAY_MS = 1200;
|
|
19
19
|
const SYNC_LOADING_UPDATE_MS = 5000;
|
|
20
|
-
const
|
|
21
|
-
const DOCKER_CLI_PACKAGE_JSON_PATH = '/opt/nb/node_modules/@nocobase/cli/package.json';
|
|
20
|
+
const LOCAL_APP_PACKAGE_JSON_PATH = 'node_modules/@nocobase/app/package.json';
|
|
22
21
|
const DEFAULT_DOCKER_REGISTRY = 'nocobase/nocobase';
|
|
23
22
|
const DEFAULT_DOCKER_VERSION = 'alpha';
|
|
24
23
|
function formatActionLabel(action) {
|
|
@@ -78,13 +77,13 @@ async function parseVersionFromPackageJson(content, sourceLabel) {
|
|
|
78
77
|
return version;
|
|
79
78
|
}
|
|
80
79
|
async function resolveLocalAppVersion(runtime) {
|
|
81
|
-
const packageJsonPath = path.join(runtime.projectRoot,
|
|
80
|
+
const packageJsonPath = path.join(runtime.projectRoot, LOCAL_APP_PACKAGE_JSON_PATH);
|
|
82
81
|
let content;
|
|
83
82
|
try {
|
|
84
83
|
content = await readFile(packageJsonPath, 'utf8');
|
|
85
84
|
}
|
|
86
85
|
catch {
|
|
87
|
-
throw new Error(`Missing ${
|
|
86
|
+
throw new Error(`Missing ${LOCAL_APP_PACKAGE_JSON_PATH} for env "${runtime.envName}" at ${packageJsonPath}.`);
|
|
88
87
|
}
|
|
89
88
|
return await parseVersionFromPackageJson(content, packageJsonPath);
|
|
90
89
|
}
|
|
@@ -101,7 +100,7 @@ async function resolveDockerAppVersion(runtime) {
|
|
|
101
100
|
if (dockerPlatform) {
|
|
102
101
|
args.push('--platform', dockerPlatform);
|
|
103
102
|
}
|
|
104
|
-
args.push('--entrypoint', '
|
|
103
|
+
args.push('--entrypoint', 'nb', imageRef, '--version');
|
|
105
104
|
let output;
|
|
106
105
|
try {
|
|
107
106
|
output = await commandOutput('docker', args, {
|
|
@@ -110,11 +109,12 @@ async function resolveDockerAppVersion(runtime) {
|
|
|
110
109
|
}
|
|
111
110
|
catch (error) {
|
|
112
111
|
const message = error instanceof Error ? error.message : String(error);
|
|
113
|
-
throw new Error(`
|
|
112
|
+
throw new Error(`Failed to read app version for env "${runtime.envName}" from Docker image ${imageRef}. ${message}`);
|
|
114
113
|
}
|
|
115
|
-
const
|
|
114
|
+
const versionMatch = output.match(/@nocobase\/cli\/([^\s]+)/);
|
|
115
|
+
const version = trimValue(versionMatch?.[1] ?? output.replace(/^"+|"+$/g, ''));
|
|
116
116
|
if (!version) {
|
|
117
|
-
throw new Error(`Missing version
|
|
117
|
+
throw new Error(`Missing app version for env "${runtime.envName}" inside Docker image ${imageRef}.`);
|
|
118
118
|
}
|
|
119
119
|
return version;
|
|
120
120
|
}
|
|
@@ -148,7 +148,6 @@ export default class LicensePluginsSync extends Command {
|
|
|
148
148
|
description: 'Registry version or dist-tag to synchronize. Defaults to the current workspace version.',
|
|
149
149
|
}),
|
|
150
150
|
verbose: Flags.boolean({
|
|
151
|
-
char: 'V',
|
|
152
151
|
description: 'Show detailed per-plugin sync logs',
|
|
153
152
|
default: false,
|
|
154
153
|
}),
|
|
@@ -156,6 +155,9 @@ export default class LicensePluginsSync extends Command {
|
|
|
156
155
|
async run() {
|
|
157
156
|
const { flags } = await this.parse(LicensePluginsSync);
|
|
158
157
|
const runtime = await requireLicenseRuntime(flags.env);
|
|
158
|
+
if (!flags.json) {
|
|
159
|
+
announceTargetEnv(runtime.envName);
|
|
160
|
+
}
|
|
159
161
|
const version = trimValue(flags.version) || await resolveManagedAppVersion(runtime);
|
|
160
162
|
const registryVersion = normalizePluginRegistryVersion(version);
|
|
161
163
|
const shouldStreamLogs = !flags.json && Boolean(flags.verbose);
|
|
@@ -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
|
|
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(
|
|
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(
|
|
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
|
|
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 { Args, Command, Flags } from '@oclif/core';
|
|
10
10
|
import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runDockerNocoBaseCommand, runLocalNocoBaseCommand, } from '../../lib/app-runtime.js';
|
|
11
|
+
import { announceTargetEnv } from '../../lib/ui.js';
|
|
11
12
|
export default class PluginDisable extends Command {
|
|
12
13
|
static hidden = false;
|
|
13
14
|
static args = {
|
|
@@ -39,6 +40,7 @@ export default class PluginDisable extends Command {
|
|
|
39
40
|
if (!runtime) {
|
|
40
41
|
this.error(formatMissingManagedAppEnvMessage(flags.env));
|
|
41
42
|
}
|
|
43
|
+
announceTargetEnv(runtime.envName);
|
|
42
44
|
if (runtime.kind === 'local') {
|
|
43
45
|
try {
|
|
44
46
|
await runLocalNocoBaseCommand(runtime, ['pm', 'disable', ...packages]);
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
10
10
|
import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runDockerNocoBaseCommand, runLocalNocoBaseCommand, } from '../../lib/app-runtime.js';
|
|
11
|
+
import { announceTargetEnv } from '../../lib/ui.js';
|
|
11
12
|
export default class PluginEnable extends Command {
|
|
12
13
|
static hidden = false;
|
|
13
14
|
static args = {
|
|
@@ -39,6 +40,7 @@ export default class PluginEnable extends Command {
|
|
|
39
40
|
if (!runtime) {
|
|
40
41
|
this.error(formatMissingManagedAppEnvMessage(flags.env));
|
|
41
42
|
}
|
|
43
|
+
announceTargetEnv(runtime.envName);
|
|
42
44
|
if (runtime.kind === 'local') {
|
|
43
45
|
try {
|
|
44
46
|
await runLocalNocoBaseCommand(runtime, ['pm', 'enable', ...packages]);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Command, Flags } from '@oclif/core';
|
|
10
10
|
import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime, runLocalNocoBaseCommand, } from '../../lib/app-runtime.js';
|
|
11
|
-
import { printInfo } from '../../lib/ui.js';
|
|
11
|
+
import { announceTargetEnv, printInfo } from '../../lib/ui.js';
|
|
12
12
|
function formatUnsupportedRuntimeMessage(kind, envName) {
|
|
13
13
|
if (kind === 'docker') {
|
|
14
14
|
return [
|
|
@@ -110,6 +110,7 @@ export default class SourceDev extends Command {
|
|
|
110
110
|
if (runtime.kind === 'docker' || runtime.kind === 'http' || runtime.kind === 'ssh') {
|
|
111
111
|
this.error(formatUnsupportedRuntimeMessage(runtime.kind, runtime.envName));
|
|
112
112
|
}
|
|
113
|
+
announceTargetEnv(runtime.envName);
|
|
113
114
|
const devPort = flags.port
|
|
114
115
|
|| (runtime.env.appPort !== undefined && runtime.env.appPort !== null
|
|
115
116
|
? String(runtime.env.appPort).trim()
|
|
@@ -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
|
|
96
|
-
const
|
|
97
|
-
const
|
|
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:
|
|
187
|
-
dbHost:
|
|
188
|
-
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,
|
package/dist/lib/app-runtime.js
CHANGED
|
@@ -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:
|
|
122
|
+
env: envVars,
|
|
121
123
|
stdio: options?.stdio,
|
|
122
124
|
});
|
|
123
125
|
}
|
package/dist/lib/auth-store.js
CHANGED
|
@@ -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
|
-
|
|
199
|
-
|
|
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);
|
package/dist/lib/bootstrap.js
CHANGED
|
@@ -36,14 +36,10 @@ function hasBooleanFlag(argv, name) {
|
|
|
36
36
|
const exact = `--${name}`;
|
|
37
37
|
const negated = `--no-${name}`;
|
|
38
38
|
const prefix = `--${name}=`;
|
|
39
|
-
const alias = name === 'verbose' ? '-V' : undefined;
|
|
40
39
|
for (const value of argv) {
|
|
41
40
|
if (value === exact) {
|
|
42
41
|
return true;
|
|
43
42
|
}
|
|
44
|
-
if (alias && value === alias) {
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
43
|
if (value === negated) {
|
|
48
44
|
return false;
|
|
49
45
|
}
|
|
@@ -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
|
+
}
|
package/dist/lib/env-config.js
CHANGED
|
@@ -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) {
|
package/dist/lib/run-npm.js
CHANGED
|
@@ -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 ??
|
|
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/dist/lib/ui.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli",
|
|
3
|
-
"version": "2.1.0-alpha.
|
|
3
|
+
"version": "2.1.0-alpha.29",
|
|
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": "
|
|
106
|
+
"gitHead": "526e36e399a570755286f9a0d34fa202b4a58a03"
|
|
107
107
|
}
|