@nocobase/cli 2.2.0-alpha.1 → 2.2.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/env-proxy/nginx/snippets/proxy-location.conf +1 -0
- package/assets/env-proxy/nginx/snippets/uploads-location.conf +4 -1
- package/bin/early-locale.js +89 -0
- package/bin/node-version.js +35 -0
- package/bin/run.js +9 -0
- package/bin/windows-admin.js +60 -0
- package/dist/commands/app/destroy.js +4 -3
- package/dist/commands/app/restart.js +38 -0
- package/dist/commands/app/shared.js +49 -3
- package/dist/commands/app/start.js +95 -0
- package/dist/commands/app/upgrade.js +11 -0
- package/dist/commands/config/set.js +1 -0
- package/dist/commands/env/info.js +11 -1
- package/dist/commands/examples/prompts-stages.js +2 -2
- package/dist/commands/examples/prompts-test.js +2 -2
- package/dist/commands/init.js +152 -14
- package/dist/commands/install.js +256 -109
- package/dist/commands/license/activate.js +4 -1
- package/dist/commands/license/shared.js +24 -15
- package/dist/commands/portal/config.js +88 -0
- package/dist/commands/portal/create.js +104 -0
- package/dist/commands/portal/deploy.js +81 -0
- package/dist/commands/portal/destroy.js +104 -0
- package/dist/commands/portal/dev.js +71 -0
- package/dist/commands/portal/index.js +20 -0
- package/dist/commands/portal/info.js +82 -0
- package/dist/commands/portal/list.js +98 -0
- package/dist/commands/portal/pull.js +84 -0
- package/dist/commands/portal/push.js +79 -0
- package/dist/commands/proxy/caddy/generate.js +93 -7
- package/dist/commands/proxy/nginx/generate.js +98 -7
- package/dist/commands/revision/create.js +1 -1
- package/dist/commands/self/check.js +1 -1
- package/dist/commands/self/update.js +4 -4
- package/dist/commands/skills/check.js +4 -5
- package/dist/commands/skills/install.js +18 -1
- package/dist/commands/skills/update.js +19 -4
- package/dist/commands/source/dev.js +10 -6
- package/dist/commands/source/download.js +85 -16
- package/dist/lib/api-command-compat.js +51 -8
- package/dist/lib/app-managed-resources.js +104 -5
- package/dist/lib/auth-store.js +105 -13
- package/dist/lib/cli-config.js +93 -2
- package/dist/lib/docker-image.js +94 -6
- package/dist/lib/env-auth.js +291 -45
- package/dist/lib/env-config.js +14 -0
- package/dist/lib/env-proxy-config.js +48 -0
- package/dist/lib/env-proxy.js +266 -61
- package/dist/lib/hook-script.js +160 -0
- package/dist/lib/managed-init-env.js +6 -1
- package/dist/lib/portal-command-env.js +31 -0
- package/dist/lib/portal-config.js +133 -0
- package/dist/lib/portal-configure.js +117 -0
- package/dist/lib/portal-create.js +433 -0
- package/dist/lib/portal-deploy.js +283 -0
- package/dist/lib/portal-destroy.js +100 -0
- package/dist/lib/portal-dev.js +79 -0
- package/dist/lib/portal-env-files.js +53 -0
- package/dist/lib/portal-info.js +31 -0
- package/dist/lib/portal-list.js +211 -0
- package/dist/lib/portal-source.js +523 -0
- package/dist/lib/prompt-catalog-terminal.js +32 -19
- package/dist/lib/prompt-validators.js +1 -1
- package/dist/lib/prompt-web-ui.js +20 -13
- package/dist/lib/proxy-caddy.js +77 -9
- package/dist/lib/proxy-nginx.js +71 -11
- package/dist/lib/run-npm.js +21 -16
- package/dist/lib/self-manager.js +254 -46
- package/dist/lib/skills-manager.js +116 -23
- package/dist/lib/source-publish.js +2 -2
- package/dist/lib/startup-update.js +1 -1
- package/dist/lib/ui.js +28 -1
- package/dist/locale/en-US.json +227 -43
- package/dist/locale/zh-CN.json +227 -43
- package/package.json +11 -2
- package/scripts/build.mjs +0 -34
- package/scripts/clean.mjs +0 -9
- package/tsconfig.json +0 -19
package/dist/commands/init.js
CHANGED
|
@@ -15,22 +15,29 @@ 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";
|
|
30
33
|
const DEFAULT_INIT_API_BASE_URL = 'http://localhost:13000/api';
|
|
31
34
|
const DEFAULT_INIT_APP_NAME = 'local';
|
|
35
|
+
const DEFAULT_INIT_PORTAL_TYPE = 'no-code';
|
|
36
|
+
const DEFAULT_INIT_PORTAL_NAME = 'admin';
|
|
37
|
+
const DEFAULT_INIT_PORTAL_TEMPLATE = '@nocobase/portal-template-default';
|
|
32
38
|
const DOWNLOAD_OUTPUT_DIR_PROMPT = Download.prompts.outputDir;
|
|
33
39
|
const INIT_SETUP_MODES = ['install-new', 'manage-local', 'connect-remote'];
|
|
40
|
+
const INIT_PORTAL_TYPES = ['no-code', 'ai'];
|
|
34
41
|
const INIT_ENV_ADD_FLAG_NAMES = [
|
|
35
42
|
'locale',
|
|
36
43
|
'default-api-base-url',
|
|
@@ -77,6 +84,9 @@ function isInstallNewSetupMode(values) {
|
|
|
77
84
|
function isInstallLikeSetupMode(values) {
|
|
78
85
|
return !isRemoteSetupMode(values);
|
|
79
86
|
}
|
|
87
|
+
function isAiMode(values) {
|
|
88
|
+
return String(values.portalType ?? DEFAULT_INIT_PORTAL_TYPE).trim() === 'ai';
|
|
89
|
+
}
|
|
80
90
|
function remoteConnectionOnly(def) {
|
|
81
91
|
return withExtraHidden(def, (values) => !isRemoteSetupMode(values));
|
|
82
92
|
}
|
|
@@ -246,16 +256,12 @@ function formatBrowserOpenError(error) {
|
|
|
246
256
|
return String(error);
|
|
247
257
|
}
|
|
248
258
|
export default class Init extends Command {
|
|
249
|
-
static summary = 'Set up
|
|
250
|
-
static description = `Set up NocoBase
|
|
251
|
-
|
|
252
|
-
\`nb init\` prepares a NocoBase environment that coding agents can use. It supports three setup paths:
|
|
259
|
+
static summary = 'Set up or connect a NocoBase environment in the current workspace';
|
|
260
|
+
static description = `Set up NocoBase in the current workspace.
|
|
253
261
|
|
|
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.
|
|
262
|
+
\`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.
|
|
257
263
|
|
|
258
|
-
It can also install NocoBase AI coding skills (\`nocobase/skills\`)
|
|
264
|
+
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
265
|
|
|
260
266
|
If setup was interrupted earlier, use \`--resume\` with an existing env name to continue from the saved workspace config.
|
|
261
267
|
|
|
@@ -388,6 +394,42 @@ Prompt modes:
|
|
|
388
394
|
devDependencies: installLikeDownloadExecutionOnly(Download.prompts.devDependencies),
|
|
389
395
|
build: installLikeDownloadExecutionOnly(Download.prompts.build),
|
|
390
396
|
buildDts: installLikeDownloadExecutionOnly(Download.prompts.buildDts),
|
|
397
|
+
portalType: installNewOnly({
|
|
398
|
+
type: 'select',
|
|
399
|
+
variant: 'radio',
|
|
400
|
+
message: initText('prompts.portalType.message'),
|
|
401
|
+
options: [
|
|
402
|
+
{
|
|
403
|
+
value: 'no-code',
|
|
404
|
+
label: initText('prompts.portalType.noCodeLabel'),
|
|
405
|
+
hint: initText('prompts.portalType.noCodeHint'),
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
value: 'ai',
|
|
409
|
+
label: initText('prompts.portalType.aiLabel'),
|
|
410
|
+
hint: initText('prompts.portalType.aiHint'),
|
|
411
|
+
},
|
|
412
|
+
],
|
|
413
|
+
initialValue: DEFAULT_INIT_PORTAL_TYPE,
|
|
414
|
+
yesInitialValue: DEFAULT_INIT_PORTAL_TYPE,
|
|
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
|
+
required: true,
|
|
424
|
+
}),
|
|
425
|
+
portalTemplate: installNewOnly({
|
|
426
|
+
type: 'text',
|
|
427
|
+
message: initText('prompts.portalTemplate.message'),
|
|
428
|
+
placeholder: DEFAULT_INIT_PORTAL_TEMPLATE,
|
|
429
|
+
yesInitialValue: DEFAULT_INIT_PORTAL_TEMPLATE,
|
|
430
|
+
hidden: (values) => !isAiMode(values),
|
|
431
|
+
required: true,
|
|
432
|
+
}),
|
|
391
433
|
dbDialect: installLikeOnly(Install.dbPrompts.dbDialect),
|
|
392
434
|
builtinDb: installLikeOnly(Install.dbPrompts.builtinDb),
|
|
393
435
|
builtinDbImage: installLikeOnly(Install.dbPrompts.builtinDbImage),
|
|
@@ -413,6 +455,13 @@ Prompt modes:
|
|
|
413
455
|
...Init.prompts,
|
|
414
456
|
installApiBaseUrl: createInstallConnectionApiBaseUrlPrompt(options.defaultApiHost),
|
|
415
457
|
};
|
|
458
|
+
const defaultPortalTemplate = String(options.defaultPortalTemplate ?? '').trim();
|
|
459
|
+
if (defaultPortalTemplate) {
|
|
460
|
+
prompts.portalTemplate = {
|
|
461
|
+
...prompts.portalTemplate,
|
|
462
|
+
yesInitialValue: defaultPortalTemplate,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
416
465
|
if (flags['skip-auth']) {
|
|
417
466
|
const accessTokenPrompt = {
|
|
418
467
|
...EnvAdd.prompts.accessToken,
|
|
@@ -462,6 +511,16 @@ Prompt modes:
|
|
|
462
511
|
description: 'Setup mode: install a new app, manage a local app by reusing its database, or connect a remote app',
|
|
463
512
|
options: [...INIT_SETUP_MODES],
|
|
464
513
|
}),
|
|
514
|
+
'portal-type': Flags.string({
|
|
515
|
+
description: 'Initial portal type: no-code or ai',
|
|
516
|
+
options: [...INIT_PORTAL_TYPES],
|
|
517
|
+
}),
|
|
518
|
+
'portal-name': Flags.string({
|
|
519
|
+
description: 'Initial portal name',
|
|
520
|
+
}),
|
|
521
|
+
'portal-template': Flags.string({
|
|
522
|
+
description: 'Initial portal template npm package or local path when --portal-type ai is used',
|
|
523
|
+
}),
|
|
465
524
|
ui: Flags.boolean({
|
|
466
525
|
description: 'Open the guided setup flow in a local browser form (not valid with --yes)',
|
|
467
526
|
default: false,
|
|
@@ -475,7 +534,7 @@ Prompt modes:
|
|
|
475
534
|
default: false,
|
|
476
535
|
}),
|
|
477
536
|
'ui-host': Flags.string({
|
|
478
|
-
description: '
|
|
537
|
+
description: 'Browser-accessible host for the --ui setup page URL (default: 127.0.0.1)',
|
|
479
538
|
}),
|
|
480
539
|
'ui-port': Flags.integer({
|
|
481
540
|
description: 'Port for the local --ui setup server; 0 lets the OS choose an available port',
|
|
@@ -579,7 +638,8 @@ Prompt modes:
|
|
|
579
638
|
const dynamicInitialValues = await Init.buildDynamicInitialValuesForInstall(normalizedFlags, presetValues);
|
|
580
639
|
const defaultUiHost = await resolveDefaultUiHost();
|
|
581
640
|
const defaultApiHost = await resolveDefaultApiHost();
|
|
582
|
-
const
|
|
641
|
+
const defaultPortalTemplate = String(dynamicInitialValues.portalTemplate ?? '').trim();
|
|
642
|
+
const promptCatalog = this.buildPromptCatalog(normalizedFlags, { defaultApiHost, defaultPortalTemplate });
|
|
583
643
|
if (useBrowserUi) {
|
|
584
644
|
presetValues = await runPromptCatalogWebUI({
|
|
585
645
|
stages: Init.buildWebUiStages(promptCatalog),
|
|
@@ -608,6 +668,7 @@ Prompt modes:
|
|
|
608
668
|
? { setupMode: normalizeInitSetupMode(presetValues.hasNocobase) }
|
|
609
669
|
: {}),
|
|
610
670
|
},
|
|
671
|
+
yesInitialValues: pickKeys(dynamicInitialValues, ['portalTemplate']),
|
|
611
672
|
values: presetValues,
|
|
612
673
|
yes: normalizedFlags.yes || useBrowserUi || !interactive,
|
|
613
674
|
hooks: {
|
|
@@ -680,7 +741,9 @@ Prompt modes:
|
|
|
680
741
|
}
|
|
681
742
|
static async buildDynamicInitialValuesForInstall(flags, presetValues) {
|
|
682
743
|
const out = {};
|
|
683
|
-
|
|
744
|
+
const shouldResolveAppInitialValues = !Object.prototype.hasOwnProperty.call(presetValues, 'appPort') ||
|
|
745
|
+
!Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate');
|
|
746
|
+
if (shouldResolveAppInitialValues) {
|
|
684
747
|
const appInitialValues = await Install.buildAppPromptInitialValues({
|
|
685
748
|
envName: String(presetValues.appName ?? '').trim(),
|
|
686
749
|
flags: {
|
|
@@ -688,17 +751,31 @@ Prompt modes:
|
|
|
688
751
|
'app-path': flags['app-path'] ?? '',
|
|
689
752
|
'app-root-path': flags['app-root-path'] ?? '',
|
|
690
753
|
'storage-path': flags['storage-path'] ?? '',
|
|
754
|
+
'portal-template': flags['portal-template'] ??
|
|
755
|
+
(Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate')
|
|
756
|
+
? String(presetValues.portalTemplate ?? '')
|
|
757
|
+
: undefined),
|
|
691
758
|
},
|
|
692
759
|
warnOnPortFallback: false,
|
|
693
760
|
});
|
|
694
|
-
if (appInitialValues.appPort !== undefined) {
|
|
761
|
+
if (appInitialValues.appPort !== undefined && !Object.prototype.hasOwnProperty.call(presetValues, 'appPort')) {
|
|
695
762
|
out.appPort = appInitialValues.appPort;
|
|
696
763
|
}
|
|
764
|
+
if (appInitialValues.portalTemplate !== undefined &&
|
|
765
|
+
!Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate')) {
|
|
766
|
+
out.portalTemplate = appInitialValues.portalTemplate;
|
|
767
|
+
}
|
|
697
768
|
}
|
|
698
769
|
const downloadSeed = { ...presetValues };
|
|
699
770
|
if (flags.yes && !Object.prototype.hasOwnProperty.call(downloadSeed, 'source')) {
|
|
700
771
|
downloadSeed.source = 'docker';
|
|
701
772
|
}
|
|
773
|
+
const builtinDbImageRegistry = String(presetValues.dockerRegistry ?? '').trim() ||
|
|
774
|
+
resolveOfficialDockerRegistry(await getCliConfigValue('nb-image-registry'));
|
|
775
|
+
if (!Object.prototype.hasOwnProperty.call(presetValues, 'dockerRegistry')) {
|
|
776
|
+
out.dockerRegistry = builtinDbImageRegistry;
|
|
777
|
+
}
|
|
778
|
+
out.builtinDbImageRegistry = builtinDbImageRegistry;
|
|
702
779
|
const dbInitial = await Install.buildDbPromptInitialValues({
|
|
703
780
|
flags,
|
|
704
781
|
downloadResults: downloadSeed,
|
|
@@ -706,6 +783,9 @@ Prompt modes:
|
|
|
706
783
|
warnOnPortFallback: false,
|
|
707
784
|
});
|
|
708
785
|
for (const [key, value] of Object.entries(dbInitial)) {
|
|
786
|
+
if (key === 'builtinDbImage') {
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
709
789
|
if (!Object.prototype.hasOwnProperty.call(presetValues, key)) {
|
|
710
790
|
out[key] = value;
|
|
711
791
|
}
|
|
@@ -763,6 +843,14 @@ Prompt modes:
|
|
|
763
843
|
buildDts: c.buildDts,
|
|
764
844
|
},
|
|
765
845
|
},
|
|
846
|
+
{
|
|
847
|
+
sectionTitle: initText('webUi.portalType.title'),
|
|
848
|
+
sectionDescription: initText('webUi.portalType.description'),
|
|
849
|
+
catalog: {
|
|
850
|
+
portalName: c.portalName,
|
|
851
|
+
portalType: c.portalType,
|
|
852
|
+
},
|
|
853
|
+
},
|
|
766
854
|
{
|
|
767
855
|
sectionTitle: initText('webUi.configureDatabase.title'),
|
|
768
856
|
sectionDescription: initText('webUi.configureDatabase.description'),
|
|
@@ -863,6 +951,15 @@ Prompt modes:
|
|
|
863
951
|
if (flags['app-public-path'] !== undefined && String(flags['app-public-path']).trim() !== '') {
|
|
864
952
|
preset.appPublicPath = String(flags['app-public-path']).trim();
|
|
865
953
|
}
|
|
954
|
+
if (flags['portal-type'] !== undefined && String(flags['portal-type']).trim() !== '') {
|
|
955
|
+
preset.portalType = String(flags['portal-type']).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
|
+
}
|
|
866
963
|
if (flags['root-username'] !== undefined) {
|
|
867
964
|
preset.rootUsername = String(flags['root-username'] ?? '').trim();
|
|
868
965
|
}
|
|
@@ -1000,6 +1097,9 @@ Prompt modes:
|
|
|
1000
1097
|
const existingEnv = await getEnv(envName, { scope: resolveDefaultConfigScope() });
|
|
1001
1098
|
const appPort = String(results.appPort ?? '').trim();
|
|
1002
1099
|
const appPublicPath = String(results.appPublicPath ?? '').trim();
|
|
1100
|
+
const portalType = String(results.portalType ?? '').trim();
|
|
1101
|
+
const portalName = String(results.portalName ?? '').trim();
|
|
1102
|
+
const portalTemplate = String(results.portalTemplate ?? '').trim();
|
|
1003
1103
|
const source = String(results.source ?? '').trim();
|
|
1004
1104
|
const version = resolveInitDownloadVersion(results);
|
|
1005
1105
|
const dockerRegistry = String(results.dockerRegistry ?? '').trim();
|
|
@@ -1032,6 +1132,14 @@ Prompt modes:
|
|
|
1032
1132
|
const skipDownload = results.skipDownload === true;
|
|
1033
1133
|
const appKey = resolveManagedAppKey(results.appKey ?? existingEnv?.config.appKey);
|
|
1034
1134
|
const timeZone = resolveManagedTimeZone(results.timeZone ?? existingEnv?.config.timezone);
|
|
1135
|
+
const hookScriptInput = String(flags['hook-script'] ?? '').trim();
|
|
1136
|
+
const hookAppPath = appPath || `./${envName}/`;
|
|
1137
|
+
const hookScript = hookScriptInput
|
|
1138
|
+
? await persistHookScript({
|
|
1139
|
+
sourcePath: hookScriptInput,
|
|
1140
|
+
appPath: resolveConfiguredEnvPath(hookAppPath) ?? resolveEnvRelativePath(hookAppPath),
|
|
1141
|
+
})
|
|
1142
|
+
: String(results.hookScript ?? '').trim();
|
|
1035
1143
|
const builtinDb = explicitDbHostFlag(flags)
|
|
1036
1144
|
? false
|
|
1037
1145
|
: results.builtinDb === undefined
|
|
@@ -1040,6 +1148,7 @@ Prompt modes:
|
|
|
1040
1148
|
results.appKey = appKey;
|
|
1041
1149
|
results.timeZone = timeZone;
|
|
1042
1150
|
await upsertEnv(envName, {
|
|
1151
|
+
schemaVersion: ENV_CONFIG_SCHEMA_VERSION,
|
|
1043
1152
|
...(source === 'docker'
|
|
1044
1153
|
? { kind: 'docker' }
|
|
1045
1154
|
: source || appPath || appRootPath
|
|
@@ -1057,11 +1166,15 @@ Prompt modes:
|
|
|
1057
1166
|
...(dockerPlatform ? { dockerPlatform } : {}),
|
|
1058
1167
|
...(gitUrl ? { gitUrl } : {}),
|
|
1059
1168
|
...(npmRegistry ? { npmRegistry } : {}),
|
|
1169
|
+
...(hookScript ? { hookScript } : {}),
|
|
1060
1170
|
...(appPath ? { appPath } : {}),
|
|
1061
1171
|
...(appRootPath && !areConfiguredPathsEquivalent(appRootPath, derivedAppRootPath) ? { appRootPath } : {}),
|
|
1062
1172
|
...(storagePath && !areConfiguredPathsEquivalent(storagePath, derivedStoragePath) ? { storagePath } : {}),
|
|
1063
1173
|
...(appPort ? { appPort } : {}),
|
|
1064
1174
|
...(appPublicPath ? { appPublicPath } : {}),
|
|
1175
|
+
...(portalType && portalType !== DEFAULT_INIT_PORTAL_TYPE ? { portalType } : {}),
|
|
1176
|
+
...(portalName ? { portalName } : {}),
|
|
1177
|
+
...(portalTemplate ? { portalTemplate } : {}),
|
|
1065
1178
|
...(appKey ? { appKey } : {}),
|
|
1066
1179
|
...(timeZone ? { timezone: timeZone } : {}),
|
|
1067
1180
|
...(!skipDownload && results.devDependencies !== undefined
|
|
@@ -1132,6 +1245,10 @@ Prompt modes:
|
|
|
1132
1245
|
if (flags['prepare-only']) {
|
|
1133
1246
|
argv.push('--prepare-only');
|
|
1134
1247
|
}
|
|
1248
|
+
const hookScript = String(results.hookScript ?? flags['hook-script'] ?? '').trim();
|
|
1249
|
+
if (hookScript) {
|
|
1250
|
+
argv.push('--hook-script', hookScript);
|
|
1251
|
+
}
|
|
1135
1252
|
if (flags.verbose) {
|
|
1136
1253
|
argv.push('--verbose');
|
|
1137
1254
|
}
|
|
@@ -1182,6 +1299,18 @@ Prompt modes:
|
|
|
1182
1299
|
if (appPublicPath) {
|
|
1183
1300
|
argv.push('--app-public-path', appPublicPath);
|
|
1184
1301
|
}
|
|
1302
|
+
const portalType = String(results.portalType ?? '').trim();
|
|
1303
|
+
if (portalType && portalType !== DEFAULT_INIT_PORTAL_TYPE) {
|
|
1304
|
+
argv.push('--portal-type', portalType);
|
|
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
|
+
}
|
|
1185
1314
|
if (flags.force) {
|
|
1186
1315
|
argv.push('--force');
|
|
1187
1316
|
}
|
|
@@ -1379,6 +1508,15 @@ Prompt modes:
|
|
|
1379
1508
|
delete normalized.rootPassword;
|
|
1380
1509
|
delete normalized.rootNickname;
|
|
1381
1510
|
}
|
|
1511
|
+
const portalType = normalizeConnectionString(normalized.portalType) || DEFAULT_INIT_PORTAL_TYPE;
|
|
1512
|
+
normalized.portalType = portalType;
|
|
1513
|
+
normalized.portalName = normalizeConnectionString(normalized.portalName) || DEFAULT_INIT_PORTAL_NAME;
|
|
1514
|
+
if (portalType === 'ai') {
|
|
1515
|
+
normalized.portalTemplate = normalizeConnectionString(normalized.portalTemplate);
|
|
1516
|
+
}
|
|
1517
|
+
else {
|
|
1518
|
+
delete normalized.portalTemplate;
|
|
1519
|
+
}
|
|
1382
1520
|
delete normalized.installApiBaseUrl;
|
|
1383
1521
|
delete normalized.installAuthType;
|
|
1384
1522
|
delete normalized.installUsername;
|