@nocobase/cli 2.1.0-alpha.46 → 2.1.0-alpha.47
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/LICENSE +201 -0
- package/README.md +63 -380
- package/assets/env-proxy/nginx/app.conf.tpl +23 -0
- package/assets/env-proxy/nginx/nocobase.conf.tpl +5 -0
- package/assets/env-proxy/nginx/snippets/dist-location.conf +5 -0
- package/assets/env-proxy/nginx/snippets/gzip.conf +17 -0
- package/assets/env-proxy/nginx/snippets/log-format-http.conf +13 -0
- package/assets/env-proxy/nginx/snippets/maps-http.conf +14 -0
- package/assets/env-proxy/nginx/snippets/mime-types.conf +98 -0
- package/assets/env-proxy/nginx/snippets/proxy-location.conf +17 -0
- package/assets/env-proxy/nginx/snippets/spa-location.conf +6 -0
- package/assets/env-proxy/nginx/snippets/uploads-location.conf +21 -0
- package/bin/run.js +40 -3
- package/dist/commands/app/autostart/disable.js +55 -0
- package/dist/commands/app/autostart/enable.js +55 -0
- package/dist/commands/app/autostart/list.js +37 -0
- package/dist/commands/app/autostart/run.js +84 -0
- package/dist/commands/app/autostart/shared.js +49 -0
- package/dist/commands/app/destroy.js +21 -12
- package/dist/commands/app/down.js +2 -2
- package/dist/commands/app/logs.js +2 -1
- package/dist/commands/app/restart.js +89 -24
- package/dist/commands/app/shared.js +3 -2
- package/dist/commands/app/start.js +142 -38
- package/dist/commands/app/stop.js +31 -2
- package/dist/commands/app/upgrade.js +9 -5
- package/dist/commands/config/delete.js +6 -1
- package/dist/commands/config/get.js +6 -1
- package/dist/commands/config/set.js +7 -2
- package/dist/commands/env/add.js +24 -44
- package/dist/commands/env/info.js +3 -2
- package/dist/commands/env/proxy/caddy.js +28 -0
- package/dist/commands/env/proxy/index.js +353 -0
- package/dist/commands/env/proxy/nginx.js +28 -0
- package/dist/commands/env/remove.js +112 -22
- package/dist/commands/env/shared.js +17 -9
- package/dist/commands/env/update.js +385 -21
- package/dist/commands/init.js +350 -98
- package/dist/commands/install.js +218 -75
- package/dist/commands/license/activate.js +63 -244
- package/dist/commands/license/plugins/shared.js +64 -13
- package/dist/commands/plugin/import.js +108 -0
- package/dist/commands/revision/create.js +89 -0
- package/dist/commands/source/test.js +13 -14
- package/dist/lib/app-health.js +5 -5
- package/dist/lib/app-managed-resources.js +24 -8
- package/dist/lib/app-public-path.js +80 -0
- package/dist/lib/app-runtime.js +10 -1
- package/dist/lib/auth-store.js +119 -4
- package/dist/lib/cli-config.js +191 -3
- package/dist/lib/cli-entry-error.js +8 -0
- package/dist/lib/command-log.js +284 -0
- package/dist/lib/docker-env-file.js +10 -2
- package/dist/lib/env-auth.js +4 -1
- package/dist/lib/env-command-config.js +45 -0
- package/dist/lib/env-config.js +7 -2
- package/dist/lib/env-guard.js +9 -10
- package/dist/lib/env-paths.js +101 -0
- package/dist/lib/env-proxy.js +1295 -0
- package/dist/lib/inquirer.js +4 -5
- package/dist/lib/managed-env-file.js +98 -0
- package/dist/lib/plugin-import.js +279 -0
- package/dist/lib/prompt-catalog-core.js +3 -2
- package/dist/lib/prompt-validators.js +14 -0
- package/dist/lib/prompt-web-ui.js +8 -1
- package/dist/lib/run-npm.js +56 -12
- package/dist/lib/skills-manager.js +3 -1
- package/dist/lib/source-publish.js +18 -1
- package/dist/lib/ui.js +2 -1
- package/dist/locale/en-US.json +116 -22
- package/dist/locale/zh-CN.json +113 -19
- package/package.json +5 -7
- package/scripts/build.mjs +34 -0
- package/scripts/clean.mjs +9 -0
- package/tsconfig.json +19 -0
- package/LICENSE.txt +0 -107
- package/README.zh-CN.md +0 -355
package/dist/commands/init.js
CHANGED
|
@@ -16,6 +16,8 @@ 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
18
|
import { resolveDefaultConfigScope } from '../lib/cli-home.js';
|
|
19
|
+
import { resolveDefaultApiHost, resolveDefaultUiHost } from '../lib/cli-config.js';
|
|
20
|
+
import { areConfiguredPathsEquivalent, deriveConfiguredSourcePath, deriveConfiguredStoragePath, inferConfiguredAppPathFromLegacyConfig, } from '../lib/env-paths.js';
|
|
19
21
|
import { runPromptCatalogWebUI } from "../lib/prompt-web-ui.js";
|
|
20
22
|
import { validateApiBaseUrl, validateEnvKey } from "../lib/prompt-validators.js";
|
|
21
23
|
import { installNocoBaseSkills, isNpmRegistryUnavailable } from '../lib/skills-manager.js';
|
|
@@ -27,6 +29,7 @@ import Install, { defaultDbPortForDialect } from "./install.js";
|
|
|
27
29
|
const DEFAULT_INIT_API_BASE_URL = 'http://localhost:13000/api';
|
|
28
30
|
const DEFAULT_INIT_APP_NAME = 'local';
|
|
29
31
|
const DOWNLOAD_OUTPUT_DIR_PROMPT = Download.prompts.outputDir;
|
|
32
|
+
const INIT_SETUP_MODES = ['install-new', 'manage-local', 'connect-remote'];
|
|
30
33
|
const INIT_ENV_ADD_FLAG_NAMES = [
|
|
31
34
|
'locale',
|
|
32
35
|
'default-api-base-url',
|
|
@@ -48,14 +51,45 @@ function withExtraHidden(def, extraHidden) {
|
|
|
48
51
|
hidden: (values) => extraHidden(values) || (def.hidden?.(values) ?? false),
|
|
49
52
|
};
|
|
50
53
|
}
|
|
51
|
-
function
|
|
52
|
-
|
|
54
|
+
function normalizeInitSetupMode(value) {
|
|
55
|
+
const mode = String(value ?? '').trim();
|
|
56
|
+
if (mode === 'manage-local' || mode === 'connect-remote' || mode === 'install-new') {
|
|
57
|
+
return mode;
|
|
58
|
+
}
|
|
59
|
+
if (mode === 'yes') {
|
|
60
|
+
return 'connect-remote';
|
|
61
|
+
}
|
|
62
|
+
if (mode === 'no') {
|
|
63
|
+
return 'install-new';
|
|
64
|
+
}
|
|
65
|
+
return 'install-new';
|
|
66
|
+
}
|
|
67
|
+
function resolveInitSetupMode(values) {
|
|
68
|
+
return normalizeInitSetupMode(values.setupMode ?? values.hasNocobase);
|
|
69
|
+
}
|
|
70
|
+
function isRemoteSetupMode(values) {
|
|
71
|
+
return resolveInitSetupMode(values) === 'connect-remote';
|
|
72
|
+
}
|
|
73
|
+
function isInstallNewSetupMode(values) {
|
|
74
|
+
return resolveInitSetupMode(values) === 'install-new';
|
|
53
75
|
}
|
|
54
|
-
function
|
|
55
|
-
return
|
|
76
|
+
function isInstallLikeSetupMode(values) {
|
|
77
|
+
return !isRemoteSetupMode(values);
|
|
56
78
|
}
|
|
57
|
-
function
|
|
58
|
-
return withExtraHidden(def, (values) => values
|
|
79
|
+
function remoteConnectionOnly(def) {
|
|
80
|
+
return withExtraHidden(def, (values) => !isRemoteSetupMode(values));
|
|
81
|
+
}
|
|
82
|
+
function installLikeOnly(def) {
|
|
83
|
+
return withExtraHidden(def, (values) => !isInstallLikeSetupMode(values));
|
|
84
|
+
}
|
|
85
|
+
function installNewOnly(def) {
|
|
86
|
+
return withExtraHidden(def, (values) => !isInstallNewSetupMode(values));
|
|
87
|
+
}
|
|
88
|
+
function installConnectionOnly(def) {
|
|
89
|
+
return withExtraHidden(def, (values) => !isInstallNewSetupMode(values));
|
|
90
|
+
}
|
|
91
|
+
function installLikeDownloadExecutionOnly(def) {
|
|
92
|
+
return withExtraHidden(def, (values) => !isInstallLikeSetupMode(values) || values.skipDownload === true);
|
|
59
93
|
}
|
|
60
94
|
function argvHasToken(argv, tokens) {
|
|
61
95
|
return tokens.some((token) => argv.includes(token));
|
|
@@ -85,6 +119,26 @@ function explicitApiBaseUrlFlag(flags) {
|
|
|
85
119
|
function explicitDbHostFlag(flags) {
|
|
86
120
|
return String(flags['db-host'] ?? '').trim();
|
|
87
121
|
}
|
|
122
|
+
function explicitSetupModeFlag(flags) {
|
|
123
|
+
const mode = String(flags['setup-mode'] ?? '').trim();
|
|
124
|
+
return mode ? normalizeInitSetupMode(mode) : undefined;
|
|
125
|
+
}
|
|
126
|
+
function applyLegacyHasNocobaseAlias(values) {
|
|
127
|
+
if (!Object.prototype.hasOwnProperty.call(values, 'setupMode') &&
|
|
128
|
+
!Object.prototype.hasOwnProperty.call(values, 'hasNocobase')) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const setupMode = resolveInitSetupMode(values);
|
|
132
|
+
if (setupMode === 'connect-remote') {
|
|
133
|
+
values.hasNocobase = 'yes';
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (setupMode === 'install-new') {
|
|
137
|
+
values.hasNocobase = 'no';
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
delete values.hasNocobase;
|
|
141
|
+
}
|
|
88
142
|
function optionalInitString(value) {
|
|
89
143
|
const text = String(value ?? '').trim();
|
|
90
144
|
return text || undefined;
|
|
@@ -95,6 +149,39 @@ function resolveManagedAppKey(value) {
|
|
|
95
149
|
function resolveManagedTimeZone(value) {
|
|
96
150
|
return optionalInitString(value) ?? (Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC');
|
|
97
151
|
}
|
|
152
|
+
function normalizeConnectionString(value) {
|
|
153
|
+
return String(value ?? '').trim();
|
|
154
|
+
}
|
|
155
|
+
function deriveInstallConnectionApiBaseUrl(values, defaultApiHost = '127.0.0.1') {
|
|
156
|
+
const appPort = normalizeConnectionString(values.appPort);
|
|
157
|
+
return appPort ? `http://${defaultApiHost}:${appPort}/api` : DEFAULT_INIT_API_BASE_URL;
|
|
158
|
+
}
|
|
159
|
+
function createInstallConnectionApiBaseUrlPrompt(defaultApiHost) {
|
|
160
|
+
return installConnectionOnly({
|
|
161
|
+
type: 'text',
|
|
162
|
+
message: initText('prompts.apiBaseUrl.message'),
|
|
163
|
+
placeholder: initText('prompts.apiBaseUrl.placeholder'),
|
|
164
|
+
required: true,
|
|
165
|
+
initialValue: (values) => deriveInstallConnectionApiBaseUrl(values, defaultApiHost),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const installConnectionAuthTypePrompt = installConnectionOnly({
|
|
169
|
+
...EnvAdd.prompts.authType,
|
|
170
|
+
});
|
|
171
|
+
const installConnectionUsernamePrompt = installConnectionOnly({
|
|
172
|
+
...Install.rootUserPrompts.rootUsername,
|
|
173
|
+
hidden: () => true,
|
|
174
|
+
initialValue: (values) => normalizeConnectionString(values.rootUsername),
|
|
175
|
+
});
|
|
176
|
+
const installConnectionPasswordPrompt = installConnectionOnly({
|
|
177
|
+
...Install.rootUserPrompts.rootPassword,
|
|
178
|
+
hidden: () => true,
|
|
179
|
+
initialValue: (values) => String(values.rootPassword ?? ''),
|
|
180
|
+
});
|
|
181
|
+
const installConnectionAccessTokenPrompt = installConnectionOnly({
|
|
182
|
+
...EnvAdd.prompts.accessToken,
|
|
183
|
+
hidden: (values) => values.installAuthType !== 'token' || values.skipAuth === true,
|
|
184
|
+
});
|
|
98
185
|
function shouldAllowExistingInitEnv() {
|
|
99
186
|
return argvHasToken(process.argv.slice(2), ['--force', '-f']);
|
|
100
187
|
}
|
|
@@ -161,10 +248,11 @@ export default class Init extends Command {
|
|
|
161
248
|
static summary = 'Set up NocoBase so coding agents can connect and work with it';
|
|
162
249
|
static description = `Set up NocoBase for coding agents in the current workspace.
|
|
163
250
|
|
|
164
|
-
\`nb init\` prepares a NocoBase environment that coding agents can use. It supports
|
|
251
|
+
\`nb init\` prepares a NocoBase environment that coding agents can use. It supports three setup paths:
|
|
165
252
|
|
|
166
|
-
- Connect an existing NocoBase app and save it as a CLI env.
|
|
167
253
|
- Install a new NocoBase app, then save it as a CLI env.
|
|
254
|
+
- Take over managing an app that already exists on this machine by reusing its database.
|
|
255
|
+
- Connect a remote NocoBase app and save it as a CLI env.
|
|
168
256
|
|
|
169
257
|
It can also install NocoBase AI coding skills (\`nocobase/skills\`) so agents get the project-specific workflow guidance.
|
|
170
258
|
|
|
@@ -173,7 +261,7 @@ If setup was interrupted earlier, use \`--resume\` with an existing env name to
|
|
|
173
261
|
Prompt modes:
|
|
174
262
|
- Default: guided prompts in the terminal.
|
|
175
263
|
- \`--ui\`: open the same setup flow in a local browser form.
|
|
176
|
-
- \`-y\`, \`--yes\`: skip prompts. In this mode \`--env <envName>\` is required, and init
|
|
264
|
+
- \`-y\`, \`--yes\`: skip prompts. In this mode \`--env <envName>\` is required, and init uses flags plus safe defaults for the selected setup mode.
|
|
177
265
|
|
|
178
266
|
\`--ui\` cannot be combined with \`--yes\`.`;
|
|
179
267
|
static examples = [
|
|
@@ -184,8 +272,10 @@ Prompt modes:
|
|
|
184
272
|
'<%= config.bin %> <%= command.id %> --env app1 --yes',
|
|
185
273
|
'<%= config.bin %> <%= command.id %> --env app1 --resume',
|
|
186
274
|
'<%= config.bin %> <%= command.id %> --env app1 --yes --source docker --version alpha',
|
|
275
|
+
'<%= config.bin %> <%= command.id %> --env app1 --yes --setup-mode manage-local --source npm --version beta',
|
|
187
276
|
'<%= config.bin %> <%= command.id %> --env app1 --yes --source npm --version alpha --app-port 13080',
|
|
188
277
|
'<%= config.bin %> <%= command.id %> --env app1 --yes --source git --version fix/cli-v2',
|
|
278
|
+
'<%= config.bin %> <%= command.id %> --env staging --yes --setup-mode connect-remote --api-base-url https://demo.example.com/api',
|
|
189
279
|
'<%= config.bin %> <%= command.id %> --ui --ui-port 3000',
|
|
190
280
|
];
|
|
191
281
|
static prompts = {
|
|
@@ -216,53 +306,61 @@ Prompt modes:
|
|
|
216
306
|
required: true,
|
|
217
307
|
validate: validateInitAppName,
|
|
218
308
|
},
|
|
219
|
-
|
|
309
|
+
setupMode: {
|
|
220
310
|
type: 'select',
|
|
221
311
|
variant: 'radio',
|
|
222
|
-
message: initText('prompts.
|
|
312
|
+
message: initText('prompts.setupMode.message'),
|
|
223
313
|
options: [
|
|
224
314
|
{
|
|
225
|
-
value: '
|
|
226
|
-
label: initText('prompts.
|
|
315
|
+
value: 'install-new',
|
|
316
|
+
label: initText('prompts.setupMode.installNewLabel'),
|
|
317
|
+
hint: initText('prompts.setupMode.installNewHint'),
|
|
227
318
|
},
|
|
228
319
|
{
|
|
229
|
-
value: '
|
|
230
|
-
label: initText('prompts.
|
|
320
|
+
value: 'connect-remote',
|
|
321
|
+
label: initText('prompts.setupMode.connectRemoteLabel'),
|
|
322
|
+
hint: initText('prompts.setupMode.connectRemoteHint'),
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
value: 'manage-local',
|
|
326
|
+
label: initText('prompts.setupMode.manageLocalLabel'),
|
|
327
|
+
hint: initText('prompts.setupMode.manageLocalHint'),
|
|
328
|
+
disabled: true,
|
|
231
329
|
},
|
|
232
330
|
],
|
|
233
|
-
initialValue: '
|
|
234
|
-
yesInitialValue: '
|
|
331
|
+
initialValue: 'install-new',
|
|
332
|
+
yesInitialValue: 'install-new',
|
|
235
333
|
required: true,
|
|
236
334
|
},
|
|
237
|
-
apiBaseUrl:
|
|
335
|
+
apiBaseUrl: remoteConnectionOnly({
|
|
238
336
|
type: 'text',
|
|
239
337
|
message: initText('prompts.apiBaseUrl.message'),
|
|
240
338
|
placeholder: initText('prompts.apiBaseUrl.placeholder'),
|
|
241
339
|
required: true,
|
|
242
340
|
validate: validateApiBaseUrl,
|
|
243
341
|
}),
|
|
244
|
-
authType:
|
|
245
|
-
username:
|
|
246
|
-
password:
|
|
247
|
-
accessToken:
|
|
248
|
-
lang:
|
|
249
|
-
|
|
250
|
-
appPort:
|
|
251
|
-
|
|
252
|
-
skipDownload:
|
|
342
|
+
authType: remoteConnectionOnly(EnvAdd.prompts.authType),
|
|
343
|
+
username: remoteConnectionOnly(EnvAdd.prompts.username),
|
|
344
|
+
password: remoteConnectionOnly(EnvAdd.prompts.password),
|
|
345
|
+
accessToken: remoteConnectionOnly(EnvAdd.prompts.accessToken),
|
|
346
|
+
lang: installLikeOnly(Install.appPrompts.lang),
|
|
347
|
+
appPath: installLikeOnly(Install.appPrompts.appPath),
|
|
348
|
+
appPort: installLikeOnly(Install.appPrompts.appPort),
|
|
349
|
+
appPublicPath: installLikeOnly(Install.appPrompts.appPublicPath),
|
|
350
|
+
skipDownload: installNewOnly({
|
|
253
351
|
type: 'boolean',
|
|
254
352
|
message: initText('prompts.skipDownload.message'),
|
|
255
353
|
initialValue: false,
|
|
256
354
|
yesInitialValue: false,
|
|
257
355
|
}),
|
|
258
|
-
source:
|
|
259
|
-
version:
|
|
260
|
-
otherVersion:
|
|
261
|
-
dockerRegistry:
|
|
262
|
-
dockerPlatform:
|
|
263
|
-
dockerSave:
|
|
264
|
-
gitUrl:
|
|
265
|
-
outputDir:
|
|
356
|
+
source: installLikeOnly(Download.prompts.source),
|
|
357
|
+
version: installLikeOnly(Download.prompts.version),
|
|
358
|
+
otherVersion: installLikeOnly(Download.prompts.otherVersion),
|
|
359
|
+
dockerRegistry: installLikeOnly(Download.prompts.dockerRegistry),
|
|
360
|
+
dockerPlatform: installLikeOnly(Download.prompts.dockerPlatform),
|
|
361
|
+
dockerSave: installLikeDownloadExecutionOnly(Download.prompts.dockerSave),
|
|
362
|
+
gitUrl: installLikeOnly(Download.prompts.gitUrl),
|
|
363
|
+
outputDir: installLikeDownloadExecutionOnly({
|
|
266
364
|
...DOWNLOAD_OUTPUT_DIR_PROMPT,
|
|
267
365
|
hidden: (values) => {
|
|
268
366
|
const source = String(values.source ?? '').trim();
|
|
@@ -274,7 +372,8 @@ Prompt modes:
|
|
|
274
372
|
initialValue: (values) => {
|
|
275
373
|
const source = String(values.source ?? '').trim();
|
|
276
374
|
if (source === 'npm' || source === 'git') {
|
|
277
|
-
const
|
|
375
|
+
const appPath = String(values.appPath ?? inferConfiguredAppPathFromLegacyConfig(values) ?? '').trim();
|
|
376
|
+
const appRootPath = String(values.appRootPath ?? '').trim() || (appPath ? deriveConfiguredSourcePath(appPath) : '');
|
|
278
377
|
if (appRootPath) {
|
|
279
378
|
return appRootPath;
|
|
280
379
|
}
|
|
@@ -283,30 +382,35 @@ Prompt modes:
|
|
|
283
382
|
return typeof initialValue === 'function' ? initialValue(values) : String(initialValue ?? '');
|
|
284
383
|
},
|
|
285
384
|
}),
|
|
286
|
-
npmRegistry:
|
|
287
|
-
replace:
|
|
288
|
-
devDependencies:
|
|
289
|
-
build:
|
|
290
|
-
buildDts:
|
|
291
|
-
dbDialect:
|
|
292
|
-
builtinDb:
|
|
293
|
-
builtinDbImage:
|
|
294
|
-
dbHost:
|
|
295
|
-
dbPort:
|
|
296
|
-
dbDatabase:
|
|
297
|
-
dbUser:
|
|
298
|
-
dbPassword:
|
|
299
|
-
dbSchema:
|
|
300
|
-
dbTablePrefix:
|
|
301
|
-
dbUnderscored:
|
|
302
|
-
rootUsername:
|
|
303
|
-
rootEmail:
|
|
304
|
-
rootPassword:
|
|
305
|
-
rootNickname:
|
|
385
|
+
npmRegistry: installLikeOnly(Download.prompts.npmRegistry),
|
|
386
|
+
replace: installLikeDownloadExecutionOnly(Download.prompts.replace),
|
|
387
|
+
devDependencies: installLikeDownloadExecutionOnly(Download.prompts.devDependencies),
|
|
388
|
+
build: installLikeDownloadExecutionOnly(Download.prompts.build),
|
|
389
|
+
buildDts: installLikeDownloadExecutionOnly(Download.prompts.buildDts),
|
|
390
|
+
dbDialect: installLikeOnly(Install.dbPrompts.dbDialect),
|
|
391
|
+
builtinDb: installLikeOnly(Install.dbPrompts.builtinDb),
|
|
392
|
+
builtinDbImage: installLikeOnly(Install.dbPrompts.builtinDbImage),
|
|
393
|
+
dbHost: installLikeOnly(Install.dbPrompts.dbHost),
|
|
394
|
+
dbPort: installLikeOnly(Install.dbPrompts.dbPort),
|
|
395
|
+
dbDatabase: installLikeOnly(Install.dbPrompts.dbDatabase),
|
|
396
|
+
dbUser: installLikeOnly(Install.dbPrompts.dbUser),
|
|
397
|
+
dbPassword: installLikeOnly(Install.dbPrompts.dbPassword),
|
|
398
|
+
dbSchema: installLikeOnly(Install.dbPrompts.dbSchema),
|
|
399
|
+
dbTablePrefix: installLikeOnly(Install.dbPrompts.dbTablePrefix),
|
|
400
|
+
dbUnderscored: installLikeOnly(Install.dbPrompts.dbUnderscored),
|
|
401
|
+
rootUsername: installNewOnly(Install.rootUserPrompts.rootUsername),
|
|
402
|
+
rootEmail: installNewOnly(Install.rootUserPrompts.rootEmail),
|
|
403
|
+
rootPassword: installNewOnly(Install.rootUserPrompts.rootPassword),
|
|
404
|
+
rootNickname: installNewOnly(Install.rootUserPrompts.rootNickname),
|
|
405
|
+
installAuthType: installConnectionAuthTypePrompt,
|
|
406
|
+
installUsername: installConnectionUsernamePrompt,
|
|
407
|
+
installPassword: installConnectionPasswordPrompt,
|
|
408
|
+
installAccessToken: installConnectionAccessTokenPrompt,
|
|
306
409
|
};
|
|
307
|
-
buildPromptCatalog(flags) {
|
|
410
|
+
buildPromptCatalog(flags, options) {
|
|
308
411
|
const prompts = {
|
|
309
412
|
...Init.prompts,
|
|
413
|
+
installApiBaseUrl: createInstallConnectionApiBaseUrlPrompt(options.defaultApiHost),
|
|
310
414
|
};
|
|
311
415
|
if (flags['skip-auth']) {
|
|
312
416
|
const accessTokenPrompt = {
|
|
@@ -321,9 +425,24 @@ Prompt modes:
|
|
|
321
425
|
...EnvAdd.prompts.password,
|
|
322
426
|
hidden: () => true,
|
|
323
427
|
};
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
428
|
+
const installAccessTokenPrompt = {
|
|
429
|
+
...installConnectionAccessTokenPrompt,
|
|
430
|
+
hidden: () => true,
|
|
431
|
+
};
|
|
432
|
+
const installUsernamePrompt = {
|
|
433
|
+
...installConnectionUsernamePrompt,
|
|
434
|
+
hidden: () => true,
|
|
435
|
+
};
|
|
436
|
+
const installPasswordPrompt = {
|
|
437
|
+
...installConnectionPasswordPrompt,
|
|
438
|
+
hidden: () => true,
|
|
439
|
+
};
|
|
440
|
+
prompts.username = remoteConnectionOnly(usernamePrompt);
|
|
441
|
+
prompts.password = remoteConnectionOnly(passwordPrompt);
|
|
442
|
+
prompts.accessToken = remoteConnectionOnly(accessTokenPrompt);
|
|
443
|
+
prompts.installUsername = installUsernamePrompt;
|
|
444
|
+
prompts.installPassword = installPasswordPrompt;
|
|
445
|
+
prompts.installAccessToken = installAccessTokenPrompt;
|
|
327
446
|
}
|
|
328
447
|
return prompts;
|
|
329
448
|
}
|
|
@@ -331,13 +450,17 @@ Prompt modes:
|
|
|
331
450
|
static flags = {
|
|
332
451
|
yes: Flags.boolean({
|
|
333
452
|
char: 'y',
|
|
334
|
-
description: 'Skip prompts and
|
|
453
|
+
description: 'Skip prompts and use flags plus defaults for the selected setup mode. Requires an env name.',
|
|
335
454
|
default: false,
|
|
336
455
|
}),
|
|
337
456
|
env: Flags.string({
|
|
338
457
|
char: 'e',
|
|
339
458
|
description: 'Env name for this setup. Required with --yes and --resume',
|
|
340
459
|
}),
|
|
460
|
+
'setup-mode': Flags.string({
|
|
461
|
+
description: 'Setup mode: install a new app, manage a local app by reusing its database, or connect a remote app',
|
|
462
|
+
options: [...INIT_SETUP_MODES],
|
|
463
|
+
}),
|
|
341
464
|
ui: Flags.boolean({
|
|
342
465
|
description: 'Open the guided setup flow in a local browser form (not valid with --yes)',
|
|
343
466
|
default: false,
|
|
@@ -442,7 +565,9 @@ Prompt modes:
|
|
|
442
565
|
}
|
|
443
566
|
}
|
|
444
567
|
const dynamicInitialValues = await Init.buildDynamicInitialValuesForInstall(normalizedFlags, presetValues);
|
|
445
|
-
const
|
|
568
|
+
const defaultUiHost = await resolveDefaultUiHost();
|
|
569
|
+
const defaultApiHost = await resolveDefaultApiHost();
|
|
570
|
+
const promptCatalog = this.buildPromptCatalog(normalizedFlags, { defaultApiHost });
|
|
446
571
|
if (useBrowserUi) {
|
|
447
572
|
presetValues = await runPromptCatalogWebUI({
|
|
448
573
|
stages: Init.buildWebUiStages(promptCatalog),
|
|
@@ -450,7 +575,7 @@ Prompt modes:
|
|
|
450
575
|
...dynamicInitialValues,
|
|
451
576
|
...presetValues,
|
|
452
577
|
},
|
|
453
|
-
host: normalizedFlags['ui-host']?.trim() ||
|
|
578
|
+
host: normalizedFlags['ui-host']?.trim() || defaultUiHost,
|
|
454
579
|
port: normalizedFlags['ui-port'] ?? 0,
|
|
455
580
|
pageTitle: initText('webUi.pageTitle'),
|
|
456
581
|
documentHeading: initText('webUi.documentHeading'),
|
|
@@ -465,7 +590,12 @@ Prompt modes:
|
|
|
465
590
|
});
|
|
466
591
|
}
|
|
467
592
|
const results = await runPromptCatalog(promptCatalog, {
|
|
468
|
-
initialValues:
|
|
593
|
+
initialValues: {
|
|
594
|
+
...dynamicInitialValues,
|
|
595
|
+
...(presetValues.setupMode === undefined && presetValues.hasNocobase !== undefined
|
|
596
|
+
? { setupMode: normalizeInitSetupMode(presetValues.hasNocobase) }
|
|
597
|
+
: {}),
|
|
598
|
+
},
|
|
469
599
|
values: presetValues,
|
|
470
600
|
yes: normalizedFlags.yes || useBrowserUi || !interactive,
|
|
471
601
|
hooks: {
|
|
@@ -480,21 +610,28 @@ Prompt modes:
|
|
|
480
610
|
},
|
|
481
611
|
command: this,
|
|
482
612
|
});
|
|
483
|
-
const normalizedResults = {
|
|
613
|
+
const normalizedResults = this.normalizeInitResults({
|
|
484
614
|
...pickKeys(presetValues, [
|
|
615
|
+
'defaultApiHost',
|
|
485
616
|
'authType',
|
|
486
617
|
'accessToken',
|
|
487
618
|
'dbSchema',
|
|
488
619
|
'dbTablePrefix',
|
|
489
620
|
'dbUnderscored',
|
|
621
|
+
'installApiBaseUrl',
|
|
622
|
+
'installAuthType',
|
|
623
|
+
'installAccessToken',
|
|
624
|
+
'installUsername',
|
|
625
|
+
'installPassword',
|
|
490
626
|
'skipAuth',
|
|
491
627
|
'username',
|
|
492
628
|
'password',
|
|
493
629
|
]),
|
|
630
|
+
defaultApiHost,
|
|
494
631
|
...results,
|
|
495
|
-
};
|
|
496
|
-
const
|
|
497
|
-
const existingEnv =
|
|
632
|
+
});
|
|
633
|
+
const setupMode = resolveInitSetupMode(normalizedResults);
|
|
634
|
+
const existingEnv = isInstallLikeSetupMode(normalizedResults)
|
|
498
635
|
? await getEnv(String(normalizedResults.appName ?? '').trim(), { scope: resolveDefaultConfigScope() })
|
|
499
636
|
: undefined;
|
|
500
637
|
if (existingEnv && Boolean(normalizedFlags.force)) {
|
|
@@ -506,7 +643,7 @@ Prompt modes:
|
|
|
506
643
|
let managedInstallResults;
|
|
507
644
|
try {
|
|
508
645
|
// oclif explicit registry keys use `:` (e.g. `env:add`); users still type `nb env add`.
|
|
509
|
-
if (
|
|
646
|
+
if (setupMode === 'connect-remote') {
|
|
510
647
|
logInitStage('Connecting to the env');
|
|
511
648
|
printVerbose('Running nb env add');
|
|
512
649
|
await this.config.runCommand('env:add', this.buildEnvAddArgv(normalizedResults));
|
|
@@ -536,6 +673,7 @@ Prompt modes:
|
|
|
536
673
|
envName: String(presetValues.appName ?? '').trim(),
|
|
537
674
|
flags: {
|
|
538
675
|
...flags,
|
|
676
|
+
'app-path': flags['app-path'] ?? '',
|
|
539
677
|
'app-root-path': flags['app-root-path'] ?? '',
|
|
540
678
|
'storage-path': flags['storage-path'] ?? '',
|
|
541
679
|
},
|
|
@@ -569,7 +707,7 @@ Prompt modes:
|
|
|
569
707
|
sectionDescription: initText('webUi.gettingStarted.description'),
|
|
570
708
|
catalog: {
|
|
571
709
|
appName: c.appName,
|
|
572
|
-
|
|
710
|
+
setupMode: c.setupMode,
|
|
573
711
|
},
|
|
574
712
|
},
|
|
575
713
|
{
|
|
@@ -588,9 +726,9 @@ Prompt modes:
|
|
|
588
726
|
sectionDescription: initText('webUi.createNewApp.description'),
|
|
589
727
|
catalog: {
|
|
590
728
|
lang: c.lang,
|
|
591
|
-
|
|
729
|
+
appPath: c.appPath,
|
|
592
730
|
appPort: c.appPort,
|
|
593
|
-
|
|
731
|
+
appPublicPath: c.appPublicPath,
|
|
594
732
|
skipDownload: c.skipDownload,
|
|
595
733
|
},
|
|
596
734
|
},
|
|
@@ -640,24 +778,42 @@ Prompt modes:
|
|
|
640
778
|
rootNickname: c.rootNickname,
|
|
641
779
|
},
|
|
642
780
|
},
|
|
781
|
+
{
|
|
782
|
+
sectionTitle: initText('webUi.connectExistingApp.title'),
|
|
783
|
+
sectionDescription: initText('webUi.connectExistingApp.description'),
|
|
784
|
+
catalog: {
|
|
785
|
+
installApiBaseUrl: c.installApiBaseUrl,
|
|
786
|
+
installAuthType: c.installAuthType,
|
|
787
|
+
installAccessToken: c.installAccessToken,
|
|
788
|
+
},
|
|
789
|
+
},
|
|
643
790
|
];
|
|
644
791
|
}
|
|
645
792
|
buildPresetValuesFromFlags(flags) {
|
|
646
793
|
const preset = {};
|
|
647
794
|
const argv = process.argv.slice(2);
|
|
795
|
+
const setupMode = explicitSetupModeFlag(flags);
|
|
648
796
|
if (flags.env !== undefined && String(flags.env).trim() !== '') {
|
|
649
797
|
preset.appName = String(flags.env).trim();
|
|
650
798
|
}
|
|
799
|
+
if (setupMode) {
|
|
800
|
+
preset.setupMode = setupMode;
|
|
801
|
+
}
|
|
651
802
|
const apiBaseUrl = explicitApiBaseUrlFlag(flags);
|
|
652
803
|
if (apiBaseUrl) {
|
|
653
|
-
preset.
|
|
804
|
+
preset.setupMode ??= 'connect-remote';
|
|
654
805
|
preset.apiBaseUrl = apiBaseUrl;
|
|
806
|
+
preset.installApiBaseUrl = apiBaseUrl;
|
|
655
807
|
}
|
|
656
808
|
else if (flags['default-api-base-url'] !== undefined && String(flags['default-api-base-url']).trim() !== '') {
|
|
657
|
-
|
|
809
|
+
const defaultApiBaseUrl = String(flags['default-api-base-url']).trim();
|
|
810
|
+
preset.apiBaseUrl = defaultApiBaseUrl;
|
|
811
|
+
preset.installApiBaseUrl = defaultApiBaseUrl;
|
|
658
812
|
}
|
|
659
813
|
if (flags['auth-type'] !== undefined && String(flags['auth-type']).trim() !== '') {
|
|
660
|
-
|
|
814
|
+
const authType = String(flags['auth-type']).trim();
|
|
815
|
+
preset.authType = authType;
|
|
816
|
+
preset.installAuthType = authType;
|
|
661
817
|
}
|
|
662
818
|
if (flags['skip-auth']) {
|
|
663
819
|
preset.skipAuth = true;
|
|
@@ -665,16 +821,24 @@ Prompt modes:
|
|
|
665
821
|
const accessToken = String(flags['access-token'] ?? flags.token ?? '');
|
|
666
822
|
if (flags['access-token'] !== undefined || flags.token !== undefined) {
|
|
667
823
|
preset.accessToken = accessToken;
|
|
824
|
+
preset.installAccessToken = accessToken;
|
|
668
825
|
}
|
|
669
826
|
if (flags.username !== undefined) {
|
|
670
|
-
|
|
827
|
+
const username = String(flags.username ?? '').trim();
|
|
828
|
+
preset.username = username;
|
|
829
|
+
preset.installUsername = username;
|
|
671
830
|
}
|
|
672
831
|
if (flags.password !== undefined) {
|
|
673
|
-
|
|
832
|
+
const password = String(flags.password ?? '');
|
|
833
|
+
preset.password = password;
|
|
834
|
+
preset.installPassword = password;
|
|
674
835
|
}
|
|
675
836
|
if (flags.lang !== undefined && String(flags.lang).trim() !== '') {
|
|
676
837
|
preset.lang = String(flags.lang).trim();
|
|
677
838
|
}
|
|
839
|
+
if (flags['app-path'] !== undefined && String(flags['app-path']).trim() !== '') {
|
|
840
|
+
preset.appPath = String(flags['app-path']).trim();
|
|
841
|
+
}
|
|
678
842
|
if (flags['app-root-path'] !== undefined && String(flags['app-root-path']).trim() !== '') {
|
|
679
843
|
preset.appRootPath = String(flags['app-root-path']).trim();
|
|
680
844
|
}
|
|
@@ -684,6 +848,9 @@ Prompt modes:
|
|
|
684
848
|
if (flags['storage-path'] !== undefined && String(flags['storage-path']).trim() !== '') {
|
|
685
849
|
preset.storagePath = String(flags['storage-path']).trim();
|
|
686
850
|
}
|
|
851
|
+
if (flags['app-public-path'] !== undefined && String(flags['app-public-path']).trim() !== '') {
|
|
852
|
+
preset.appPublicPath = String(flags['app-public-path']).trim();
|
|
853
|
+
}
|
|
687
854
|
if (flags['root-username'] !== undefined) {
|
|
688
855
|
preset.rootUsername = String(flags['root-username'] ?? '').trim();
|
|
689
856
|
}
|
|
@@ -783,9 +950,13 @@ Prompt modes:
|
|
|
783
950
|
if (explicitDbHostFlag(flags)) {
|
|
784
951
|
preset.builtinDb = false;
|
|
785
952
|
}
|
|
786
|
-
if (!preset.
|
|
787
|
-
preset.
|
|
953
|
+
if (!preset.setupMode && hasDownloadOverride(flags)) {
|
|
954
|
+
preset.setupMode = 'install-new';
|
|
788
955
|
}
|
|
956
|
+
if (preset.setupMode === 'manage-local') {
|
|
957
|
+
preset.skipDownload = false;
|
|
958
|
+
}
|
|
959
|
+
applyLegacyHasNocobaseAlias(preset);
|
|
789
960
|
return preset;
|
|
790
961
|
}
|
|
791
962
|
hasAgentsDirInCwd() {
|
|
@@ -816,14 +987,23 @@ Prompt modes:
|
|
|
816
987
|
const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
|
|
817
988
|
const existingEnv = await getEnv(envName, { scope: resolveDefaultConfigScope() });
|
|
818
989
|
const appPort = String(results.appPort ?? '').trim();
|
|
990
|
+
const appPublicPath = String(results.appPublicPath ?? '').trim();
|
|
819
991
|
const source = String(results.source ?? '').trim();
|
|
820
992
|
const version = resolveInitDownloadVersion(results);
|
|
821
993
|
const dockerRegistry = String(results.dockerRegistry ?? '').trim();
|
|
822
994
|
const dockerPlatform = String(results.dockerPlatform ?? '').trim();
|
|
823
995
|
const gitUrl = String(results.gitUrl ?? '').trim();
|
|
824
996
|
const npmRegistry = String(results.npmRegistry ?? '').trim();
|
|
997
|
+
const appPath = String(results.appPath ?? '').trim() ||
|
|
998
|
+
inferConfiguredAppPathFromLegacyConfig({
|
|
999
|
+
appRootPath: results.appRootPath,
|
|
1000
|
+
storagePath: results.storagePath,
|
|
1001
|
+
}) ||
|
|
1002
|
+
'';
|
|
825
1003
|
const appRootPath = String(results.appRootPath ?? '').trim();
|
|
826
1004
|
const storagePath = String(results.storagePath ?? '').trim();
|
|
1005
|
+
const derivedAppRootPath = appPath ? deriveConfiguredSourcePath(appPath) : '';
|
|
1006
|
+
const derivedStoragePath = appPath ? deriveConfiguredStoragePath(appPath) : '';
|
|
827
1007
|
const dbDialect = String(results.dbDialect ?? '').trim();
|
|
828
1008
|
const builtinDbImage = String(results.builtinDbImage ?? '').trim();
|
|
829
1009
|
const dbHost = String(results.dbHost ?? '').trim();
|
|
@@ -850,7 +1030,7 @@ Prompt modes:
|
|
|
850
1030
|
await upsertEnv(envName, {
|
|
851
1031
|
...(source === 'docker'
|
|
852
1032
|
? { kind: 'docker' }
|
|
853
|
-
: source || appRootPath
|
|
1033
|
+
: source || appPath || appRootPath
|
|
854
1034
|
? { kind: 'local' }
|
|
855
1035
|
: appPort
|
|
856
1036
|
? { kind: 'http' }
|
|
@@ -865,9 +1045,11 @@ Prompt modes:
|
|
|
865
1045
|
...(dockerPlatform ? { dockerPlatform } : {}),
|
|
866
1046
|
...(gitUrl ? { gitUrl } : {}),
|
|
867
1047
|
...(npmRegistry ? { npmRegistry } : {}),
|
|
868
|
-
...(
|
|
869
|
-
...(
|
|
1048
|
+
...(appPath ? { appPath } : {}),
|
|
1049
|
+
...(appRootPath && !areConfiguredPathsEquivalent(appRootPath, derivedAppRootPath) ? { appRootPath } : {}),
|
|
1050
|
+
...(storagePath && !areConfiguredPathsEquivalent(storagePath, derivedStoragePath) ? { storagePath } : {}),
|
|
870
1051
|
...(appPort ? { appPort } : {}),
|
|
1052
|
+
...(appPublicPath ? { appPublicPath } : {}),
|
|
871
1053
|
...(appKey ? { appKey } : {}),
|
|
872
1054
|
...(timeZone ? { timezone: timeZone } : {}),
|
|
873
1055
|
...(!skipDownload && results.devDependencies !== undefined
|
|
@@ -919,8 +1101,11 @@ Prompt modes:
|
|
|
919
1101
|
const processArgv = process.argv.slice(2);
|
|
920
1102
|
const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
|
|
921
1103
|
const source = String(results.source ?? '').trim();
|
|
922
|
-
const
|
|
923
|
-
|
|
1104
|
+
const setupMode = resolveInitSetupMode({
|
|
1105
|
+
setupMode: results.setupMode ?? flags['setup-mode'],
|
|
1106
|
+
hasNocobase: results.hasNocobase,
|
|
1107
|
+
});
|
|
1108
|
+
const skipDownload = setupMode === 'manage-local' ? false : Boolean(flags['skip-download']) || results.skipDownload === true;
|
|
924
1109
|
const apiBaseUrl = String(results.apiBaseUrl ?? '').trim();
|
|
925
1110
|
const authType = String(results.authType ?? '').trim();
|
|
926
1111
|
const accessToken = String(results.accessToken ?? '');
|
|
@@ -933,7 +1118,7 @@ Prompt modes:
|
|
|
933
1118
|
if (flags.verbose) {
|
|
934
1119
|
argv.push('--verbose');
|
|
935
1120
|
}
|
|
936
|
-
if (
|
|
1121
|
+
if (setupMode === 'connect-remote' && apiBaseUrl) {
|
|
937
1122
|
argv.push('--api-base-url', apiBaseUrl);
|
|
938
1123
|
}
|
|
939
1124
|
if (authType) {
|
|
@@ -955,8 +1140,17 @@ Prompt modes:
|
|
|
955
1140
|
if (lang) {
|
|
956
1141
|
argv.push('--lang', lang);
|
|
957
1142
|
}
|
|
1143
|
+
const appPath = String(results.appPath ?? '').trim() ||
|
|
1144
|
+
inferConfiguredAppPathFromLegacyConfig({
|
|
1145
|
+
appRootPath: results.appRootPath,
|
|
1146
|
+
storagePath: results.storagePath,
|
|
1147
|
+
}) ||
|
|
1148
|
+
'';
|
|
1149
|
+
if (appPath) {
|
|
1150
|
+
argv.push('--app-path', appPath);
|
|
1151
|
+
}
|
|
958
1152
|
const appRootPath = String(results.appRootPath ?? '').trim();
|
|
959
|
-
if (appRootPath) {
|
|
1153
|
+
if (appRootPath && (!appPath || !areConfiguredPathsEquivalent(appRootPath, deriveConfiguredSourcePath(appPath)))) {
|
|
960
1154
|
argv.push('--app-root-path', appRootPath);
|
|
961
1155
|
}
|
|
962
1156
|
const appPort = String(results.appPort ?? '').trim();
|
|
@@ -964,9 +1158,13 @@ Prompt modes:
|
|
|
964
1158
|
argv.push('--app-port', appPort);
|
|
965
1159
|
}
|
|
966
1160
|
const storagePath = String(results.storagePath ?? '').trim();
|
|
967
|
-
if (storagePath) {
|
|
1161
|
+
if (storagePath && (!appPath || !areConfiguredPathsEquivalent(storagePath, deriveConfiguredStoragePath(appPath)))) {
|
|
968
1162
|
argv.push('--storage-path', storagePath);
|
|
969
1163
|
}
|
|
1164
|
+
const appPublicPath = String(results.appPublicPath ?? '').trim();
|
|
1165
|
+
if (appPublicPath) {
|
|
1166
|
+
argv.push('--app-public-path', appPublicPath);
|
|
1167
|
+
}
|
|
970
1168
|
if (flags.force) {
|
|
971
1169
|
argv.push('--force');
|
|
972
1170
|
}
|
|
@@ -1072,20 +1270,21 @@ Prompt modes:
|
|
|
1072
1270
|
if (results.dbUnderscored !== undefined) {
|
|
1073
1271
|
argv.push(results.dbUnderscored ? '--db-underscored' : '--no-db-underscored');
|
|
1074
1272
|
}
|
|
1273
|
+
const includeRootUser = setupMode === 'install-new';
|
|
1075
1274
|
const rootUsername = String(results.rootUsername ?? '').trim();
|
|
1076
|
-
if (rootUsername) {
|
|
1275
|
+
if (includeRootUser && rootUsername) {
|
|
1077
1276
|
argv.push('--root-username', rootUsername);
|
|
1078
1277
|
}
|
|
1079
1278
|
const rootEmail = String(results.rootEmail ?? '').trim();
|
|
1080
|
-
if (rootEmail) {
|
|
1279
|
+
if (includeRootUser && rootEmail) {
|
|
1081
1280
|
argv.push('--root-email', rootEmail);
|
|
1082
1281
|
}
|
|
1083
1282
|
const rootPassword = String(results.rootPassword ?? '');
|
|
1084
|
-
if (rootPassword) {
|
|
1283
|
+
if (includeRootUser && rootPassword) {
|
|
1085
1284
|
argv.push('--root-password', rootPassword);
|
|
1086
1285
|
}
|
|
1087
1286
|
const rootNickname = String(results.rootNickname ?? '').trim();
|
|
1088
|
-
if (rootNickname) {
|
|
1287
|
+
if (includeRootUser && rootNickname) {
|
|
1089
1288
|
argv.push('--root-nickname', rootNickname);
|
|
1090
1289
|
}
|
|
1091
1290
|
return argv;
|
|
@@ -1097,8 +1296,12 @@ Prompt modes:
|
|
|
1097
1296
|
}
|
|
1098
1297
|
const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
|
|
1099
1298
|
argv.push('--env', envName);
|
|
1299
|
+
const setupMode = resolveInitSetupMode(results);
|
|
1300
|
+
if (setupMode === 'manage-local') {
|
|
1301
|
+
argv.push('--setup-mode', 'manage-local');
|
|
1302
|
+
}
|
|
1100
1303
|
const source = String(results.source ?? '').trim();
|
|
1101
|
-
const skipDownload = Boolean(flags['skip-download']) || results.skipDownload === true;
|
|
1304
|
+
const skipDownload = setupMode === 'manage-local' ? false : Boolean(flags['skip-download']) || results.skipDownload === true;
|
|
1102
1305
|
if (source) {
|
|
1103
1306
|
argv.push('--source', source);
|
|
1104
1307
|
}
|
|
@@ -1127,7 +1330,14 @@ Prompt modes:
|
|
|
1127
1330
|
}
|
|
1128
1331
|
else {
|
|
1129
1332
|
const outputDir = String(results.outputDir ?? '').trim();
|
|
1130
|
-
|
|
1333
|
+
const appPath = String(results.appPath ?? '').trim() ||
|
|
1334
|
+
inferConfiguredAppPathFromLegacyConfig({
|
|
1335
|
+
appRootPath: results.appRootPath,
|
|
1336
|
+
storagePath: results.storagePath,
|
|
1337
|
+
}) ||
|
|
1338
|
+
'';
|
|
1339
|
+
const expectedOutputDir = String(results.appRootPath ?? '').trim() || (appPath ? deriveConfiguredSourcePath(appPath) : '');
|
|
1340
|
+
if (outputDir && outputDir !== expectedOutputDir) {
|
|
1131
1341
|
argv.push('--output-dir', outputDir);
|
|
1132
1342
|
}
|
|
1133
1343
|
if (results.devDependencies) {
|
|
@@ -1152,14 +1362,20 @@ Prompt modes:
|
|
|
1152
1362
|
}
|
|
1153
1363
|
buildResumeInstallArgv(flags) {
|
|
1154
1364
|
const preset = this.buildPresetValuesFromFlags(flags);
|
|
1365
|
+
const setupMode = resolveInitSetupMode(preset);
|
|
1155
1366
|
if (flags.yes) {
|
|
1156
1367
|
preset.lang ??= yesInitialValue(Install.appPrompts.lang, 'en-US');
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1368
|
+
if (setupMode === 'install-new') {
|
|
1369
|
+
preset.rootUsername ??= yesInitialValue(Install.rootUserPrompts.rootUsername, 'nocobase');
|
|
1370
|
+
preset.rootEmail ??= yesInitialValue(Install.rootUserPrompts.rootEmail, 'admin@nocobase.com');
|
|
1371
|
+
preset.rootPassword ??= yesInitialValue(Install.rootUserPrompts.rootPassword, 'admin123');
|
|
1372
|
+
preset.rootNickname ??= yesInitialValue(Install.rootUserPrompts.rootNickname, 'Super Admin');
|
|
1373
|
+
}
|
|
1161
1374
|
}
|
|
1162
|
-
if (
|
|
1375
|
+
if (setupMode === 'manage-local') {
|
|
1376
|
+
preset.skipDownload = false;
|
|
1377
|
+
}
|
|
1378
|
+
else if (!flags['skip-download']) {
|
|
1163
1379
|
preset.replace ??= true;
|
|
1164
1380
|
}
|
|
1165
1381
|
return this.buildInstallArgv(preset, flags, {
|
|
@@ -1167,4 +1383,40 @@ Prompt modes:
|
|
|
1167
1383
|
resume: true,
|
|
1168
1384
|
});
|
|
1169
1385
|
}
|
|
1386
|
+
normalizeInitResults(results) {
|
|
1387
|
+
const normalized = { ...results };
|
|
1388
|
+
const setupMode = resolveInitSetupMode(normalized);
|
|
1389
|
+
const defaultApiHost = normalizeConnectionString(normalized.defaultApiHost) || '127.0.0.1';
|
|
1390
|
+
if (setupMode === 'install-new') {
|
|
1391
|
+
normalized.apiBaseUrl =
|
|
1392
|
+
normalizeConnectionString(normalized.installApiBaseUrl) ||
|
|
1393
|
+
deriveInstallConnectionApiBaseUrl(normalized, defaultApiHost);
|
|
1394
|
+
normalized.authType = normalizeConnectionString(normalized.installAuthType) || 'oauth';
|
|
1395
|
+
normalized.username =
|
|
1396
|
+
normalized.authType === 'basic'
|
|
1397
|
+
? normalizeConnectionString(normalized.installUsername) || normalizeConnectionString(normalized.rootUsername)
|
|
1398
|
+
: normalizeConnectionString(normalized.installUsername);
|
|
1399
|
+
normalized.password =
|
|
1400
|
+
normalized.authType === 'basic'
|
|
1401
|
+
? String(normalized.installPassword ?? '') || String(normalized.rootPassword ?? '')
|
|
1402
|
+
: String(normalized.installPassword ?? '');
|
|
1403
|
+
normalized.accessToken = String(normalized.installAccessToken ?? '');
|
|
1404
|
+
}
|
|
1405
|
+
normalized.setupMode = setupMode;
|
|
1406
|
+
applyLegacyHasNocobaseAlias(normalized);
|
|
1407
|
+
if (setupMode === 'manage-local') {
|
|
1408
|
+
normalized.skipDownload = false;
|
|
1409
|
+
delete normalized.rootUsername;
|
|
1410
|
+
delete normalized.rootEmail;
|
|
1411
|
+
delete normalized.rootPassword;
|
|
1412
|
+
delete normalized.rootNickname;
|
|
1413
|
+
}
|
|
1414
|
+
delete normalized.installApiBaseUrl;
|
|
1415
|
+
delete normalized.installAuthType;
|
|
1416
|
+
delete normalized.installUsername;
|
|
1417
|
+
delete normalized.installPassword;
|
|
1418
|
+
delete normalized.installAccessToken;
|
|
1419
|
+
delete normalized.defaultApiHost;
|
|
1420
|
+
return normalized;
|
|
1421
|
+
}
|
|
1170
1422
|
}
|