@nocobase/cli 2.2.0-test.16 → 2.2.1
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/dist/commands/api/resource/create.js +11 -2
- package/dist/commands/app/start.js +1 -21
- package/dist/commands/config/set.js +0 -1
- package/dist/commands/init.js +3 -120
- package/dist/commands/install.js +4 -121
- package/dist/commands/source/dev.js +1 -1
- package/dist/lib/api-client.js +7 -0
- package/dist/lib/auth-store.js +1 -3
- package/dist/lib/browser.js +29 -0
- package/dist/lib/cli-config.js +1 -20
- package/dist/lib/env-config.js +0 -3
- package/dist/lib/env-proxy.js +1 -65
- package/dist/lib/generated-command.js +81 -0
- package/dist/lib/managed-init-env.js +1 -6
- package/dist/lib/naming.js +9 -0
- package/dist/lib/plugin-import.js +30 -8
- package/dist/lib/resource-command.js +18 -2
- package/dist/lib/resource-request.js +8 -0
- package/dist/lib/run-npm.js +16 -17
- package/dist/lib/runtime-generator.js +28 -1
- package/dist/lib/ui.js +1 -28
- package/dist/locale/en-US.json +0 -154
- package/dist/locale/zh-CN.json +0 -154
- package/nocobase-ctl.config.json +111 -0
- package/package.json +3 -5
- package/dist/commands/portal/create.js +0 -104
- package/dist/commands/portal/deploy.js +0 -81
- package/dist/commands/portal/destroy.js +0 -104
- package/dist/commands/portal/dev.js +0 -71
- package/dist/commands/portal/index.js +0 -20
- package/dist/commands/portal/info.js +0 -82
- package/dist/commands/portal/list.js +0 -98
- package/dist/commands/portal/pull.js +0 -77
- package/dist/commands/portal/push.js +0 -79
- package/dist/lib/portal-command-env.js +0 -31
- package/dist/lib/portal-create.js +0 -488
- package/dist/lib/portal-deploy.js +0 -275
- package/dist/lib/portal-destroy.js +0 -100
- package/dist/lib/portal-dev.js +0 -79
- package/dist/lib/portal-env-files.js +0 -53
- package/dist/lib/portal-info.js +0 -31
- package/dist/lib/portal-list.js +0 -197
- package/dist/lib/portal-source.js +0 -416
- package/dist/lib/portal-template.js +0 -190
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
1
9
|
import { Command } from '@oclif/core';
|
|
2
10
|
import { buildCreateArgs, createFlags, runResourceCommand } from '../../../lib/resource-command.js';
|
|
3
11
|
export default class ResourceCreate extends Command {
|
|
4
|
-
static summary = 'Create
|
|
5
|
-
static description = 'Create
|
|
12
|
+
static summary = 'Create one or more records in a resource';
|
|
13
|
+
static description = 'Create records in a generic resource. Pass record content through --values as a JSON object, or as a JSON array of objects to create multiple records in a single request.';
|
|
6
14
|
static examples = [
|
|
7
15
|
`<%= config.bin %> <%= command.id %> --resource users --values '{"nickname":"Ada"}'`,
|
|
16
|
+
`<%= config.bin %> <%= command.id %> --resource users --values '[{"nickname":"Ada"},{"nickname":"Grace"}]'`,
|
|
8
17
|
`<%= config.bin %> <%= command.id %> --resource posts.comments --source-id 1 --values '{"content":"Hello"}'`,
|
|
9
18
|
];
|
|
10
19
|
static flags = createFlags;
|
|
@@ -14,7 +14,6 @@ import { AppHealthCheckError, formatAppUrl, isAppReady, resolveManagedAppApiBase
|
|
|
14
14
|
import { ensureBuiltinDbReady, ensureLocalPostinstall, ensureSavedLocalSource, recreateSavedDockerApp, } from '../../lib/app-managed-resources.js';
|
|
15
15
|
import { clearEnvRootSetup, getEnv, upsertEnv } from '../../lib/auth-store.js';
|
|
16
16
|
import { buildInitAppEnvVarsFromConfig, isPreparedSetupState } from '../../lib/managed-init-env.js';
|
|
17
|
-
import { prepareInitialPortalTemplate } from '../../lib/portal-template.js';
|
|
18
17
|
import { resolveAppUrlFromApiBaseUrl } from '../env/shared.js';
|
|
19
18
|
import { readManagedRuntimeEnvValues } from '../../lib/managed-env-file.js';
|
|
20
19
|
import { run } from '../../lib/run-npm.js';
|
|
@@ -182,19 +181,6 @@ async function finalizePreparedEnv(envName) {
|
|
|
182
181
|
setupState: 'installed',
|
|
183
182
|
});
|
|
184
183
|
}
|
|
185
|
-
async function prepareInitialPortalForRuntime(runtime, verbose) {
|
|
186
|
-
await prepareInitialPortalTemplate({
|
|
187
|
-
developmentMode: runtime.env.config?.developmentMode,
|
|
188
|
-
portalName: runtime.env.config?.portalName,
|
|
189
|
-
portalTemplate: runtime.env.config?.portalTemplate,
|
|
190
|
-
npmRegistry: runtime.env.config?.npmRegistry,
|
|
191
|
-
storagePath: runtime.env.storagePath || runtime.env.config?.storagePath,
|
|
192
|
-
verbose,
|
|
193
|
-
onStartTask: startTask,
|
|
194
|
-
onSucceedTask: succeedTask,
|
|
195
|
-
onFailTask: failTask,
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
184
|
export default class AppStart extends Command {
|
|
199
185
|
static hidden = false;
|
|
200
186
|
static description = 'Start NocoBase for the selected env. When applicable, the CLI synchronizes licensed commercial plugins first, then prepares and starts the app or recreates the saved Docker container.';
|
|
@@ -263,7 +249,7 @@ export default class AppStart extends Command {
|
|
|
263
249
|
}
|
|
264
250
|
const daemonFlagWasProvided = argvHasToken(this.argv, ['--daemon', '--no-daemon']);
|
|
265
251
|
const runtime = await resolveManagedAppRuntime(requestedEnv);
|
|
266
|
-
const preparedInitEnvVars = buildInitAppEnvVarsFromConfig(runtime?.env.config
|
|
252
|
+
const preparedInitEnvVars = buildInitAppEnvVarsFromConfig(runtime?.env.config);
|
|
267
253
|
const isPreparedEnv = isPreparedSetupState(runtime?.env.config?.setupState);
|
|
268
254
|
const hookCommand = resolveHookCommand(flags['hook-command']);
|
|
269
255
|
const hookPhase = resolveAppStartHookPhase({
|
|
@@ -336,9 +322,6 @@ export default class AppStart extends Command {
|
|
|
336
322
|
command: hookCommand,
|
|
337
323
|
});
|
|
338
324
|
}
|
|
339
|
-
if (isPreparedEnv) {
|
|
340
|
-
await prepareInitialPortalForRuntime(runtime, flags.verbose);
|
|
341
|
-
}
|
|
342
325
|
await recreateSavedDockerApp(runtime, {
|
|
343
326
|
initEnvVars: isPreparedEnv ? preparedInitEnvVars : undefined,
|
|
344
327
|
verbose: flags.verbose,
|
|
@@ -487,9 +470,6 @@ export default class AppStart extends Command {
|
|
|
487
470
|
command: hookCommand,
|
|
488
471
|
});
|
|
489
472
|
}
|
|
490
|
-
if (isPreparedEnv) {
|
|
491
|
-
await prepareInitialPortalForRuntime(runtime, flags.verbose);
|
|
492
|
-
}
|
|
493
473
|
await runLocalNocoBaseCommand(runtime, npmArgs, {
|
|
494
474
|
env: startEnv,
|
|
495
475
|
stdio: commandStdio,
|
|
@@ -14,7 +14,6 @@ export default class ConfigSet extends Command {
|
|
|
14
14
|
static description = 'Set a CLI configuration value for a supported configuration key.';
|
|
15
15
|
static examples = [
|
|
16
16
|
'<%= config.bin %> <%= command.id %> locale zh-CN',
|
|
17
|
-
'<%= config.bin %> <%= command.id %> default-portal-template git@github.com:nocobase/admin-starter.git',
|
|
18
17
|
'<%= config.bin %> <%= command.id %> update.policy prompt',
|
|
19
18
|
'<%= config.bin %> <%= command.id %> docker.network nocobase',
|
|
20
19
|
'<%= config.bin %> <%= command.id %> docker.container-prefix nb',
|
package/dist/commands/init.js
CHANGED
|
@@ -32,12 +32,8 @@ import EnvAdd from "./env/add.js";
|
|
|
32
32
|
import Install, { defaultDbPortForDialect } from "./install.js";
|
|
33
33
|
const DEFAULT_INIT_API_BASE_URL = 'http://localhost:13000/api';
|
|
34
34
|
const DEFAULT_INIT_APP_NAME = 'local';
|
|
35
|
-
const DEFAULT_INIT_DEVELOPMENT_MODE = 'no-code';
|
|
36
|
-
const DEFAULT_INIT_PORTAL_NAME = 'admin';
|
|
37
|
-
const DEFAULT_INIT_PORTAL_TEMPLATE = 'git@github.com:nocobase/admin-starter.git';
|
|
38
35
|
const DOWNLOAD_OUTPUT_DIR_PROMPT = Download.prompts.outputDir;
|
|
39
36
|
const INIT_SETUP_MODES = ['install-new', 'manage-local', 'connect-remote'];
|
|
40
|
-
const INIT_DEVELOPMENT_MODES = ['no-code', 'vibe-coding'];
|
|
41
37
|
const INIT_ENV_ADD_FLAG_NAMES = [
|
|
42
38
|
'locale',
|
|
43
39
|
'default-api-base-url',
|
|
@@ -84,9 +80,6 @@ function isInstallNewSetupMode(values) {
|
|
|
84
80
|
function isInstallLikeSetupMode(values) {
|
|
85
81
|
return !isRemoteSetupMode(values);
|
|
86
82
|
}
|
|
87
|
-
function isVibeCodingMode(values) {
|
|
88
|
-
return String(values.developmentMode ?? DEFAULT_INIT_DEVELOPMENT_MODE).trim() === 'vibe-coding';
|
|
89
|
-
}
|
|
90
83
|
function remoteConnectionOnly(def) {
|
|
91
84
|
return withExtraHidden(def, (values) => !isRemoteSetupMode(values));
|
|
92
85
|
}
|
|
@@ -394,43 +387,6 @@ Prompt modes:
|
|
|
394
387
|
devDependencies: installLikeDownloadExecutionOnly(Download.prompts.devDependencies),
|
|
395
388
|
build: installLikeDownloadExecutionOnly(Download.prompts.build),
|
|
396
389
|
buildDts: installLikeDownloadExecutionOnly(Download.prompts.buildDts),
|
|
397
|
-
developmentMode: installNewOnly({
|
|
398
|
-
type: 'select',
|
|
399
|
-
variant: 'radio',
|
|
400
|
-
message: initText('prompts.developmentMode.message'),
|
|
401
|
-
options: [
|
|
402
|
-
{
|
|
403
|
-
value: 'no-code',
|
|
404
|
-
label: initText('prompts.developmentMode.noCodeLabel'),
|
|
405
|
-
hint: initText('prompts.developmentMode.noCodeHint'),
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
value: 'vibe-coding',
|
|
409
|
-
label: initText('prompts.developmentMode.vibeCodingLabel'),
|
|
410
|
-
hint: initText('prompts.developmentMode.vibeCodingHint'),
|
|
411
|
-
},
|
|
412
|
-
],
|
|
413
|
-
initialValue: DEFAULT_INIT_DEVELOPMENT_MODE,
|
|
414
|
-
yesInitialValue: DEFAULT_INIT_DEVELOPMENT_MODE,
|
|
415
|
-
required: true,
|
|
416
|
-
}),
|
|
417
|
-
portalName: installNewOnly({
|
|
418
|
-
type: 'text',
|
|
419
|
-
message: initText('prompts.portalName.message'),
|
|
420
|
-
placeholder: DEFAULT_INIT_PORTAL_NAME,
|
|
421
|
-
initialValue: DEFAULT_INIT_PORTAL_NAME,
|
|
422
|
-
yesInitialValue: DEFAULT_INIT_PORTAL_NAME,
|
|
423
|
-
hidden: (values) => !isVibeCodingMode(values),
|
|
424
|
-
required: true,
|
|
425
|
-
}),
|
|
426
|
-
portalTemplate: installNewOnly({
|
|
427
|
-
type: 'text',
|
|
428
|
-
message: initText('prompts.portalTemplate.message'),
|
|
429
|
-
placeholder: DEFAULT_INIT_PORTAL_TEMPLATE,
|
|
430
|
-
yesInitialValue: DEFAULT_INIT_PORTAL_TEMPLATE,
|
|
431
|
-
hidden: (values) => !isVibeCodingMode(values),
|
|
432
|
-
required: true,
|
|
433
|
-
}),
|
|
434
390
|
dbDialect: installLikeOnly(Install.dbPrompts.dbDialect),
|
|
435
391
|
builtinDb: installLikeOnly(Install.dbPrompts.builtinDb),
|
|
436
392
|
builtinDbImage: installLikeOnly(Install.dbPrompts.builtinDbImage),
|
|
@@ -456,13 +412,6 @@ Prompt modes:
|
|
|
456
412
|
...Init.prompts,
|
|
457
413
|
installApiBaseUrl: createInstallConnectionApiBaseUrlPrompt(options.defaultApiHost),
|
|
458
414
|
};
|
|
459
|
-
const defaultPortalTemplate = String(options.defaultPortalTemplate ?? '').trim();
|
|
460
|
-
if (defaultPortalTemplate) {
|
|
461
|
-
prompts.portalTemplate = {
|
|
462
|
-
...prompts.portalTemplate,
|
|
463
|
-
yesInitialValue: defaultPortalTemplate,
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
415
|
if (flags['skip-auth']) {
|
|
467
416
|
const accessTokenPrompt = {
|
|
468
417
|
...EnvAdd.prompts.accessToken,
|
|
@@ -512,16 +461,6 @@ Prompt modes:
|
|
|
512
461
|
description: 'Setup mode: install a new app, manage a local app by reusing its database, or connect a remote app',
|
|
513
462
|
options: [...INIT_SETUP_MODES],
|
|
514
463
|
}),
|
|
515
|
-
'development-mode': Flags.string({
|
|
516
|
-
description: 'Initial development mode: no-code or vibe-coding',
|
|
517
|
-
options: [...INIT_DEVELOPMENT_MODES],
|
|
518
|
-
}),
|
|
519
|
-
'portal-name': Flags.string({
|
|
520
|
-
description: 'Initial portal name when --development-mode vibe-coding is used',
|
|
521
|
-
}),
|
|
522
|
-
'portal-template': Flags.string({
|
|
523
|
-
description: 'Initial portal template Git URL or local path when --development-mode vibe-coding is used',
|
|
524
|
-
}),
|
|
525
464
|
ui: Flags.boolean({
|
|
526
465
|
description: 'Open the guided setup flow in a local browser form (not valid with --yes)',
|
|
527
466
|
default: false,
|
|
@@ -639,8 +578,7 @@ Prompt modes:
|
|
|
639
578
|
const dynamicInitialValues = await Init.buildDynamicInitialValuesForInstall(normalizedFlags, presetValues);
|
|
640
579
|
const defaultUiHost = await resolveDefaultUiHost();
|
|
641
580
|
const defaultApiHost = await resolveDefaultApiHost();
|
|
642
|
-
const
|
|
643
|
-
const promptCatalog = this.buildPromptCatalog(normalizedFlags, { defaultApiHost, defaultPortalTemplate });
|
|
581
|
+
const promptCatalog = this.buildPromptCatalog(normalizedFlags, { defaultApiHost });
|
|
644
582
|
if (useBrowserUi) {
|
|
645
583
|
presetValues = await runPromptCatalogWebUI({
|
|
646
584
|
stages: Init.buildWebUiStages(promptCatalog),
|
|
@@ -669,7 +607,6 @@ Prompt modes:
|
|
|
669
607
|
? { setupMode: normalizeInitSetupMode(presetValues.hasNocobase) }
|
|
670
608
|
: {}),
|
|
671
609
|
},
|
|
672
|
-
yesInitialValues: pickKeys(dynamicInitialValues, ['portalTemplate']),
|
|
673
610
|
values: presetValues,
|
|
674
611
|
yes: normalizedFlags.yes || useBrowserUi || !interactive,
|
|
675
612
|
hooks: {
|
|
@@ -742,9 +679,7 @@ Prompt modes:
|
|
|
742
679
|
}
|
|
743
680
|
static async buildDynamicInitialValuesForInstall(flags, presetValues) {
|
|
744
681
|
const out = {};
|
|
745
|
-
|
|
746
|
-
!Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate');
|
|
747
|
-
if (shouldResolveAppInitialValues) {
|
|
682
|
+
if (!Object.prototype.hasOwnProperty.call(presetValues, 'appPort')) {
|
|
748
683
|
const appInitialValues = await Install.buildAppPromptInitialValues({
|
|
749
684
|
envName: String(presetValues.appName ?? '').trim(),
|
|
750
685
|
flags: {
|
|
@@ -752,20 +687,12 @@ Prompt modes:
|
|
|
752
687
|
'app-path': flags['app-path'] ?? '',
|
|
753
688
|
'app-root-path': flags['app-root-path'] ?? '',
|
|
754
689
|
'storage-path': flags['storage-path'] ?? '',
|
|
755
|
-
'portal-template': flags['portal-template'] ??
|
|
756
|
-
(Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate')
|
|
757
|
-
? String(presetValues.portalTemplate ?? '')
|
|
758
|
-
: undefined),
|
|
759
690
|
},
|
|
760
691
|
warnOnPortFallback: false,
|
|
761
692
|
});
|
|
762
|
-
if (appInitialValues.appPort !== undefined
|
|
693
|
+
if (appInitialValues.appPort !== undefined) {
|
|
763
694
|
out.appPort = appInitialValues.appPort;
|
|
764
695
|
}
|
|
765
|
-
if (appInitialValues.portalTemplate !== undefined &&
|
|
766
|
-
!Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate')) {
|
|
767
|
-
out.portalTemplate = appInitialValues.portalTemplate;
|
|
768
|
-
}
|
|
769
696
|
}
|
|
770
697
|
const downloadSeed = { ...presetValues };
|
|
771
698
|
if (flags.yes && !Object.prototype.hasOwnProperty.call(downloadSeed, 'source')) {
|
|
@@ -844,13 +771,6 @@ Prompt modes:
|
|
|
844
771
|
buildDts: c.buildDts,
|
|
845
772
|
},
|
|
846
773
|
},
|
|
847
|
-
{
|
|
848
|
-
sectionTitle: initText('webUi.developmentMode.title'),
|
|
849
|
-
sectionDescription: initText('webUi.developmentMode.description'),
|
|
850
|
-
catalog: {
|
|
851
|
-
developmentMode: c.developmentMode,
|
|
852
|
-
},
|
|
853
|
-
},
|
|
854
774
|
{
|
|
855
775
|
sectionTitle: initText('webUi.configureDatabase.title'),
|
|
856
776
|
sectionDescription: initText('webUi.configureDatabase.description'),
|
|
@@ -951,15 +871,6 @@ Prompt modes:
|
|
|
951
871
|
if (flags['app-public-path'] !== undefined && String(flags['app-public-path']).trim() !== '') {
|
|
952
872
|
preset.appPublicPath = String(flags['app-public-path']).trim();
|
|
953
873
|
}
|
|
954
|
-
if (flags['development-mode'] !== undefined && String(flags['development-mode']).trim() !== '') {
|
|
955
|
-
preset.developmentMode = String(flags['development-mode']).trim();
|
|
956
|
-
}
|
|
957
|
-
if (flags['portal-name'] !== undefined && String(flags['portal-name']).trim() !== '') {
|
|
958
|
-
preset.portalName = String(flags['portal-name']).trim();
|
|
959
|
-
}
|
|
960
|
-
if (flags['portal-template'] !== undefined && String(flags['portal-template']).trim() !== '') {
|
|
961
|
-
preset.portalTemplate = String(flags['portal-template']).trim();
|
|
962
|
-
}
|
|
963
874
|
if (flags['root-username'] !== undefined) {
|
|
964
875
|
preset.rootUsername = String(flags['root-username'] ?? '').trim();
|
|
965
876
|
}
|
|
@@ -1097,9 +1008,6 @@ Prompt modes:
|
|
|
1097
1008
|
const existingEnv = await getEnv(envName, { scope: resolveDefaultConfigScope() });
|
|
1098
1009
|
const appPort = String(results.appPort ?? '').trim();
|
|
1099
1010
|
const appPublicPath = String(results.appPublicPath ?? '').trim();
|
|
1100
|
-
const developmentMode = String(results.developmentMode ?? '').trim();
|
|
1101
|
-
const portalName = String(results.portalName ?? '').trim();
|
|
1102
|
-
const portalTemplate = String(results.portalTemplate ?? '').trim();
|
|
1103
1011
|
const source = String(results.source ?? '').trim();
|
|
1104
1012
|
const version = resolveInitDownloadVersion(results);
|
|
1105
1013
|
const dockerRegistry = String(results.dockerRegistry ?? '').trim();
|
|
@@ -1172,9 +1080,6 @@ Prompt modes:
|
|
|
1172
1080
|
...(storagePath && !areConfiguredPathsEquivalent(storagePath, derivedStoragePath) ? { storagePath } : {}),
|
|
1173
1081
|
...(appPort ? { appPort } : {}),
|
|
1174
1082
|
...(appPublicPath ? { appPublicPath } : {}),
|
|
1175
|
-
...(developmentMode && developmentMode !== DEFAULT_INIT_DEVELOPMENT_MODE ? { developmentMode } : {}),
|
|
1176
|
-
...(portalName ? { portalName } : {}),
|
|
1177
|
-
...(portalTemplate ? { portalTemplate } : {}),
|
|
1178
1083
|
...(appKey ? { appKey } : {}),
|
|
1179
1084
|
...(timeZone ? { timezone: timeZone } : {}),
|
|
1180
1085
|
...(!skipDownload && results.devDependencies !== undefined
|
|
@@ -1299,18 +1204,6 @@ Prompt modes:
|
|
|
1299
1204
|
if (appPublicPath) {
|
|
1300
1205
|
argv.push('--app-public-path', appPublicPath);
|
|
1301
1206
|
}
|
|
1302
|
-
const developmentMode = String(results.developmentMode ?? '').trim();
|
|
1303
|
-
if (developmentMode && developmentMode !== DEFAULT_INIT_DEVELOPMENT_MODE) {
|
|
1304
|
-
argv.push('--development-mode', developmentMode);
|
|
1305
|
-
}
|
|
1306
|
-
const portalName = String(results.portalName ?? '').trim();
|
|
1307
|
-
if (portalName) {
|
|
1308
|
-
argv.push('--portal-name', portalName);
|
|
1309
|
-
}
|
|
1310
|
-
const portalTemplate = String(results.portalTemplate ?? '').trim();
|
|
1311
|
-
if (portalTemplate) {
|
|
1312
|
-
argv.push('--portal-template', portalTemplate);
|
|
1313
|
-
}
|
|
1314
1207
|
if (flags.force) {
|
|
1315
1208
|
argv.push('--force');
|
|
1316
1209
|
}
|
|
@@ -1508,16 +1401,6 @@ Prompt modes:
|
|
|
1508
1401
|
delete normalized.rootPassword;
|
|
1509
1402
|
delete normalized.rootNickname;
|
|
1510
1403
|
}
|
|
1511
|
-
const developmentMode = normalizeConnectionString(normalized.developmentMode) || DEFAULT_INIT_DEVELOPMENT_MODE;
|
|
1512
|
-
normalized.developmentMode = developmentMode;
|
|
1513
|
-
if (developmentMode === 'vibe-coding') {
|
|
1514
|
-
normalized.portalName = normalizeConnectionString(normalized.portalName) || DEFAULT_INIT_PORTAL_NAME;
|
|
1515
|
-
normalized.portalTemplate = normalizeConnectionString(normalized.portalTemplate);
|
|
1516
|
-
}
|
|
1517
|
-
else {
|
|
1518
|
-
delete normalized.portalName;
|
|
1519
|
-
delete normalized.portalTemplate;
|
|
1520
|
-
}
|
|
1521
1404
|
delete normalized.installApiBaseUrl;
|
|
1522
1405
|
delete normalized.installAuthType;
|
|
1523
1406
|
delete normalized.installUsername;
|
package/dist/commands/install.js
CHANGED
|
@@ -29,7 +29,6 @@ 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 { prepareInitialPortalTemplate } from '../lib/portal-template.js';
|
|
33
32
|
import { buildHookContext, persistHookScript, resolveHookScriptPath, runHookScriptHook, } from '../lib/hook-script.js';
|
|
34
33
|
import { areConfiguredPathsEquivalent, deriveConfiguredSourcePath, deriveConfiguredStoragePath, inferConfiguredAppPathFromLegacyConfig, } from '../lib/env-paths.js';
|
|
35
34
|
import Download from './download.js';
|
|
@@ -54,10 +53,6 @@ const DEFAULT_INSTALL_ROOT_EMAIL = 'admin@nocobase.com';
|
|
|
54
53
|
const DEFAULT_INSTALL_ROOT_PASSWORD = 'admin123';
|
|
55
54
|
const DEFAULT_INSTALL_ROOT_NICKNAME = 'Super Admin';
|
|
56
55
|
const DEFAULT_INSTALL_API_HOST = '127.0.0.1';
|
|
57
|
-
const DEFAULT_INSTALL_DEVELOPMENT_MODE = 'no-code';
|
|
58
|
-
const DEFAULT_INSTALL_PORTAL_NAME = 'admin';
|
|
59
|
-
const DEFAULT_INSTALL_PORTAL_TEMPLATE = 'git@github.com:nocobase/admin-starter.git';
|
|
60
|
-
const INSTALL_DEVELOPMENT_MODES = ['no-code', 'vibe-coding'];
|
|
61
56
|
function toOptionalPromptString(value) {
|
|
62
57
|
const text = String(value ?? '').trim();
|
|
63
58
|
return text || undefined;
|
|
@@ -185,9 +180,6 @@ function defaultBuiltinDbImageForDialect(value, options) {
|
|
|
185
180
|
function defaultDbDatabaseForDialect(value) {
|
|
186
181
|
return String(value ?? '').trim() === 'kingbase' ? 'kingbase' : DEFAULT_INSTALL_DB_DATABASE;
|
|
187
182
|
}
|
|
188
|
-
function isVibeCodingMode(values) {
|
|
189
|
-
return String(values.developmentMode ?? DEFAULT_INSTALL_DEVELOPMENT_MODE).trim() === 'vibe-coding';
|
|
190
|
-
}
|
|
191
183
|
function supportsDbSchemaPrompt(value) {
|
|
192
184
|
const dialect = String(value ?? '').trim();
|
|
193
185
|
return dialect === 'postgres' || dialect === 'kingbase';
|
|
@@ -412,16 +404,6 @@ export default class Install extends Command {
|
|
|
412
404
|
'app-public-path': Flags.string({
|
|
413
405
|
description: 'Public path for the local app, for example / or /console/',
|
|
414
406
|
}),
|
|
415
|
-
'development-mode': Flags.string({
|
|
416
|
-
description: 'Initial development mode for the installed app',
|
|
417
|
-
options: [...INSTALL_DEVELOPMENT_MODES],
|
|
418
|
-
}),
|
|
419
|
-
'portal-name': Flags.string({
|
|
420
|
-
description: 'Initial portal name when --development-mode vibe-coding is used',
|
|
421
|
-
}),
|
|
422
|
-
'portal-template': Flags.string({
|
|
423
|
-
description: 'Initial portal template Git URL or local path when --development-mode vibe-coding is used',
|
|
424
|
-
}),
|
|
425
407
|
'root-username': Flags.string({
|
|
426
408
|
description: 'Initial admin username for the installed app',
|
|
427
409
|
required: false,
|
|
@@ -531,42 +513,6 @@ export default class Install extends Command {
|
|
|
531
513
|
yesInitialValue: '/',
|
|
532
514
|
validate: validateAppPublicPath,
|
|
533
515
|
},
|
|
534
|
-
developmentMode: {
|
|
535
|
-
type: 'select',
|
|
536
|
-
message: installText('prompts.developmentMode.message'),
|
|
537
|
-
options: [
|
|
538
|
-
{
|
|
539
|
-
value: 'no-code',
|
|
540
|
-
label: installText('prompts.developmentMode.noCodeLabel'),
|
|
541
|
-
hint: installText('prompts.developmentMode.noCodeHint'),
|
|
542
|
-
},
|
|
543
|
-
{
|
|
544
|
-
value: 'vibe-coding',
|
|
545
|
-
label: installText('prompts.developmentMode.vibeCodingLabel'),
|
|
546
|
-
hint: installText('prompts.developmentMode.vibeCodingHint'),
|
|
547
|
-
},
|
|
548
|
-
],
|
|
549
|
-
initialValue: DEFAULT_INSTALL_DEVELOPMENT_MODE,
|
|
550
|
-
yesInitialValue: DEFAULT_INSTALL_DEVELOPMENT_MODE,
|
|
551
|
-
required: true,
|
|
552
|
-
},
|
|
553
|
-
portalName: {
|
|
554
|
-
type: 'text',
|
|
555
|
-
message: installText('prompts.portalName.message'),
|
|
556
|
-
placeholder: DEFAULT_INSTALL_PORTAL_NAME,
|
|
557
|
-
initialValue: DEFAULT_INSTALL_PORTAL_NAME,
|
|
558
|
-
yesInitialValue: DEFAULT_INSTALL_PORTAL_NAME,
|
|
559
|
-
hidden: (values) => !isVibeCodingMode(values),
|
|
560
|
-
required: true,
|
|
561
|
-
},
|
|
562
|
-
portalTemplate: {
|
|
563
|
-
type: 'text',
|
|
564
|
-
message: installText('prompts.portalTemplate.message'),
|
|
565
|
-
placeholder: DEFAULT_INSTALL_PORTAL_TEMPLATE,
|
|
566
|
-
yesInitialValue: DEFAULT_INSTALL_PORTAL_TEMPLATE,
|
|
567
|
-
hidden: (values) => !isVibeCodingMode(values),
|
|
568
|
-
required: true,
|
|
569
|
-
},
|
|
570
516
|
};
|
|
571
517
|
}
|
|
572
518
|
static dbPrompts = {
|
|
@@ -826,24 +772,6 @@ export default class Install extends Command {
|
|
|
826
772
|
preset.appPublicPath = v;
|
|
827
773
|
}
|
|
828
774
|
}
|
|
829
|
-
if (flags['development-mode'] !== undefined) {
|
|
830
|
-
const v = String(flags['development-mode'] ?? '').trim();
|
|
831
|
-
if (v) {
|
|
832
|
-
preset.developmentMode = v;
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
if (flags['portal-name'] !== undefined) {
|
|
836
|
-
const v = String(flags['portal-name'] ?? '').trim();
|
|
837
|
-
if (v) {
|
|
838
|
-
preset.portalName = v;
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
if (flags['portal-template'] !== undefined) {
|
|
842
|
-
const v = String(flags['portal-template'] ?? '').trim();
|
|
843
|
-
if (v) {
|
|
844
|
-
preset.portalTemplate = v;
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
775
|
if (flags['root-username'] !== undefined) {
|
|
848
776
|
preset.rootUsername = String(flags['root-username'] ?? '').trim();
|
|
849
777
|
}
|
|
@@ -935,9 +863,6 @@ export default class Install extends Command {
|
|
|
935
863
|
'appPort',
|
|
936
864
|
'storagePath',
|
|
937
865
|
'appPublicPath',
|
|
938
|
-
'developmentMode',
|
|
939
|
-
'portalName',
|
|
940
|
-
'portalTemplate',
|
|
941
866
|
]);
|
|
942
867
|
}
|
|
943
868
|
static buildDbPresetValuesFromFlags(flags, argv = process.argv.slice(2)) {
|
|
@@ -1187,9 +1112,6 @@ export default class Install extends Command {
|
|
|
1187
1112
|
const rootPassword = Install.toOptionalPromptString(config.rootPassword);
|
|
1188
1113
|
const rootNickname = Install.toOptionalPromptString(config.rootNickname);
|
|
1189
1114
|
const lang = Install.toOptionalPromptString(config.lang);
|
|
1190
|
-
const developmentMode = Install.toOptionalPromptString(config.developmentMode);
|
|
1191
|
-
const portalName = Install.toOptionalPromptString(config.portalName);
|
|
1192
|
-
const portalTemplate = Install.toOptionalPromptString(config.portalTemplate);
|
|
1193
1115
|
const auth = config.auth;
|
|
1194
1116
|
const savedAuthType = Install.toOptionalPromptString(config.authType) ?? Install.toOptionalPromptString(auth?.type);
|
|
1195
1117
|
const appPreset = {
|
|
@@ -1199,9 +1121,6 @@ export default class Install extends Command {
|
|
|
1199
1121
|
...(appPort ? { appPort } : {}),
|
|
1200
1122
|
...(storagePath ? { storagePath } : {}),
|
|
1201
1123
|
...(appPublicPath ? { appPublicPath } : {}),
|
|
1202
|
-
...(developmentMode ? { developmentMode } : {}),
|
|
1203
|
-
...(portalName ? { portalName } : {}),
|
|
1204
|
-
...(portalTemplate ? { portalTemplate } : {}),
|
|
1205
1124
|
...(hookScript ? { hookScript } : {}),
|
|
1206
1125
|
};
|
|
1207
1126
|
const downloadPreset = {
|
|
@@ -1344,12 +1263,6 @@ export default class Install extends Command {
|
|
|
1344
1263
|
warn: params.warnOnPortFallback ?? true,
|
|
1345
1264
|
});
|
|
1346
1265
|
}
|
|
1347
|
-
if (params.flags['portal-template'] === undefined) {
|
|
1348
|
-
const defaultPortalTemplate = Install.toOptionalPromptString(await getCliConfigValue('default-portal-template'));
|
|
1349
|
-
if (defaultPortalTemplate) {
|
|
1350
|
-
initialValues.portalTemplate = defaultPortalTemplate;
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
1266
|
return initialValues;
|
|
1354
1267
|
}
|
|
1355
1268
|
static shouldPublishBuiltinDbPortForValues(values) {
|
|
@@ -1517,17 +1430,14 @@ export default class Install extends Command {
|
|
|
1517
1430
|
static buildDockerAppContainerName(envName, containerPrefix) {
|
|
1518
1431
|
return Install.sanitizeDockerResourceName(`${Install.buildBuiltinDbContainerPrefix(containerPrefix)}-${envName}-app`);
|
|
1519
1432
|
}
|
|
1520
|
-
static buildInitAppEnvVars(params
|
|
1433
|
+
static buildInitAppEnvVars(params) {
|
|
1521
1434
|
return buildInitAppEnvVarsFromConfig({
|
|
1522
1435
|
lang: String(params.appResults.lang ?? ''),
|
|
1523
1436
|
rootUsername: String(params.rootResults.rootUsername ?? ''),
|
|
1524
1437
|
rootEmail: String(params.rootResults.rootEmail ?? ''),
|
|
1525
1438
|
rootPassword: String(params.rootResults.rootPassword ?? ''),
|
|
1526
1439
|
rootNickname: String(params.rootResults.rootNickname ?? ''),
|
|
1527
|
-
|
|
1528
|
-
portalName: String(params.appResults.portalName ?? ''),
|
|
1529
|
-
portalTemplate: String(params.appResults.portalTemplate ?? ''),
|
|
1530
|
-
}, options);
|
|
1440
|
+
});
|
|
1531
1441
|
}
|
|
1532
1442
|
static shouldPublishBuiltinDbPort(source) {
|
|
1533
1443
|
return String(source ?? '').trim() !== 'docker';
|
|
@@ -1882,7 +1792,7 @@ export default class Install extends Command {
|
|
|
1882
1792
|
const initEnvVars = Install.buildInitAppEnvVars({
|
|
1883
1793
|
appResults: params.appResults,
|
|
1884
1794
|
rootResults: params.rootResults,
|
|
1885
|
-
}
|
|
1795
|
+
});
|
|
1886
1796
|
const containerPort = resolveDockerImageContainerPort(imageRef);
|
|
1887
1797
|
const args = [
|
|
1888
1798
|
'run',
|
|
@@ -2159,7 +2069,7 @@ export default class Install extends Command {
|
|
|
2159
2069
|
...Install.buildInitAppEnvVars({
|
|
2160
2070
|
appResults: params.appResults,
|
|
2161
2071
|
rootResults: params.rootResults,
|
|
2162
|
-
}
|
|
2072
|
+
}),
|
|
2163
2073
|
};
|
|
2164
2074
|
setOptionalEnvVar(env, 'APP_PUBLIC_PATH', Install.toOptionalPromptString(params.appResults.appPublicPath));
|
|
2165
2075
|
setOptionalEnvVar(env, 'DB_SCHEMA', optionalEnvString(params.dbResults.dbSchema));
|
|
@@ -2356,19 +2266,6 @@ export default class Install extends Command {
|
|
|
2356
2266
|
}
|
|
2357
2267
|
return argv;
|
|
2358
2268
|
}
|
|
2359
|
-
async prepareInitialPortalIfNeeded(params) {
|
|
2360
|
-
await prepareInitialPortalTemplate({
|
|
2361
|
-
developmentMode: Install.toOptionalPromptString(params.appResults.developmentMode),
|
|
2362
|
-
portalName: Install.toOptionalPromptString(params.appResults.portalName),
|
|
2363
|
-
portalTemplate: Install.toOptionalPromptString(params.appResults.portalTemplate),
|
|
2364
|
-
npmRegistry: Install.toOptionalPromptString(params.appResults.npmRegistry),
|
|
2365
|
-
storagePath: Install.resolveAbsoluteStoragePath(params.envName, params.appResults),
|
|
2366
|
-
verbose: params.verbose,
|
|
2367
|
-
onStartTask: (message) => this.logStage(message),
|
|
2368
|
-
onSucceedTask: (message) => printInfo(message),
|
|
2369
|
-
onFailTask: (message) => printWarning(message),
|
|
2370
|
-
});
|
|
2371
|
-
}
|
|
2372
2269
|
async runInstallHookIfNeeded(params) {
|
|
2373
2270
|
const appPath = Install.resolveAbsoluteAppPath(params.envName, params.appResults);
|
|
2374
2271
|
const savedHookScript = Install.toOptionalPromptString(params.appResults.hookScript);
|
|
@@ -2412,9 +2309,6 @@ export default class Install extends Command {
|
|
|
2412
2309
|
const appRootPath = Install.toOptionalPromptString(params.appResults.appRootPath);
|
|
2413
2310
|
const storagePath = Install.toOptionalPromptString(params.appResults.storagePath);
|
|
2414
2311
|
const appPublicPath = Install.toOptionalPromptString(params.appResults.appPublicPath);
|
|
2415
|
-
const developmentMode = Install.toOptionalPromptString(params.appResults.developmentMode);
|
|
2416
|
-
const portalName = Install.toOptionalPromptString(params.appResults.portalName);
|
|
2417
|
-
const portalTemplate = Install.toOptionalPromptString(params.appResults.portalTemplate);
|
|
2418
2312
|
const derivedAppRootPath = appPath ? deriveConfiguredSourcePath(appPath) : undefined;
|
|
2419
2313
|
const derivedStoragePath = appPath ? deriveConfiguredStoragePath(appPath) : undefined;
|
|
2420
2314
|
const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT;
|
|
@@ -2449,9 +2343,6 @@ export default class Install extends Command {
|
|
|
2449
2343
|
...(appPublicPath ? { appPublicPath } : {}),
|
|
2450
2344
|
...(envFile ? { envFile } : {}),
|
|
2451
2345
|
lang: params.appResults.lang,
|
|
2452
|
-
developmentMode,
|
|
2453
|
-
portalName,
|
|
2454
|
-
portalTemplate,
|
|
2455
2346
|
appKey: params.appResults.appKey,
|
|
2456
2347
|
timezone: params.appResults.timeZone,
|
|
2457
2348
|
builtinDb: params.dbResults.builtinDb,
|
|
@@ -2503,7 +2394,6 @@ export default class Install extends Command {
|
|
|
2503
2394
|
'app-root-path': parsed['app-root-path'] ?? Install.toOptionalPromptString(appPreset.appRootPath),
|
|
2504
2395
|
'app-port': parsed['app-port'] ?? Install.toOptionalPromptString(appPreset.appPort),
|
|
2505
2396
|
'storage-path': parsed['storage-path'] ?? Install.toOptionalPromptString(appPreset.storagePath),
|
|
2506
|
-
'portal-template': parsed['portal-template'] ?? Install.toOptionalPromptString(appPreset.portalTemplate),
|
|
2507
2397
|
},
|
|
2508
2398
|
}),
|
|
2509
2399
|
values: appPreset,
|
|
@@ -2742,13 +2632,6 @@ export default class Install extends Command {
|
|
|
2742
2632
|
envAddResults,
|
|
2743
2633
|
});
|
|
2744
2634
|
}
|
|
2745
|
-
if (shouldStartApp) {
|
|
2746
|
-
await this.prepareInitialPortalIfNeeded({
|
|
2747
|
-
envName,
|
|
2748
|
-
appResults,
|
|
2749
|
-
verbose: parsed.verbose,
|
|
2750
|
-
});
|
|
2751
|
-
}
|
|
2752
2635
|
if (shouldStartApp) {
|
|
2753
2636
|
this.logStage('Starting NocoBase');
|
|
2754
2637
|
await this.config.runCommand('app:start', this.buildAppStartArgv({ envName, verbose: parsed.verbose }));
|
|
@@ -140,7 +140,7 @@ export default class SourceDev extends Command {
|
|
|
140
140
|
: `Run \`nb app stop --env ${runtime.envName}\` before starting dev mode, or choose another dev port with --port.`,
|
|
141
141
|
].join('\n'));
|
|
142
142
|
}
|
|
143
|
-
const npmArgs = ['dev', '--rsbuild'
|
|
143
|
+
const npmArgs = ['dev', '--rsbuild'];
|
|
144
144
|
if (flags['db-sync']) {
|
|
145
145
|
npmArgs.push('--db-sync');
|
|
146
146
|
}
|
package/dist/lib/api-client.js
CHANGED
|
@@ -199,6 +199,13 @@ async function createMultipartBody(flags, operation) {
|
|
|
199
199
|
if (value === undefined) {
|
|
200
200
|
continue;
|
|
201
201
|
}
|
|
202
|
+
if (Array.isArray(value)) {
|
|
203
|
+
for (const item of value) {
|
|
204
|
+
formData.append(parameter.name, typeof item === 'object' ? JSON.stringify(item) : String(item));
|
|
205
|
+
}
|
|
206
|
+
hasValues = hasValues || value.length > 0;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
202
209
|
formData.append(parameter.name, typeof value === 'object' ? JSON.stringify(value) : String(value));
|
|
203
210
|
hasValues = true;
|
|
204
211
|
}
|
package/dist/lib/auth-store.js
CHANGED
|
@@ -97,7 +97,6 @@ function normalizeAuthConfig(config) {
|
|
|
97
97
|
const locale = normalizeOptionalCliLocale(settings.locale);
|
|
98
98
|
const defaultUiHost = normalizeOptionalString(settings.init?.defaultUiHost);
|
|
99
99
|
const defaultApiHost = normalizeOptionalString(settings.init?.defaultApiHost);
|
|
100
|
-
const defaultPortalTemplate = normalizeOptionalString(settings.init?.defaultPortalTemplate);
|
|
101
100
|
const updatePolicy = normalizeOptionalCliUpdatePolicy(settings.update?.policy);
|
|
102
101
|
const logRetentionDays = typeof settings.log?.retentionDays === 'number' && Number.isInteger(settings.log.retentionDays)
|
|
103
102
|
? settings.log.retentionDays
|
|
@@ -118,12 +117,11 @@ function normalizeAuthConfig(config) {
|
|
|
118
117
|
name: config.name || config.dockerResourcePrefix,
|
|
119
118
|
settings: {
|
|
120
119
|
...(locale ? { locale } : {}),
|
|
121
|
-
...(defaultUiHost || defaultApiHost
|
|
120
|
+
...(defaultUiHost || defaultApiHost
|
|
122
121
|
? {
|
|
123
122
|
init: {
|
|
124
123
|
...(defaultUiHost ? { defaultUiHost } : {}),
|
|
125
124
|
...(defaultApiHost ? { defaultApiHost } : {}),
|
|
126
|
-
...(defaultPortalTemplate ? { defaultPortalTemplate } : {}),
|
|
127
125
|
},
|
|
128
126
|
}
|
|
129
127
|
: {}),
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { spawn } from 'node:child_process';
|
|
10
|
+
export async function openUrlInDefaultBrowser(url) {
|
|
11
|
+
const [command, args, options] = process.platform === 'darwin'
|
|
12
|
+
? ['open', [url], { detached: true, stdio: 'ignore' }]
|
|
13
|
+
: process.platform === 'win32'
|
|
14
|
+
? ['cmd', ['/c', 'start', '', url], { detached: true, stdio: 'ignore', windowsHide: true }]
|
|
15
|
+
: ['xdg-open', [url], { detached: true, stdio: 'ignore' }];
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
try {
|
|
18
|
+
const child = spawn(command, args, options);
|
|
19
|
+
child.once('error', () => resolve(false));
|
|
20
|
+
child.once('spawn', () => {
|
|
21
|
+
child.unref();
|
|
22
|
+
resolve(true);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
resolve(false);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|