@nocobase/cli 2.1.0-beta.20 → 2.1.0-beta.22
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 +32 -50
- package/README.zh-CN.md +29 -46
- package/bin/run.js +15 -0
- package/dist/commands/app/down.js +260 -0
- package/dist/commands/app/info.js +140 -0
- package/dist/commands/app/logs.js +98 -0
- package/dist/commands/app/ps.js +60 -0
- package/dist/commands/app/restart.js +75 -0
- package/dist/commands/app/shared.js +95 -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/list.js +10 -15
- package/dist/commands/env/remove.js +4 -10
- 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 +262 -63
- 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/ps.js +3 -107
- package/dist/commands/restart.js +3 -65
- 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 +3 -2
- 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/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 +26 -3
package/dist/commands/install.js
CHANGED
|
@@ -16,11 +16,13 @@ import path from 'node:path';
|
|
|
16
16
|
import { exit } from 'node:process';
|
|
17
17
|
import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
18
18
|
import { applyCliLocale, localeText, resolveCliLocale, translateCli, } from "../lib/cli-locale.js";
|
|
19
|
+
import { resolveConfiguredEnvPath, resolveDefaultConfigScope, resolveEnvRoot, resolveEnvRelativePath, } from '../lib/cli-home.js';
|
|
19
20
|
import { findAvailableTcpPort, validateAvailableTcpPort, validateTcpPort, validateEnvKey, } from "../lib/prompt-validators.js";
|
|
20
21
|
import { formatMissingManagedAppEnvMessage } from '../lib/app-runtime.js';
|
|
21
22
|
import { run, runNocoBaseCommand } from '../lib/run-npm.js';
|
|
22
23
|
import { startTask, stopTask, updateTask } from '../lib/ui.js';
|
|
23
|
-
import { ensureWorkspaceName, getEnv } from '../lib/auth-store.js';
|
|
24
|
+
import { ensureWorkspaceName, getEnv, loadAuthConfig, upsertEnv } from '../lib/auth-store.js';
|
|
25
|
+
import { buildStoredEnvConfig } from '../lib/env-config.js';
|
|
24
26
|
import Download, { defaultDockerRegistryForLang, } from './download.js';
|
|
25
27
|
import EnvAdd from "./env/add.js";
|
|
26
28
|
const DEFAULT_INSTALL_ENV_NAME = 'local';
|
|
@@ -53,7 +55,6 @@ const DEFAULT_INSTALL_ROOT_USERNAME = 'nocobase';
|
|
|
53
55
|
const DEFAULT_INSTALL_ROOT_EMAIL = 'admin@nocobase.com';
|
|
54
56
|
const DEFAULT_INSTALL_ROOT_PASSWORD = 'admin123';
|
|
55
57
|
const DEFAULT_INSTALL_ROOT_NICKNAME = 'Super Admin';
|
|
56
|
-
const CONFIG_SCOPE = 'project';
|
|
57
58
|
const APP_HEALTH_CHECK_INTERVAL_MS = 2_000;
|
|
58
59
|
const APP_HEALTH_CHECK_TIMEOUT_MS = 600_000;
|
|
59
60
|
const APP_HEALTH_CHECK_REQUEST_TIMEOUT_MS = 5_000;
|
|
@@ -137,6 +138,11 @@ function argvHasToken(argv, tokens) {
|
|
|
137
138
|
function isInstallDbDialect(value) {
|
|
138
139
|
return INSTALL_DB_DIALECTS.includes(value);
|
|
139
140
|
}
|
|
141
|
+
function downloadVersionPromptValue(version) {
|
|
142
|
+
return version === 'latest' || version === 'beta' || version === 'alpha'
|
|
143
|
+
? version
|
|
144
|
+
: 'other';
|
|
145
|
+
}
|
|
140
146
|
function supportsBuiltinDbDialect(value) {
|
|
141
147
|
const dialect = String(value ?? '').trim();
|
|
142
148
|
return Object.prototype.hasOwnProperty.call(DEFAULT_INSTALL_BUILTIN_DB_IMAGES, dialect);
|
|
@@ -240,7 +246,8 @@ async function commandOutput(command, args, options) {
|
|
|
240
246
|
});
|
|
241
247
|
}
|
|
242
248
|
export default class Install extends Command {
|
|
243
|
-
static
|
|
249
|
+
static hidden = true;
|
|
250
|
+
static description = 'Install NocoBase: database, storage, admin user, and `nocobase-v1 install`. Optionally run `nb source download` first; distribution and image details are configured on `nb source download`, not here. Use `--resume` to continue an interrupted setup from the saved workspace env config.';
|
|
244
251
|
static examples = [
|
|
245
252
|
'<%= config.bin %> <%= command.id %>',
|
|
246
253
|
'<%= config.bin %> <%= command.id %> --env app1',
|
|
@@ -271,6 +278,25 @@ export default class Install extends Command {
|
|
|
271
278
|
char: 'e',
|
|
272
279
|
description: 'App/env name to create or update. Defaults app paths to ./<envName>/source/ and ./<envName>/storage/.',
|
|
273
280
|
}),
|
|
281
|
+
'default-api-base-url': Flags.string({
|
|
282
|
+
char: 'd',
|
|
283
|
+
hidden: true,
|
|
284
|
+
description: 'Default API base URL for HTTP API calls, including the /api prefix (e.g. http://localhost:13000/api)',
|
|
285
|
+
}),
|
|
286
|
+
'api-base-url': Flags.string({
|
|
287
|
+
char: 'u',
|
|
288
|
+
description: 'Root URL for HTTP API calls, including the /api prefix (e.g. http://localhost:13000/api)',
|
|
289
|
+
}),
|
|
290
|
+
'auth-type': Flags.string({
|
|
291
|
+
char: 'a',
|
|
292
|
+
description: 'Authentication: token (API key) or oauth (browser login via `nb env auth`)',
|
|
293
|
+
options: ['token', 'oauth'],
|
|
294
|
+
}),
|
|
295
|
+
'access-token': Flags.string({
|
|
296
|
+
char: 't',
|
|
297
|
+
aliases: ['token'],
|
|
298
|
+
description: 'API key or access token when using --auth-type token',
|
|
299
|
+
}),
|
|
274
300
|
lang: Flags.string({ description: 'Language for the installed NocoBase app', char: 'l', required: false }),
|
|
275
301
|
force: Flags.boolean({
|
|
276
302
|
description: 'Reconfigure an existing env and replace conflicting runtime resources when needed',
|
|
@@ -303,6 +329,7 @@ export default class Install extends Command {
|
|
|
303
329
|
required: false,
|
|
304
330
|
}),
|
|
305
331
|
'builtin-db': Flags.boolean({
|
|
332
|
+
allowNo: true,
|
|
306
333
|
description: 'Create and connect a CLI-managed built-in database for the app',
|
|
307
334
|
default: false,
|
|
308
335
|
}),
|
|
@@ -368,7 +395,7 @@ export default class Install extends Command {
|
|
|
368
395
|
type: 'text',
|
|
369
396
|
message: installText('prompts.appPort.message'),
|
|
370
397
|
placeholder: installText('prompts.appPort.placeholder'),
|
|
371
|
-
validate:
|
|
398
|
+
validate: Install.validateAppPort,
|
|
372
399
|
},
|
|
373
400
|
storagePath: {
|
|
374
401
|
type: 'text',
|
|
@@ -428,7 +455,7 @@ export default class Install extends Command {
|
|
|
428
455
|
placeholder: installText('prompts.dbPort.placeholder'),
|
|
429
456
|
initialValue: (values) => defaultDbPortForDialect(values.dbDialect),
|
|
430
457
|
required: true,
|
|
431
|
-
validate:
|
|
458
|
+
validate: Install.validateDbPort,
|
|
432
459
|
hidden: (values) => Boolean(values.builtinDb)
|
|
433
460
|
&& String(values.source ?? '').trim() === 'docker',
|
|
434
461
|
},
|
|
@@ -486,7 +513,7 @@ export default class Install extends Command {
|
|
|
486
513
|
* App catalog with `env` seeded into `out` first so `storagePath`’s `initialValue(values)`
|
|
487
514
|
* sees `values.env` (same iteration order as {@link runPromptCatalog}).
|
|
488
515
|
*/
|
|
489
|
-
static buildAppPromptsCatalog(seedEnv) {
|
|
516
|
+
static buildAppPromptsCatalog(seedEnv, options) {
|
|
490
517
|
return {
|
|
491
518
|
seedEnv: {
|
|
492
519
|
type: 'run',
|
|
@@ -494,12 +521,27 @@ export default class Install extends Command {
|
|
|
494
521
|
values.env = seedEnv;
|
|
495
522
|
},
|
|
496
523
|
},
|
|
524
|
+
seedResume: {
|
|
525
|
+
type: 'run',
|
|
526
|
+
run: (values) => {
|
|
527
|
+
const record = values;
|
|
528
|
+
record.resume = Boolean(options?.resume);
|
|
529
|
+
},
|
|
530
|
+
},
|
|
497
531
|
...Install.appPrompts,
|
|
498
532
|
};
|
|
499
533
|
}
|
|
500
|
-
static buildDbPromptsCatalog(downloadResults) {
|
|
534
|
+
static buildDbPromptsCatalog(envName, downloadResults, options) {
|
|
501
535
|
const source = String(downloadResults.source ?? '').trim();
|
|
502
536
|
return {
|
|
537
|
+
seedEnv: {
|
|
538
|
+
type: 'run',
|
|
539
|
+
run: (values) => {
|
|
540
|
+
if (envName) {
|
|
541
|
+
values.env = envName;
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
},
|
|
503
545
|
seedDownloadSource: {
|
|
504
546
|
type: 'run',
|
|
505
547
|
run: (values) => {
|
|
@@ -508,6 +550,13 @@ export default class Install extends Command {
|
|
|
508
550
|
}
|
|
509
551
|
},
|
|
510
552
|
},
|
|
553
|
+
seedResume: {
|
|
554
|
+
type: 'run',
|
|
555
|
+
run: (values) => {
|
|
556
|
+
const record = values;
|
|
557
|
+
record.resume = Boolean(options?.resume);
|
|
558
|
+
},
|
|
559
|
+
},
|
|
511
560
|
...Install.dbPrompts,
|
|
512
561
|
};
|
|
513
562
|
}
|
|
@@ -527,6 +576,25 @@ export default class Install extends Command {
|
|
|
527
576
|
static buildPresetValuesFromFlags(flags) {
|
|
528
577
|
const preset = {};
|
|
529
578
|
const argv = process.argv.slice(2);
|
|
579
|
+
const apiBaseUrl = Install.toOptionalPromptString(flags['api-base-url']);
|
|
580
|
+
if (apiBaseUrl) {
|
|
581
|
+
preset.apiBaseUrl = apiBaseUrl;
|
|
582
|
+
}
|
|
583
|
+
else if (flags['default-api-base-url'] !== undefined) {
|
|
584
|
+
const defaultApiBaseUrl = Install.toOptionalPromptString(flags['default-api-base-url']);
|
|
585
|
+
if (defaultApiBaseUrl) {
|
|
586
|
+
preset.apiBaseUrl = defaultApiBaseUrl;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
if (flags['auth-type'] !== undefined) {
|
|
590
|
+
const authType = Install.toOptionalPromptString(flags['auth-type']);
|
|
591
|
+
if (authType) {
|
|
592
|
+
preset.authType = authType;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if (flags['access-token'] !== undefined || flags.token !== undefined) {
|
|
596
|
+
preset.accessToken = String(flags['access-token'] ?? flags.token ?? '');
|
|
597
|
+
}
|
|
530
598
|
if (flags.lang !== undefined) {
|
|
531
599
|
const v = String(flags.lang).trim();
|
|
532
600
|
if (v) {
|
|
@@ -569,7 +637,7 @@ export default class Install extends Command {
|
|
|
569
637
|
if (argvHasToken(argv, ['--fetch-source'])) {
|
|
570
638
|
preset.fetchSource = flags['fetch-source'];
|
|
571
639
|
}
|
|
572
|
-
if (argvHasToken(argv, ['--builtin-db'])) {
|
|
640
|
+
if (argvHasToken(argv, ['--builtin-db', '--no-builtin-db'])) {
|
|
573
641
|
preset.builtinDb = flags['builtin-db'];
|
|
574
642
|
}
|
|
575
643
|
if (flags['db-dialect'] !== undefined) {
|
|
@@ -588,6 +656,7 @@ export default class Install extends Command {
|
|
|
588
656
|
const v = String(flags['db-host'] ?? '').trim();
|
|
589
657
|
if (v) {
|
|
590
658
|
preset.dbHost = v;
|
|
659
|
+
preset.builtinDb = false;
|
|
591
660
|
}
|
|
592
661
|
}
|
|
593
662
|
if (flags['db-port'] !== undefined) {
|
|
@@ -643,6 +712,13 @@ export default class Install extends Command {
|
|
|
643
712
|
'rootNickname',
|
|
644
713
|
]);
|
|
645
714
|
}
|
|
715
|
+
static buildEnvAddPresetValuesFromFlags(flags) {
|
|
716
|
+
return pickPresetKeys(Install.buildPresetValuesFromFlags(flags), [
|
|
717
|
+
'apiBaseUrl',
|
|
718
|
+
'authType',
|
|
719
|
+
'accessToken',
|
|
720
|
+
]);
|
|
721
|
+
}
|
|
646
722
|
static toOptionalPromptString(value) {
|
|
647
723
|
if (value === undefined || value === null) {
|
|
648
724
|
return undefined;
|
|
@@ -650,6 +726,131 @@ export default class Install extends Command {
|
|
|
650
726
|
const text = String(value).trim();
|
|
651
727
|
return text || undefined;
|
|
652
728
|
}
|
|
729
|
+
static async validateAppPort(value, values) {
|
|
730
|
+
const formatError = validateTcpPort(value);
|
|
731
|
+
if (formatError) {
|
|
732
|
+
return formatError;
|
|
733
|
+
}
|
|
734
|
+
return await Install.validateResumeAwareTcpPort(value, values, 'app');
|
|
735
|
+
}
|
|
736
|
+
static async validateDbPort(value, values) {
|
|
737
|
+
const formatError = validateTcpPort(value);
|
|
738
|
+
if (formatError) {
|
|
739
|
+
return formatError;
|
|
740
|
+
}
|
|
741
|
+
const builtinDb = values.builtinDb === undefined ? true : Boolean(values.builtinDb);
|
|
742
|
+
const source = String(values.source ?? '').trim();
|
|
743
|
+
if (!builtinDb || source === 'docker') {
|
|
744
|
+
return undefined;
|
|
745
|
+
}
|
|
746
|
+
return await Install.validateResumeAwareTcpPort(value, values, 'db');
|
|
747
|
+
}
|
|
748
|
+
static async validateResumeAwareTcpPort(value, values, target) {
|
|
749
|
+
const portError = await validateAvailableTcpPort(value);
|
|
750
|
+
if (!portError) {
|
|
751
|
+
return undefined;
|
|
752
|
+
}
|
|
753
|
+
const context = await Install.readResumePortValidationContext(values);
|
|
754
|
+
if (!context) {
|
|
755
|
+
return portError;
|
|
756
|
+
}
|
|
757
|
+
const port = Install.toOptionalPromptString(value);
|
|
758
|
+
if (!port) {
|
|
759
|
+
return portError;
|
|
760
|
+
}
|
|
761
|
+
const reusesManagedPort = await Install.isResumeManagedPortReuse({
|
|
762
|
+
target,
|
|
763
|
+
port,
|
|
764
|
+
context,
|
|
765
|
+
});
|
|
766
|
+
return reusesManagedPort ? undefined : portError;
|
|
767
|
+
}
|
|
768
|
+
static async readResumePortValidationContext(values) {
|
|
769
|
+
if (!Boolean(values.resume)) {
|
|
770
|
+
return undefined;
|
|
771
|
+
}
|
|
772
|
+
const envName = Install.toOptionalPromptString(values.env);
|
|
773
|
+
if (!envName) {
|
|
774
|
+
return undefined;
|
|
775
|
+
}
|
|
776
|
+
const source = Install.toOptionalPromptString(values.source);
|
|
777
|
+
const builtinDb = values.builtinDb === undefined ? undefined : Boolean(values.builtinDb);
|
|
778
|
+
const dbDialect = Install.toOptionalPromptString(values.dbDialect);
|
|
779
|
+
const appRootPath = Install.toOptionalPromptString(values.appRootPath);
|
|
780
|
+
const workspaceName = Install.toOptionalPromptString(values.workspaceName)
|
|
781
|
+
?? await Install.resolveResumeWorkspaceName(envName);
|
|
782
|
+
return {
|
|
783
|
+
envName,
|
|
784
|
+
...(workspaceName ? { workspaceName } : {}),
|
|
785
|
+
...(source ? { source } : {}),
|
|
786
|
+
...(builtinDb !== undefined ? { builtinDb } : {}),
|
|
787
|
+
...(dbDialect ? { dbDialect } : {}),
|
|
788
|
+
...(appRootPath ? { appRootPath } : {}),
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
static async resolveResumeWorkspaceName(envName) {
|
|
792
|
+
if (!envName) {
|
|
793
|
+
return undefined;
|
|
794
|
+
}
|
|
795
|
+
const config = await loadAuthConfig({ scope: resolveDefaultConfigScope() });
|
|
796
|
+
const stored = String(config.name ?? '').trim();
|
|
797
|
+
return stored || Install.defaultWorkspaceName();
|
|
798
|
+
}
|
|
799
|
+
static async isResumeManagedPortReuse(params) {
|
|
800
|
+
if (params.target === 'app') {
|
|
801
|
+
if ((params.context.source === 'npm' || params.context.source === 'git')
|
|
802
|
+
&& params.context.appRootPath) {
|
|
803
|
+
return await Install.isLocalPm2ProcessUsingPort(params.context.appRootPath, params.port);
|
|
804
|
+
}
|
|
805
|
+
const containerName = Install.buildDockerAppContainerName(params.context.envName, params.context.workspaceName);
|
|
806
|
+
return await Install.isDockerContainerPublishingPort(containerName, params.port);
|
|
807
|
+
}
|
|
808
|
+
if (!params.context.builtinDb || params.context.source === 'docker') {
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
811
|
+
const containerName = Install.buildBuiltinDbContainerName(params.context.envName, params.context.dbDialect ?? 'postgres', params.context.workspaceName);
|
|
812
|
+
return await Install.isDockerContainerPublishingPort(containerName, params.port);
|
|
813
|
+
}
|
|
814
|
+
static async isDockerContainerPublishingPort(containerName, port) {
|
|
815
|
+
if (!containerName || !port) {
|
|
816
|
+
return false;
|
|
817
|
+
}
|
|
818
|
+
const exists = await commandSucceeds('docker', [
|
|
819
|
+
'container',
|
|
820
|
+
'inspect',
|
|
821
|
+
containerName,
|
|
822
|
+
]);
|
|
823
|
+
if (!exists) {
|
|
824
|
+
return false;
|
|
825
|
+
}
|
|
826
|
+
try {
|
|
827
|
+
const output = await commandOutput('docker', ['port', containerName]);
|
|
828
|
+
return output
|
|
829
|
+
.split(/\r?\n/)
|
|
830
|
+
.some((line) => line.includes(`:${port}`));
|
|
831
|
+
}
|
|
832
|
+
catch {
|
|
833
|
+
return false;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
static async isLocalPm2ProcessUsingPort(appRootPath, port) {
|
|
837
|
+
const cwd = resolveConfiguredEnvPath(appRootPath);
|
|
838
|
+
if (!cwd) {
|
|
839
|
+
return false;
|
|
840
|
+
}
|
|
841
|
+
try {
|
|
842
|
+
const output = await commandOutput('pm2', ['jlist'], { cwd });
|
|
843
|
+
const rows = JSON.parse(output);
|
|
844
|
+
return rows.some((row) => {
|
|
845
|
+
const pmCwd = Install.toOptionalPromptString(row.pm2_env?.pm_cwd);
|
|
846
|
+
const appPort = Install.toOptionalPromptString(row.pm2_env?.env?.APP_PORT);
|
|
847
|
+
return Boolean(pmCwd && appPort && pmCwd === cwd && appPort === port);
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
catch {
|
|
851
|
+
return false;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
653
854
|
static buildResumePresetValues(env) {
|
|
654
855
|
const envName = String(env.name ?? '').trim();
|
|
655
856
|
const config = env.config ?? {};
|
|
@@ -669,6 +870,10 @@ export default class Install extends Command {
|
|
|
669
870
|
const dbUser = Install.toOptionalPromptString(config.dbUser);
|
|
670
871
|
const dbPassword = Install.toOptionalPromptString(config.dbPassword);
|
|
671
872
|
const builtinDbImage = Install.toOptionalPromptString(config.builtinDbImage);
|
|
873
|
+
const rootUsername = Install.toOptionalPromptString(config.rootUsername);
|
|
874
|
+
const rootEmail = Install.toOptionalPromptString(config.rootEmail);
|
|
875
|
+
const rootPassword = Install.toOptionalPromptString(config.rootPassword);
|
|
876
|
+
const rootNickname = Install.toOptionalPromptString(config.rootNickname);
|
|
672
877
|
const auth = config.auth;
|
|
673
878
|
const appPreset = {
|
|
674
879
|
...(appRootPath ? { appRootPath } : {}),
|
|
@@ -682,7 +887,14 @@ export default class Install extends Command {
|
|
|
682
887
|
};
|
|
683
888
|
const downloadPreset = {
|
|
684
889
|
...(source ? { source } : {}),
|
|
685
|
-
...(downloadVersion
|
|
890
|
+
...(downloadVersion
|
|
891
|
+
? {
|
|
892
|
+
version: downloadVersionPromptValue(downloadVersion),
|
|
893
|
+
...(downloadVersionPromptValue(downloadVersion) === 'other'
|
|
894
|
+
? { otherVersion: downloadVersion }
|
|
895
|
+
: {}),
|
|
896
|
+
}
|
|
897
|
+
: {}),
|
|
686
898
|
...(dockerRegistry ? { dockerRegistry } : {}),
|
|
687
899
|
...(dockerPlatform ? { dockerPlatform } : {}),
|
|
688
900
|
...(gitUrl ? { gitUrl } : {}),
|
|
@@ -703,6 +915,12 @@ export default class Install extends Command {
|
|
|
703
915
|
...(dbUser ? { dbUser } : {}),
|
|
704
916
|
...(dbPassword ? { dbPassword } : {}),
|
|
705
917
|
};
|
|
918
|
+
const rootPreset = {
|
|
919
|
+
...(rootUsername ? { rootUsername } : {}),
|
|
920
|
+
...(rootEmail ? { rootEmail } : {}),
|
|
921
|
+
...(rootPassword ? { rootPassword } : {}),
|
|
922
|
+
...(rootNickname ? { rootNickname } : {}),
|
|
923
|
+
};
|
|
706
924
|
const envAddPreset = {};
|
|
707
925
|
if (auth?.type === 'token') {
|
|
708
926
|
envAddPreset.authType = 'token';
|
|
@@ -720,6 +938,7 @@ export default class Install extends Command {
|
|
|
720
938
|
appPreset,
|
|
721
939
|
downloadPreset,
|
|
722
940
|
dbPreset,
|
|
941
|
+
rootPreset,
|
|
723
942
|
envAddPreset,
|
|
724
943
|
};
|
|
725
944
|
}
|
|
@@ -746,7 +965,7 @@ export default class Install extends Command {
|
|
|
746
965
|
if (!parsed.resume) {
|
|
747
966
|
return undefined;
|
|
748
967
|
}
|
|
749
|
-
const env = await getEnv(parsed.env, { scope:
|
|
968
|
+
const env = await getEnv(parsed.env, { scope: resolveDefaultConfigScope() });
|
|
750
969
|
if (!env) {
|
|
751
970
|
throw new Error(formatMissingManagedAppEnvMessage(parsed.env));
|
|
752
971
|
}
|
|
@@ -756,7 +975,7 @@ export default class Install extends Command {
|
|
|
756
975
|
throw new Error([
|
|
757
976
|
`Cannot continue setup for "${env.name}" in non-interactive resume mode yet.`,
|
|
758
977
|
`These setup-only flags are not saved in the env config: ${missingFlags.join(', ')}`,
|
|
759
|
-
`Run \`nb
|
|
978
|
+
`Run \`nb init --env ${env.name} --resume\` without \`--yes\`, or pass those flags again.`,
|
|
760
979
|
].join('\n'));
|
|
761
980
|
}
|
|
762
981
|
}
|
|
@@ -861,7 +1080,11 @@ export default class Install extends Command {
|
|
|
861
1080
|
preset.source = String(flags.source).trim();
|
|
862
1081
|
}
|
|
863
1082
|
if (flags.version !== undefined) {
|
|
864
|
-
|
|
1083
|
+
const version = String(flags.version).trim() || 'latest';
|
|
1084
|
+
preset.version = downloadVersionPromptValue(version);
|
|
1085
|
+
if (preset.version === 'other') {
|
|
1086
|
+
preset.otherVersion = version;
|
|
1087
|
+
}
|
|
865
1088
|
}
|
|
866
1089
|
if (flags['docker-registry'] !== undefined) {
|
|
867
1090
|
const value = String(flags['docker-registry'] ?? '').trim();
|
|
@@ -891,7 +1114,10 @@ export default class Install extends Command {
|
|
|
891
1114
|
preset.npmRegistry =
|
|
892
1115
|
typeof flags['npm-registry'] === 'string' ? flags['npm-registry'] : '';
|
|
893
1116
|
}
|
|
894
|
-
if (argvHasToken(argv, ['--replace', '-r'])) {
|
|
1117
|
+
if (flags.resume && !argvHasToken(argv, ['--replace', '-r'])) {
|
|
1118
|
+
preset.replace = true;
|
|
1119
|
+
}
|
|
1120
|
+
else if (argvHasToken(argv, ['--replace', '-r'])) {
|
|
895
1121
|
preset.replace = flags.replace;
|
|
896
1122
|
}
|
|
897
1123
|
if (argvHasToken(argv, ['--dev-dependencies', '--no-dev-dependencies', '-D'])) {
|
|
@@ -923,7 +1149,7 @@ export default class Install extends Command {
|
|
|
923
1149
|
return normalized || 'nocobase';
|
|
924
1150
|
}
|
|
925
1151
|
static defaultWorkspaceName() {
|
|
926
|
-
return Install.sanitizeDockerResourceName(`nb-${path.basename(
|
|
1152
|
+
return Install.sanitizeDockerResourceName(`nb-${path.basename(resolveEnvRoot(resolveDefaultConfigScope()))}`);
|
|
927
1153
|
}
|
|
928
1154
|
static buildBuiltinDbResourcePrefix(envName, workspaceName) {
|
|
929
1155
|
void envName;
|
|
@@ -933,7 +1159,7 @@ export default class Install extends Command {
|
|
|
933
1159
|
: Install.defaultWorkspaceName();
|
|
934
1160
|
}
|
|
935
1161
|
static async ensureWorkspaceName() {
|
|
936
|
-
return await ensureWorkspaceName(Install.defaultWorkspaceName(), { scope:
|
|
1162
|
+
return await ensureWorkspaceName(Install.defaultWorkspaceName(), { scope: resolveDefaultConfigScope() });
|
|
937
1163
|
}
|
|
938
1164
|
static buildBuiltinDbNetworkName(envName, workspaceName) {
|
|
939
1165
|
return Install.buildBuiltinDbResourcePrefix(envName, workspaceName);
|
|
@@ -982,9 +1208,11 @@ export default class Install extends Command {
|
|
|
982
1208
|
&& dbHostInput !== 'localhost'
|
|
983
1209
|
? dbHostInput
|
|
984
1210
|
: containerName);
|
|
1211
|
+
const storagePath = resolveConfiguredEnvPath(params.storagePath)
|
|
1212
|
+
?? resolveEnvRelativePath(defaultInstallStoragePath(params.envName));
|
|
985
1213
|
if (dbDialect === 'postgres') {
|
|
986
1214
|
const image = String(params.builtinDbImage ?? '').trim() || defaultBuiltinDbImageForDialect(dbDialect);
|
|
987
|
-
const dataDir = path.resolve(
|
|
1215
|
+
const dataDir = path.resolve(storagePath, 'db', 'postgres');
|
|
988
1216
|
const args = [
|
|
989
1217
|
'run',
|
|
990
1218
|
'-d',
|
|
@@ -1028,7 +1256,7 @@ export default class Install extends Command {
|
|
|
1028
1256
|
}
|
|
1029
1257
|
if (dbDialect === 'mysql') {
|
|
1030
1258
|
const image = String(params.builtinDbImage ?? '').trim() || defaultBuiltinDbImageForDialect(dbDialect);
|
|
1031
|
-
const dataDir = path.resolve(
|
|
1259
|
+
const dataDir = path.resolve(storagePath, 'db', 'mysql');
|
|
1032
1260
|
const dbUser = String(params.dbUser ?? DEFAULT_INSTALL_DB_USER).trim() || DEFAULT_INSTALL_DB_USER;
|
|
1033
1261
|
const dbDatabase = String(params.dbDatabase ?? defaultDbDatabase).trim() || defaultDbDatabase;
|
|
1034
1262
|
const dbPassword = String(params.dbPassword ?? DEFAULT_INSTALL_DB_PASSWORD) || DEFAULT_INSTALL_DB_PASSWORD;
|
|
@@ -1074,7 +1302,7 @@ export default class Install extends Command {
|
|
|
1074
1302
|
}
|
|
1075
1303
|
if (dbDialect === 'mariadb') {
|
|
1076
1304
|
const image = String(params.builtinDbImage ?? '').trim() || defaultBuiltinDbImageForDialect(dbDialect);
|
|
1077
|
-
const dataDir = path.resolve(
|
|
1305
|
+
const dataDir = path.resolve(storagePath, 'db', 'mariadb');
|
|
1078
1306
|
const dbUser = String(params.dbUser ?? DEFAULT_INSTALL_DB_USER).trim() || DEFAULT_INSTALL_DB_USER;
|
|
1079
1307
|
const dbDatabase = String(params.dbDatabase ?? defaultDbDatabase).trim() || defaultDbDatabase;
|
|
1080
1308
|
const dbPassword = String(params.dbPassword ?? DEFAULT_INSTALL_DB_PASSWORD) || DEFAULT_INSTALL_DB_PASSWORD;
|
|
@@ -1120,7 +1348,7 @@ export default class Install extends Command {
|
|
|
1120
1348
|
}
|
|
1121
1349
|
if (dbDialect === 'kingbase') {
|
|
1122
1350
|
const image = String(params.builtinDbImage ?? '').trim() || defaultBuiltinDbImageForDialect(dbDialect);
|
|
1123
|
-
const dataDir = path.resolve(
|
|
1351
|
+
const dataDir = path.resolve(storagePath, 'db', 'kingbase');
|
|
1124
1352
|
const dbUser = String(params.dbUser ?? DEFAULT_INSTALL_DB_USER).trim() || DEFAULT_INSTALL_DB_USER;
|
|
1125
1353
|
const dbDatabase = String(params.dbDatabase ?? defaultDbDatabase).trim() || defaultDbDatabase;
|
|
1126
1354
|
const dbPassword = String(params.dbPassword ?? DEFAULT_INSTALL_DB_PASSWORD) || DEFAULT_INSTALL_DB_PASSWORD;
|
|
@@ -1269,12 +1497,12 @@ export default class Install extends Command {
|
|
|
1269
1497
|
});
|
|
1270
1498
|
p.log.step(`Preparing built-in ${plan.dbDialect} database`);
|
|
1271
1499
|
await this.ensureDockerNetwork(plan.networkName);
|
|
1272
|
-
await this.removeDockerContainerIfForced({
|
|
1500
|
+
const existingContainerKept = await this.removeDockerContainerIfForced({
|
|
1273
1501
|
containerName: plan.containerName,
|
|
1274
1502
|
displayName: `built-in ${plan.dbDialect} container`,
|
|
1275
1503
|
force: params.force,
|
|
1276
1504
|
});
|
|
1277
|
-
if (Install.shouldPublishBuiltinDbPort(params.downloadResults.source)) {
|
|
1505
|
+
if (!existingContainerKept && Install.shouldPublishBuiltinDbPort(params.downloadResults.source)) {
|
|
1278
1506
|
const portError = await validateAvailableTcpPort(plan.dbPort);
|
|
1279
1507
|
if (portError) {
|
|
1280
1508
|
throw new Error(`Built-in ${plan.dbDialect} needs host port ${plan.dbPort}, but ${portError}`);
|
|
@@ -1291,8 +1519,9 @@ export default class Install extends Command {
|
|
|
1291
1519
|
|| defaultDockerRegistryForLang(process.env.NB_LOCALE);
|
|
1292
1520
|
const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || 'latest';
|
|
1293
1521
|
const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT;
|
|
1294
|
-
const storagePath =
|
|
1295
|
-
|| defaultInstallStoragePath(params.envName))
|
|
1522
|
+
const storagePath = resolveConfiguredEnvPath(String(params.appResults.storagePath ?? '').trim()
|
|
1523
|
+
|| defaultInstallStoragePath(params.envName))
|
|
1524
|
+
?? resolveEnvRelativePath(defaultInstallStoragePath(params.envName));
|
|
1296
1525
|
const dbDialect = String(params.dbResults.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
1297
1526
|
const dbHost = String(params.dbResults.dbHost ?? DEFAULT_INSTALL_DB_HOST).trim() || DEFAULT_INSTALL_DB_HOST;
|
|
1298
1527
|
const dbPort = String(params.dbResults.dbPort ?? defaultDbPortForDialect(dbDialect)).trim()
|
|
@@ -1387,12 +1616,16 @@ export default class Install extends Command {
|
|
|
1387
1616
|
}
|
|
1388
1617
|
static buildDownloadArgvFromResults(results, options) {
|
|
1389
1618
|
const argv = ['-y', '--no-intro'];
|
|
1619
|
+
const source = String(results.source ?? '').trim();
|
|
1390
1620
|
if (options?.verbose) {
|
|
1391
1621
|
argv.push('--verbose');
|
|
1392
1622
|
}
|
|
1393
1623
|
Install.pushDownloadArgIfValue(argv, '--source', results.source);
|
|
1394
|
-
Install.pushDownloadArgIfValue(argv, '--version', results
|
|
1395
|
-
Install.pushDownloadArgIfValue(argv, '--output-dir',
|
|
1624
|
+
Install.pushDownloadArgIfValue(argv, '--version', downloadResultsValue(results, 'version'));
|
|
1625
|
+
Install.pushDownloadArgIfValue(argv, '--output-dir', source === 'npm' || source === 'git'
|
|
1626
|
+
? (resolveConfiguredEnvPath(results.outputDir)
|
|
1627
|
+
?? resolveConfiguredEnvPath(String(results.outputDir ?? '').trim() || defaultInstallAppRootPath(results.env)))
|
|
1628
|
+
: results.outputDir);
|
|
1396
1629
|
Install.pushDownloadArgIfValue(argv, '--git-url', results.gitUrl);
|
|
1397
1630
|
Install.pushDownloadArgIfValue(argv, '--docker-registry', results.dockerRegistry);
|
|
1398
1631
|
Install.pushDownloadArgIfValue(argv, '--docker-platform', results.dockerPlatform);
|
|
@@ -1422,7 +1655,12 @@ export default class Install extends Command {
|
|
|
1422
1655
|
const outputDir = String(params.downloadResults.outputDir ?? '').trim()
|
|
1423
1656
|
|| String(params.appResults.appRootPath ?? '').trim()
|
|
1424
1657
|
|| defaultInstallAppRootPath(params.envName);
|
|
1425
|
-
return
|
|
1658
|
+
return resolveConfiguredEnvPath(outputDir) ?? resolveEnvRelativePath(defaultInstallAppRootPath(params.envName));
|
|
1659
|
+
}
|
|
1660
|
+
static resolveLocalProjectConfigPath(params) {
|
|
1661
|
+
return (String(params.downloadResults.outputDir ?? '').trim()
|
|
1662
|
+
|| String(params.appResults.appRootPath ?? '').trim()
|
|
1663
|
+
|| defaultInstallAppRootPath(params.envName));
|
|
1426
1664
|
}
|
|
1427
1665
|
commandStdio(verbose) {
|
|
1428
1666
|
return verbose ? 'inherit' : 'ignore';
|
|
@@ -1435,25 +1673,31 @@ export default class Install extends Command {
|
|
|
1435
1673
|
p.log.step(source === 'docker'
|
|
1436
1674
|
? 'Downloading Docker image'
|
|
1437
1675
|
: 'Downloading local NocoBase app files');
|
|
1438
|
-
return await this.config.runCommand('download', argv);
|
|
1676
|
+
return await this.config.runCommand('source:download', argv);
|
|
1439
1677
|
}
|
|
1440
1678
|
async downloadLocalApp(params) {
|
|
1441
1679
|
const result = await this.downloadManagedSource({
|
|
1442
1680
|
downloadResults: params.downloadResults,
|
|
1443
1681
|
verbose: params.verbose,
|
|
1444
1682
|
});
|
|
1445
|
-
const
|
|
1683
|
+
const downloadedProjectRoot = Install.resolveLocalProjectRoot({
|
|
1446
1684
|
envName: params.envName,
|
|
1447
1685
|
appResults: params.appResults,
|
|
1448
1686
|
downloadResults: params.downloadResults,
|
|
1449
1687
|
downloadCommandResult: result,
|
|
1450
1688
|
});
|
|
1451
|
-
params.appResults.appRootPath =
|
|
1452
|
-
|
|
1689
|
+
params.appResults.appRootPath = Install.resolveLocalProjectConfigPath({
|
|
1690
|
+
envName: params.envName,
|
|
1691
|
+
appResults: params.appResults,
|
|
1692
|
+
downloadResults: params.downloadResults,
|
|
1693
|
+
});
|
|
1694
|
+
return downloadedProjectRoot;
|
|
1453
1695
|
}
|
|
1454
1696
|
static buildLocalAppEnvVars(params) {
|
|
1455
|
-
const
|
|
1456
|
-
|| defaultInstallStoragePath(params.envName)
|
|
1697
|
+
const configuredStoragePath = String(params.appResults.storagePath ?? '').trim()
|
|
1698
|
+
|| defaultInstallStoragePath(params.envName);
|
|
1699
|
+
const storagePath = resolveConfiguredEnvPath(configuredStoragePath)
|
|
1700
|
+
?? resolveEnvRelativePath(defaultInstallStoragePath(params.envName));
|
|
1457
1701
|
const dbDialect = String(params.dbResults.dbDialect ?? 'postgres').trim()
|
|
1458
1702
|
|| 'postgres';
|
|
1459
1703
|
const appKey = crypto.randomBytes(32).toString('hex');
|
|
@@ -1618,21 +1862,20 @@ export default class Install extends Command {
|
|
|
1618
1862
|
throw new Error(`The application did not become ready in time. Expected \`${healthCheckUrl}\` to respond with \`ok\`, but the last status was: ${Install.formatHealthCheckMessage(lastMessage)}.${logHint}`);
|
|
1619
1863
|
}
|
|
1620
1864
|
async saveInstalledEnv(params) {
|
|
1621
|
-
await
|
|
1622
|
-
}
|
|
1623
|
-
static pushArgIfValue(argv, flag, value) {
|
|
1624
|
-
const text = String(value ?? '').trim();
|
|
1625
|
-
if (text) {
|
|
1626
|
-
argv.push(flag, text);
|
|
1627
|
-
}
|
|
1865
|
+
await upsertEnv(params.envName, Install.buildSavedEnvConfig(params), { scope: resolveDefaultConfigScope() });
|
|
1628
1866
|
}
|
|
1629
|
-
|
|
1630
|
-
if (
|
|
1867
|
+
async syncInstalledEnvConnection(params) {
|
|
1868
|
+
if (!params.appReady) {
|
|
1631
1869
|
return;
|
|
1632
1870
|
}
|
|
1633
|
-
|
|
1871
|
+
const authType = String(params.envAddResults.authType ?? 'oauth').trim()
|
|
1872
|
+
|| 'oauth';
|
|
1873
|
+
if (authType === 'oauth') {
|
|
1874
|
+
await this.config.runCommand('env:auth', [params.envName]);
|
|
1875
|
+
}
|
|
1876
|
+
await this.config.runCommand('env:update', [params.envName]);
|
|
1634
1877
|
}
|
|
1635
|
-
static
|
|
1878
|
+
static buildSavedEnvConfig(params) {
|
|
1636
1879
|
const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim()
|
|
1637
1880
|
|| DEFAULT_INSTALL_APP_PORT;
|
|
1638
1881
|
const storagePath = String(params.appResults.storagePath ?? '').trim()
|
|
@@ -1643,44 +1886,37 @@ export default class Install extends Command {
|
|
|
1643
1886
|
});
|
|
1644
1887
|
const authType = String(params.envAddResults.authType ?? 'oauth').trim()
|
|
1645
1888
|
|| 'oauth';
|
|
1646
|
-
|
|
1647
|
-
params.envName,
|
|
1648
|
-
'--no-intro',
|
|
1649
|
-
'--scope',
|
|
1650
|
-
CONFIG_SCOPE,
|
|
1651
|
-
'--api-base-url',
|
|
1889
|
+
return buildStoredEnvConfig({
|
|
1652
1890
|
apiBaseUrl,
|
|
1653
|
-
'--auth-type',
|
|
1654
1891
|
authType,
|
|
1655
|
-
|
|
1892
|
+
accessToken: params.envAddResults.accessToken,
|
|
1893
|
+
source: downloadResultsValue(params.downloadResults, 'source'),
|
|
1894
|
+
downloadVersion: downloadResultsValue(params.downloadResults, 'version'),
|
|
1895
|
+
dockerRegistry: downloadResultsValue(params.downloadResults, 'dockerRegistry'),
|
|
1896
|
+
dockerPlatform: downloadResultsValue(params.downloadResults, 'dockerPlatform'),
|
|
1897
|
+
gitUrl: downloadResultsValue(params.downloadResults, 'gitUrl'),
|
|
1898
|
+
npmRegistry: downloadResultsValue(params.downloadResults, 'npmRegistry'),
|
|
1899
|
+
devDependencies: downloadResultsValue(params.downloadResults, 'devDependencies'),
|
|
1900
|
+
build: downloadResultsValue(params.downloadResults, 'build'),
|
|
1901
|
+
buildDts: downloadResultsValue(params.downloadResults, 'buildDts'),
|
|
1902
|
+
appRootPath: params.appResults.appRootPath,
|
|
1656
1903
|
appPort,
|
|
1657
|
-
'--storage-path',
|
|
1658
1904
|
storagePath,
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
Install.pushArgIfValue(argv, '--builtin-db-image', params.dbResults.builtinDbImage);
|
|
1675
|
-
Install.pushArgIfValue(argv, '--db-host', params.dbResults.dbHost);
|
|
1676
|
-
Install.pushArgIfValue(argv, '--db-port', params.dbResults.dbPort);
|
|
1677
|
-
Install.pushArgIfValue(argv, '--db-database', params.dbResults.dbDatabase);
|
|
1678
|
-
Install.pushArgIfValue(argv, '--db-user', params.dbResults.dbUser);
|
|
1679
|
-
Install.pushArgIfValue(argv, '--db-password', params.dbResults.dbPassword);
|
|
1680
|
-
if (authType === 'token') {
|
|
1681
|
-
argv.push('--access-token', String(params.envAddResults.accessToken ?? ''));
|
|
1682
|
-
}
|
|
1683
|
-
return argv;
|
|
1905
|
+
appKey: params.appResults.appKey,
|
|
1906
|
+
timezone: params.appResults.timeZone,
|
|
1907
|
+
builtinDb: params.dbResults.builtinDb,
|
|
1908
|
+
dbDialect: params.dbResults.dbDialect,
|
|
1909
|
+
builtinDbImage: params.dbResults.builtinDbImage,
|
|
1910
|
+
dbHost: params.dbResults.dbHost,
|
|
1911
|
+
dbPort: params.dbResults.dbPort,
|
|
1912
|
+
dbDatabase: params.dbResults.dbDatabase,
|
|
1913
|
+
dbUser: params.dbResults.dbUser,
|
|
1914
|
+
dbPassword: params.dbResults.dbPassword,
|
|
1915
|
+
rootUsername: params.rootResults.rootUsername,
|
|
1916
|
+
rootEmail: params.rootResults.rootEmail,
|
|
1917
|
+
rootPassword: params.rootResults.rootPassword,
|
|
1918
|
+
rootNickname: params.rootResults.rootNickname,
|
|
1919
|
+
});
|
|
1684
1920
|
}
|
|
1685
1921
|
async collectPromptResults(parsed, yes) {
|
|
1686
1922
|
const resumePreset = await this.resolveResumePresetValues(parsed, yes);
|
|
@@ -1700,7 +1936,9 @@ export default class Install extends Command {
|
|
|
1700
1936
|
...(resumePreset?.appPreset ?? {}),
|
|
1701
1937
|
...Install.buildAppPresetValuesFromFlags(parsed),
|
|
1702
1938
|
};
|
|
1703
|
-
const appCatalog = Install.buildAppPromptsCatalog(envName
|
|
1939
|
+
const appCatalog = Install.buildAppPromptsCatalog(envName, {
|
|
1940
|
+
resume: parsed.resume,
|
|
1941
|
+
});
|
|
1704
1942
|
const appResults = await runPromptCatalog(appCatalog, {
|
|
1705
1943
|
initialValues: await Install.buildAppPromptInitialValues({
|
|
1706
1944
|
envName,
|
|
@@ -1715,6 +1953,7 @@ export default class Install extends Command {
|
|
|
1715
1953
|
},
|
|
1716
1954
|
}),
|
|
1717
1955
|
values: appPreset,
|
|
1956
|
+
yesInitialValues: { resume: parsed.resume },
|
|
1718
1957
|
yes,
|
|
1719
1958
|
});
|
|
1720
1959
|
let downloadResults = {};
|
|
@@ -1732,7 +1971,9 @@ export default class Install extends Command {
|
|
|
1732
1971
|
...(resumePreset?.dbPreset ?? {}),
|
|
1733
1972
|
...Install.buildDbPresetValuesFromFlags(parsed),
|
|
1734
1973
|
};
|
|
1735
|
-
const dbResults = await runPromptCatalog(Install.buildDbPromptsCatalog(downloadResults
|
|
1974
|
+
const dbResults = await runPromptCatalog(Install.buildDbPromptsCatalog(envName, downloadResults, {
|
|
1975
|
+
resume: parsed.resume,
|
|
1976
|
+
}), {
|
|
1736
1977
|
initialValues: {
|
|
1737
1978
|
...downloadResults,
|
|
1738
1979
|
...await Install.buildDbPromptInitialValues({
|
|
@@ -1751,7 +1992,10 @@ export default class Install extends Command {
|
|
|
1751
1992
|
const rootPreset = Install.buildRootPresetValuesFromFlags(parsed);
|
|
1752
1993
|
const rootResults = await runPromptCatalog(Install.rootUserPrompts, {
|
|
1753
1994
|
initialValues: {},
|
|
1754
|
-
values:
|
|
1995
|
+
values: {
|
|
1996
|
+
...(resumePreset?.rootPreset ?? {}),
|
|
1997
|
+
...rootPreset,
|
|
1998
|
+
},
|
|
1755
1999
|
yes,
|
|
1756
2000
|
});
|
|
1757
2001
|
const envAddResults = await runPromptCatalog(EnvAdd.prompts, {
|
|
@@ -1760,8 +2004,8 @@ export default class Install extends Command {
|
|
|
1760
2004
|
},
|
|
1761
2005
|
values: {
|
|
1762
2006
|
name: envName,
|
|
1763
|
-
scope: 'project',
|
|
1764
2007
|
...(resumePreset?.envAddPreset ?? {}),
|
|
2008
|
+
...Install.buildEnvAddPresetValuesFromFlags(parsed),
|
|
1765
2009
|
},
|
|
1766
2010
|
yes,
|
|
1767
2011
|
});
|
|
@@ -1800,6 +2044,16 @@ export default class Install extends Command {
|
|
|
1800
2044
|
const workspaceName = usesDockerResources
|
|
1801
2045
|
? await Install.ensureWorkspaceName()
|
|
1802
2046
|
: undefined;
|
|
2047
|
+
if (!parsed.resume) {
|
|
2048
|
+
await this.saveInstalledEnv({
|
|
2049
|
+
envName,
|
|
2050
|
+
appResults,
|
|
2051
|
+
downloadResults,
|
|
2052
|
+
dbResults,
|
|
2053
|
+
rootResults,
|
|
2054
|
+
envAddResults,
|
|
2055
|
+
});
|
|
2056
|
+
}
|
|
1803
2057
|
let builtinDbPlan;
|
|
1804
2058
|
if (Boolean(dbResults.builtinDb)) {
|
|
1805
2059
|
builtinDbPlan = await this.startBuiltinDb({
|
|
@@ -1841,6 +2095,7 @@ export default class Install extends Command {
|
|
|
1841
2095
|
appResults.timeZone = dockerAppPlan.timeZone;
|
|
1842
2096
|
}
|
|
1843
2097
|
else if (source === 'npm' || source === 'git') {
|
|
2098
|
+
const localSource = source === 'npm' ? 'npm' : 'git';
|
|
1844
2099
|
const projectRoot = await this.downloadLocalApp({
|
|
1845
2100
|
envName,
|
|
1846
2101
|
appResults,
|
|
@@ -1849,7 +2104,7 @@ export default class Install extends Command {
|
|
|
1849
2104
|
});
|
|
1850
2105
|
localAppPlan = await this.startLocalApp({
|
|
1851
2106
|
envName,
|
|
1852
|
-
source,
|
|
2107
|
+
source: localSource,
|
|
1853
2108
|
projectRoot,
|
|
1854
2109
|
appResults,
|
|
1855
2110
|
dbResults,
|
|
@@ -1871,12 +2126,20 @@ export default class Install extends Command {
|
|
|
1871
2126
|
containerName: dockerAppPlan?.containerName,
|
|
1872
2127
|
});
|
|
1873
2128
|
}
|
|
1874
|
-
|
|
2129
|
+
if (dockerAppPlan || localAppPlan || builtinDbPlan) {
|
|
2130
|
+
await this.saveInstalledEnv({
|
|
2131
|
+
envName,
|
|
2132
|
+
appResults,
|
|
2133
|
+
downloadResults,
|
|
2134
|
+
dbResults,
|
|
2135
|
+
rootResults,
|
|
2136
|
+
envAddResults,
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
await this.syncInstalledEnvConnection({
|
|
1875
2140
|
envName,
|
|
1876
|
-
appResults,
|
|
1877
|
-
downloadResults,
|
|
1878
|
-
dbResults,
|
|
1879
2141
|
envAddResults,
|
|
2142
|
+
appReady: Boolean(dockerAppPlan || localAppPlan),
|
|
1880
2143
|
});
|
|
1881
2144
|
p.outro(dockerAppPlan || localAppPlan
|
|
1882
2145
|
? `NocoBase is ready at http://127.0.0.1:${dockerAppPlan?.appPort ?? localAppPlan?.appPort}`
|
|
@@ -1884,5 +2147,8 @@ export default class Install extends Command {
|
|
|
1884
2147
|
}
|
|
1885
2148
|
}
|
|
1886
2149
|
function downloadResultsValue(downloadResults, key) {
|
|
2150
|
+
if (key === 'version' && String(downloadResults.version ?? '').trim() === 'other') {
|
|
2151
|
+
return downloadResults.otherVersion;
|
|
2152
|
+
}
|
|
1887
2153
|
return downloadResults[key];
|
|
1888
2154
|
}
|