@nocobase/cli 2.2.0-alpha.1 → 2.2.0-alpha.10
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/assets/env-proxy/nginx/snippets/proxy-location.conf +1 -0
- package/assets/env-proxy/nginx/snippets/uploads-location.conf +4 -1
- package/bin/early-locale.js +89 -0
- package/bin/node-version.js +35 -0
- package/bin/run.js +9 -0
- package/bin/windows-admin.js +60 -0
- package/dist/commands/app/destroy.js +4 -3
- package/dist/commands/app/restart.js +38 -0
- package/dist/commands/app/shared.js +49 -3
- package/dist/commands/app/start.js +95 -0
- package/dist/commands/app/upgrade.js +11 -0
- package/dist/commands/config/set.js +1 -0
- package/dist/commands/env/info.js +11 -1
- package/dist/commands/examples/prompts-stages.js +2 -2
- package/dist/commands/examples/prompts-test.js +2 -2
- package/dist/commands/init.js +152 -14
- package/dist/commands/install.js +256 -109
- package/dist/commands/license/activate.js +4 -1
- package/dist/commands/license/shared.js +24 -15
- package/dist/commands/portal/config.js +88 -0
- package/dist/commands/portal/create.js +104 -0
- package/dist/commands/portal/deploy.js +81 -0
- package/dist/commands/portal/destroy.js +104 -0
- package/dist/commands/portal/dev.js +71 -0
- package/dist/commands/portal/index.js +20 -0
- package/dist/commands/portal/info.js +82 -0
- package/dist/commands/portal/list.js +98 -0
- package/dist/commands/portal/pull.js +84 -0
- package/dist/commands/portal/push.js +79 -0
- package/dist/commands/proxy/caddy/generate.js +93 -7
- package/dist/commands/proxy/nginx/generate.js +98 -7
- package/dist/commands/revision/create.js +1 -1
- package/dist/commands/self/check.js +1 -1
- package/dist/commands/self/update.js +4 -4
- package/dist/commands/skills/check.js +4 -5
- package/dist/commands/skills/install.js +18 -1
- package/dist/commands/skills/update.js +19 -4
- package/dist/commands/source/dev.js +10 -6
- package/dist/commands/source/download.js +85 -16
- package/dist/lib/api-command-compat.js +51 -8
- package/dist/lib/app-managed-resources.js +104 -5
- package/dist/lib/auth-store.js +105 -13
- package/dist/lib/cli-config.js +93 -2
- package/dist/lib/docker-image.js +94 -6
- package/dist/lib/env-auth.js +291 -45
- package/dist/lib/env-config.js +14 -0
- package/dist/lib/env-proxy-config.js +48 -0
- package/dist/lib/env-proxy.js +266 -61
- package/dist/lib/hook-script.js +160 -0
- package/dist/lib/managed-init-env.js +6 -1
- package/dist/lib/portal-command-env.js +31 -0
- package/dist/lib/portal-config.js +133 -0
- package/dist/lib/portal-configure.js +117 -0
- package/dist/lib/portal-create.js +433 -0
- package/dist/lib/portal-deploy.js +283 -0
- package/dist/lib/portal-destroy.js +100 -0
- package/dist/lib/portal-dev.js +79 -0
- package/dist/lib/portal-env-files.js +53 -0
- package/dist/lib/portal-info.js +31 -0
- package/dist/lib/portal-list.js +211 -0
- package/dist/lib/portal-source.js +523 -0
- package/dist/lib/prompt-catalog-terminal.js +32 -19
- package/dist/lib/prompt-validators.js +1 -1
- package/dist/lib/prompt-web-ui.js +20 -13
- package/dist/lib/proxy-caddy.js +77 -9
- package/dist/lib/proxy-nginx.js +71 -11
- package/dist/lib/run-npm.js +21 -16
- package/dist/lib/self-manager.js +254 -46
- package/dist/lib/skills-manager.js +116 -23
- package/dist/lib/source-publish.js +2 -2
- package/dist/lib/startup-update.js +1 -1
- package/dist/lib/ui.js +28 -1
- package/dist/locale/en-US.json +227 -43
- package/dist/locale/zh-CN.json +227 -43
- package/package.json +11 -2
- package/scripts/build.mjs +0 -34
- package/scripts/clean.mjs +0 -9
- package/tsconfig.json +0 -19
package/dist/commands/install.js
CHANGED
|
@@ -13,11 +13,11 @@ import path from 'node:path';
|
|
|
13
13
|
import { exit } from 'node:process';
|
|
14
14
|
import { appendAppPublicPath } from '../lib/app-public-path.js';
|
|
15
15
|
import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
16
|
-
import { applyCliLocale, localeText,
|
|
16
|
+
import { applyCliLocale, localeText, translateCli } from "../lib/cli-locale.js";
|
|
17
17
|
import { resolveConfiguredEnvPath, resolveDefaultConfigScope, resolveEnvRoot, resolveEnvRelativePath, } from '../lib/cli-home.js';
|
|
18
|
-
import { defaultDockerContainerPrefix, defaultDockerNetworkName } from '../lib/app-runtime.js';
|
|
19
|
-
import { resolveDefaultApiHost, resolveDockerContainerPrefix, resolveDockerNetworkName } from '../lib/cli-config.js';
|
|
20
|
-
import { DEFAULT_DOCKER_VERSION, resolveDockerImageRef } from "../lib/docker-image.js";
|
|
18
|
+
import { defaultDockerContainerPrefix, defaultDockerNetworkName, managedAppLifecycleEnvVars, } from '../lib/app-runtime.js';
|
|
19
|
+
import { getCliConfigValue, resolveDefaultApiHost, resolveDockerContainerPrefix, resolveDockerNetworkName, } from '../lib/cli-config.js';
|
|
20
|
+
import { DEFAULT_DOCKER_VERSION, DEFAULT_NB_IMAGE_VARIANT, inferNbImageRegistryFromRepository, normalizeNbImageVariant, resolveBuiltinDbImage, resolveDockerImageContainerPort, resolveDockerImageRef, resolveOfficialDockerRegistry, } from "../lib/docker-image.js";
|
|
21
21
|
import { findAvailableTcpPort, validateAppPublicPath, validateAvailableTcpPort, validateTcpPort, validateEnvKey, } from "../lib/prompt-validators.js";
|
|
22
22
|
import { validateExternalDbConfig, validateMysqlLowerCaseTableNamesCompatibility } from "../lib/db-connection-check.js";
|
|
23
23
|
import { formatMissingManagedAppEnvMessage } from '../lib/app-runtime.js';
|
|
@@ -29,8 +29,9 @@ import { buildStoredEnvConfig } from '../lib/env-config.js';
|
|
|
29
29
|
import { resolveDockerEnvFileArg } from "../lib/docker-env-file.js";
|
|
30
30
|
import { startDockerLogFollower } from '../lib/docker-log-stream.js';
|
|
31
31
|
import { buildInitAppEnvVarsFromConfig } from '../lib/managed-init-env.js';
|
|
32
|
+
import { buildHookContext, persistHookScript, resolveHookScriptPath, runHookScriptHook, } from '../lib/hook-script.js';
|
|
32
33
|
import { areConfiguredPathsEquivalent, deriveConfiguredSourcePath, deriveConfiguredStoragePath, inferConfiguredAppPathFromLegacyConfig, } from '../lib/env-paths.js';
|
|
33
|
-
import Download
|
|
34
|
+
import Download from './download.js';
|
|
34
35
|
import EnvAdd from "./env/add.js";
|
|
35
36
|
import { resolveAppUrlFromApiBaseUrl } from "./env/shared.js";
|
|
36
37
|
const DEFAULT_INSTALL_ENV_NAME = 'local';
|
|
@@ -44,18 +45,6 @@ const DEFAULT_INSTALL_DB_PORTS = {
|
|
|
44
45
|
mariadb: '3306',
|
|
45
46
|
kingbase: '54321',
|
|
46
47
|
};
|
|
47
|
-
const DEFAULT_INSTALL_BUILTIN_DB_IMAGES = {
|
|
48
|
-
postgres: 'postgres:16',
|
|
49
|
-
mysql: 'mysql:8',
|
|
50
|
-
mariadb: 'mariadb:11',
|
|
51
|
-
kingbase: 'registry.cn-shanghai.aliyuncs.com/nocobase/kingbase:v009r001c001b0030_single_x86',
|
|
52
|
-
};
|
|
53
|
-
const DEFAULT_INSTALL_BUILTIN_DB_IMAGES_ZH_CN = {
|
|
54
|
-
postgres: 'registry.cn-shanghai.aliyuncs.com/nocobase/postgres:16',
|
|
55
|
-
mysql: 'registry.cn-shanghai.aliyuncs.com/nocobase/mysql:8',
|
|
56
|
-
mariadb: 'registry.cn-shanghai.aliyuncs.com/nocobase/mariadb:11',
|
|
57
|
-
kingbase: 'registry.cn-shanghai.aliyuncs.com/nocobase/kingbase:v009r001c001b0030_single_x86',
|
|
58
|
-
};
|
|
59
48
|
const DEFAULT_INSTALL_DB_DATABASE = 'nocobase';
|
|
60
49
|
const DEFAULT_INSTALL_DB_USER = 'nocobase';
|
|
61
50
|
const DEFAULT_INSTALL_DB_PASSWORD = 'nocobase';
|
|
@@ -64,6 +53,10 @@ const DEFAULT_INSTALL_ROOT_EMAIL = 'admin@nocobase.com';
|
|
|
64
53
|
const DEFAULT_INSTALL_ROOT_PASSWORD = 'admin123';
|
|
65
54
|
const DEFAULT_INSTALL_ROOT_NICKNAME = 'Super Admin';
|
|
66
55
|
const DEFAULT_INSTALL_API_HOST = '127.0.0.1';
|
|
56
|
+
const DEFAULT_INSTALL_PORTAL_TYPE = 'no-code';
|
|
57
|
+
const DEFAULT_INSTALL_PORTAL_NAME = 'admin';
|
|
58
|
+
const DEFAULT_INSTALL_PORTAL_TEMPLATE = '@nocobase/portal-template-default';
|
|
59
|
+
const INSTALL_PORTAL_TYPES = ['no-code', 'ai'];
|
|
67
60
|
function toOptionalPromptString(value) {
|
|
68
61
|
const text = String(value ?? '').trim();
|
|
69
62
|
return text || undefined;
|
|
@@ -178,22 +171,26 @@ function downloadVersionPromptValue(version) {
|
|
|
178
171
|
}
|
|
179
172
|
function supportsBuiltinDbDialect(value) {
|
|
180
173
|
const dialect = String(value ?? '').trim();
|
|
181
|
-
return
|
|
174
|
+
return INSTALL_DB_DIALECTS.includes(dialect);
|
|
182
175
|
}
|
|
183
176
|
export function defaultDbPortForDialect(value) {
|
|
184
177
|
const dialect = String(value ?? 'postgres').trim();
|
|
185
178
|
return DEFAULT_INSTALL_DB_PORTS[isInstallDbDialect(dialect) ? dialect : 'postgres'];
|
|
186
179
|
}
|
|
187
|
-
function defaultBuiltinDbImageForDialect(value) {
|
|
180
|
+
function defaultBuiltinDbImageForDialect(value, options) {
|
|
188
181
|
const dialect = String(value ?? 'postgres').trim();
|
|
189
|
-
|
|
190
|
-
? DEFAULT_INSTALL_BUILTIN_DB_IMAGES_ZH_CN
|
|
191
|
-
: DEFAULT_INSTALL_BUILTIN_DB_IMAGES;
|
|
192
|
-
return supportsBuiltinDbDialect(dialect) ? defaults[dialect] : defaults.postgres;
|
|
182
|
+
return resolveBuiltinDbImage(dialect, { registry: options?.registry });
|
|
193
183
|
}
|
|
194
184
|
function defaultDbDatabaseForDialect(value) {
|
|
195
185
|
return String(value ?? '').trim() === 'kingbase' ? 'kingbase' : DEFAULT_INSTALL_DB_DATABASE;
|
|
196
186
|
}
|
|
187
|
+
function isAiMode(values) {
|
|
188
|
+
return String(values.portalType ?? DEFAULT_INSTALL_PORTAL_TYPE).trim() === 'ai';
|
|
189
|
+
}
|
|
190
|
+
function supportsDbSchemaPrompt(value) {
|
|
191
|
+
const dialect = String(value ?? '').trim();
|
|
192
|
+
return dialect === 'postgres' || dialect === 'kingbase';
|
|
193
|
+
}
|
|
197
194
|
function defaultDbHostForBuiltinDb(values) {
|
|
198
195
|
return values.builtinDb ? DEFAULT_INSTALL_BUILTIN_DB_HOST : DEFAULT_INSTALL_DB_HOST;
|
|
199
196
|
}
|
|
@@ -414,6 +411,16 @@ export default class Install extends Command {
|
|
|
414
411
|
'app-public-path': Flags.string({
|
|
415
412
|
description: 'Public path for the local app, for example / or /console/',
|
|
416
413
|
}),
|
|
414
|
+
'portal-type': Flags.string({
|
|
415
|
+
description: 'Initial portal type for the installed app',
|
|
416
|
+
options: [...INSTALL_PORTAL_TYPES],
|
|
417
|
+
}),
|
|
418
|
+
'portal-name': Flags.string({
|
|
419
|
+
description: 'Initial portal name',
|
|
420
|
+
}),
|
|
421
|
+
'portal-template': Flags.string({
|
|
422
|
+
description: 'Initial portal template npm package or local path when --portal-type ai is used',
|
|
423
|
+
}),
|
|
417
424
|
'root-username': Flags.string({
|
|
418
425
|
description: 'Initial admin username for the installed app',
|
|
419
426
|
required: false,
|
|
@@ -472,7 +479,10 @@ export default class Install extends Command {
|
|
|
472
479
|
description: 'Skip the download step and reuse an existing local app directory or Docker image',
|
|
473
480
|
default: false,
|
|
474
481
|
}),
|
|
475
|
-
|
|
482
|
+
'hook-script': Flags.string({
|
|
483
|
+
description: 'Hook module copied to <appPath>/.nb/hooks.mjs and run before npm/git dependency installation.',
|
|
484
|
+
}),
|
|
485
|
+
...omitKeys(Download.flags, ['yes', 'hook-script']),
|
|
476
486
|
};
|
|
477
487
|
/** Environment name only: run before {@link Install.prompts} (see `run`). */
|
|
478
488
|
static envPrompts = {
|
|
@@ -520,6 +530,41 @@ export default class Install extends Command {
|
|
|
520
530
|
yesInitialValue: '/',
|
|
521
531
|
validate: validateAppPublicPath,
|
|
522
532
|
},
|
|
533
|
+
portalType: {
|
|
534
|
+
type: 'select',
|
|
535
|
+
message: installText('prompts.portalType.message'),
|
|
536
|
+
options: [
|
|
537
|
+
{
|
|
538
|
+
value: 'no-code',
|
|
539
|
+
label: installText('prompts.portalType.noCodeLabel'),
|
|
540
|
+
hint: installText('prompts.portalType.noCodeHint'),
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
value: 'ai',
|
|
544
|
+
label: installText('prompts.portalType.aiLabel'),
|
|
545
|
+
hint: installText('prompts.portalType.aiHint'),
|
|
546
|
+
},
|
|
547
|
+
],
|
|
548
|
+
initialValue: DEFAULT_INSTALL_PORTAL_TYPE,
|
|
549
|
+
yesInitialValue: DEFAULT_INSTALL_PORTAL_TYPE,
|
|
550
|
+
required: true,
|
|
551
|
+
},
|
|
552
|
+
portalName: {
|
|
553
|
+
type: 'text',
|
|
554
|
+
message: installText('prompts.portalName.message'),
|
|
555
|
+
placeholder: DEFAULT_INSTALL_PORTAL_NAME,
|
|
556
|
+
initialValue: DEFAULT_INSTALL_PORTAL_NAME,
|
|
557
|
+
yesInitialValue: DEFAULT_INSTALL_PORTAL_NAME,
|
|
558
|
+
required: true,
|
|
559
|
+
},
|
|
560
|
+
portalTemplate: {
|
|
561
|
+
type: 'text',
|
|
562
|
+
message: installText('prompts.portalTemplate.message'),
|
|
563
|
+
placeholder: DEFAULT_INSTALL_PORTAL_TEMPLATE,
|
|
564
|
+
yesInitialValue: DEFAULT_INSTALL_PORTAL_TEMPLATE,
|
|
565
|
+
hidden: (values) => !isAiMode(values),
|
|
566
|
+
required: true,
|
|
567
|
+
},
|
|
523
568
|
};
|
|
524
569
|
}
|
|
525
570
|
static dbPrompts = {
|
|
@@ -547,7 +592,9 @@ export default class Install extends Command {
|
|
|
547
592
|
type: 'text',
|
|
548
593
|
message: installText('prompts.builtinDbImage.message'),
|
|
549
594
|
placeholder: installText('prompts.builtinDbImage.placeholder'),
|
|
550
|
-
initialValue: (values) => defaultBuiltinDbImageForDialect(values.dbDialect
|
|
595
|
+
initialValue: (values) => defaultBuiltinDbImageForDialect(values.dbDialect, {
|
|
596
|
+
registry: String(values.builtinDbImageRegistry ?? '').trim() || undefined,
|
|
597
|
+
}),
|
|
551
598
|
hidden: (values) => !values.builtinDb || !supportsBuiltinDbDialect(values.dbDialect),
|
|
552
599
|
required: true,
|
|
553
600
|
},
|
|
@@ -597,7 +644,7 @@ export default class Install extends Command {
|
|
|
597
644
|
type: 'text',
|
|
598
645
|
message: installText('prompts.dbSchema.message'),
|
|
599
646
|
placeholder: installText('prompts.dbSchema.placeholder'),
|
|
600
|
-
hidden: (values) =>
|
|
647
|
+
hidden: (values) => !supportsDbSchemaPrompt(values.dbDialect),
|
|
601
648
|
},
|
|
602
649
|
dbTablePrefix: {
|
|
603
650
|
type: 'text',
|
|
@@ -777,6 +824,24 @@ export default class Install extends Command {
|
|
|
777
824
|
preset.appPublicPath = v;
|
|
778
825
|
}
|
|
779
826
|
}
|
|
827
|
+
if (flags['portal-type'] !== undefined) {
|
|
828
|
+
const v = String(flags['portal-type'] ?? '').trim();
|
|
829
|
+
if (v) {
|
|
830
|
+
preset.portalType = v;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
if (flags['portal-name'] !== undefined) {
|
|
834
|
+
const v = String(flags['portal-name'] ?? '').trim();
|
|
835
|
+
if (v) {
|
|
836
|
+
preset.portalName = v;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
if (flags['portal-template'] !== undefined) {
|
|
840
|
+
const v = String(flags['portal-template'] ?? '').trim();
|
|
841
|
+
if (v) {
|
|
842
|
+
preset.portalTemplate = v;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
780
845
|
if (flags['root-username'] !== undefined) {
|
|
781
846
|
preset.rootUsername = String(flags['root-username'] ?? '').trim();
|
|
782
847
|
}
|
|
@@ -868,6 +933,9 @@ export default class Install extends Command {
|
|
|
868
933
|
'appPort',
|
|
869
934
|
'storagePath',
|
|
870
935
|
'appPublicPath',
|
|
936
|
+
'portalType',
|
|
937
|
+
'portalName',
|
|
938
|
+
'portalTemplate',
|
|
871
939
|
]);
|
|
872
940
|
}
|
|
873
941
|
static buildDbPresetValuesFromFlags(flags, argv = process.argv.slice(2)) {
|
|
@@ -1095,6 +1163,7 @@ export default class Install extends Command {
|
|
|
1095
1163
|
const appPort = Install.toOptionalPromptString(config.appPort);
|
|
1096
1164
|
const storagePath = Install.toOptionalPromptString(config.storagePath);
|
|
1097
1165
|
const appPublicPath = Install.toOptionalPromptString(config.appPublicPath);
|
|
1166
|
+
const hookScript = Install.toOptionalPromptString(config.hookScript);
|
|
1098
1167
|
const apiBaseUrl = Install.toOptionalPromptString(config.apiBaseUrl);
|
|
1099
1168
|
const downloadVersion = Install.toOptionalPromptString(config.downloadVersion);
|
|
1100
1169
|
const dockerRegistry = Install.toOptionalPromptString(config.dockerRegistry);
|
|
@@ -1116,6 +1185,9 @@ export default class Install extends Command {
|
|
|
1116
1185
|
const rootPassword = Install.toOptionalPromptString(config.rootPassword);
|
|
1117
1186
|
const rootNickname = Install.toOptionalPromptString(config.rootNickname);
|
|
1118
1187
|
const lang = Install.toOptionalPromptString(config.lang);
|
|
1188
|
+
const portalType = Install.toOptionalPromptString(config.portalType);
|
|
1189
|
+
const portalName = Install.toOptionalPromptString(config.portalName);
|
|
1190
|
+
const portalTemplate = Install.toOptionalPromptString(config.portalTemplate);
|
|
1119
1191
|
const auth = config.auth;
|
|
1120
1192
|
const savedAuthType = Install.toOptionalPromptString(config.authType) ?? Install.toOptionalPromptString(auth?.type);
|
|
1121
1193
|
const appPreset = {
|
|
@@ -1125,6 +1197,10 @@ export default class Install extends Command {
|
|
|
1125
1197
|
...(appPort ? { appPort } : {}),
|
|
1126
1198
|
...(storagePath ? { storagePath } : {}),
|
|
1127
1199
|
...(appPublicPath ? { appPublicPath } : {}),
|
|
1200
|
+
...(portalType ? { portalType } : {}),
|
|
1201
|
+
...(portalName ? { portalName } : {}),
|
|
1202
|
+
...(portalTemplate ? { portalTemplate } : {}),
|
|
1203
|
+
...(hookScript ? { hookScript } : {}),
|
|
1128
1204
|
};
|
|
1129
1205
|
const downloadPreset = {
|
|
1130
1206
|
...(source ? { source } : {}),
|
|
@@ -1266,6 +1342,12 @@ export default class Install extends Command {
|
|
|
1266
1342
|
warn: params.warnOnPortFallback ?? true,
|
|
1267
1343
|
});
|
|
1268
1344
|
}
|
|
1345
|
+
if (params.flags['portal-template'] === undefined) {
|
|
1346
|
+
const defaultPortalTemplate = Install.toOptionalPromptString(await getCliConfigValue('default-portal-template'));
|
|
1347
|
+
if (defaultPortalTemplate) {
|
|
1348
|
+
initialValues.portalTemplate = defaultPortalTemplate;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1269
1351
|
return initialValues;
|
|
1270
1352
|
}
|
|
1271
1353
|
static shouldPublishBuiltinDbPortForValues(values) {
|
|
@@ -1273,19 +1355,25 @@ export default class Install extends Command {
|
|
|
1273
1355
|
return builtinDb && Install.shouldPublishBuiltinDbPort(values.source);
|
|
1274
1356
|
}
|
|
1275
1357
|
static async buildDbPromptInitialValues(params) {
|
|
1276
|
-
|
|
1277
|
-
return {};
|
|
1278
|
-
}
|
|
1358
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
1279
1359
|
const values = {
|
|
1280
1360
|
...params.downloadResults,
|
|
1281
1361
|
...params.dbPreset,
|
|
1282
1362
|
};
|
|
1363
|
+
const dockerRegistry = String(values.dockerRegistry ?? '').trim() || resolveOfficialDockerRegistry(configuredRegistry);
|
|
1364
|
+
const dialect = String(values.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
1365
|
+
const initialValues = values.builtinDb !== false && params.dbPreset.builtinDbImage === undefined
|
|
1366
|
+
? { builtinDbImage: defaultBuiltinDbImageForDialect(dialect, { registry: dockerRegistry }) }
|
|
1367
|
+
: {};
|
|
1368
|
+
if (params.flags['db-port'] !== undefined) {
|
|
1369
|
+
return initialValues;
|
|
1370
|
+
}
|
|
1283
1371
|
if (!Install.shouldPublishBuiltinDbPortForValues(values)) {
|
|
1284
|
-
return
|
|
1372
|
+
return initialValues;
|
|
1285
1373
|
}
|
|
1286
|
-
const dialect = String(values.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
1287
1374
|
const defaultPort = defaultDbPortForDialect(dialect);
|
|
1288
1375
|
return {
|
|
1376
|
+
...initialValues,
|
|
1289
1377
|
dbPort: await Install.resolveAvailableDefaultPort(defaultPort, {
|
|
1290
1378
|
label: `Default ${dialect} port`,
|
|
1291
1379
|
warn: params.warnOnPortFallback ?? true,
|
|
@@ -1296,12 +1384,13 @@ export default class Install extends Command {
|
|
|
1296
1384
|
* When install runs {@link Download.prompts} after app prompts, align the download
|
|
1297
1385
|
* output directory with app settings, while Docker registry defaults follow the CLI locale.
|
|
1298
1386
|
*/
|
|
1299
|
-
static buildDownloadPromptOptionsForInstall(appResults, envName) {
|
|
1387
|
+
static async buildDownloadPromptOptionsForInstall(appResults, envName) {
|
|
1300
1388
|
const appRoot = resolveConfiguredSourcePathValue(appResults, envName);
|
|
1301
1389
|
const lang = String(appResults.lang ?? DEFAULT_INSTALL_LANG).trim() || DEFAULT_INSTALL_LANG;
|
|
1390
|
+
const dockerRegistry = resolveOfficialDockerRegistry(await getCliConfigValue('nb-image-registry'));
|
|
1302
1391
|
const initialValues = {
|
|
1303
1392
|
lang,
|
|
1304
|
-
dockerRegistry
|
|
1393
|
+
dockerRegistry,
|
|
1305
1394
|
outputDir: appRoot,
|
|
1306
1395
|
};
|
|
1307
1396
|
const values = {
|
|
@@ -1426,14 +1515,17 @@ export default class Install extends Command {
|
|
|
1426
1515
|
static buildDockerAppContainerName(envName, containerPrefix) {
|
|
1427
1516
|
return Install.sanitizeDockerResourceName(`${Install.buildBuiltinDbContainerPrefix(containerPrefix)}-${envName}-app`);
|
|
1428
1517
|
}
|
|
1429
|
-
static buildInitAppEnvVars(params) {
|
|
1518
|
+
static buildInitAppEnvVars(params, options = {}) {
|
|
1430
1519
|
return buildInitAppEnvVarsFromConfig({
|
|
1431
1520
|
lang: String(params.appResults.lang ?? ''),
|
|
1432
1521
|
rootUsername: String(params.rootResults.rootUsername ?? ''),
|
|
1433
1522
|
rootEmail: String(params.rootResults.rootEmail ?? ''),
|
|
1434
1523
|
rootPassword: String(params.rootResults.rootPassword ?? ''),
|
|
1435
1524
|
rootNickname: String(params.rootResults.rootNickname ?? ''),
|
|
1436
|
-
|
|
1525
|
+
portalType: String(params.appResults.portalType ?? ''),
|
|
1526
|
+
portalName: String(params.appResults.portalName ?? ''),
|
|
1527
|
+
portalTemplate: String(params.appResults.portalTemplate ?? ''),
|
|
1528
|
+
}, options);
|
|
1437
1529
|
}
|
|
1438
1530
|
static shouldPublishBuiltinDbPort(source) {
|
|
1439
1531
|
return String(source ?? '').trim() !== 'docker';
|
|
@@ -1462,8 +1554,6 @@ export default class Install extends Command {
|
|
|
1462
1554
|
'-d',
|
|
1463
1555
|
'--name',
|
|
1464
1556
|
containerName,
|
|
1465
|
-
'--restart',
|
|
1466
|
-
'always',
|
|
1467
1557
|
'--network',
|
|
1468
1558
|
networkName,
|
|
1469
1559
|
'-e',
|
|
@@ -1506,8 +1596,6 @@ export default class Install extends Command {
|
|
|
1506
1596
|
'-d',
|
|
1507
1597
|
'--name',
|
|
1508
1598
|
containerName,
|
|
1509
|
-
'--restart',
|
|
1510
|
-
'always',
|
|
1511
1599
|
'--network',
|
|
1512
1600
|
networkName,
|
|
1513
1601
|
'-e',
|
|
@@ -1552,8 +1640,6 @@ export default class Install extends Command {
|
|
|
1552
1640
|
'-d',
|
|
1553
1641
|
'--name',
|
|
1554
1642
|
containerName,
|
|
1555
|
-
'--restart',
|
|
1556
|
-
'always',
|
|
1557
1643
|
'--network',
|
|
1558
1644
|
networkName,
|
|
1559
1645
|
'-e',
|
|
@@ -1598,8 +1684,6 @@ export default class Install extends Command {
|
|
|
1598
1684
|
'-d',
|
|
1599
1685
|
'--name',
|
|
1600
1686
|
containerName,
|
|
1601
|
-
'--restart',
|
|
1602
|
-
'always',
|
|
1603
1687
|
'--network',
|
|
1604
1688
|
networkName,
|
|
1605
1689
|
'--platform',
|
|
@@ -1762,12 +1846,15 @@ export default class Install extends Command {
|
|
|
1762
1846
|
return plan;
|
|
1763
1847
|
}
|
|
1764
1848
|
static async buildDockerAppPlan(params) {
|
|
1849
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
1850
|
+
const configuredVariant = normalizeNbImageVariant(await getCliConfigValue('nb-image-variant')) ?? DEFAULT_NB_IMAGE_VARIANT;
|
|
1765
1851
|
const dockerRegistry = String(downloadResultsValue(params.downloadResults, 'dockerRegistry') ?? '').trim() ||
|
|
1766
|
-
|
|
1852
|
+
resolveOfficialDockerRegistry(configuredRegistry);
|
|
1767
1853
|
const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || DEFAULT_DOCKER_VERSION;
|
|
1768
1854
|
const imageRef = resolveDockerImageRef(dockerRegistry, version, {
|
|
1769
|
-
defaultRegistry:
|
|
1855
|
+
defaultRegistry: resolveOfficialDockerRegistry(configuredRegistry),
|
|
1770
1856
|
defaultVersion: DEFAULT_DOCKER_VERSION,
|
|
1857
|
+
variant: inferNbImageRegistryFromRepository(dockerRegistry) ? configuredVariant : undefined,
|
|
1771
1858
|
});
|
|
1772
1859
|
const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT;
|
|
1773
1860
|
const configuredStoragePath = resolveConfiguredStoragePathValue(params.appResults, params.envName);
|
|
@@ -1794,17 +1881,16 @@ export default class Install extends Command {
|
|
|
1794
1881
|
appResults: params.appResults,
|
|
1795
1882
|
rootResults: params.rootResults,
|
|
1796
1883
|
});
|
|
1884
|
+
const containerPort = resolveDockerImageContainerPort(imageRef);
|
|
1797
1885
|
const args = [
|
|
1798
1886
|
'run',
|
|
1799
1887
|
'-d',
|
|
1800
1888
|
'--name',
|
|
1801
1889
|
containerName,
|
|
1802
|
-
'--restart',
|
|
1803
|
-
'always',
|
|
1804
1890
|
'--network',
|
|
1805
1891
|
params.networkName,
|
|
1806
1892
|
'-p',
|
|
1807
|
-
`${appPort}
|
|
1893
|
+
`${appPort}:${containerPort}`,
|
|
1808
1894
|
];
|
|
1809
1895
|
if (envFile) {
|
|
1810
1896
|
args.push('--env-file', envFile);
|
|
@@ -1916,6 +2002,12 @@ export default class Install extends Command {
|
|
|
1916
2002
|
if (results.buildDts) {
|
|
1917
2003
|
argv.push('--build-dts');
|
|
1918
2004
|
}
|
|
2005
|
+
Install.pushDownloadArgIfValue(argv, '--hook-script', results.hookScript);
|
|
2006
|
+
Install.pushDownloadArgIfValue(argv, '--hook-phase', results.hookPhase);
|
|
2007
|
+
Install.pushDownloadArgIfValue(argv, '--hook-command', results.hookCommand);
|
|
2008
|
+
Install.pushDownloadArgIfValue(argv, '--hook-env-name', results.hookEnvName);
|
|
2009
|
+
Install.pushDownloadArgIfValue(argv, '--hook-app-path', results.hookAppPath);
|
|
2010
|
+
Install.pushDownloadArgIfValue(argv, '--hook-storage-path', results.hookStoragePath);
|
|
1919
2011
|
return argv;
|
|
1920
2012
|
}
|
|
1921
2013
|
static resolveLocalProjectRoot(params) {
|
|
@@ -1942,6 +2034,40 @@ export default class Install extends Command {
|
|
|
1942
2034
|
buildDts: false,
|
|
1943
2035
|
};
|
|
1944
2036
|
}
|
|
2037
|
+
static resolveAbsoluteAppPath(envName, appResults) {
|
|
2038
|
+
const configuredAppPath = resolveConfiguredAppPathValue(appResults) ?? defaultInstallAppPath(envName);
|
|
2039
|
+
return resolveConfiguredEnvPath(configuredAppPath) ?? resolveEnvRelativePath(defaultInstallAppPath(envName));
|
|
2040
|
+
}
|
|
2041
|
+
static resolveAbsoluteStoragePath(envName, appResults) {
|
|
2042
|
+
const configuredStoragePath = resolveConfiguredStoragePathValue(appResults, envName);
|
|
2043
|
+
return (resolveConfiguredEnvPath(configuredStoragePath) ?? resolveEnvRelativePath(defaultInstallStoragePath(envName)));
|
|
2044
|
+
}
|
|
2045
|
+
async prepareHookScriptForInstall(params) {
|
|
2046
|
+
const appPath = Install.resolveAbsoluteAppPath(params.envName, params.appResults);
|
|
2047
|
+
const storagePath = Install.resolveAbsoluteStoragePath(params.envName, params.appResults);
|
|
2048
|
+
const inputHookScript = Install.toOptionalPromptString(params.hookScript);
|
|
2049
|
+
if (inputHookScript) {
|
|
2050
|
+
params.appResults.hookScript = await persistHookScript({
|
|
2051
|
+
sourcePath: inputHookScript,
|
|
2052
|
+
appPath,
|
|
2053
|
+
});
|
|
2054
|
+
printInfo(`Saved hook script to ${path.join(appPath, String(params.appResults.hookScript))}.`);
|
|
2055
|
+
}
|
|
2056
|
+
const savedHookScript = Install.toOptionalPromptString(params.appResults.hookScript);
|
|
2057
|
+
const hookScriptPath = resolveHookScriptPath({
|
|
2058
|
+
appPath,
|
|
2059
|
+
hookScript: savedHookScript,
|
|
2060
|
+
});
|
|
2061
|
+
if (!hookScriptPath) {
|
|
2062
|
+
return;
|
|
2063
|
+
}
|
|
2064
|
+
params.downloadResults.hookScript = hookScriptPath;
|
|
2065
|
+
params.downloadResults.hookPhase = 'init';
|
|
2066
|
+
params.downloadResults.hookCommand = 'init';
|
|
2067
|
+
params.downloadResults.hookEnvName = params.envName;
|
|
2068
|
+
params.downloadResults.hookAppPath = appPath;
|
|
2069
|
+
params.downloadResults.hookStoragePath = storagePath;
|
|
2070
|
+
}
|
|
1945
2071
|
commandStdio(verbose) {
|
|
1946
2072
|
return verbose ? 'inherit' : 'ignore';
|
|
1947
2073
|
}
|
|
@@ -1954,12 +2080,15 @@ export default class Install extends Command {
|
|
|
1954
2080
|
}
|
|
1955
2081
|
async ensureSkippedDownloadInputsReady(params) {
|
|
1956
2082
|
if (params.source === 'docker') {
|
|
2083
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
2084
|
+
const configuredVariant = normalizeNbImageVariant(await getCliConfigValue('nb-image-variant')) ?? DEFAULT_NB_IMAGE_VARIANT;
|
|
1957
2085
|
const dockerRegistry = String(downloadResultsValue(params.downloadResults, 'dockerRegistry') ?? '').trim() ||
|
|
1958
|
-
|
|
2086
|
+
resolveOfficialDockerRegistry(configuredRegistry);
|
|
1959
2087
|
const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || DEFAULT_DOCKER_VERSION;
|
|
1960
2088
|
const imageRef = resolveDockerImageRef(dockerRegistry, version, {
|
|
1961
|
-
defaultRegistry:
|
|
2089
|
+
defaultRegistry: resolveOfficialDockerRegistry(configuredRegistry),
|
|
1962
2090
|
defaultVersion: DEFAULT_DOCKER_VERSION,
|
|
2091
|
+
variant: inferNbImageRegistryFromRepository(dockerRegistry) ? configuredVariant : undefined,
|
|
1963
2092
|
});
|
|
1964
2093
|
const imageExists = await commandSucceeds('docker', ['image', 'inspect', imageRef]);
|
|
1965
2094
|
if (!imageExists) {
|
|
@@ -2011,7 +2140,9 @@ export default class Install extends Command {
|
|
|
2011
2140
|
const dbDialect = String(params.dbResults.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
2012
2141
|
const appKey = Install.resolveManagedAppKey(params.appResults.appKey);
|
|
2013
2142
|
const timeZone = Install.resolveManagedTimeZone(params.appResults.timeZone);
|
|
2143
|
+
const lifecycleEnvVars = managedAppLifecycleEnvVars();
|
|
2014
2144
|
const env = {
|
|
2145
|
+
...lifecycleEnvVars,
|
|
2015
2146
|
STORAGE_PATH: storagePath,
|
|
2016
2147
|
APP_PORT: String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT,
|
|
2017
2148
|
APP_KEY: appKey,
|
|
@@ -2216,11 +2347,59 @@ export default class Install extends Command {
|
|
|
2216
2347
|
}
|
|
2217
2348
|
await this.config.runCommand('env:update', [params.envName]);
|
|
2218
2349
|
}
|
|
2350
|
+
buildAppStartArgv(params) {
|
|
2351
|
+
const argv = ['--env', params.envName, '--yes', '--no-sync-licensed-plugins', '--hook-command', 'init'];
|
|
2352
|
+
if (params.verbose) {
|
|
2353
|
+
argv.push('--verbose');
|
|
2354
|
+
}
|
|
2355
|
+
return argv;
|
|
2356
|
+
}
|
|
2357
|
+
async runInstallHookIfNeeded(params) {
|
|
2358
|
+
const appPath = Install.resolveAbsoluteAppPath(params.envName, params.appResults);
|
|
2359
|
+
const savedHookScript = Install.toOptionalPromptString(params.appResults.hookScript);
|
|
2360
|
+
const hookScriptPath = resolveHookScriptPath({
|
|
2361
|
+
appPath,
|
|
2362
|
+
hookScript: savedHookScript,
|
|
2363
|
+
});
|
|
2364
|
+
if (!hookScriptPath) {
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
const storagePath = Install.resolveAbsoluteStoragePath(params.envName, params.appResults);
|
|
2368
|
+
const sourcePath = params.projectRoot ??
|
|
2369
|
+
resolveConfiguredEnvPath(resolveConfiguredSourcePathValue(params.appResults, params.envName)) ??
|
|
2370
|
+
path.join(appPath, 'source');
|
|
2371
|
+
const context = buildHookContext({
|
|
2372
|
+
phase: 'init',
|
|
2373
|
+
command: 'init',
|
|
2374
|
+
envName: params.envName,
|
|
2375
|
+
source: params.source,
|
|
2376
|
+
version: downloadResultsValue(params.downloadResults, 'version'),
|
|
2377
|
+
appPath,
|
|
2378
|
+
sourcePath,
|
|
2379
|
+
storagePath,
|
|
2380
|
+
hookScript: savedHookScript,
|
|
2381
|
+
envConfig: Install.buildSavedEnvConfig(params, {
|
|
2382
|
+
defaultApiHost: params.defaultApiHost,
|
|
2383
|
+
}),
|
|
2384
|
+
});
|
|
2385
|
+
if (!context) {
|
|
2386
|
+
return;
|
|
2387
|
+
}
|
|
2388
|
+
this.log(`Running hook ${params.hookName}: ${hookScriptPath}`);
|
|
2389
|
+
await runHookScriptHook({
|
|
2390
|
+
hookScriptPath,
|
|
2391
|
+
hookName: params.hookName,
|
|
2392
|
+
context,
|
|
2393
|
+
});
|
|
2394
|
+
}
|
|
2219
2395
|
static buildSavedEnvConfig(params, options = {}) {
|
|
2220
2396
|
const appPath = resolveConfiguredAppPathValue(params.appResults);
|
|
2221
2397
|
const appRootPath = Install.toOptionalPromptString(params.appResults.appRootPath);
|
|
2222
2398
|
const storagePath = Install.toOptionalPromptString(params.appResults.storagePath);
|
|
2223
2399
|
const appPublicPath = Install.toOptionalPromptString(params.appResults.appPublicPath);
|
|
2400
|
+
const portalType = Install.toOptionalPromptString(params.appResults.portalType);
|
|
2401
|
+
const portalName = Install.toOptionalPromptString(params.appResults.portalName);
|
|
2402
|
+
const portalTemplate = Install.toOptionalPromptString(params.appResults.portalTemplate);
|
|
2224
2403
|
const derivedAppRootPath = appPath ? deriveConfiguredSourcePath(appPath) : undefined;
|
|
2225
2404
|
const derivedStoragePath = appPath ? deriveConfiguredStoragePath(appPath) : undefined;
|
|
2226
2405
|
const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT;
|
|
@@ -2247,6 +2426,7 @@ export default class Install extends Command {
|
|
|
2247
2426
|
devDependencies: downloadResultsValue(params.downloadResults, 'devDependencies'),
|
|
2248
2427
|
build: downloadResultsValue(params.downloadResults, 'build'),
|
|
2249
2428
|
buildDts: downloadResultsValue(params.downloadResults, 'buildDts'),
|
|
2429
|
+
hookScript: params.appResults.hookScript,
|
|
2250
2430
|
...(appPath ? { appPath } : {}),
|
|
2251
2431
|
...(appRootPath && !areConfiguredPathsEquivalent(appRootPath, derivedAppRootPath) ? { appRootPath } : {}),
|
|
2252
2432
|
appPort,
|
|
@@ -2254,6 +2434,9 @@ export default class Install extends Command {
|
|
|
2254
2434
|
...(appPublicPath ? { appPublicPath } : {}),
|
|
2255
2435
|
...(envFile ? { envFile } : {}),
|
|
2256
2436
|
lang: params.appResults.lang,
|
|
2437
|
+
portalType,
|
|
2438
|
+
portalName,
|
|
2439
|
+
portalTemplate,
|
|
2257
2440
|
appKey: params.appResults.appKey,
|
|
2258
2441
|
timezone: params.appResults.timeZone,
|
|
2259
2442
|
builtinDb: params.dbResults.builtinDb,
|
|
@@ -2305,13 +2488,17 @@ export default class Install extends Command {
|
|
|
2305
2488
|
'app-root-path': parsed['app-root-path'] ?? Install.toOptionalPromptString(appPreset.appRootPath),
|
|
2306
2489
|
'app-port': parsed['app-port'] ?? Install.toOptionalPromptString(appPreset.appPort),
|
|
2307
2490
|
'storage-path': parsed['storage-path'] ?? Install.toOptionalPromptString(appPreset.storagePath),
|
|
2491
|
+
'portal-template': parsed['portal-template'] ?? Install.toOptionalPromptString(appPreset.portalTemplate),
|
|
2308
2492
|
},
|
|
2309
2493
|
}),
|
|
2310
2494
|
values: appPreset,
|
|
2311
2495
|
yesInitialValues: { resume: parsed.resume },
|
|
2312
2496
|
yes,
|
|
2313
2497
|
});
|
|
2314
|
-
|
|
2498
|
+
if (resumePreset?.appPreset?.hookScript !== undefined && appResults.hookScript === undefined) {
|
|
2499
|
+
appResults.hookScript = resumePreset.appPreset.hookScript;
|
|
2500
|
+
}
|
|
2501
|
+
const downloadOpts = await Install.buildDownloadPromptOptionsForInstall(appResults, envName);
|
|
2315
2502
|
downloadOpts.values = {
|
|
2316
2503
|
...(resumePreset?.downloadPreset ?? {}),
|
|
2317
2504
|
...downloadOpts.values,
|
|
@@ -2418,7 +2605,6 @@ export default class Install extends Command {
|
|
|
2418
2605
|
const parsed = {
|
|
2419
2606
|
...flags,
|
|
2420
2607
|
};
|
|
2421
|
-
const defaultApiHost = await resolveDefaultApiHost();
|
|
2422
2608
|
if (parsed['skip-auth'] && (parsed['access-token'] !== undefined || parsed.token !== undefined)) {
|
|
2423
2609
|
this.error('--skip-auth cannot be used with --access-token or --token.');
|
|
2424
2610
|
}
|
|
@@ -2440,6 +2626,12 @@ export default class Install extends Command {
|
|
|
2440
2626
|
appResults,
|
|
2441
2627
|
});
|
|
2442
2628
|
appResults.setupState = 'prepared';
|
|
2629
|
+
await this.prepareHookScriptForInstall({
|
|
2630
|
+
envName,
|
|
2631
|
+
appResults,
|
|
2632
|
+
downloadResults,
|
|
2633
|
+
hookScript: parsed['hook-script'],
|
|
2634
|
+
});
|
|
2443
2635
|
const source = String(downloadResultsValue(downloadResults, 'source') ?? '').trim();
|
|
2444
2636
|
const usesDockerResources = Boolean(dbResults.builtinDb) || source === 'docker';
|
|
2445
2637
|
const dockerNetworkName = usesDockerResources
|
|
@@ -2492,8 +2684,7 @@ export default class Install extends Command {
|
|
|
2492
2684
|
dbResults.dbUser = builtinDbPlan.dbUser;
|
|
2493
2685
|
dbResults.dbPassword = builtinDbPlan.dbPassword;
|
|
2494
2686
|
}
|
|
2495
|
-
let
|
|
2496
|
-
let localAppPlan;
|
|
2687
|
+
let shouldStartApp = false;
|
|
2497
2688
|
if (source === 'docker' || source === 'npm' || source === 'git') {
|
|
2498
2689
|
this.logStage('Preparing application');
|
|
2499
2690
|
if (source === 'docker') {
|
|
@@ -2505,76 +2696,28 @@ export default class Install extends Command {
|
|
|
2505
2696
|
printInfo('Application image ready.');
|
|
2506
2697
|
}
|
|
2507
2698
|
if (!parsed['prepare-only']) {
|
|
2508
|
-
|
|
2509
|
-
envName,
|
|
2510
|
-
dockerNetworkName,
|
|
2511
|
-
dockerContainerPrefix,
|
|
2512
|
-
appResults,
|
|
2513
|
-
downloadResults,
|
|
2514
|
-
dbResults,
|
|
2515
|
-
rootResults,
|
|
2516
|
-
builtinDbPlan,
|
|
2517
|
-
force: parsed.force,
|
|
2518
|
-
commandStdio,
|
|
2519
|
-
});
|
|
2520
|
-
appResults.appKey = dockerAppPlan.appKey;
|
|
2521
|
-
appResults.timeZone = dockerAppPlan.timeZone;
|
|
2699
|
+
shouldStartApp = true;
|
|
2522
2700
|
}
|
|
2523
2701
|
}
|
|
2524
2702
|
else if (source === 'npm' || source === 'git') {
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
? Install.resolveLocalProjectRoot({
|
|
2528
|
-
envName,
|
|
2529
|
-
appResults,
|
|
2530
|
-
downloadResults,
|
|
2531
|
-
})
|
|
2532
|
-
: await this.downloadLocalApp({
|
|
2703
|
+
if (!parsed['skip-download'] && !parsed['prepare-only']) {
|
|
2704
|
+
await this.downloadLocalApp({
|
|
2533
2705
|
envName,
|
|
2534
2706
|
appResults,
|
|
2535
2707
|
downloadResults,
|
|
2536
2708
|
verbose: parsed.verbose,
|
|
2537
2709
|
});
|
|
2538
|
-
if (!parsed['skip-download']) {
|
|
2539
2710
|
printInfo('Application files ready.');
|
|
2540
2711
|
}
|
|
2541
2712
|
if (!parsed['prepare-only']) {
|
|
2542
|
-
|
|
2543
|
-
envName,
|
|
2544
|
-
source: localSource,
|
|
2545
|
-
projectRoot,
|
|
2546
|
-
appResults,
|
|
2547
|
-
dbResults,
|
|
2548
|
-
rootResults,
|
|
2549
|
-
commandStdio,
|
|
2550
|
-
});
|
|
2551
|
-
appResults.appKey = localAppPlan.appKey;
|
|
2552
|
-
appResults.timeZone = localAppPlan.timeZone;
|
|
2713
|
+
shouldStartApp = true;
|
|
2553
2714
|
}
|
|
2554
2715
|
}
|
|
2555
2716
|
}
|
|
2556
2717
|
else {
|
|
2557
2718
|
this.logDetail('Skipped app download and install.');
|
|
2558
2719
|
}
|
|
2559
|
-
if (
|
|
2560
|
-
this.logStage('Starting NocoBase');
|
|
2561
|
-
await this.waitForAppHealthCheck(Install.resolveApiBaseUrl({
|
|
2562
|
-
appResults,
|
|
2563
|
-
envAddResults,
|
|
2564
|
-
defaultApiHost,
|
|
2565
|
-
}), {
|
|
2566
|
-
containerName: dockerAppPlan?.containerName,
|
|
2567
|
-
verbose: parsed.verbose,
|
|
2568
|
-
});
|
|
2569
|
-
const displayApiBaseUrl = Install.resolveApiBaseUrl({
|
|
2570
|
-
appResults,
|
|
2571
|
-
envAddResults,
|
|
2572
|
-
defaultApiHost,
|
|
2573
|
-
});
|
|
2574
|
-
printInfo(`NocoBase is ready at ${formatInstallDisplayUrl(displayApiBaseUrl)}`);
|
|
2575
|
-
appResults.setupState = 'installed';
|
|
2576
|
-
}
|
|
2577
|
-
if (dockerAppPlan || localAppPlan || builtinDbPlan) {
|
|
2720
|
+
if (shouldStartApp || builtinDbPlan) {
|
|
2578
2721
|
await this.saveInstalledEnv({
|
|
2579
2722
|
envName,
|
|
2580
2723
|
appResults,
|
|
@@ -2584,10 +2727,14 @@ export default class Install extends Command {
|
|
|
2584
2727
|
envAddResults,
|
|
2585
2728
|
});
|
|
2586
2729
|
}
|
|
2730
|
+
if (shouldStartApp) {
|
|
2731
|
+
this.logStage('Starting NocoBase');
|
|
2732
|
+
await this.config.runCommand('app:start', this.buildAppStartArgv({ envName, verbose: parsed.verbose }));
|
|
2733
|
+
}
|
|
2587
2734
|
await this.syncInstalledEnvConnection({
|
|
2588
2735
|
envName,
|
|
2589
2736
|
envAddResults,
|
|
2590
|
-
appReady:
|
|
2737
|
+
appReady: shouldStartApp,
|
|
2591
2738
|
skipAuth: Boolean(parsed['skip-auth']),
|
|
2592
2739
|
});
|
|
2593
2740
|
if (!parsed['prepare-only']) {
|
|
@@ -2596,7 +2743,7 @@ export default class Install extends Command {
|
|
|
2596
2743
|
if (parsed['prepare-only']) {
|
|
2597
2744
|
printInfo(`Preparation complete for "${envName}". Activate the license, then run \`nb app start --env ${envName}\`.`);
|
|
2598
2745
|
}
|
|
2599
|
-
else if (!
|
|
2746
|
+
else if (!shouldStartApp) {
|
|
2600
2747
|
printInfo(`Install config for "${envName}" has been saved.`);
|
|
2601
2748
|
}
|
|
2602
2749
|
}
|