@nocobase/cli 2.2.0-beta.1 → 2.2.0-beta.11
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/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/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 +33 -11
- package/dist/commands/install.js +159 -107
- package/dist/commands/license/activate.js +4 -1
- package/dist/commands/license/shared.js +24 -15
- 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 +9 -5
- 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 +102 -12
- package/dist/lib/cli-config.js +73 -1
- package/dist/lib/docker-image.js +94 -6
- package/dist/lib/env-auth.js +291 -45
- package/dist/lib/env-config.js +11 -0
- package/dist/lib/env-proxy-config.js +48 -0
- package/dist/lib/env-proxy.js +164 -58
- package/dist/lib/hook-script.js +160 -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 +4 -0
- 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/locale/en-US.json +49 -43
- package/dist/locale/zh-CN.json +49 -43
- package/package.json +8 -2
- package/scripts/build.mjs +0 -34
- package/scripts/clean.mjs +0 -9
- package/tsconfig.json +0 -19
package/dist/commands/init.js
CHANGED
|
@@ -15,15 +15,18 @@ 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';
|
|
19
|
-
import { resolveDefaultApiHost, resolveDefaultUiHost } from '../lib/cli-config.js';
|
|
18
|
+
import { resolveConfiguredEnvPath, resolveDefaultConfigScope, resolveEnvRelativePath } from '../lib/cli-home.js';
|
|
19
|
+
import { getCliConfigValue, resolveDefaultApiHost, resolveDefaultUiHost } from '../lib/cli-config.js';
|
|
20
|
+
import { resolveOfficialDockerRegistry } from '../lib/docker-image.js';
|
|
20
21
|
import { areConfiguredPathsEquivalent, deriveConfiguredSourcePath, deriveConfiguredStoragePath, inferConfiguredAppPathFromLegacyConfig, } from '../lib/env-paths.js';
|
|
21
22
|
import { formatMissingManagedAppEnvMessage } from '../lib/app-runtime.js';
|
|
22
23
|
import { runPromptCatalogWebUI } from "../lib/prompt-web-ui.js";
|
|
23
24
|
import { validateApiBaseUrl, validateEnvKey } from "../lib/prompt-validators.js";
|
|
24
25
|
import { installNocoBaseSkills, isNpmRegistryUnavailable } from '../lib/skills-manager.js';
|
|
25
26
|
import { omitKeys, pickKeys } from "../lib/object-utils.js";
|
|
27
|
+
import { ENV_CONFIG_SCHEMA_VERSION } from '../lib/env-config.js';
|
|
26
28
|
import { printInfo, printStage, printVerbose, printWarning } from '../lib/ui.js';
|
|
29
|
+
import { persistHookScript } from '../lib/hook-script.js';
|
|
27
30
|
import Download from "./download.js";
|
|
28
31
|
import EnvAdd from "./env/add.js";
|
|
29
32
|
import Install, { defaultDbPortForDialect } from "./install.js";
|
|
@@ -246,16 +249,12 @@ function formatBrowserOpenError(error) {
|
|
|
246
249
|
return String(error);
|
|
247
250
|
}
|
|
248
251
|
export default class Init extends Command {
|
|
249
|
-
static summary = 'Set up
|
|
250
|
-
static description = `Set up NocoBase
|
|
252
|
+
static summary = 'Set up or connect a NocoBase environment in the current workspace';
|
|
253
|
+
static description = `Set up NocoBase in the current workspace.
|
|
251
254
|
|
|
252
|
-
\`nb init\`
|
|
255
|
+
\`nb init\` helps you install a new NocoBase app, take over managing one that already exists on this machine, or connect a remote NocoBase app and save it as a CLI env.
|
|
253
256
|
|
|
254
|
-
|
|
255
|
-
- Take over managing an app that already exists on this machine by reusing its database.
|
|
256
|
-
- Connect a remote NocoBase app and save it as a CLI env.
|
|
257
|
-
|
|
258
|
-
It can also install NocoBase AI coding skills (\`nocobase/skills\`) so agents get the project-specific workflow guidance.
|
|
257
|
+
You can use the saved environment directly, or let a coding agent access it later. It can also install NocoBase AI coding skills (\`nocobase/skills\`) when you want agent-specific workflow guidance.
|
|
259
258
|
|
|
260
259
|
If setup was interrupted earlier, use \`--resume\` with an existing env name to continue from the saved workspace config.
|
|
261
260
|
|
|
@@ -475,7 +474,7 @@ Prompt modes:
|
|
|
475
474
|
default: false,
|
|
476
475
|
}),
|
|
477
476
|
'ui-host': Flags.string({
|
|
478
|
-
description: '
|
|
477
|
+
description: 'Browser-accessible host for the --ui setup page URL (default: 127.0.0.1)',
|
|
479
478
|
}),
|
|
480
479
|
'ui-port': Flags.integer({
|
|
481
480
|
description: 'Port for the local --ui setup server; 0 lets the OS choose an available port',
|
|
@@ -699,6 +698,12 @@ Prompt modes:
|
|
|
699
698
|
if (flags.yes && !Object.prototype.hasOwnProperty.call(downloadSeed, 'source')) {
|
|
700
699
|
downloadSeed.source = 'docker';
|
|
701
700
|
}
|
|
701
|
+
const builtinDbImageRegistry = String(presetValues.dockerRegistry ?? '').trim() ||
|
|
702
|
+
resolveOfficialDockerRegistry(await getCliConfigValue('nb-image-registry'));
|
|
703
|
+
if (!Object.prototype.hasOwnProperty.call(presetValues, 'dockerRegistry')) {
|
|
704
|
+
out.dockerRegistry = builtinDbImageRegistry;
|
|
705
|
+
}
|
|
706
|
+
out.builtinDbImageRegistry = builtinDbImageRegistry;
|
|
702
707
|
const dbInitial = await Install.buildDbPromptInitialValues({
|
|
703
708
|
flags,
|
|
704
709
|
downloadResults: downloadSeed,
|
|
@@ -706,6 +711,9 @@ Prompt modes:
|
|
|
706
711
|
warnOnPortFallback: false,
|
|
707
712
|
});
|
|
708
713
|
for (const [key, value] of Object.entries(dbInitial)) {
|
|
714
|
+
if (key === 'builtinDbImage') {
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
709
717
|
if (!Object.prototype.hasOwnProperty.call(presetValues, key)) {
|
|
710
718
|
out[key] = value;
|
|
711
719
|
}
|
|
@@ -1032,6 +1040,14 @@ Prompt modes:
|
|
|
1032
1040
|
const skipDownload = results.skipDownload === true;
|
|
1033
1041
|
const appKey = resolveManagedAppKey(results.appKey ?? existingEnv?.config.appKey);
|
|
1034
1042
|
const timeZone = resolveManagedTimeZone(results.timeZone ?? existingEnv?.config.timezone);
|
|
1043
|
+
const hookScriptInput = String(flags['hook-script'] ?? '').trim();
|
|
1044
|
+
const hookAppPath = appPath || `./${envName}/`;
|
|
1045
|
+
const hookScript = hookScriptInput
|
|
1046
|
+
? await persistHookScript({
|
|
1047
|
+
sourcePath: hookScriptInput,
|
|
1048
|
+
appPath: resolveConfiguredEnvPath(hookAppPath) ?? resolveEnvRelativePath(hookAppPath),
|
|
1049
|
+
})
|
|
1050
|
+
: String(results.hookScript ?? '').trim();
|
|
1035
1051
|
const builtinDb = explicitDbHostFlag(flags)
|
|
1036
1052
|
? false
|
|
1037
1053
|
: results.builtinDb === undefined
|
|
@@ -1040,6 +1056,7 @@ Prompt modes:
|
|
|
1040
1056
|
results.appKey = appKey;
|
|
1041
1057
|
results.timeZone = timeZone;
|
|
1042
1058
|
await upsertEnv(envName, {
|
|
1059
|
+
schemaVersion: ENV_CONFIG_SCHEMA_VERSION,
|
|
1043
1060
|
...(source === 'docker'
|
|
1044
1061
|
? { kind: 'docker' }
|
|
1045
1062
|
: source || appPath || appRootPath
|
|
@@ -1057,6 +1074,7 @@ Prompt modes:
|
|
|
1057
1074
|
...(dockerPlatform ? { dockerPlatform } : {}),
|
|
1058
1075
|
...(gitUrl ? { gitUrl } : {}),
|
|
1059
1076
|
...(npmRegistry ? { npmRegistry } : {}),
|
|
1077
|
+
...(hookScript ? { hookScript } : {}),
|
|
1060
1078
|
...(appPath ? { appPath } : {}),
|
|
1061
1079
|
...(appRootPath && !areConfiguredPathsEquivalent(appRootPath, derivedAppRootPath) ? { appRootPath } : {}),
|
|
1062
1080
|
...(storagePath && !areConfiguredPathsEquivalent(storagePath, derivedStoragePath) ? { storagePath } : {}),
|
|
@@ -1132,6 +1150,10 @@ Prompt modes:
|
|
|
1132
1150
|
if (flags['prepare-only']) {
|
|
1133
1151
|
argv.push('--prepare-only');
|
|
1134
1152
|
}
|
|
1153
|
+
const hookScript = String(results.hookScript ?? flags['hook-script'] ?? '').trim();
|
|
1154
|
+
if (hookScript) {
|
|
1155
|
+
argv.push('--hook-script', hookScript);
|
|
1156
|
+
}
|
|
1135
1157
|
if (flags.verbose) {
|
|
1136
1158
|
argv.push('--verbose');
|
|
1137
1159
|
}
|
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';
|
|
@@ -178,22 +167,23 @@ function downloadVersionPromptValue(version) {
|
|
|
178
167
|
}
|
|
179
168
|
function supportsBuiltinDbDialect(value) {
|
|
180
169
|
const dialect = String(value ?? '').trim();
|
|
181
|
-
return
|
|
170
|
+
return INSTALL_DB_DIALECTS.includes(dialect);
|
|
182
171
|
}
|
|
183
172
|
export function defaultDbPortForDialect(value) {
|
|
184
173
|
const dialect = String(value ?? 'postgres').trim();
|
|
185
174
|
return DEFAULT_INSTALL_DB_PORTS[isInstallDbDialect(dialect) ? dialect : 'postgres'];
|
|
186
175
|
}
|
|
187
|
-
function defaultBuiltinDbImageForDialect(value) {
|
|
176
|
+
function defaultBuiltinDbImageForDialect(value, options) {
|
|
188
177
|
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;
|
|
178
|
+
return resolveBuiltinDbImage(dialect, { registry: options?.registry });
|
|
193
179
|
}
|
|
194
180
|
function defaultDbDatabaseForDialect(value) {
|
|
195
181
|
return String(value ?? '').trim() === 'kingbase' ? 'kingbase' : DEFAULT_INSTALL_DB_DATABASE;
|
|
196
182
|
}
|
|
183
|
+
function supportsDbSchemaPrompt(value) {
|
|
184
|
+
const dialect = String(value ?? '').trim();
|
|
185
|
+
return dialect === 'postgres' || dialect === 'kingbase';
|
|
186
|
+
}
|
|
197
187
|
function defaultDbHostForBuiltinDb(values) {
|
|
198
188
|
return values.builtinDb ? DEFAULT_INSTALL_BUILTIN_DB_HOST : DEFAULT_INSTALL_DB_HOST;
|
|
199
189
|
}
|
|
@@ -472,7 +462,10 @@ export default class Install extends Command {
|
|
|
472
462
|
description: 'Skip the download step and reuse an existing local app directory or Docker image',
|
|
473
463
|
default: false,
|
|
474
464
|
}),
|
|
475
|
-
|
|
465
|
+
'hook-script': Flags.string({
|
|
466
|
+
description: 'Hook module copied to <appPath>/.nb/hooks.mjs and run before npm/git dependency installation.',
|
|
467
|
+
}),
|
|
468
|
+
...omitKeys(Download.flags, ['yes', 'hook-script']),
|
|
476
469
|
};
|
|
477
470
|
/** Environment name only: run before {@link Install.prompts} (see `run`). */
|
|
478
471
|
static envPrompts = {
|
|
@@ -547,7 +540,9 @@ export default class Install extends Command {
|
|
|
547
540
|
type: 'text',
|
|
548
541
|
message: installText('prompts.builtinDbImage.message'),
|
|
549
542
|
placeholder: installText('prompts.builtinDbImage.placeholder'),
|
|
550
|
-
initialValue: (values) => defaultBuiltinDbImageForDialect(values.dbDialect
|
|
543
|
+
initialValue: (values) => defaultBuiltinDbImageForDialect(values.dbDialect, {
|
|
544
|
+
registry: String(values.builtinDbImageRegistry ?? '').trim() || undefined,
|
|
545
|
+
}),
|
|
551
546
|
hidden: (values) => !values.builtinDb || !supportsBuiltinDbDialect(values.dbDialect),
|
|
552
547
|
required: true,
|
|
553
548
|
},
|
|
@@ -597,7 +592,7 @@ export default class Install extends Command {
|
|
|
597
592
|
type: 'text',
|
|
598
593
|
message: installText('prompts.dbSchema.message'),
|
|
599
594
|
placeholder: installText('prompts.dbSchema.placeholder'),
|
|
600
|
-
hidden: (values) =>
|
|
595
|
+
hidden: (values) => !supportsDbSchemaPrompt(values.dbDialect),
|
|
601
596
|
},
|
|
602
597
|
dbTablePrefix: {
|
|
603
598
|
type: 'text',
|
|
@@ -1095,6 +1090,7 @@ export default class Install extends Command {
|
|
|
1095
1090
|
const appPort = Install.toOptionalPromptString(config.appPort);
|
|
1096
1091
|
const storagePath = Install.toOptionalPromptString(config.storagePath);
|
|
1097
1092
|
const appPublicPath = Install.toOptionalPromptString(config.appPublicPath);
|
|
1093
|
+
const hookScript = Install.toOptionalPromptString(config.hookScript);
|
|
1098
1094
|
const apiBaseUrl = Install.toOptionalPromptString(config.apiBaseUrl);
|
|
1099
1095
|
const downloadVersion = Install.toOptionalPromptString(config.downloadVersion);
|
|
1100
1096
|
const dockerRegistry = Install.toOptionalPromptString(config.dockerRegistry);
|
|
@@ -1125,6 +1121,7 @@ export default class Install extends Command {
|
|
|
1125
1121
|
...(appPort ? { appPort } : {}),
|
|
1126
1122
|
...(storagePath ? { storagePath } : {}),
|
|
1127
1123
|
...(appPublicPath ? { appPublicPath } : {}),
|
|
1124
|
+
...(hookScript ? { hookScript } : {}),
|
|
1128
1125
|
};
|
|
1129
1126
|
const downloadPreset = {
|
|
1130
1127
|
...(source ? { source } : {}),
|
|
@@ -1273,19 +1270,25 @@ export default class Install extends Command {
|
|
|
1273
1270
|
return builtinDb && Install.shouldPublishBuiltinDbPort(values.source);
|
|
1274
1271
|
}
|
|
1275
1272
|
static async buildDbPromptInitialValues(params) {
|
|
1276
|
-
|
|
1277
|
-
return {};
|
|
1278
|
-
}
|
|
1273
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
1279
1274
|
const values = {
|
|
1280
1275
|
...params.downloadResults,
|
|
1281
1276
|
...params.dbPreset,
|
|
1282
1277
|
};
|
|
1278
|
+
const dockerRegistry = String(values.dockerRegistry ?? '').trim() || resolveOfficialDockerRegistry(configuredRegistry);
|
|
1279
|
+
const dialect = String(values.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
1280
|
+
const initialValues = values.builtinDb !== false && params.dbPreset.builtinDbImage === undefined
|
|
1281
|
+
? { builtinDbImage: defaultBuiltinDbImageForDialect(dialect, { registry: dockerRegistry }) }
|
|
1282
|
+
: {};
|
|
1283
|
+
if (params.flags['db-port'] !== undefined) {
|
|
1284
|
+
return initialValues;
|
|
1285
|
+
}
|
|
1283
1286
|
if (!Install.shouldPublishBuiltinDbPortForValues(values)) {
|
|
1284
|
-
return
|
|
1287
|
+
return initialValues;
|
|
1285
1288
|
}
|
|
1286
|
-
const dialect = String(values.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
1287
1289
|
const defaultPort = defaultDbPortForDialect(dialect);
|
|
1288
1290
|
return {
|
|
1291
|
+
...initialValues,
|
|
1289
1292
|
dbPort: await Install.resolveAvailableDefaultPort(defaultPort, {
|
|
1290
1293
|
label: `Default ${dialect} port`,
|
|
1291
1294
|
warn: params.warnOnPortFallback ?? true,
|
|
@@ -1296,12 +1299,13 @@ export default class Install extends Command {
|
|
|
1296
1299
|
* When install runs {@link Download.prompts} after app prompts, align the download
|
|
1297
1300
|
* output directory with app settings, while Docker registry defaults follow the CLI locale.
|
|
1298
1301
|
*/
|
|
1299
|
-
static buildDownloadPromptOptionsForInstall(appResults, envName) {
|
|
1302
|
+
static async buildDownloadPromptOptionsForInstall(appResults, envName) {
|
|
1300
1303
|
const appRoot = resolveConfiguredSourcePathValue(appResults, envName);
|
|
1301
1304
|
const lang = String(appResults.lang ?? DEFAULT_INSTALL_LANG).trim() || DEFAULT_INSTALL_LANG;
|
|
1305
|
+
const dockerRegistry = resolveOfficialDockerRegistry(await getCliConfigValue('nb-image-registry'));
|
|
1302
1306
|
const initialValues = {
|
|
1303
1307
|
lang,
|
|
1304
|
-
dockerRegistry
|
|
1308
|
+
dockerRegistry,
|
|
1305
1309
|
outputDir: appRoot,
|
|
1306
1310
|
};
|
|
1307
1311
|
const values = {
|
|
@@ -1462,8 +1466,6 @@ export default class Install extends Command {
|
|
|
1462
1466
|
'-d',
|
|
1463
1467
|
'--name',
|
|
1464
1468
|
containerName,
|
|
1465
|
-
'--restart',
|
|
1466
|
-
'always',
|
|
1467
1469
|
'--network',
|
|
1468
1470
|
networkName,
|
|
1469
1471
|
'-e',
|
|
@@ -1506,8 +1508,6 @@ export default class Install extends Command {
|
|
|
1506
1508
|
'-d',
|
|
1507
1509
|
'--name',
|
|
1508
1510
|
containerName,
|
|
1509
|
-
'--restart',
|
|
1510
|
-
'always',
|
|
1511
1511
|
'--network',
|
|
1512
1512
|
networkName,
|
|
1513
1513
|
'-e',
|
|
@@ -1552,8 +1552,6 @@ export default class Install extends Command {
|
|
|
1552
1552
|
'-d',
|
|
1553
1553
|
'--name',
|
|
1554
1554
|
containerName,
|
|
1555
|
-
'--restart',
|
|
1556
|
-
'always',
|
|
1557
1555
|
'--network',
|
|
1558
1556
|
networkName,
|
|
1559
1557
|
'-e',
|
|
@@ -1598,8 +1596,6 @@ export default class Install extends Command {
|
|
|
1598
1596
|
'-d',
|
|
1599
1597
|
'--name',
|
|
1600
1598
|
containerName,
|
|
1601
|
-
'--restart',
|
|
1602
|
-
'always',
|
|
1603
1599
|
'--network',
|
|
1604
1600
|
networkName,
|
|
1605
1601
|
'--platform',
|
|
@@ -1762,12 +1758,15 @@ export default class Install extends Command {
|
|
|
1762
1758
|
return plan;
|
|
1763
1759
|
}
|
|
1764
1760
|
static async buildDockerAppPlan(params) {
|
|
1761
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
1762
|
+
const configuredVariant = normalizeNbImageVariant(await getCliConfigValue('nb-image-variant')) ?? DEFAULT_NB_IMAGE_VARIANT;
|
|
1765
1763
|
const dockerRegistry = String(downloadResultsValue(params.downloadResults, 'dockerRegistry') ?? '').trim() ||
|
|
1766
|
-
|
|
1764
|
+
resolveOfficialDockerRegistry(configuredRegistry);
|
|
1767
1765
|
const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || DEFAULT_DOCKER_VERSION;
|
|
1768
1766
|
const imageRef = resolveDockerImageRef(dockerRegistry, version, {
|
|
1769
|
-
defaultRegistry:
|
|
1767
|
+
defaultRegistry: resolveOfficialDockerRegistry(configuredRegistry),
|
|
1770
1768
|
defaultVersion: DEFAULT_DOCKER_VERSION,
|
|
1769
|
+
variant: inferNbImageRegistryFromRepository(dockerRegistry) ? configuredVariant : undefined,
|
|
1771
1770
|
});
|
|
1772
1771
|
const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT;
|
|
1773
1772
|
const configuredStoragePath = resolveConfiguredStoragePathValue(params.appResults, params.envName);
|
|
@@ -1794,17 +1793,16 @@ export default class Install extends Command {
|
|
|
1794
1793
|
appResults: params.appResults,
|
|
1795
1794
|
rootResults: params.rootResults,
|
|
1796
1795
|
});
|
|
1796
|
+
const containerPort = resolveDockerImageContainerPort(imageRef);
|
|
1797
1797
|
const args = [
|
|
1798
1798
|
'run',
|
|
1799
1799
|
'-d',
|
|
1800
1800
|
'--name',
|
|
1801
1801
|
containerName,
|
|
1802
|
-
'--restart',
|
|
1803
|
-
'always',
|
|
1804
1802
|
'--network',
|
|
1805
1803
|
params.networkName,
|
|
1806
1804
|
'-p',
|
|
1807
|
-
`${appPort}
|
|
1805
|
+
`${appPort}:${containerPort}`,
|
|
1808
1806
|
];
|
|
1809
1807
|
if (envFile) {
|
|
1810
1808
|
args.push('--env-file', envFile);
|
|
@@ -1916,6 +1914,12 @@ export default class Install extends Command {
|
|
|
1916
1914
|
if (results.buildDts) {
|
|
1917
1915
|
argv.push('--build-dts');
|
|
1918
1916
|
}
|
|
1917
|
+
Install.pushDownloadArgIfValue(argv, '--hook-script', results.hookScript);
|
|
1918
|
+
Install.pushDownloadArgIfValue(argv, '--hook-phase', results.hookPhase);
|
|
1919
|
+
Install.pushDownloadArgIfValue(argv, '--hook-command', results.hookCommand);
|
|
1920
|
+
Install.pushDownloadArgIfValue(argv, '--hook-env-name', results.hookEnvName);
|
|
1921
|
+
Install.pushDownloadArgIfValue(argv, '--hook-app-path', results.hookAppPath);
|
|
1922
|
+
Install.pushDownloadArgIfValue(argv, '--hook-storage-path', results.hookStoragePath);
|
|
1919
1923
|
return argv;
|
|
1920
1924
|
}
|
|
1921
1925
|
static resolveLocalProjectRoot(params) {
|
|
@@ -1942,6 +1946,40 @@ export default class Install extends Command {
|
|
|
1942
1946
|
buildDts: false,
|
|
1943
1947
|
};
|
|
1944
1948
|
}
|
|
1949
|
+
static resolveAbsoluteAppPath(envName, appResults) {
|
|
1950
|
+
const configuredAppPath = resolveConfiguredAppPathValue(appResults) ?? defaultInstallAppPath(envName);
|
|
1951
|
+
return resolveConfiguredEnvPath(configuredAppPath) ?? resolveEnvRelativePath(defaultInstallAppPath(envName));
|
|
1952
|
+
}
|
|
1953
|
+
static resolveAbsoluteStoragePath(envName, appResults) {
|
|
1954
|
+
const configuredStoragePath = resolveConfiguredStoragePathValue(appResults, envName);
|
|
1955
|
+
return (resolveConfiguredEnvPath(configuredStoragePath) ?? resolveEnvRelativePath(defaultInstallStoragePath(envName)));
|
|
1956
|
+
}
|
|
1957
|
+
async prepareHookScriptForInstall(params) {
|
|
1958
|
+
const appPath = Install.resolveAbsoluteAppPath(params.envName, params.appResults);
|
|
1959
|
+
const storagePath = Install.resolveAbsoluteStoragePath(params.envName, params.appResults);
|
|
1960
|
+
const inputHookScript = Install.toOptionalPromptString(params.hookScript);
|
|
1961
|
+
if (inputHookScript) {
|
|
1962
|
+
params.appResults.hookScript = await persistHookScript({
|
|
1963
|
+
sourcePath: inputHookScript,
|
|
1964
|
+
appPath,
|
|
1965
|
+
});
|
|
1966
|
+
printInfo(`Saved hook script to ${path.join(appPath, String(params.appResults.hookScript))}.`);
|
|
1967
|
+
}
|
|
1968
|
+
const savedHookScript = Install.toOptionalPromptString(params.appResults.hookScript);
|
|
1969
|
+
const hookScriptPath = resolveHookScriptPath({
|
|
1970
|
+
appPath,
|
|
1971
|
+
hookScript: savedHookScript,
|
|
1972
|
+
});
|
|
1973
|
+
if (!hookScriptPath) {
|
|
1974
|
+
return;
|
|
1975
|
+
}
|
|
1976
|
+
params.downloadResults.hookScript = hookScriptPath;
|
|
1977
|
+
params.downloadResults.hookPhase = 'init';
|
|
1978
|
+
params.downloadResults.hookCommand = 'init';
|
|
1979
|
+
params.downloadResults.hookEnvName = params.envName;
|
|
1980
|
+
params.downloadResults.hookAppPath = appPath;
|
|
1981
|
+
params.downloadResults.hookStoragePath = storagePath;
|
|
1982
|
+
}
|
|
1945
1983
|
commandStdio(verbose) {
|
|
1946
1984
|
return verbose ? 'inherit' : 'ignore';
|
|
1947
1985
|
}
|
|
@@ -1954,12 +1992,15 @@ export default class Install extends Command {
|
|
|
1954
1992
|
}
|
|
1955
1993
|
async ensureSkippedDownloadInputsReady(params) {
|
|
1956
1994
|
if (params.source === 'docker') {
|
|
1995
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
1996
|
+
const configuredVariant = normalizeNbImageVariant(await getCliConfigValue('nb-image-variant')) ?? DEFAULT_NB_IMAGE_VARIANT;
|
|
1957
1997
|
const dockerRegistry = String(downloadResultsValue(params.downloadResults, 'dockerRegistry') ?? '').trim() ||
|
|
1958
|
-
|
|
1998
|
+
resolveOfficialDockerRegistry(configuredRegistry);
|
|
1959
1999
|
const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || DEFAULT_DOCKER_VERSION;
|
|
1960
2000
|
const imageRef = resolveDockerImageRef(dockerRegistry, version, {
|
|
1961
|
-
defaultRegistry:
|
|
2001
|
+
defaultRegistry: resolveOfficialDockerRegistry(configuredRegistry),
|
|
1962
2002
|
defaultVersion: DEFAULT_DOCKER_VERSION,
|
|
2003
|
+
variant: inferNbImageRegistryFromRepository(dockerRegistry) ? configuredVariant : undefined,
|
|
1963
2004
|
});
|
|
1964
2005
|
const imageExists = await commandSucceeds('docker', ['image', 'inspect', imageRef]);
|
|
1965
2006
|
if (!imageExists) {
|
|
@@ -2011,7 +2052,9 @@ export default class Install extends Command {
|
|
|
2011
2052
|
const dbDialect = String(params.dbResults.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
2012
2053
|
const appKey = Install.resolveManagedAppKey(params.appResults.appKey);
|
|
2013
2054
|
const timeZone = Install.resolveManagedTimeZone(params.appResults.timeZone);
|
|
2055
|
+
const lifecycleEnvVars = managedAppLifecycleEnvVars();
|
|
2014
2056
|
const env = {
|
|
2057
|
+
...lifecycleEnvVars,
|
|
2015
2058
|
STORAGE_PATH: storagePath,
|
|
2016
2059
|
APP_PORT: String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT,
|
|
2017
2060
|
APP_KEY: appKey,
|
|
@@ -2216,6 +2259,51 @@ export default class Install extends Command {
|
|
|
2216
2259
|
}
|
|
2217
2260
|
await this.config.runCommand('env:update', [params.envName]);
|
|
2218
2261
|
}
|
|
2262
|
+
buildAppStartArgv(params) {
|
|
2263
|
+
const argv = ['--env', params.envName, '--yes', '--no-sync-licensed-plugins', '--hook-command', 'init'];
|
|
2264
|
+
if (params.verbose) {
|
|
2265
|
+
argv.push('--verbose');
|
|
2266
|
+
}
|
|
2267
|
+
return argv;
|
|
2268
|
+
}
|
|
2269
|
+
async runInstallHookIfNeeded(params) {
|
|
2270
|
+
const appPath = Install.resolveAbsoluteAppPath(params.envName, params.appResults);
|
|
2271
|
+
const savedHookScript = Install.toOptionalPromptString(params.appResults.hookScript);
|
|
2272
|
+
const hookScriptPath = resolveHookScriptPath({
|
|
2273
|
+
appPath,
|
|
2274
|
+
hookScript: savedHookScript,
|
|
2275
|
+
});
|
|
2276
|
+
if (!hookScriptPath) {
|
|
2277
|
+
return;
|
|
2278
|
+
}
|
|
2279
|
+
const storagePath = Install.resolveAbsoluteStoragePath(params.envName, params.appResults);
|
|
2280
|
+
const sourcePath = params.projectRoot ??
|
|
2281
|
+
resolveConfiguredEnvPath(resolveConfiguredSourcePathValue(params.appResults, params.envName)) ??
|
|
2282
|
+
path.join(appPath, 'source');
|
|
2283
|
+
const context = buildHookContext({
|
|
2284
|
+
phase: 'init',
|
|
2285
|
+
command: 'init',
|
|
2286
|
+
envName: params.envName,
|
|
2287
|
+
source: params.source,
|
|
2288
|
+
version: downloadResultsValue(params.downloadResults, 'version'),
|
|
2289
|
+
appPath,
|
|
2290
|
+
sourcePath,
|
|
2291
|
+
storagePath,
|
|
2292
|
+
hookScript: savedHookScript,
|
|
2293
|
+
envConfig: Install.buildSavedEnvConfig(params, {
|
|
2294
|
+
defaultApiHost: params.defaultApiHost,
|
|
2295
|
+
}),
|
|
2296
|
+
});
|
|
2297
|
+
if (!context) {
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
2300
|
+
this.log(`Running hook ${params.hookName}: ${hookScriptPath}`);
|
|
2301
|
+
await runHookScriptHook({
|
|
2302
|
+
hookScriptPath,
|
|
2303
|
+
hookName: params.hookName,
|
|
2304
|
+
context,
|
|
2305
|
+
});
|
|
2306
|
+
}
|
|
2219
2307
|
static buildSavedEnvConfig(params, options = {}) {
|
|
2220
2308
|
const appPath = resolveConfiguredAppPathValue(params.appResults);
|
|
2221
2309
|
const appRootPath = Install.toOptionalPromptString(params.appResults.appRootPath);
|
|
@@ -2247,6 +2335,7 @@ export default class Install extends Command {
|
|
|
2247
2335
|
devDependencies: downloadResultsValue(params.downloadResults, 'devDependencies'),
|
|
2248
2336
|
build: downloadResultsValue(params.downloadResults, 'build'),
|
|
2249
2337
|
buildDts: downloadResultsValue(params.downloadResults, 'buildDts'),
|
|
2338
|
+
hookScript: params.appResults.hookScript,
|
|
2250
2339
|
...(appPath ? { appPath } : {}),
|
|
2251
2340
|
...(appRootPath && !areConfiguredPathsEquivalent(appRootPath, derivedAppRootPath) ? { appRootPath } : {}),
|
|
2252
2341
|
appPort,
|
|
@@ -2311,7 +2400,10 @@ export default class Install extends Command {
|
|
|
2311
2400
|
yesInitialValues: { resume: parsed.resume },
|
|
2312
2401
|
yes,
|
|
2313
2402
|
});
|
|
2314
|
-
|
|
2403
|
+
if (resumePreset?.appPreset?.hookScript !== undefined && appResults.hookScript === undefined) {
|
|
2404
|
+
appResults.hookScript = resumePreset.appPreset.hookScript;
|
|
2405
|
+
}
|
|
2406
|
+
const downloadOpts = await Install.buildDownloadPromptOptionsForInstall(appResults, envName);
|
|
2315
2407
|
downloadOpts.values = {
|
|
2316
2408
|
...(resumePreset?.downloadPreset ?? {}),
|
|
2317
2409
|
...downloadOpts.values,
|
|
@@ -2418,7 +2510,6 @@ export default class Install extends Command {
|
|
|
2418
2510
|
const parsed = {
|
|
2419
2511
|
...flags,
|
|
2420
2512
|
};
|
|
2421
|
-
const defaultApiHost = await resolveDefaultApiHost();
|
|
2422
2513
|
if (parsed['skip-auth'] && (parsed['access-token'] !== undefined || parsed.token !== undefined)) {
|
|
2423
2514
|
this.error('--skip-auth cannot be used with --access-token or --token.');
|
|
2424
2515
|
}
|
|
@@ -2440,6 +2531,12 @@ export default class Install extends Command {
|
|
|
2440
2531
|
appResults,
|
|
2441
2532
|
});
|
|
2442
2533
|
appResults.setupState = 'prepared';
|
|
2534
|
+
await this.prepareHookScriptForInstall({
|
|
2535
|
+
envName,
|
|
2536
|
+
appResults,
|
|
2537
|
+
downloadResults,
|
|
2538
|
+
hookScript: parsed['hook-script'],
|
|
2539
|
+
});
|
|
2443
2540
|
const source = String(downloadResultsValue(downloadResults, 'source') ?? '').trim();
|
|
2444
2541
|
const usesDockerResources = Boolean(dbResults.builtinDb) || source === 'docker';
|
|
2445
2542
|
const dockerNetworkName = usesDockerResources
|
|
@@ -2492,8 +2589,7 @@ export default class Install extends Command {
|
|
|
2492
2589
|
dbResults.dbUser = builtinDbPlan.dbUser;
|
|
2493
2590
|
dbResults.dbPassword = builtinDbPlan.dbPassword;
|
|
2494
2591
|
}
|
|
2495
|
-
let
|
|
2496
|
-
let localAppPlan;
|
|
2592
|
+
let shouldStartApp = false;
|
|
2497
2593
|
if (source === 'docker' || source === 'npm' || source === 'git') {
|
|
2498
2594
|
this.logStage('Preparing application');
|
|
2499
2595
|
if (source === 'docker') {
|
|
@@ -2505,76 +2601,28 @@ export default class Install extends Command {
|
|
|
2505
2601
|
printInfo('Application image ready.');
|
|
2506
2602
|
}
|
|
2507
2603
|
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;
|
|
2604
|
+
shouldStartApp = true;
|
|
2522
2605
|
}
|
|
2523
2606
|
}
|
|
2524
2607
|
else if (source === 'npm' || source === 'git') {
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
? Install.resolveLocalProjectRoot({
|
|
2528
|
-
envName,
|
|
2529
|
-
appResults,
|
|
2530
|
-
downloadResults,
|
|
2531
|
-
})
|
|
2532
|
-
: await this.downloadLocalApp({
|
|
2608
|
+
if (!parsed['skip-download'] && !parsed['prepare-only']) {
|
|
2609
|
+
await this.downloadLocalApp({
|
|
2533
2610
|
envName,
|
|
2534
2611
|
appResults,
|
|
2535
2612
|
downloadResults,
|
|
2536
2613
|
verbose: parsed.verbose,
|
|
2537
2614
|
});
|
|
2538
|
-
if (!parsed['skip-download']) {
|
|
2539
2615
|
printInfo('Application files ready.');
|
|
2540
2616
|
}
|
|
2541
2617
|
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;
|
|
2618
|
+
shouldStartApp = true;
|
|
2553
2619
|
}
|
|
2554
2620
|
}
|
|
2555
2621
|
}
|
|
2556
2622
|
else {
|
|
2557
2623
|
this.logDetail('Skipped app download and install.');
|
|
2558
2624
|
}
|
|
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) {
|
|
2625
|
+
if (shouldStartApp || builtinDbPlan) {
|
|
2578
2626
|
await this.saveInstalledEnv({
|
|
2579
2627
|
envName,
|
|
2580
2628
|
appResults,
|
|
@@ -2584,10 +2632,14 @@ export default class Install extends Command {
|
|
|
2584
2632
|
envAddResults,
|
|
2585
2633
|
});
|
|
2586
2634
|
}
|
|
2635
|
+
if (shouldStartApp) {
|
|
2636
|
+
this.logStage('Starting NocoBase');
|
|
2637
|
+
await this.config.runCommand('app:start', this.buildAppStartArgv({ envName, verbose: parsed.verbose }));
|
|
2638
|
+
}
|
|
2587
2639
|
await this.syncInstalledEnvConnection({
|
|
2588
2640
|
envName,
|
|
2589
2641
|
envAddResults,
|
|
2590
|
-
appReady:
|
|
2642
|
+
appReady: shouldStartApp,
|
|
2591
2643
|
skipAuth: Boolean(parsed['skip-auth']),
|
|
2592
2644
|
});
|
|
2593
2645
|
if (!parsed['prepare-only']) {
|
|
@@ -2596,7 +2648,7 @@ export default class Install extends Command {
|
|
|
2596
2648
|
if (parsed['prepare-only']) {
|
|
2597
2649
|
printInfo(`Preparation complete for "${envName}". Activate the license, then run \`nb app start --env ${envName}\`.`);
|
|
2598
2650
|
}
|
|
2599
|
-
else if (!
|
|
2651
|
+
else if (!shouldStartApp) {
|
|
2600
2652
|
printInfo(`Install config for "${envName}" has been saved.`);
|
|
2601
2653
|
}
|
|
2602
2654
|
}
|
|
@@ -143,11 +143,14 @@ export default class LicenseActivate extends Command {
|
|
|
143
143
|
const validation = await validateLicenseKey(runtime, resolvedKey);
|
|
144
144
|
const ok = !validation.keyStatus && validation.envMatch && validation.domainMatch && validation.licenseStatus === 'active';
|
|
145
145
|
const licenseKeyPath = ok ? await saveLicenseKey(runtime, resolvedKey) : resolveLicenseKeyFile(runtime);
|
|
146
|
+
const shouldResolveInstanceId = Boolean(interactiveKeyFlowInstanceId || ok || (flags.json && !validation.keyStatus));
|
|
146
147
|
const payload = {
|
|
147
148
|
ok,
|
|
148
149
|
env: runtime.envName,
|
|
149
150
|
kind: runtime.kind,
|
|
150
|
-
instanceId:
|
|
151
|
+
instanceId: shouldResolveInstanceId
|
|
152
|
+
? interactiveKeyFlowInstanceId ?? (await ensureInstanceId(runtime))
|
|
153
|
+
: undefined,
|
|
151
154
|
mode: 'key',
|
|
152
155
|
key: redactLicenseKey(resolvedKey),
|
|
153
156
|
keyFile: keyFile || undefined,
|