@nocobase/cli 2.1.0-alpha.24 → 2.1.0-alpha.26
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/README.md +41 -49
- package/README.zh-CN.md +38 -45
- package/bin/run.js +15 -0
- package/dist/commands/app/down.js +260 -0
- package/dist/commands/app/logs.js +98 -0
- package/dist/commands/app/restart.js +75 -0
- package/dist/commands/app/start.js +252 -0
- package/dist/commands/app/stop.js +98 -0
- package/dist/commands/app/upgrade.js +595 -0
- package/dist/commands/build.js +3 -48
- package/dist/commands/db/shared.js +19 -5
- package/dist/commands/dev.js +3 -140
- package/dist/commands/down.js +3 -184
- package/dist/commands/download.js +4 -856
- package/dist/commands/env/add.js +33 -48
- package/dist/commands/env/auth.js +6 -13
- package/dist/commands/env/info.js +152 -0
- package/dist/commands/env/list.js +27 -18
- package/dist/commands/env/remove.js +4 -10
- package/dist/commands/env/shared.js +158 -0
- package/dist/commands/env/update.js +7 -13
- package/dist/commands/env/use.js +5 -13
- package/dist/commands/{prompts-stages.js → examples/prompts-stages.js} +3 -3
- package/dist/commands/{prompts-test.js → examples/prompts-test.js} +3 -3
- package/dist/commands/init.js +270 -64
- package/dist/commands/install.js +352 -86
- package/dist/commands/logs.js +3 -81
- package/dist/commands/plugin/disable.js +64 -0
- package/dist/commands/plugin/enable.js +64 -0
- package/dist/commands/plugin/list.js +62 -0
- package/dist/commands/pm/disable.js +3 -54
- package/dist/commands/pm/enable.js +3 -54
- package/dist/commands/pm/list.js +3 -45
- package/dist/commands/restart.js +12 -0
- package/dist/commands/scaffold/migration.js +1 -1
- package/dist/commands/scaffold/plugin.js +1 -1
- package/dist/commands/self/check.js +1 -1
- package/dist/commands/self/update.js +13 -3
- package/dist/commands/skills/check.js +11 -5
- package/dist/commands/skills/index.js +1 -1
- package/dist/commands/skills/install.js +20 -7
- package/dist/commands/skills/remove.js +71 -0
- package/dist/commands/skills/update.js +27 -7
- package/dist/commands/source/build.js +58 -0
- package/dist/commands/source/dev.js +157 -0
- package/dist/commands/source/download.js +866 -0
- package/dist/commands/source/test.js +467 -0
- package/dist/commands/start.js +3 -202
- package/dist/commands/stop.js +3 -81
- package/dist/commands/test.js +3 -457
- package/dist/commands/upgrade.js +3 -574
- package/dist/help/runtime-help.js +3 -0
- package/dist/lib/api-client.js +22 -7
- package/dist/lib/app-health.js +126 -0
- package/dist/lib/app-managed-resources.js +264 -0
- package/dist/lib/app-runtime.js +16 -5
- package/dist/lib/auth-store.js +162 -43
- package/dist/lib/bootstrap.js +13 -12
- package/dist/lib/cli-home.js +38 -6
- package/dist/lib/cli-locale.js +15 -1
- package/dist/lib/env-auth.js +3 -3
- package/dist/lib/env-config.js +80 -0
- package/dist/lib/generated-command.js +10 -2
- package/dist/lib/http-request.js +49 -0
- package/dist/lib/prompt-web-ui.js +13 -6
- package/dist/lib/resource-command.js +10 -2
- package/dist/lib/runtime-generator.js +1 -1
- package/dist/lib/self-manager.js +1 -1
- package/dist/lib/skills-manager.js +173 -79
- package/dist/lib/startup-update.js +203 -0
- package/dist/locale/en-US.json +4 -1
- package/dist/locale/zh-CN.json +4 -1
- package/package.json +27 -4
- package/dist/commands/ps.js +0 -116
package/dist/commands/env/use.js
CHANGED
|
@@ -6,21 +6,14 @@
|
|
|
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 { Args, Command
|
|
9
|
+
import { Args, Command } from '@oclif/core';
|
|
10
10
|
import { setCurrentEnv } from '../../lib/auth-store.js';
|
|
11
|
-
import {
|
|
11
|
+
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
12
12
|
export default class EnvUse extends Command {
|
|
13
13
|
static summary = 'Switch the current environment';
|
|
14
14
|
static examples = [
|
|
15
15
|
'<%= config.bin %> <%= command.id %> local',
|
|
16
16
|
];
|
|
17
|
-
static flags = {
|
|
18
|
-
scope: Flags.string({
|
|
19
|
-
char: 's',
|
|
20
|
-
description: 'Config scope',
|
|
21
|
-
options: ['project', 'global'],
|
|
22
|
-
}),
|
|
23
|
-
};
|
|
24
17
|
static args = {
|
|
25
18
|
name: Args.string({
|
|
26
19
|
description: 'Configured environment name',
|
|
@@ -28,9 +21,8 @@ export default class EnvUse extends Command {
|
|
|
28
21
|
}),
|
|
29
22
|
};
|
|
30
23
|
async run() {
|
|
31
|
-
const { args
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.log(`Current env: ${args.name}${scope ? ` (${formatCliHomeScope(scope)} scope)` : ''}`);
|
|
24
|
+
const { args } = await this.parse(EnvUse);
|
|
25
|
+
await setCurrentEnv(args.name, { scope: resolveDefaultConfigScope() });
|
|
26
|
+
this.log(`Current env: ${args.name}`);
|
|
35
27
|
}
|
|
36
28
|
}
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
10
|
-
import { runPromptCatalog, } from "
|
|
11
|
-
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, } from "
|
|
12
|
-
import { runPromptCatalogWebUI } from "
|
|
10
|
+
import { runPromptCatalog, } from "../../lib/prompt-catalog.js";
|
|
11
|
+
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, } from "../../lib/cli-locale.js";
|
|
12
|
+
import { runPromptCatalogWebUI } from "../../lib/prompt-web-ui.js";
|
|
13
13
|
import PromptsTest from "./prompts-test.js";
|
|
14
14
|
function buildWebUiStagesFromTestPrompts(c) {
|
|
15
15
|
return [
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import * as p from '@clack/prompts';
|
|
10
10
|
import { Args, Command, Flags } from '@oclif/core';
|
|
11
|
-
import { runPromptCatalog, } from "
|
|
12
|
-
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, } from "
|
|
13
|
-
import { runPromptCatalogWebUI, } from "
|
|
11
|
+
import { runPromptCatalog, } from "../../lib/prompt-catalog.js";
|
|
12
|
+
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, } from "../../lib/cli-locale.js";
|
|
13
|
+
import { runPromptCatalogWebUI, } from "../../lib/prompt-web-ui.js";
|
|
14
14
|
export default class PromptsTest extends Command {
|
|
15
15
|
static hidden = true;
|
|
16
16
|
static args = {
|
package/dist/commands/init.js
CHANGED
|
@@ -15,9 +15,10 @@ import { stdin as stdinStream, stdout as stdoutStream } from 'node:process';
|
|
|
15
15
|
import { getEnv, upsertEnv } from "../lib/auth-store.js";
|
|
16
16
|
import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
17
17
|
import { applyCliLocale, localeText, translateCli } from "../lib/cli-locale.js";
|
|
18
|
+
import { resolveDefaultConfigScope } from '../lib/cli-home.js';
|
|
18
19
|
import { runPromptCatalogWebUI, } from "../lib/prompt-web-ui.js";
|
|
19
20
|
import { validateApiBaseUrl, validateEnvKey } from "../lib/prompt-validators.js";
|
|
20
|
-
import { installNocoBaseSkills } from '../lib/skills-manager.js';
|
|
21
|
+
import { inspectSkillsStatus, installNocoBaseSkills, updateNocoBaseSkills, } from '../lib/skills-manager.js';
|
|
21
22
|
import Download from "./download.js";
|
|
22
23
|
import EnvAdd from "./env/add.js";
|
|
23
24
|
import Install, { defaultDbPortForDialect } from "./install.js";
|
|
@@ -25,7 +26,14 @@ import _ from 'lodash';
|
|
|
25
26
|
const DEFAULT_INIT_API_BASE_URL = 'http://localhost:13000/api';
|
|
26
27
|
const DEFAULT_INIT_APP_NAME = 'local';
|
|
27
28
|
const DOWNLOAD_OUTPUT_DIR_PROMPT = Download.prompts.outputDir;
|
|
28
|
-
const
|
|
29
|
+
const INIT_ENV_ADD_FLAG_NAMES = [
|
|
30
|
+
'locale',
|
|
31
|
+
'default-api-base-url',
|
|
32
|
+
'api-base-url',
|
|
33
|
+
'auth-type',
|
|
34
|
+
'access-token',
|
|
35
|
+
'token',
|
|
36
|
+
];
|
|
29
37
|
const initText = (key, values) => localeText(`commands.init.${key}`, values);
|
|
30
38
|
function withExtraHidden(def, extraHidden) {
|
|
31
39
|
if (def.type === 'run') {
|
|
@@ -55,6 +63,27 @@ function resolveInitDownloadVersion(results) {
|
|
|
55
63
|
}
|
|
56
64
|
return preset;
|
|
57
65
|
}
|
|
66
|
+
function initVersionPromptValue(version) {
|
|
67
|
+
return version === 'latest' || version === 'beta' || version === 'alpha'
|
|
68
|
+
? version
|
|
69
|
+
: 'other';
|
|
70
|
+
}
|
|
71
|
+
function yesInitialValue(def, fallback) {
|
|
72
|
+
if ('yesInitialValue' in def && def.yesInitialValue !== undefined) {
|
|
73
|
+
return String(def.yesInitialValue);
|
|
74
|
+
}
|
|
75
|
+
return fallback;
|
|
76
|
+
}
|
|
77
|
+
function hasDownloadOverride(flags) {
|
|
78
|
+
return Boolean(String(flags.source ?? '').trim()
|
|
79
|
+
|| String(flags.version ?? '').trim());
|
|
80
|
+
}
|
|
81
|
+
function explicitApiBaseUrlFlag(flags) {
|
|
82
|
+
return String(flags['api-base-url'] ?? '').trim();
|
|
83
|
+
}
|
|
84
|
+
function explicitDbHostFlag(flags) {
|
|
85
|
+
return String(flags['db-host'] ?? '').trim();
|
|
86
|
+
}
|
|
58
87
|
function shouldAllowExistingInitEnv() {
|
|
59
88
|
return argvHasToken(process.argv.slice(2), ['--force', '-f']);
|
|
60
89
|
}
|
|
@@ -67,7 +96,7 @@ async function validateInitAppName(value) {
|
|
|
67
96
|
if (!envName) {
|
|
68
97
|
return undefined;
|
|
69
98
|
}
|
|
70
|
-
const existingEnv = await getEnv(envName, { scope:
|
|
99
|
+
const existingEnv = await getEnv(envName, { scope: resolveDefaultConfigScope() });
|
|
71
100
|
if (existingEnv) {
|
|
72
101
|
if (shouldAllowExistingInitEnv()) {
|
|
73
102
|
return undefined;
|
|
@@ -94,6 +123,11 @@ function formatSkippedAppNameRequiredMessage() {
|
|
|
94
123
|
translateCli('commands.init.messages.appNameEnvHelp'),
|
|
95
124
|
].join('\n');
|
|
96
125
|
}
|
|
126
|
+
function shellQuoteArg(value) {
|
|
127
|
+
return /^[A-Za-z0-9_@%+=:,./-]+$/.test(value)
|
|
128
|
+
? value
|
|
129
|
+
: `'${value.replace(/'/g, `'\\''`)}'`;
|
|
130
|
+
}
|
|
97
131
|
function initTitle() {
|
|
98
132
|
return translateCli('commands.init.messages.title');
|
|
99
133
|
}
|
|
@@ -105,6 +139,12 @@ function logInitUiReady(command, url) {
|
|
|
105
139
|
function logInitUiBrowserOpenFallback() {
|
|
106
140
|
p.log.warn(translateCli('commands.init.messages.uiOpenBrowserFallback'));
|
|
107
141
|
}
|
|
142
|
+
function formatBrowserOpenError(error) {
|
|
143
|
+
if (error instanceof Error) {
|
|
144
|
+
return error.message;
|
|
145
|
+
}
|
|
146
|
+
return String(error);
|
|
147
|
+
}
|
|
108
148
|
export default class Init extends Command {
|
|
109
149
|
static summary = 'Set up NocoBase so coding agents can connect and work with it';
|
|
110
150
|
static description = `Set up NocoBase for coding agents in the current workspace.
|
|
@@ -137,6 +177,26 @@ Prompt modes:
|
|
|
137
177
|
'<%= config.bin %> <%= command.id %> --ui --ui-port 3000',
|
|
138
178
|
];
|
|
139
179
|
static prompts = {
|
|
180
|
+
seedResume: {
|
|
181
|
+
type: 'run',
|
|
182
|
+
run: (values, command) => {
|
|
183
|
+
const record = values;
|
|
184
|
+
if (record.resume === undefined) {
|
|
185
|
+
const flags = command?.parsedFlagsForPromptSeeds;
|
|
186
|
+
record.resume = Boolean(flags?.resume);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
seedEnvName: {
|
|
191
|
+
type: 'run',
|
|
192
|
+
run: (values) => {
|
|
193
|
+
const record = values;
|
|
194
|
+
const appName = String(record.appName ?? '').trim();
|
|
195
|
+
if (appName && record.env === undefined) {
|
|
196
|
+
record.env = appName;
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
},
|
|
140
200
|
appName: {
|
|
141
201
|
type: 'text',
|
|
142
202
|
message: initText('prompts.appName.message'),
|
|
@@ -162,12 +222,6 @@ Prompt modes:
|
|
|
162
222
|
yesInitialValue: 'no',
|
|
163
223
|
required: true,
|
|
164
224
|
},
|
|
165
|
-
installSkills: {
|
|
166
|
-
type: 'boolean',
|
|
167
|
-
message: initText('prompts.installSkills.message'),
|
|
168
|
-
initialValue: true,
|
|
169
|
-
yesInitialValue: true,
|
|
170
|
-
},
|
|
171
225
|
apiBaseUrl: existingAppOnly({
|
|
172
226
|
type: 'text',
|
|
173
227
|
message: initText('prompts.apiBaseUrl.message'),
|
|
@@ -228,6 +282,7 @@ Prompt modes:
|
|
|
228
282
|
rootPassword: newInstallOnly(Install.rootUserPrompts.rootPassword),
|
|
229
283
|
rootNickname: newInstallOnly(Install.rootUserPrompts.rootNickname),
|
|
230
284
|
};
|
|
285
|
+
parsedFlagsForPromptSeeds;
|
|
231
286
|
static flags = {
|
|
232
287
|
yes: Flags.boolean({
|
|
233
288
|
char: 'y',
|
|
@@ -238,10 +293,6 @@ Prompt modes:
|
|
|
238
293
|
char: 'e',
|
|
239
294
|
description: 'Env name for this setup. Required with --yes and --resume',
|
|
240
295
|
}),
|
|
241
|
-
'install-skills': Flags.boolean({
|
|
242
|
-
description: 'Install NocoBase AI coding skills (`nocobase/skills`) for this workspace',
|
|
243
|
-
default: false,
|
|
244
|
-
}),
|
|
245
296
|
ui: Flags.boolean({
|
|
246
297
|
description: 'Open the guided setup flow in a local browser form (not valid with --yes)',
|
|
247
298
|
default: false,
|
|
@@ -250,6 +301,11 @@ Prompt modes:
|
|
|
250
301
|
description: 'Show detailed command output',
|
|
251
302
|
default: false,
|
|
252
303
|
}),
|
|
304
|
+
'skip-skills': Flags.boolean({
|
|
305
|
+
description: 'Skip installing or updating NocoBase AI coding skills during init',
|
|
306
|
+
hidden: true,
|
|
307
|
+
default: false,
|
|
308
|
+
}),
|
|
253
309
|
'ui-host': Flags.string({
|
|
254
310
|
description: 'Host for the local --ui setup server (default: 127.0.0.1)',
|
|
255
311
|
}),
|
|
@@ -258,6 +314,7 @@ Prompt modes:
|
|
|
258
314
|
min: 0,
|
|
259
315
|
max: 65535,
|
|
260
316
|
}),
|
|
317
|
+
..._.pick(EnvAdd.flags, INIT_ENV_ADD_FLAG_NAMES),
|
|
261
318
|
..._.omit(Install.flags, ['yes', 'env']),
|
|
262
319
|
};
|
|
263
320
|
async run() {
|
|
@@ -265,6 +322,9 @@ Prompt modes:
|
|
|
265
322
|
applyCliLocale(parsedResult.flags.locale);
|
|
266
323
|
const flags = parsedResult.flags;
|
|
267
324
|
const normalizedFlags = { ...flags };
|
|
325
|
+
this.parsedFlagsForPromptSeeds = {
|
|
326
|
+
resume: Boolean(normalizedFlags.resume),
|
|
327
|
+
};
|
|
268
328
|
if (normalizedFlags.ui && normalizedFlags.yes) {
|
|
269
329
|
this.error('--ui cannot be used with --yes.');
|
|
270
330
|
}
|
|
@@ -282,24 +342,14 @@ Prompt modes:
|
|
|
282
342
|
this.exit(1);
|
|
283
343
|
}
|
|
284
344
|
p.intro(initTitle());
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
await installNocoBaseSkills();
|
|
289
|
-
}
|
|
290
|
-
catch (error) {
|
|
291
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
292
|
-
p.outro(pc.red(`Skills install failed: ${message}`));
|
|
293
|
-
this.error(message);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
345
|
+
await this.syncNocoBaseSkills({
|
|
346
|
+
skip: Boolean(normalizedFlags['skip-skills']),
|
|
347
|
+
});
|
|
296
348
|
try {
|
|
297
|
-
p.log.step(`Resuming setup for env "${envName}" from the saved workspace config`);
|
|
298
349
|
await this.config.runCommand('install', this.buildResumeInstallArgv(normalizedFlags));
|
|
299
350
|
}
|
|
300
351
|
catch (error) {
|
|
301
352
|
const message = error instanceof Error ? error.message : String(error);
|
|
302
|
-
p.outro(pc.red(message));
|
|
303
353
|
this.error(message);
|
|
304
354
|
}
|
|
305
355
|
p.outro('Workspace init finished.');
|
|
@@ -308,6 +358,24 @@ Prompt modes:
|
|
|
308
358
|
const interactive = Boolean(stdinStream.isTTY && stdoutStream.isTTY);
|
|
309
359
|
const useBrowserUi = Boolean(normalizedFlags.ui);
|
|
310
360
|
let presetValues = this.buildPresetValuesFromFlags(normalizedFlags);
|
|
361
|
+
if (normalizedFlags.resume) {
|
|
362
|
+
const resumeEnvName = String(normalizedFlags.env ?? '').trim();
|
|
363
|
+
if (resumeEnvName) {
|
|
364
|
+
const resumeEnv = await getEnv(resumeEnvName, {
|
|
365
|
+
scope: resolveDefaultConfigScope(),
|
|
366
|
+
});
|
|
367
|
+
if (resumeEnv) {
|
|
368
|
+
const savedAppPort = String(resumeEnv.config.appPort ?? '').trim();
|
|
369
|
+
const savedDbPort = String(resumeEnv.config.dbPort ?? '').trim();
|
|
370
|
+
if (savedAppPort) {
|
|
371
|
+
presetValues.resumeSavedAppPort = savedAppPort;
|
|
372
|
+
}
|
|
373
|
+
if (savedDbPort) {
|
|
374
|
+
presetValues.resumeSavedDbPort = savedDbPort;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
311
379
|
if (normalizedFlags.yes && !String(presetValues.appName ?? '').trim()) {
|
|
312
380
|
const formatted = formatSkippedAppNameRequiredMessage();
|
|
313
381
|
p.log.error(highlightInitValidationMessage(formatted));
|
|
@@ -343,8 +411,9 @@ Prompt modes:
|
|
|
343
411
|
onServerStart: ({ url }) => {
|
|
344
412
|
logInitUiReady(this, url);
|
|
345
413
|
},
|
|
346
|
-
onOpenBrowserError: (_url,
|
|
414
|
+
onOpenBrowserError: (_url, err) => {
|
|
347
415
|
logInitUiBrowserOpenFallback();
|
|
416
|
+
p.log.info(`Browser open error: ${formatBrowserOpenError(err)}`);
|
|
348
417
|
},
|
|
349
418
|
});
|
|
350
419
|
}
|
|
@@ -365,28 +434,17 @@ Prompt modes:
|
|
|
365
434
|
},
|
|
366
435
|
command: this,
|
|
367
436
|
});
|
|
368
|
-
const installSkills = Boolean(results.installSkills);
|
|
369
437
|
const hasNocobase = results.hasNocobase === 'yes';
|
|
370
438
|
const existingEnv = !hasNocobase
|
|
371
|
-
? await getEnv(String(results.appName ?? '').trim(), { scope:
|
|
439
|
+
? await getEnv(String(results.appName ?? '').trim(), { scope: resolveDefaultConfigScope() })
|
|
372
440
|
: undefined;
|
|
373
441
|
if (existingEnv && Boolean(normalizedFlags.force)) {
|
|
374
|
-
p.log.warn(`Reconfiguring existing env ${pc.cyan(pc.bold(`"${existingEnv.name}"`))}
|
|
375
|
-
}
|
|
376
|
-
if (installSkills) {
|
|
377
|
-
try {
|
|
378
|
-
p.log.step('Installing NocoBase agent skills (nb skills install)');
|
|
379
|
-
await installNocoBaseSkills();
|
|
380
|
-
}
|
|
381
|
-
catch (error) {
|
|
382
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
383
|
-
p.outro(pc.red(`Skills install failed: ${message}`));
|
|
384
|
-
this.error(message);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
else {
|
|
388
|
-
p.log.info('Skipped NocoBase agent skills install.');
|
|
442
|
+
p.log.warn(`Reconfiguring existing env ${pc.cyan(pc.bold(`"${existingEnv.name}"`))} from the global config because ${pc.bold('--force')} was set. The env config will be updated before install starts, then refreshed again after install succeeds.`);
|
|
389
443
|
}
|
|
444
|
+
await this.syncNocoBaseSkills({
|
|
445
|
+
skip: Boolean(normalizedFlags['skip-skills']),
|
|
446
|
+
});
|
|
447
|
+
let managedInstallResults;
|
|
390
448
|
try {
|
|
391
449
|
// oclif explicit registry keys use `:` (e.g. `env:add`); users still type `nb env add`.
|
|
392
450
|
if (hasNocobase) {
|
|
@@ -395,15 +453,19 @@ Prompt modes:
|
|
|
395
453
|
}
|
|
396
454
|
else {
|
|
397
455
|
p.log.step('Saving the local env config');
|
|
398
|
-
await this.persistManagedEnvConfig(results);
|
|
399
|
-
|
|
456
|
+
await this.persistManagedEnvConfig(results, normalizedFlags);
|
|
457
|
+
managedInstallResults = results;
|
|
458
|
+
p.log.step('Running nb init');
|
|
400
459
|
await this.config.runCommand('install', this.buildInstallArgv(results, normalizedFlags));
|
|
401
460
|
}
|
|
402
461
|
}
|
|
403
462
|
catch (error) {
|
|
404
463
|
const message = error instanceof Error ? error.message : String(error);
|
|
405
|
-
|
|
406
|
-
|
|
464
|
+
const formatted = managedInstallResults
|
|
465
|
+
? this.formatManagedInstallFailureMessage(message, managedInstallResults, normalizedFlags)
|
|
466
|
+
: message;
|
|
467
|
+
p.outro(pc.red(formatted));
|
|
468
|
+
this.exit(1);
|
|
407
469
|
}
|
|
408
470
|
p.outro('Workspace init finished.');
|
|
409
471
|
}
|
|
@@ -451,7 +513,6 @@ Prompt modes:
|
|
|
451
513
|
catalog: {
|
|
452
514
|
appName: c.appName,
|
|
453
515
|
hasNocobase: c.hasNocobase,
|
|
454
|
-
installSkills: c.installSkills,
|
|
455
516
|
},
|
|
456
517
|
},
|
|
457
518
|
{
|
|
@@ -525,6 +586,22 @@ Prompt modes:
|
|
|
525
586
|
if (flags.env !== undefined && String(flags.env).trim() !== '') {
|
|
526
587
|
preset.appName = String(flags.env).trim();
|
|
527
588
|
}
|
|
589
|
+
const apiBaseUrl = explicitApiBaseUrlFlag(flags);
|
|
590
|
+
if (apiBaseUrl) {
|
|
591
|
+
preset.hasNocobase = 'yes';
|
|
592
|
+
preset.apiBaseUrl = apiBaseUrl;
|
|
593
|
+
}
|
|
594
|
+
else if (flags['default-api-base-url'] !== undefined
|
|
595
|
+
&& String(flags['default-api-base-url']).trim() !== '') {
|
|
596
|
+
preset.apiBaseUrl = String(flags['default-api-base-url']).trim();
|
|
597
|
+
}
|
|
598
|
+
if (flags['auth-type'] !== undefined && String(flags['auth-type']).trim() !== '') {
|
|
599
|
+
preset.authType = String(flags['auth-type']).trim();
|
|
600
|
+
}
|
|
601
|
+
const accessToken = String(flags['access-token'] ?? flags.token ?? '');
|
|
602
|
+
if (flags['access-token'] !== undefined || flags.token !== undefined) {
|
|
603
|
+
preset.accessToken = accessToken;
|
|
604
|
+
}
|
|
528
605
|
if (flags.lang !== undefined && String(flags.lang).trim() !== '') {
|
|
529
606
|
preset.lang = String(flags.lang).trim();
|
|
530
607
|
}
|
|
@@ -557,6 +634,7 @@ Prompt modes:
|
|
|
557
634
|
}
|
|
558
635
|
if (flags['db-host'] !== undefined && String(flags['db-host']).trim() !== '') {
|
|
559
636
|
preset.dbHost = String(flags['db-host']).trim();
|
|
637
|
+
preset.builtinDb = false;
|
|
560
638
|
}
|
|
561
639
|
if (flags['db-port'] !== undefined && String(flags['db-port']).trim() !== '') {
|
|
562
640
|
preset.dbPort = String(flags['db-port']).trim();
|
|
@@ -577,7 +655,11 @@ Prompt modes:
|
|
|
577
655
|
preset.source = String(flags.source).trim();
|
|
578
656
|
}
|
|
579
657
|
if (flags.version !== undefined) {
|
|
580
|
-
|
|
658
|
+
const version = String(flags.version).trim() || 'latest';
|
|
659
|
+
preset.version = initVersionPromptValue(version);
|
|
660
|
+
if (preset.version === 'other') {
|
|
661
|
+
preset.otherVersion = version;
|
|
662
|
+
}
|
|
581
663
|
}
|
|
582
664
|
if (flags['docker-registry'] !== undefined && String(flags['docker-registry']).trim() !== '') {
|
|
583
665
|
preset.dockerRegistry = String(flags['docker-registry']).trim();
|
|
@@ -609,21 +691,42 @@ Prompt modes:
|
|
|
609
691
|
if (argvHasToken(argv, ['--build-dts', '--no-build-dts'])) {
|
|
610
692
|
preset.buildDts = Boolean(flags['build-dts']);
|
|
611
693
|
}
|
|
612
|
-
if (argvHasToken(argv, ['--builtin-db'])) {
|
|
694
|
+
if (argvHasToken(argv, ['--builtin-db', '--no-builtin-db'])) {
|
|
613
695
|
preset.builtinDb = Boolean(flags['builtin-db']);
|
|
614
696
|
}
|
|
615
|
-
if (
|
|
616
|
-
preset.
|
|
697
|
+
if (explicitDbHostFlag(flags)) {
|
|
698
|
+
preset.builtinDb = false;
|
|
617
699
|
}
|
|
618
|
-
|
|
619
|
-
preset.
|
|
700
|
+
if (!preset.hasNocobase && hasDownloadOverride(flags)) {
|
|
701
|
+
preset.hasNocobase = 'no';
|
|
620
702
|
}
|
|
621
703
|
return preset;
|
|
622
704
|
}
|
|
623
705
|
hasAgentsDirInCwd() {
|
|
624
706
|
return existsSync(path.resolve(process.cwd(), '.agents'));
|
|
625
707
|
}
|
|
626
|
-
async
|
|
708
|
+
async syncNocoBaseSkills(options) {
|
|
709
|
+
if (options?.skip) {
|
|
710
|
+
p.log.step('Skipped NocoBase agent skills sync.');
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
try {
|
|
714
|
+
const status = await inspectSkillsStatus();
|
|
715
|
+
if (!status.installed) {
|
|
716
|
+
p.log.step('Installing NocoBase agent skills (nb skills install)');
|
|
717
|
+
await installNocoBaseSkills();
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
p.log.step('Updating NocoBase agent skills (nb skills update)');
|
|
721
|
+
await updateNocoBaseSkills();
|
|
722
|
+
}
|
|
723
|
+
catch (error) {
|
|
724
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
725
|
+
p.outro(pc.red(`Skills sync failed: ${message}`));
|
|
726
|
+
this.exit(1);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
async persistManagedEnvConfig(results, flags = {}) {
|
|
627
730
|
const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
|
|
628
731
|
const appPort = String(results.appPort ?? '').trim();
|
|
629
732
|
const source = String(results.source ?? '').trim();
|
|
@@ -641,8 +744,24 @@ Prompt modes:
|
|
|
641
744
|
const dbDatabase = String(results.dbDatabase ?? '').trim();
|
|
642
745
|
const dbUser = String(results.dbUser ?? '').trim();
|
|
643
746
|
const dbPassword = String(results.dbPassword ?? '');
|
|
747
|
+
const apiBaseUrl = String(results.apiBaseUrl ?? '').trim();
|
|
748
|
+
const authType = String(results.authType ?? '').trim() || 'oauth';
|
|
749
|
+
const accessToken = String(results.accessToken ?? '');
|
|
750
|
+
const builtinDb = explicitDbHostFlag(flags)
|
|
751
|
+
? false
|
|
752
|
+
: results.builtinDb === undefined
|
|
753
|
+
? undefined
|
|
754
|
+
: Boolean(results.builtinDb);
|
|
644
755
|
await upsertEnv(envName, {
|
|
645
|
-
...(
|
|
756
|
+
...(source === 'docker'
|
|
757
|
+
? { kind: 'docker' }
|
|
758
|
+
: source || appRootPath
|
|
759
|
+
? { kind: 'local' }
|
|
760
|
+
: appPort
|
|
761
|
+
? { kind: 'http' }
|
|
762
|
+
: {}),
|
|
763
|
+
...(apiBaseUrl ? { apiBaseUrl } : appPort ? { apiBaseUrl: `http://127.0.0.1:${appPort}/api` } : {}),
|
|
764
|
+
...(authType === 'token' && accessToken ? { accessToken } : {}),
|
|
646
765
|
...(source ? { source } : {}),
|
|
647
766
|
...(version ? { downloadVersion: version } : {}),
|
|
648
767
|
...(dockerRegistry ? { dockerRegistry } : {}),
|
|
@@ -655,20 +774,19 @@ Prompt modes:
|
|
|
655
774
|
...(results.devDependencies !== undefined ? { devDependencies: Boolean(results.devDependencies) } : {}),
|
|
656
775
|
...(results.build !== undefined ? { build: Boolean(results.build) } : {}),
|
|
657
776
|
...(results.buildDts !== undefined ? { buildDts: Boolean(results.buildDts) } : {}),
|
|
658
|
-
...(
|
|
777
|
+
...(builtinDb !== undefined ? { builtinDb } : {}),
|
|
659
778
|
...(dbDialect ? { dbDialect } : {}),
|
|
660
|
-
...(builtinDbImage ||
|
|
779
|
+
...(builtinDbImage || builtinDb === false ? { builtinDbImage: builtinDbImage || undefined } : {}),
|
|
661
780
|
...(dbHost ? { dbHost } : {}),
|
|
662
781
|
...(dbPort ? { dbPort } : {}),
|
|
663
782
|
...(dbDatabase ? { dbDatabase } : {}),
|
|
664
783
|
...(dbUser ? { dbUser } : {}),
|
|
665
784
|
...(dbPassword ? { dbPassword } : {}),
|
|
666
|
-
}, { scope:
|
|
785
|
+
}, { scope: resolveDefaultConfigScope() });
|
|
667
786
|
}
|
|
668
787
|
buildEnvAddArgv(results) {
|
|
669
788
|
const argv = [String(results.appName ?? DEFAULT_INIT_APP_NAME)];
|
|
670
789
|
argv.push('--no-intro');
|
|
671
|
-
argv.push('--scope', CONFIG_SCOPE);
|
|
672
790
|
argv.push('--api-base-url', String(results.apiBaseUrl ?? DEFAULT_INIT_API_BASE_URL));
|
|
673
791
|
argv.push('--auth-type', String(results.authType ?? 'oauth'));
|
|
674
792
|
if (results.authType === 'token') {
|
|
@@ -684,6 +802,9 @@ Prompt modes:
|
|
|
684
802
|
const processArgv = process.argv.slice(2);
|
|
685
803
|
const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
|
|
686
804
|
const source = String(results.source ?? '').trim();
|
|
805
|
+
const apiBaseUrl = String(results.apiBaseUrl ?? '').trim();
|
|
806
|
+
const authType = String(results.authType ?? '').trim();
|
|
807
|
+
const accessToken = String(results.accessToken ?? '');
|
|
687
808
|
argv.push('--env', envName);
|
|
688
809
|
if (options?.resume) {
|
|
689
810
|
argv.push('--resume');
|
|
@@ -691,6 +812,15 @@ Prompt modes:
|
|
|
691
812
|
if (Boolean(flags.verbose)) {
|
|
692
813
|
argv.push('--verbose');
|
|
693
814
|
}
|
|
815
|
+
if (apiBaseUrl) {
|
|
816
|
+
argv.push('--api-base-url', apiBaseUrl);
|
|
817
|
+
}
|
|
818
|
+
if (authType) {
|
|
819
|
+
argv.push('--auth-type', authType);
|
|
820
|
+
}
|
|
821
|
+
if (authType === 'token' && accessToken) {
|
|
822
|
+
argv.push('--access-token', accessToken);
|
|
823
|
+
}
|
|
694
824
|
const lang = String(results.lang ?? '').trim();
|
|
695
825
|
if (lang) {
|
|
696
826
|
argv.push('--lang', lang);
|
|
@@ -758,10 +888,15 @@ Prompt modes:
|
|
|
758
888
|
argv.push('--build-dts');
|
|
759
889
|
}
|
|
760
890
|
}
|
|
761
|
-
const
|
|
891
|
+
const explicitDbHost = explicitDbHostFlag(flags);
|
|
892
|
+
const dbHost = explicitDbHost || String(results.dbHost ?? '').trim();
|
|
893
|
+
const builtinDb = explicitDbHost ? false : Boolean(results.builtinDb);
|
|
762
894
|
if (builtinDb) {
|
|
763
895
|
argv.push('--builtin-db');
|
|
764
896
|
}
|
|
897
|
+
else if (explicitDbHost || results.builtinDb !== undefined) {
|
|
898
|
+
argv.push('--no-builtin-db');
|
|
899
|
+
}
|
|
765
900
|
const dbDialect = String(results.dbDialect ?? '').trim();
|
|
766
901
|
if (dbDialect) {
|
|
767
902
|
argv.push('--db-dialect', dbDialect);
|
|
@@ -770,7 +905,6 @@ Prompt modes:
|
|
|
770
905
|
if (builtinDb && builtinDbImage) {
|
|
771
906
|
argv.push('--builtin-db-image', builtinDbImage);
|
|
772
907
|
}
|
|
773
|
-
const dbHost = String(results.dbHost ?? '').trim();
|
|
774
908
|
if (dbHost) {
|
|
775
909
|
argv.push('--db-host', dbHost);
|
|
776
910
|
}
|
|
@@ -813,8 +947,80 @@ Prompt modes:
|
|
|
813
947
|
}
|
|
814
948
|
return argv;
|
|
815
949
|
}
|
|
950
|
+
buildManagedInstallResumeCommand(results, flags) {
|
|
951
|
+
const argv = ['nb', 'init'];
|
|
952
|
+
if (Boolean(flags.yes)) {
|
|
953
|
+
argv.push('--yes');
|
|
954
|
+
}
|
|
955
|
+
const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
|
|
956
|
+
argv.push('--env', envName);
|
|
957
|
+
if (Boolean(results.fetchSource)) {
|
|
958
|
+
const source = String(results.source ?? '').trim();
|
|
959
|
+
if (source) {
|
|
960
|
+
argv.push('--source', source);
|
|
961
|
+
}
|
|
962
|
+
const version = resolveInitDownloadVersion(results);
|
|
963
|
+
if (version) {
|
|
964
|
+
argv.push('--version', version);
|
|
965
|
+
}
|
|
966
|
+
const outputDir = String(results.outputDir ?? '').trim();
|
|
967
|
+
if (outputDir && outputDir !== String(results.appRootPath ?? '').trim()) {
|
|
968
|
+
argv.push('--output-dir', outputDir);
|
|
969
|
+
}
|
|
970
|
+
const gitUrl = String(results.gitUrl ?? '').trim();
|
|
971
|
+
if (gitUrl) {
|
|
972
|
+
argv.push('--git-url', gitUrl);
|
|
973
|
+
}
|
|
974
|
+
const dockerRegistry = String(results.dockerRegistry ?? '').trim();
|
|
975
|
+
if (dockerRegistry) {
|
|
976
|
+
argv.push('--docker-registry', dockerRegistry);
|
|
977
|
+
}
|
|
978
|
+
const dockerPlatform = String(results.dockerPlatform ?? '').trim();
|
|
979
|
+
if (dockerPlatform) {
|
|
980
|
+
argv.push('--docker-platform', dockerPlatform);
|
|
981
|
+
}
|
|
982
|
+
const npmRegistry = String(results.npmRegistry ?? '').trim();
|
|
983
|
+
if (npmRegistry) {
|
|
984
|
+
argv.push('--npm-registry', npmRegistry);
|
|
985
|
+
}
|
|
986
|
+
if (Boolean(results.devDependencies)) {
|
|
987
|
+
argv.push('--dev-dependencies');
|
|
988
|
+
}
|
|
989
|
+
if (Boolean(results.dockerSave)) {
|
|
990
|
+
argv.push('--docker-save');
|
|
991
|
+
}
|
|
992
|
+
if (results.build !== undefined && !Boolean(results.build)) {
|
|
993
|
+
argv.push('--no-build');
|
|
994
|
+
}
|
|
995
|
+
if (Boolean(results.buildDts)) {
|
|
996
|
+
argv.push('--build-dts');
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
argv.push('--resume', '--verbose');
|
|
1000
|
+
return argv.map(shellQuoteArg).join(' ');
|
|
1001
|
+
}
|
|
1002
|
+
formatManagedInstallFailureMessage(message, results, flags) {
|
|
1003
|
+
const command = this.buildManagedInstallResumeCommand(results, flags);
|
|
1004
|
+
return [
|
|
1005
|
+
message,
|
|
1006
|
+
'',
|
|
1007
|
+
translateCli('commands.init.messages.resumeAfterInstallFailure', { command }),
|
|
1008
|
+
].join('\n');
|
|
1009
|
+
}
|
|
816
1010
|
buildResumeInstallArgv(flags) {
|
|
817
|
-
|
|
1011
|
+
const preset = this.buildPresetValuesFromFlags(flags);
|
|
1012
|
+
if (flags.yes) {
|
|
1013
|
+
preset.lang ??= yesInitialValue(Install.appPrompts.lang, 'en-US');
|
|
1014
|
+
preset.rootUsername ??= yesInitialValue(Install.rootUserPrompts.rootUsername, 'nocobase');
|
|
1015
|
+
preset.rootEmail ??= yesInitialValue(Install.rootUserPrompts.rootEmail, 'admin@nocobase.com');
|
|
1016
|
+
preset.rootPassword ??= yesInitialValue(Install.rootUserPrompts.rootPassword, 'admin123');
|
|
1017
|
+
preset.rootNickname ??= yesInitialValue(Install.rootUserPrompts.rootNickname, 'Super Admin');
|
|
1018
|
+
}
|
|
1019
|
+
if (hasDownloadOverride(flags)) {
|
|
1020
|
+
preset.fetchSource ??= true;
|
|
1021
|
+
}
|
|
1022
|
+
preset.replace ??= true;
|
|
1023
|
+
return this.buildInstallArgv(preset, flags, {
|
|
818
1024
|
nonInteractive: Boolean(flags.yes),
|
|
819
1025
|
resume: true,
|
|
820
1026
|
});
|