@nocobase/cli 2.1.0-alpha.21 → 2.1.0-alpha.22
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/download.js +33 -22
- package/dist/commands/env/add.js +39 -12
- package/dist/commands/init.js +72 -45
- package/dist/commands/install.js +166 -51
- package/dist/commands/prompts-stages.js +6 -0
- package/dist/commands/prompts-test.js +6 -0
- package/dist/lib/api-client.js +49 -5
- package/dist/lib/cli-locale.js +115 -0
- package/dist/lib/env-auth.js +2 -2
- package/dist/lib/prompt-catalog.js +76 -54
- package/dist/lib/prompt-validators.js +9 -8
- package/dist/lib/prompt-web-ui.js +98 -64
- package/dist/lib/runtime-generator.js +12 -1
- package/dist/locale/en-US.json +282 -0
- package/dist/locale/zh-CN.json +282 -0
- package/package.json +4 -3
|
@@ -12,11 +12,13 @@ import * as p from '@clack/prompts';
|
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
import { stdin as stdinStream, stdout as stdoutStream } from 'node:process';
|
|
14
14
|
import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
15
|
+
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, localeText, } from "../lib/cli-locale.js";
|
|
15
16
|
import { run } from "../lib/run-npm.js";
|
|
16
17
|
import { printVerbose, setVerboseMode, startTask, stopTask, updateTask } from '../lib/ui.js';
|
|
17
18
|
const DEFAULT_DOCKER_REGISTRY = 'nocobase/nocobase';
|
|
18
19
|
const DEFAULT_DOCKER_REGISTRY_ZH_CN = 'registry.cn-shanghai.aliyuncs.com/nocobase/nocobase';
|
|
19
20
|
const DEFAULT_DOCKER_PLATFORM = 'auto';
|
|
21
|
+
const downloadText = (key, values) => localeText(`commands.download.${key}`, values);
|
|
20
22
|
function defaultOutputDirForVersion(versionTag) {
|
|
21
23
|
const safe = versionTag.replace(/[/\\]/g, '-');
|
|
22
24
|
return `./nocobase-${safe}`;
|
|
@@ -109,6 +111,10 @@ export default class Download extends Command {
|
|
|
109
111
|
description: 'Show detailed command output',
|
|
110
112
|
default: false,
|
|
111
113
|
}),
|
|
114
|
+
locale: Flags.string({
|
|
115
|
+
description: CLI_LOCALE_FLAG_DESCRIPTION,
|
|
116
|
+
options: CLI_LOCALE_FLAG_OPTIONS,
|
|
117
|
+
}),
|
|
112
118
|
'no-intro': Flags.boolean({
|
|
113
119
|
hidden: true,
|
|
114
120
|
description: 'Skip command intro when invoked by another CLI command',
|
|
@@ -143,7 +149,7 @@ export default class Download extends Command {
|
|
|
143
149
|
description: 'Git repository URL to clone when --source git is used.',
|
|
144
150
|
}),
|
|
145
151
|
'docker-registry': Flags.string({
|
|
146
|
-
description: 'Docker
|
|
152
|
+
description: 'Docker registry to pull when --source docker is used; combine it with --version as the image tag.',
|
|
147
153
|
}),
|
|
148
154
|
'docker-platform': Flags.string({
|
|
149
155
|
description: 'Docker image platform to pull; use auto to let Docker choose.',
|
|
@@ -170,11 +176,11 @@ export default class Download extends Command {
|
|
|
170
176
|
static prompts = {
|
|
171
177
|
source: {
|
|
172
178
|
type: 'select',
|
|
173
|
-
message: '
|
|
179
|
+
message: downloadText('prompts.source.message'),
|
|
174
180
|
options: [
|
|
175
|
-
{ value: 'npm', label: '
|
|
176
|
-
{ value: 'git', label: '
|
|
177
|
-
{ value: 'docker', label: '
|
|
181
|
+
{ value: 'npm', label: downloadText('prompts.source.npmLabel') },
|
|
182
|
+
{ value: 'git', label: downloadText('prompts.source.gitLabel') },
|
|
183
|
+
{ value: 'docker', label: downloadText('prompts.source.dockerLabel') },
|
|
178
184
|
],
|
|
179
185
|
yesInitialValue: 'docker',
|
|
180
186
|
initialValue: 'docker',
|
|
@@ -182,16 +188,16 @@ export default class Download extends Command {
|
|
|
182
188
|
},
|
|
183
189
|
version: {
|
|
184
190
|
type: 'text',
|
|
185
|
-
message: '
|
|
186
|
-
placeholder: '
|
|
191
|
+
message: downloadText('prompts.version.message'),
|
|
192
|
+
placeholder: downloadText('prompts.version.placeholder'),
|
|
187
193
|
initialValue: 'alpha',
|
|
188
194
|
yesInitialValue: 'alpha',
|
|
189
195
|
required: true,
|
|
190
196
|
},
|
|
191
197
|
dockerRegistry: {
|
|
192
198
|
type: 'text',
|
|
193
|
-
message: '
|
|
194
|
-
placeholder:
|
|
199
|
+
message: downloadText('prompts.dockerRegistry.message'),
|
|
200
|
+
placeholder: downloadText('prompts.dockerRegistry.placeholder'),
|
|
195
201
|
initialValue: (values) => defaultDockerRegistryForLang(values.lang),
|
|
196
202
|
yesInitialValue: DEFAULT_DOCKER_REGISTRY,
|
|
197
203
|
required: true,
|
|
@@ -199,9 +205,13 @@ export default class Download extends Command {
|
|
|
199
205
|
},
|
|
200
206
|
dockerPlatform: {
|
|
201
207
|
type: 'select',
|
|
202
|
-
message: '
|
|
208
|
+
message: downloadText('prompts.dockerPlatform.message'),
|
|
203
209
|
options: [
|
|
204
|
-
{
|
|
210
|
+
{
|
|
211
|
+
value: 'auto',
|
|
212
|
+
label: downloadText('prompts.dockerPlatform.autoLabel'),
|
|
213
|
+
hint: downloadText('prompts.dockerPlatform.autoHint'),
|
|
214
|
+
},
|
|
205
215
|
{ value: 'linux/amd64', label: 'linux/amd64' },
|
|
206
216
|
{ value: 'linux/arm64', label: 'linux/arm64' },
|
|
207
217
|
],
|
|
@@ -212,14 +222,14 @@ export default class Download extends Command {
|
|
|
212
222
|
},
|
|
213
223
|
dockerSave: {
|
|
214
224
|
type: 'boolean',
|
|
215
|
-
message: '
|
|
225
|
+
message: downloadText('prompts.dockerSave.message'),
|
|
216
226
|
initialValue: false,
|
|
217
227
|
hidden: (values) => values.source !== 'docker',
|
|
218
228
|
},
|
|
219
229
|
gitUrl: {
|
|
220
230
|
type: 'text',
|
|
221
|
-
message: '
|
|
222
|
-
placeholder: '
|
|
231
|
+
message: downloadText('prompts.gitUrl.message'),
|
|
232
|
+
placeholder: downloadText('prompts.gitUrl.placeholder'),
|
|
223
233
|
initialValue: 'https://github.com/nocobase/nocobase.git',
|
|
224
234
|
yesInitialValue: 'https://github.com/nocobase/nocobase.git',
|
|
225
235
|
required: true,
|
|
@@ -227,8 +237,8 @@ export default class Download extends Command {
|
|
|
227
237
|
},
|
|
228
238
|
outputDir: {
|
|
229
239
|
type: 'text',
|
|
230
|
-
message: '
|
|
231
|
-
placeholder: '
|
|
240
|
+
message: downloadText('prompts.outputDir.message'),
|
|
241
|
+
placeholder: downloadText('prompts.outputDir.placeholder'),
|
|
232
242
|
initialValue: (values) => defaultOutputDirForVersion(String(values.version ?? 'latest').trim() || 'latest'),
|
|
233
243
|
required: true,
|
|
234
244
|
hidden: (values) => {
|
|
@@ -244,33 +254,33 @@ export default class Download extends Command {
|
|
|
244
254
|
},
|
|
245
255
|
npmRegistry: {
|
|
246
256
|
type: 'text',
|
|
247
|
-
message: '
|
|
248
|
-
placeholder: '
|
|
257
|
+
message: downloadText('prompts.npmRegistry.message'),
|
|
258
|
+
placeholder: downloadText('prompts.npmRegistry.placeholder'),
|
|
249
259
|
initialValue: '',
|
|
250
260
|
hidden: (values) => values.source !== 'npm' && values.source !== 'git',
|
|
251
261
|
},
|
|
252
262
|
replace: {
|
|
253
263
|
type: 'boolean',
|
|
254
|
-
message: '
|
|
264
|
+
message: downloadText('prompts.replace.message'),
|
|
255
265
|
initialValue: false,
|
|
256
266
|
hidden: (values) => Download.hideOutputDirAndReplaceSteps(values),
|
|
257
267
|
},
|
|
258
268
|
devDependencies: {
|
|
259
269
|
type: 'boolean',
|
|
260
|
-
message: '
|
|
270
|
+
message: downloadText('prompts.devDependencies.message'),
|
|
261
271
|
initialValue: false,
|
|
262
272
|
hidden: (values) => values.source !== 'npm',
|
|
263
273
|
},
|
|
264
274
|
build: {
|
|
265
275
|
type: 'boolean',
|
|
266
|
-
message: '
|
|
276
|
+
message: downloadText('prompts.build.message'),
|
|
267
277
|
initialValue: true,
|
|
268
278
|
yesInitialValue: true,
|
|
269
279
|
hidden: () => true,
|
|
270
280
|
},
|
|
271
281
|
buildDts: {
|
|
272
282
|
type: 'boolean',
|
|
273
|
-
message: '
|
|
283
|
+
message: downloadText('prompts.buildDts.message'),
|
|
274
284
|
initialValue: false,
|
|
275
285
|
hidden: (values) => values.source !== 'git',
|
|
276
286
|
},
|
|
@@ -689,6 +699,7 @@ export default class Download extends Command {
|
|
|
689
699
|
async download() {
|
|
690
700
|
const { flags } = await this.parse(Download);
|
|
691
701
|
this._flags = flags;
|
|
702
|
+
applyCliLocale(this._flags.locale);
|
|
692
703
|
setVerboseMode(Boolean(flags.verbose));
|
|
693
704
|
if (!flags['no-intro']) {
|
|
694
705
|
p.intro('Get NocoBase');
|
package/dist/commands/env/add.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
10
10
|
import { upsertEnv } from '../../lib/auth-store.js';
|
|
11
11
|
import { runPromptCatalog, } from '../../lib/prompt-catalog.js';
|
|
12
|
+
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, localeText, } from '../../lib/cli-locale.js';
|
|
12
13
|
import { validateApiBaseUrl } from '../../lib/prompt-validators.js';
|
|
13
14
|
import { printVerbose, setVerboseMode } from '../../lib/ui.js';
|
|
14
15
|
import * as p from '@clack/prompts';
|
|
@@ -25,6 +26,7 @@ const ENV_RUNTIME_FLAG_MAP = {
|
|
|
25
26
|
'app-key': 'appKey',
|
|
26
27
|
timezone: 'timezone',
|
|
27
28
|
'db-dialect': 'dbDialect',
|
|
29
|
+
'builtin-db-image': 'builtinDbImage',
|
|
28
30
|
'db-host': 'dbHost',
|
|
29
31
|
'db-port': 'dbPort',
|
|
30
32
|
'db-database': 'dbDatabase',
|
|
@@ -37,6 +39,7 @@ const ENV_BOOLEAN_RUNTIME_FLAG_MAP = {
|
|
|
37
39
|
build: 'build',
|
|
38
40
|
'build-dts': 'buildDts',
|
|
39
41
|
};
|
|
42
|
+
const envAddText = (key, values) => localeText(`commands.envAdd.${key}`, values);
|
|
40
43
|
export default class EnvAdd extends Command {
|
|
41
44
|
static summary = 'Save a named NocoBase API endpoint (token or OAuth), then switch the CLI to use it';
|
|
42
45
|
static examples = [
|
|
@@ -61,6 +64,10 @@ export default class EnvAdd extends Command {
|
|
|
61
64
|
description: 'Print detailed progress while writing config',
|
|
62
65
|
default: false,
|
|
63
66
|
}),
|
|
67
|
+
locale: Flags.string({
|
|
68
|
+
description: CLI_LOCALE_FLAG_DESCRIPTION,
|
|
69
|
+
options: CLI_LOCALE_FLAG_OPTIONS,
|
|
70
|
+
}),
|
|
64
71
|
'no-intro': Flags.boolean({
|
|
65
72
|
hidden: true,
|
|
66
73
|
description: 'Skip command intro when invoked by another CLI command',
|
|
@@ -160,6 +167,10 @@ export default class EnvAdd extends Command {
|
|
|
160
167
|
hidden: true,
|
|
161
168
|
description: 'Database dialect saved with this env',
|
|
162
169
|
}),
|
|
170
|
+
'builtin-db-image': Flags.string({
|
|
171
|
+
hidden: true,
|
|
172
|
+
description: 'Built-in database image saved with this env',
|
|
173
|
+
}),
|
|
163
174
|
'db-host': Flags.string({
|
|
164
175
|
hidden: true,
|
|
165
176
|
description: 'Database host saved with this env',
|
|
@@ -184,41 +195,53 @@ export default class EnvAdd extends Command {
|
|
|
184
195
|
static prompts = {
|
|
185
196
|
name: {
|
|
186
197
|
type: 'text',
|
|
187
|
-
message: '
|
|
188
|
-
placeholder: '
|
|
198
|
+
message: envAddText('prompts.name.message'),
|
|
199
|
+
placeholder: envAddText('prompts.name.placeholder'),
|
|
189
200
|
required: true,
|
|
190
201
|
},
|
|
191
202
|
scope: {
|
|
192
203
|
type: 'select',
|
|
193
|
-
message: '
|
|
204
|
+
message: envAddText('prompts.scope.message'),
|
|
194
205
|
options: [
|
|
195
|
-
{
|
|
196
|
-
|
|
206
|
+
{
|
|
207
|
+
value: 'project',
|
|
208
|
+
label: envAddText('prompts.scope.projectLabel'),
|
|
209
|
+
hint: envAddText('prompts.scope.projectHint'),
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
value: 'global',
|
|
213
|
+
label: envAddText('prompts.scope.globalLabel'),
|
|
214
|
+
hint: envAddText('prompts.scope.globalHint'),
|
|
215
|
+
},
|
|
197
216
|
],
|
|
198
217
|
initialValue: 'project',
|
|
199
218
|
required: true,
|
|
200
219
|
},
|
|
201
220
|
apiBaseUrl: {
|
|
202
221
|
type: 'text',
|
|
203
|
-
message: '
|
|
204
|
-
placeholder: '
|
|
222
|
+
message: envAddText('prompts.apiBaseUrl.message'),
|
|
223
|
+
placeholder: envAddText('prompts.apiBaseUrl.placeholder'),
|
|
205
224
|
required: true,
|
|
206
225
|
validate: validateApiBaseUrl,
|
|
207
226
|
},
|
|
208
227
|
authType: {
|
|
209
228
|
type: 'select',
|
|
210
|
-
message: '
|
|
229
|
+
message: envAddText('prompts.authType.message'),
|
|
211
230
|
options: [
|
|
212
|
-
{
|
|
213
|
-
|
|
231
|
+
{
|
|
232
|
+
value: 'oauth',
|
|
233
|
+
label: envAddText('prompts.authType.oauthLabel'),
|
|
234
|
+
hint: envAddText('prompts.authType.oauthHint'),
|
|
235
|
+
},
|
|
236
|
+
{ value: 'token', label: envAddText('prompts.authType.tokenLabel') },
|
|
214
237
|
],
|
|
215
238
|
initialValue: 'oauth',
|
|
216
239
|
required: true,
|
|
217
240
|
},
|
|
218
241
|
accessToken: {
|
|
219
242
|
type: 'text',
|
|
220
|
-
message: '
|
|
221
|
-
placeholder: '
|
|
243
|
+
message: envAddText('prompts.accessToken.message'),
|
|
244
|
+
placeholder: envAddText('prompts.accessToken.placeholder'),
|
|
222
245
|
required: true,
|
|
223
246
|
hidden: (values) => values.authType !== 'token',
|
|
224
247
|
},
|
|
@@ -269,6 +292,9 @@ export default class EnvAdd extends Command {
|
|
|
269
292
|
envConfig[configKey] = value;
|
|
270
293
|
}
|
|
271
294
|
}
|
|
295
|
+
if (flags['builtin-db'] === false) {
|
|
296
|
+
envConfig.builtinDbImage = undefined;
|
|
297
|
+
}
|
|
272
298
|
if (results.authType === 'token' && results.accessToken != null) {
|
|
273
299
|
envConfig.accessToken = String(results.accessToken);
|
|
274
300
|
}
|
|
@@ -277,6 +303,7 @@ export default class EnvAdd extends Command {
|
|
|
277
303
|
async run() {
|
|
278
304
|
const { args, flags } = await this.parse(EnvAdd);
|
|
279
305
|
const parsedFlags = flags;
|
|
306
|
+
applyCliLocale(parsedFlags.locale);
|
|
280
307
|
setVerboseMode(parsedFlags.verbose);
|
|
281
308
|
if (!parsedFlags['no-intro']) {
|
|
282
309
|
p.intro('Connect a NocoBase Environment');
|
package/dist/commands/init.js
CHANGED
|
@@ -14,6 +14,7 @@ import path from 'node:path';
|
|
|
14
14
|
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
|
+
import { applyCliLocale, localeText, translateCli } from "../lib/cli-locale.js";
|
|
17
18
|
import { runPromptCatalogWebUI, } from "../lib/prompt-web-ui.js";
|
|
18
19
|
import { validateApiBaseUrl, validateEnvKey } from "../lib/prompt-validators.js";
|
|
19
20
|
import { run } from "../lib/run-npm.js";
|
|
@@ -25,6 +26,7 @@ const DEFAULT_INIT_API_BASE_URL = 'http://localhost:13000/api';
|
|
|
25
26
|
const DEFAULT_INIT_APP_NAME = 'local';
|
|
26
27
|
const DOWNLOAD_OUTPUT_DIR_PROMPT = Download.prompts.outputDir;
|
|
27
28
|
const CONFIG_SCOPE = 'project';
|
|
29
|
+
const initText = (key, values) => localeText(`commands.init.${key}`, values);
|
|
28
30
|
function withExtraHidden(def, extraHidden) {
|
|
29
31
|
if (def.type === 'run') {
|
|
30
32
|
return def;
|
|
@@ -63,7 +65,7 @@ async function validateInitAppName(value) {
|
|
|
63
65
|
if (shouldAllowExistingInitEnv()) {
|
|
64
66
|
return undefined;
|
|
65
67
|
}
|
|
66
|
-
return
|
|
68
|
+
return translateCli('commands.init.validation.envExists', { envName });
|
|
67
69
|
}
|
|
68
70
|
return undefined;
|
|
69
71
|
}
|
|
@@ -71,20 +73,31 @@ function highlightInitValidationMessage(message) {
|
|
|
71
73
|
return message.replace(/Env "([^"]+)"/, (_match, envName) => `Env ${pc.cyan(pc.bold(`"${envName}"`))}`);
|
|
72
74
|
}
|
|
73
75
|
function formatInitValidationMessage(message) {
|
|
74
|
-
if (/"appName" is required/.test(message)) {
|
|
75
|
-
return [
|
|
76
|
-
'App name is required when prompts are skipped.',
|
|
77
|
-
'The app name is also the CLI env name. Use `nb init --yes --env <envName>` to continue.',
|
|
78
|
-
].join('\n');
|
|
79
|
-
}
|
|
80
76
|
return message;
|
|
81
77
|
}
|
|
82
78
|
function formatResumeEnvRequiredMessage() {
|
|
83
79
|
return [
|
|
84
|
-
'
|
|
85
|
-
'
|
|
80
|
+
translateCli('commands.init.messages.resumeEnvRequired'),
|
|
81
|
+
translateCli('commands.init.messages.resumeEnvHelp'),
|
|
86
82
|
].join('\n');
|
|
87
83
|
}
|
|
84
|
+
function formatSkippedAppNameRequiredMessage() {
|
|
85
|
+
return [
|
|
86
|
+
translateCli('commands.init.messages.appNameRequiredWhenSkipped'),
|
|
87
|
+
translateCli('commands.init.messages.appNameEnvHelp'),
|
|
88
|
+
].join('\n');
|
|
89
|
+
}
|
|
90
|
+
function initTitle() {
|
|
91
|
+
return translateCli('commands.init.messages.title');
|
|
92
|
+
}
|
|
93
|
+
function logInitUiReady(command, url) {
|
|
94
|
+
p.log.step(translateCli('commands.init.messages.uiReady'));
|
|
95
|
+
p.log.info(translateCli('commands.init.messages.uiReadyHelp'));
|
|
96
|
+
command.log(`URL: ${url}`);
|
|
97
|
+
}
|
|
98
|
+
function logInitUiBrowserOpenFallback() {
|
|
99
|
+
p.log.warn(translateCli('commands.init.messages.uiOpenBrowserFallback'));
|
|
100
|
+
}
|
|
88
101
|
export default class Init extends Command {
|
|
89
102
|
static summary = 'Set up NocoBase so coding agents can connect and work with it';
|
|
90
103
|
static description = `Set up NocoBase for coding agents in the current workspace.
|
|
@@ -119,23 +132,23 @@ Prompt modes:
|
|
|
119
132
|
static prompts = {
|
|
120
133
|
appName: {
|
|
121
134
|
type: 'text',
|
|
122
|
-
message: '
|
|
123
|
-
placeholder:
|
|
135
|
+
message: initText('prompts.appName.message'),
|
|
136
|
+
placeholder: initText('prompts.appName.placeholder'),
|
|
124
137
|
required: true,
|
|
125
138
|
validate: validateInitAppName,
|
|
126
139
|
},
|
|
127
140
|
hasNocobase: {
|
|
128
141
|
type: 'select',
|
|
129
142
|
variant: 'radio',
|
|
130
|
-
message: '
|
|
143
|
+
message: initText('prompts.hasNocobase.message'),
|
|
131
144
|
options: [
|
|
132
145
|
{
|
|
133
146
|
value: 'no',
|
|
134
|
-
label:
|
|
147
|
+
label: initText('prompts.hasNocobase.noLabel'),
|
|
135
148
|
},
|
|
136
149
|
{
|
|
137
150
|
value: 'yes',
|
|
138
|
-
label: '
|
|
151
|
+
label: initText('prompts.hasNocobase.yesLabel'),
|
|
139
152
|
},
|
|
140
153
|
],
|
|
141
154
|
initialValue: 'no',
|
|
@@ -144,14 +157,14 @@ Prompt modes:
|
|
|
144
157
|
},
|
|
145
158
|
installSkills: {
|
|
146
159
|
type: 'boolean',
|
|
147
|
-
message: '
|
|
160
|
+
message: initText('prompts.installSkills.message'),
|
|
148
161
|
initialValue: true,
|
|
149
162
|
yesInitialValue: true,
|
|
150
163
|
},
|
|
151
164
|
apiBaseUrl: existingAppOnly({
|
|
152
165
|
type: 'text',
|
|
153
|
-
message: '
|
|
154
|
-
placeholder:
|
|
166
|
+
message: initText('prompts.apiBaseUrl.message'),
|
|
167
|
+
placeholder: initText('prompts.apiBaseUrl.placeholder'),
|
|
155
168
|
required: true,
|
|
156
169
|
validate: validateApiBaseUrl,
|
|
157
170
|
}),
|
|
@@ -194,8 +207,9 @@ Prompt modes:
|
|
|
194
207
|
devDependencies: downloadInNewInstallOnly(Download.prompts.devDependencies),
|
|
195
208
|
build: downloadInNewInstallOnly(Download.prompts.build),
|
|
196
209
|
buildDts: downloadInNewInstallOnly(Download.prompts.buildDts),
|
|
197
|
-
builtinDb: newInstallOnly(Install.dbPrompts.builtinDb),
|
|
198
210
|
dbDialect: newInstallOnly(Install.dbPrompts.dbDialect),
|
|
211
|
+
builtinDb: newInstallOnly(Install.dbPrompts.builtinDb),
|
|
212
|
+
builtinDbImage: newInstallOnly(Install.dbPrompts.builtinDbImage),
|
|
199
213
|
dbHost: newInstallOnly(Install.dbPrompts.dbHost),
|
|
200
214
|
dbPort: newInstallOnly(Install.dbPrompts.dbPort),
|
|
201
215
|
dbDatabase: newInstallOnly(Install.dbPrompts.dbDatabase),
|
|
@@ -209,12 +223,12 @@ Prompt modes:
|
|
|
209
223
|
static flags = {
|
|
210
224
|
yes: Flags.boolean({
|
|
211
225
|
char: 'y',
|
|
212
|
-
description: 'Skip prompts and create a new local NocoBase app. Requires an
|
|
226
|
+
description: 'Skip prompts and create a new local NocoBase app. Requires an env name.',
|
|
213
227
|
default: false,
|
|
214
228
|
}),
|
|
215
229
|
env: Flags.string({
|
|
216
230
|
char: 'e',
|
|
217
|
-
description: '
|
|
231
|
+
description: 'Env name for this setup. Required with --yes and --resume',
|
|
218
232
|
}),
|
|
219
233
|
'install-skills': Flags.boolean({
|
|
220
234
|
description: 'Install NocoBase AI coding skills (`nocobase/skills`) for this workspace',
|
|
@@ -236,6 +250,7 @@ Prompt modes:
|
|
|
236
250
|
};
|
|
237
251
|
async run() {
|
|
238
252
|
const parsedResult = await this.parse(Init);
|
|
253
|
+
applyCliLocale(parsedResult.flags.locale);
|
|
239
254
|
const flags = parsedResult.flags;
|
|
240
255
|
const normalizedFlags = { ...flags };
|
|
241
256
|
if (normalizedFlags.ui && normalizedFlags.yes) {
|
|
@@ -254,7 +269,7 @@ Prompt modes:
|
|
|
254
269
|
p.log.error(formatResumeEnvRequiredMessage());
|
|
255
270
|
this.exit(1);
|
|
256
271
|
}
|
|
257
|
-
p.intro(
|
|
272
|
+
p.intro(initTitle());
|
|
258
273
|
if (Boolean(normalizedFlags['install-skills'])) {
|
|
259
274
|
try {
|
|
260
275
|
p.log.step('Installing NocoBase agent skills (npx -y skills add nocobase/skills)');
|
|
@@ -282,17 +297,17 @@ Prompt modes:
|
|
|
282
297
|
const useBrowserUi = Boolean(normalizedFlags.ui);
|
|
283
298
|
let presetValues = this.buildPresetValuesFromFlags(normalizedFlags);
|
|
284
299
|
if (normalizedFlags.yes && !String(presetValues.appName ?? '').trim()) {
|
|
285
|
-
const formatted =
|
|
300
|
+
const formatted = formatSkippedAppNameRequiredMessage();
|
|
286
301
|
p.log.error(highlightInitValidationMessage(formatted));
|
|
287
302
|
this.exit(1);
|
|
288
303
|
}
|
|
289
304
|
const appName = String(presetValues.appName ?? '').trim();
|
|
290
305
|
if (useBrowserUi) {
|
|
291
|
-
p.intro(
|
|
292
|
-
p.log.info('
|
|
306
|
+
p.intro(initTitle());
|
|
307
|
+
p.log.info(translateCli('commands.init.messages.uiOpening'));
|
|
293
308
|
}
|
|
294
309
|
else {
|
|
295
|
-
p.intro(
|
|
310
|
+
p.intro(initTitle());
|
|
296
311
|
if (normalizedFlags.yes) {
|
|
297
312
|
p.log.info(`Prompts skipped (--yes). NocoBase will be installed for env "${appName}" using the provided flags and safe defaults.`);
|
|
298
313
|
}
|
|
@@ -310,14 +325,14 @@ Prompt modes:
|
|
|
310
325
|
},
|
|
311
326
|
host: normalizedFlags['ui-host']?.trim() || '127.0.0.1',
|
|
312
327
|
port: normalizedFlags['ui-port'] ?? 0,
|
|
313
|
-
pageTitle: '
|
|
314
|
-
documentHeading: '
|
|
315
|
-
documentHint: '
|
|
316
|
-
onServerStart: ({
|
|
317
|
-
this
|
|
328
|
+
pageTitle: initText('webUi.pageTitle'),
|
|
329
|
+
documentHeading: initText('webUi.documentHeading'),
|
|
330
|
+
documentHint: initText('webUi.documentHint'),
|
|
331
|
+
onServerStart: ({ url }) => {
|
|
332
|
+
logInitUiReady(this, url);
|
|
318
333
|
},
|
|
319
|
-
onOpenBrowserError: (
|
|
320
|
-
|
|
334
|
+
onOpenBrowserError: (_url, _err) => {
|
|
335
|
+
logInitUiBrowserOpenFallback();
|
|
321
336
|
},
|
|
322
337
|
});
|
|
323
338
|
}
|
|
@@ -390,6 +405,7 @@ Prompt modes:
|
|
|
390
405
|
'app-root-path': flags['app-root-path'] ?? '',
|
|
391
406
|
'storage-path': flags['storage-path'] ?? '',
|
|
392
407
|
},
|
|
408
|
+
warnOnPortFallback: false,
|
|
393
409
|
});
|
|
394
410
|
if (appInitialValues.appPort !== undefined) {
|
|
395
411
|
out.appPort = appInitialValues.appPort;
|
|
@@ -405,6 +421,7 @@ Prompt modes:
|
|
|
405
421
|
flags,
|
|
406
422
|
downloadResults: downloadSeed,
|
|
407
423
|
dbPreset: presetValues,
|
|
424
|
+
warnOnPortFallback: false,
|
|
408
425
|
});
|
|
409
426
|
for (const [key, value] of Object.entries(dbInitial)) {
|
|
410
427
|
if (!Object.prototype.hasOwnProperty.call(presetValues, key)) {
|
|
@@ -417,8 +434,8 @@ Prompt modes:
|
|
|
417
434
|
const c = Init.prompts;
|
|
418
435
|
return [
|
|
419
436
|
{
|
|
420
|
-
sectionTitle: '
|
|
421
|
-
sectionDescription: '
|
|
437
|
+
sectionTitle: initText('webUi.gettingStarted.title'),
|
|
438
|
+
sectionDescription: initText('webUi.gettingStarted.description'),
|
|
422
439
|
catalog: {
|
|
423
440
|
appName: c.appName,
|
|
424
441
|
hasNocobase: c.hasNocobase,
|
|
@@ -426,8 +443,8 @@ Prompt modes:
|
|
|
426
443
|
},
|
|
427
444
|
},
|
|
428
445
|
{
|
|
429
|
-
sectionTitle: '
|
|
430
|
-
sectionDescription: '
|
|
446
|
+
sectionTitle: initText('webUi.connectExistingApp.title'),
|
|
447
|
+
sectionDescription: initText('webUi.connectExistingApp.description'),
|
|
431
448
|
catalog: {
|
|
432
449
|
apiBaseUrl: c.apiBaseUrl,
|
|
433
450
|
authType: c.authType,
|
|
@@ -435,8 +452,8 @@ Prompt modes:
|
|
|
435
452
|
},
|
|
436
453
|
},
|
|
437
454
|
{
|
|
438
|
-
sectionTitle: '
|
|
439
|
-
sectionDescription: '
|
|
455
|
+
sectionTitle: initText('webUi.createNewApp.title'),
|
|
456
|
+
sectionDescription: initText('webUi.createNewApp.description'),
|
|
440
457
|
catalog: {
|
|
441
458
|
lang: c.lang,
|
|
442
459
|
appRootPath: c.appRootPath,
|
|
@@ -446,8 +463,8 @@ Prompt modes:
|
|
|
446
463
|
},
|
|
447
464
|
},
|
|
448
465
|
{
|
|
449
|
-
sectionTitle: '
|
|
450
|
-
sectionDescription: '
|
|
466
|
+
sectionTitle: initText('webUi.downloadAppFiles.title'),
|
|
467
|
+
sectionDescription: initText('webUi.downloadAppFiles.description'),
|
|
451
468
|
catalog: {
|
|
452
469
|
source: c.source,
|
|
453
470
|
version: c.version,
|
|
@@ -464,11 +481,12 @@ Prompt modes:
|
|
|
464
481
|
},
|
|
465
482
|
},
|
|
466
483
|
{
|
|
467
|
-
sectionTitle: '
|
|
468
|
-
sectionDescription: '
|
|
484
|
+
sectionTitle: initText('webUi.configureDatabase.title'),
|
|
485
|
+
sectionDescription: initText('webUi.configureDatabase.description'),
|
|
469
486
|
catalog: {
|
|
470
|
-
builtinDb: c.builtinDb,
|
|
471
487
|
dbDialect: c.dbDialect,
|
|
488
|
+
builtinDb: c.builtinDb,
|
|
489
|
+
builtinDbImage: c.builtinDbImage,
|
|
472
490
|
dbHost: c.dbHost,
|
|
473
491
|
dbPort: c.dbPort,
|
|
474
492
|
dbDatabase: c.dbDatabase,
|
|
@@ -477,8 +495,8 @@ Prompt modes:
|
|
|
477
495
|
},
|
|
478
496
|
},
|
|
479
497
|
{
|
|
480
|
-
sectionTitle: '
|
|
481
|
-
sectionDescription: '
|
|
498
|
+
sectionTitle: initText('webUi.createAdminAccount.title'),
|
|
499
|
+
sectionDescription: initText('webUi.createAdminAccount.description'),
|
|
482
500
|
catalog: {
|
|
483
501
|
rootUsername: c.rootUsername,
|
|
484
502
|
rootEmail: c.rootEmail,
|
|
@@ -521,6 +539,9 @@ Prompt modes:
|
|
|
521
539
|
if (flags['db-dialect'] !== undefined && String(flags['db-dialect']).trim() !== '') {
|
|
522
540
|
preset.dbDialect = String(flags['db-dialect']).trim();
|
|
523
541
|
}
|
|
542
|
+
if (flags['builtin-db-image'] !== undefined && String(flags['builtin-db-image']).trim() !== '') {
|
|
543
|
+
preset.builtinDbImage = String(flags['builtin-db-image']).trim();
|
|
544
|
+
}
|
|
524
545
|
if (flags['db-host'] !== undefined && String(flags['db-host']).trim() !== '') {
|
|
525
546
|
preset.dbHost = String(flags['db-host']).trim();
|
|
526
547
|
}
|
|
@@ -601,6 +622,7 @@ Prompt modes:
|
|
|
601
622
|
const appRootPath = String(results.appRootPath ?? '').trim();
|
|
602
623
|
const storagePath = String(results.storagePath ?? '').trim();
|
|
603
624
|
const dbDialect = String(results.dbDialect ?? '').trim();
|
|
625
|
+
const builtinDbImage = String(results.builtinDbImage ?? '').trim();
|
|
604
626
|
const dbHost = String(results.dbHost ?? '').trim();
|
|
605
627
|
const dbPort = String(results.dbPort ?? '').trim();
|
|
606
628
|
const dbDatabase = String(results.dbDatabase ?? '').trim();
|
|
@@ -622,6 +644,7 @@ Prompt modes:
|
|
|
622
644
|
...(results.buildDts !== undefined ? { buildDts: Boolean(results.buildDts) } : {}),
|
|
623
645
|
...(results.builtinDb !== undefined ? { builtinDb: Boolean(results.builtinDb) } : {}),
|
|
624
646
|
...(dbDialect ? { dbDialect } : {}),
|
|
647
|
+
...(builtinDbImage || results.builtinDb === false ? { builtinDbImage: builtinDbImage || undefined } : {}),
|
|
625
648
|
...(dbHost ? { dbHost } : {}),
|
|
626
649
|
...(dbPort ? { dbPort } : {}),
|
|
627
650
|
...(dbDatabase ? { dbDatabase } : {}),
|
|
@@ -727,6 +750,10 @@ Prompt modes:
|
|
|
727
750
|
if (dbDialect) {
|
|
728
751
|
argv.push('--db-dialect', dbDialect);
|
|
729
752
|
}
|
|
753
|
+
const builtinDbImage = String(results.builtinDbImage ?? '').trim();
|
|
754
|
+
if (builtinDb && builtinDbImage) {
|
|
755
|
+
argv.push('--builtin-db-image', builtinDbImage);
|
|
756
|
+
}
|
|
730
757
|
const dbHost = String(results.dbHost ?? '').trim();
|
|
731
758
|
if (dbHost) {
|
|
732
759
|
argv.push('--db-host', dbHost);
|