@nocobase/cli 2.1.0-alpha.40 → 2.1.0-alpha.46
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/README.md +20 -8
- package/README.zh-CN.md +20 -8
- package/bin/run.js +9 -37
- package/dist/commands/app/destroy.js +225 -0
- package/dist/commands/app/down.js +24 -254
- package/dist/commands/app/restart.js +12 -5
- package/dist/commands/app/shared.js +122 -0
- package/dist/commands/app/start.js +41 -59
- package/dist/commands/app/stop.js +72 -26
- package/dist/commands/app/upgrade.js +312 -429
- package/dist/commands/config/delete.js +8 -1
- package/dist/commands/config/get.js +5 -0
- package/dist/commands/config/set.js +10 -1
- package/dist/commands/db/ps.js +5 -18
- package/dist/commands/db/start.js +23 -8
- package/dist/commands/env/add.js +66 -6
- package/dist/commands/env/auth.js +86 -27
- package/dist/commands/env/info.js +52 -8
- package/dist/commands/env/list.js +6 -7
- package/dist/commands/env/shared.js +41 -3
- package/dist/commands/env/status.js +10 -7
- package/dist/commands/init.js +214 -136
- package/dist/commands/install.js +364 -294
- package/dist/commands/license/plugins/shared.js +9 -3
- package/dist/commands/license/plugins/sync.js +54 -25
- package/dist/commands/self/update.js +58 -1
- package/dist/commands/source/dev.js +5 -5
- package/dist/commands/source/download.js +29 -25
- package/dist/generated/command-registry.js +3 -2
- package/dist/lib/api-client.js +6 -0
- package/dist/lib/api-command-compat.js +641 -0
- package/dist/lib/app-health.js +31 -18
- package/dist/lib/app-managed-resources.js +1 -1
- package/dist/lib/app-runtime.js +2 -2
- package/dist/lib/auth-store.js +56 -19
- package/dist/lib/backup.js +3 -3
- package/dist/lib/bootstrap.js +14 -8
- package/dist/lib/cli-config.js +137 -4
- package/dist/lib/cli-entry-error.js +44 -0
- package/dist/lib/cli-locale.js +19 -7
- package/dist/lib/db-connection-check.js +61 -0
- package/dist/lib/docker-log-stream.js +45 -0
- package/dist/lib/env-auth.js +98 -11
- package/dist/lib/env-config.js +3 -2
- package/dist/lib/env-guard.js +1 -1
- package/dist/lib/generated-command.js +17 -0
- package/dist/lib/prompt-validators.js +23 -5
- package/dist/lib/prompt-web-ui.js +143 -19
- package/dist/lib/run-npm.js +133 -23
- package/dist/lib/skills-manager.js +80 -4
- package/dist/lib/source-publish.js +4 -1
- package/dist/lib/startup-update.js +74 -50
- package/dist/lib/ui.js +4 -1
- package/dist/locale/en-US.json +92 -5
- package/dist/locale/zh-CN.json +92 -5
- package/package.json +34 -2
|
@@ -17,6 +17,72 @@ import { commandOutput, commandOutputViaFile, run } from './run-npm.js';
|
|
|
17
17
|
export const NOCOBASE_SKILLS_SOURCE = 'nocobase/skills';
|
|
18
18
|
export const NOCOBASE_SKILLS_PACKAGE_NAME = '@nocobase/skills';
|
|
19
19
|
const NOCOBASE_SKILLS_NAME_PREFIX = 'nocobase-';
|
|
20
|
+
const SKILLS_LIST_TIMEOUT_MS = 5000;
|
|
21
|
+
const SKILLS_NPM_VIEW_TIMEOUT_MS = 3000;
|
|
22
|
+
const SKILLS_PACK_TIMEOUT_MS = 30000;
|
|
23
|
+
const SKILLS_ADD_TIMEOUT_MS = 20000;
|
|
24
|
+
const NPM_REGISTRY_UNAVAILABLE_PATTERNS = [
|
|
25
|
+
'enotfound',
|
|
26
|
+
'eai_again',
|
|
27
|
+
'etimedout',
|
|
28
|
+
'esockettimedout',
|
|
29
|
+
'econnreset',
|
|
30
|
+
'econnrefused',
|
|
31
|
+
'ehostunreach',
|
|
32
|
+
'enetunreach',
|
|
33
|
+
'socket hang up',
|
|
34
|
+
'getaddrinfo',
|
|
35
|
+
'fetch failed',
|
|
36
|
+
'network request to',
|
|
37
|
+
'self_signed_cert',
|
|
38
|
+
'depth_zero_self_signed_cert',
|
|
39
|
+
'unable_to_verify_leaf_signature',
|
|
40
|
+
'cert_has_expired',
|
|
41
|
+
'timed out after',
|
|
42
|
+
];
|
|
43
|
+
function collectErrorMessages(error) {
|
|
44
|
+
const messages = [];
|
|
45
|
+
const queue = [error];
|
|
46
|
+
const seen = new Set();
|
|
47
|
+
while (queue.length > 0) {
|
|
48
|
+
const current = queue.shift();
|
|
49
|
+
if (current === undefined || current === null || seen.has(current)) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
seen.add(current);
|
|
53
|
+
if (current instanceof Error) {
|
|
54
|
+
if (current.message) {
|
|
55
|
+
messages.push(current.message);
|
|
56
|
+
}
|
|
57
|
+
const cause = current.cause;
|
|
58
|
+
if (cause !== undefined) {
|
|
59
|
+
queue.push(cause);
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (typeof current === 'string') {
|
|
64
|
+
messages.push(current);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (typeof current === 'object') {
|
|
68
|
+
if ('message' in current && typeof current.message === 'string') {
|
|
69
|
+
messages.push(current.message);
|
|
70
|
+
}
|
|
71
|
+
if ('cause' in current) {
|
|
72
|
+
queue.push(current.cause);
|
|
73
|
+
}
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
messages.push(String(current));
|
|
77
|
+
}
|
|
78
|
+
return messages;
|
|
79
|
+
}
|
|
80
|
+
export function isNpmRegistryUnavailable(error) {
|
|
81
|
+
return collectErrorMessages(error).some((message) => {
|
|
82
|
+
const normalized = message.toLowerCase();
|
|
83
|
+
return NPM_REGISTRY_UNAVAILABLE_PATTERNS.some((pattern) => normalized.includes(pattern));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
20
86
|
function normalizePath(value) {
|
|
21
87
|
return path.resolve(value);
|
|
22
88
|
}
|
|
@@ -61,6 +127,12 @@ async function readManagedSkillsState(workspaceRoot) {
|
|
|
61
127
|
return undefined;
|
|
62
128
|
}
|
|
63
129
|
}
|
|
130
|
+
export async function readInstalledManagedSkillsVersion(options = {}) {
|
|
131
|
+
const globalRoot = resolveSkillsRoot(options);
|
|
132
|
+
const state = await readManagedSkillsState(globalRoot);
|
|
133
|
+
const installedVersion = String(state?.installedVersion ?? state?.installedRef ?? '').trim();
|
|
134
|
+
return installedVersion || undefined;
|
|
135
|
+
}
|
|
64
136
|
async function writeManagedSkillsState(workspaceRoot, state) {
|
|
65
137
|
const filePath = getManagedSkillsStateFile(workspaceRoot);
|
|
66
138
|
await fsp.mkdir(path.dirname(filePath), { recursive: true });
|
|
@@ -72,6 +144,7 @@ export async function listGlobalSkills(options = {}) {
|
|
|
72
144
|
const output = await (options.commandOutputFn ?? commandOutputViaFile)('npx', ['-y', 'skills', 'list', '-g', '--json'], {
|
|
73
145
|
cwd: globalRoot,
|
|
74
146
|
errorName: 'skills list',
|
|
147
|
+
timeoutMs: SKILLS_LIST_TIMEOUT_MS,
|
|
75
148
|
});
|
|
76
149
|
const parsed = JSON.parse(output);
|
|
77
150
|
return Array.isArray(parsed) ? parsed : [];
|
|
@@ -95,6 +168,7 @@ async function readPublishedSkillsVersion(options = {}) {
|
|
|
95
168
|
const output = await (options.commandOutputFn ?? commandOutput)('npm', ['view', NOCOBASE_SKILLS_PACKAGE_NAME, 'version', '--json'], {
|
|
96
169
|
cwd: globalRoot,
|
|
97
170
|
errorName: 'npm view',
|
|
171
|
+
timeoutMs: SKILLS_NPM_VIEW_TIMEOUT_MS,
|
|
98
172
|
});
|
|
99
173
|
const parsed = JSON.parse(output);
|
|
100
174
|
const version = String(parsed ?? '').trim();
|
|
@@ -187,6 +261,7 @@ async function prepareLocalSkillsPackage(globalRoot, options = {}, targetVersion
|
|
|
187
261
|
cwd: packRoot,
|
|
188
262
|
stdio: options.verbose ? 'inherit' : 'ignore',
|
|
189
263
|
errorName: 'npm pack',
|
|
264
|
+
timeoutMs: SKILLS_PACK_TIMEOUT_MS,
|
|
190
265
|
});
|
|
191
266
|
const tarballPath = await resolvePackedSkillsTarball(packRoot);
|
|
192
267
|
await extractPackedSkillsTarball(tarballPath, cacheRoot, targetVersion);
|
|
@@ -276,6 +351,7 @@ async function reinstallManagedSkills(globalRoot, options = {}, targetVersion) {
|
|
|
276
351
|
cwd: globalRoot,
|
|
277
352
|
stdio: options.verbose ? 'inherit' : 'ignore',
|
|
278
353
|
errorName: 'skills add',
|
|
354
|
+
timeoutMs: SKILLS_ADD_TIMEOUT_MS,
|
|
279
355
|
});
|
|
280
356
|
}
|
|
281
357
|
finally {
|
|
@@ -314,10 +390,10 @@ export async function updateNocoBaseSkills(options = {}) {
|
|
|
314
390
|
status,
|
|
315
391
|
};
|
|
316
392
|
}
|
|
317
|
-
if (status.managedByNb
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
393
|
+
if (status.managedByNb &&
|
|
394
|
+
status.latestVersion &&
|
|
395
|
+
status.installedVersion &&
|
|
396
|
+
compareVersions(status.latestVersion, status.installedVersion) <= 0) {
|
|
321
397
|
return {
|
|
322
398
|
action: 'noop',
|
|
323
399
|
reason: 'up-to-date',
|
|
@@ -292,6 +292,9 @@ export async function publishSourceSnapshot(params) {
|
|
|
292
292
|
if (publishError) {
|
|
293
293
|
throw publishError;
|
|
294
294
|
}
|
|
295
|
+
if (!result) {
|
|
296
|
+
throw new Error('Source snapshot publishing finished without a result.');
|
|
297
|
+
}
|
|
295
298
|
return result;
|
|
296
299
|
}
|
|
297
300
|
export function buildSuggestedInitCommand(result) {
|
|
@@ -299,7 +302,7 @@ export function buildSuggestedInitCommand(result) {
|
|
|
299
302
|
const normalizedRegistry = result.npmRegistry || `http://${host}:${port || DEFAULT_SOURCE_REGISTRY_PORT}`;
|
|
300
303
|
const suggestedEnv = ['snapshot', sanitizeEnvSegment(result.gitSha)].filter(Boolean).join('');
|
|
301
304
|
return [
|
|
302
|
-
`nb init --env ${suggestedEnv} --yes --source npm`,
|
|
305
|
+
`nb init --ui --env ${suggestedEnv} --yes --source npm`,
|
|
303
306
|
`--version ${result.version}`,
|
|
304
307
|
`--npm-registry=${normalizedRegistry}`,
|
|
305
308
|
].join(' ');
|
|
@@ -10,6 +10,7 @@ import fs from 'node:fs/promises';
|
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
12
|
import { confirm } from "./inquirer.js";
|
|
13
|
+
import { DEFAULT_UPDATE_POLICY, getExplicitCliConfigValue, loadCliConfig, } from './cli-config.js';
|
|
13
14
|
import { inspectSelfInstall, inspectSelfStatus, } from './self-manager.js';
|
|
14
15
|
import { inspectSkillsStatus } from './skills-manager.js';
|
|
15
16
|
import { resolveCliHomeDir } from './cli-home.js';
|
|
@@ -83,39 +84,53 @@ async function writeCurrentInstallEntry(updater) {
|
|
|
83
84
|
const state = await readState();
|
|
84
85
|
const installBinPath = getCurrentInstallBinPath();
|
|
85
86
|
const nextEntry = updater(getCurrentInstallEntry(state), state);
|
|
87
|
+
const entries = {
|
|
88
|
+
...(state.entries ?? {}),
|
|
89
|
+
};
|
|
90
|
+
if (nextEntry?.policy || nextEntry?.lastCheckedDate) {
|
|
91
|
+
entries[installBinPath] = nextEntry;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
delete entries[installBinPath];
|
|
95
|
+
}
|
|
86
96
|
await writeState({
|
|
87
97
|
...state,
|
|
88
|
-
entries:
|
|
89
|
-
...(state.entries ?? {}),
|
|
90
|
-
[installBinPath]: nextEntry,
|
|
91
|
-
},
|
|
98
|
+
entries: Object.keys(entries).length ? entries : undefined,
|
|
92
99
|
});
|
|
93
100
|
}
|
|
94
101
|
async function markChecked(now = new Date()) {
|
|
95
|
-
await writeCurrentInstallEntry((current
|
|
102
|
+
await writeCurrentInstallEntry((current) => {
|
|
96
103
|
return {
|
|
97
|
-
|
|
104
|
+
...current,
|
|
98
105
|
lastCheckedDate: todayStamp(now),
|
|
99
106
|
};
|
|
100
107
|
});
|
|
101
108
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
109
|
+
function resolveLegacyStartupUpdatePolicy(state) {
|
|
110
|
+
const policy = getCurrentInstallEntry(state)?.policy;
|
|
111
|
+
if (policy === 'disabled') {
|
|
112
|
+
return 'off';
|
|
113
|
+
}
|
|
114
|
+
if (policy === 'daily') {
|
|
115
|
+
return 'prompt';
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
110
118
|
}
|
|
111
|
-
async function
|
|
112
|
-
await
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
async function resolveStartupUpdatePolicy(state) {
|
|
120
|
+
const config = await loadCliConfig({ scope: 'global' });
|
|
121
|
+
const explicit = getExplicitCliConfigValue(config, 'update.policy');
|
|
122
|
+
return explicit ?? resolveLegacyStartupUpdatePolicy(state) ?? DEFAULT_UPDATE_POLICY;
|
|
123
|
+
}
|
|
124
|
+
export async function clearLegacyStartupUpdatePolicyForCurrentInstall() {
|
|
125
|
+
const state = await readState();
|
|
126
|
+
const current = getCurrentInstallEntry(state);
|
|
127
|
+
if (!current?.policy) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
await writeCurrentInstallEntry(() => ({
|
|
131
|
+
lastCheckedDate: current.lastCheckedDate,
|
|
132
|
+
}));
|
|
133
|
+
return true;
|
|
119
134
|
}
|
|
120
135
|
export async function shouldRunStartupUpdateCheck(argv, now = new Date()) {
|
|
121
136
|
if (process.env[NB_SKIP_STARTUP_UPDATE_ENV] === '1') {
|
|
@@ -125,19 +140,14 @@ export async function shouldRunStartupUpdateCheck(argv, now = new Date()) {
|
|
|
125
140
|
return false;
|
|
126
141
|
}
|
|
127
142
|
const state = await readState();
|
|
128
|
-
const
|
|
129
|
-
if (
|
|
143
|
+
const policy = await resolveStartupUpdatePolicy(state);
|
|
144
|
+
if (policy === 'off') {
|
|
130
145
|
return false;
|
|
131
146
|
}
|
|
132
|
-
if (currentEntry?.policy === 'daily') {
|
|
133
|
-
return readCurrentInstallLastCheckedDate(state) !== todayStamp(now);
|
|
134
|
-
}
|
|
135
147
|
const selfInstall = await inspectSelfInstall();
|
|
136
148
|
if (!shouldEnableStartupUpdateForInstallMethod(selfInstall.installMethod)) {
|
|
137
|
-
await disableStartupUpdateForCurrentInstall();
|
|
138
149
|
return false;
|
|
139
150
|
}
|
|
140
|
-
await enableDailyStartupUpdateForCurrentInstall();
|
|
141
151
|
return readCurrentInstallLastCheckedDate(state) !== todayStamp(now);
|
|
142
152
|
}
|
|
143
153
|
export function shouldEnableStartupUpdateForInstallMethod(installMethod) {
|
|
@@ -189,14 +199,13 @@ function buildPromptMessage(selfStatus, skillsStatus) {
|
|
|
189
199
|
return lines.join('\n');
|
|
190
200
|
}
|
|
191
201
|
function buildUpdateCommands(selfStatus, skillsStatus) {
|
|
192
|
-
const commands = [];
|
|
193
202
|
if (selfStatus.updateAvailable && selfStatus.updatable) {
|
|
194
|
-
|
|
203
|
+
return [skillsStatus.updateAvailable === true ? 'nb self update --yes --skills' : 'nb self update --yes'];
|
|
195
204
|
}
|
|
196
205
|
if (skillsStatus.updateAvailable === true) {
|
|
197
|
-
|
|
206
|
+
return ['nb skills update --yes'];
|
|
198
207
|
}
|
|
199
|
-
return
|
|
208
|
+
return [];
|
|
200
209
|
}
|
|
201
210
|
function buildNonInteractiveWarning(selfStatus, skillsStatus) {
|
|
202
211
|
const commands = buildUpdateCommands(selfStatus, skillsStatus);
|
|
@@ -233,26 +242,36 @@ function buildDeclinedWarning(selfStatus, skillsStatus) {
|
|
|
233
242
|
'You may run into compatibility issues until you update.',
|
|
234
243
|
].join(' ');
|
|
235
244
|
}
|
|
236
|
-
async function runStartupUpdates() {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
}
|
|
245
|
+
async function runStartupUpdates(selfStatus, skillsStatus) {
|
|
246
|
+
if (selfStatus.updateAvailable && selfStatus.updatable) {
|
|
247
|
+
const args = ['self', 'update', '--yes'];
|
|
248
|
+
if (skillsStatus.updateAvailable === true) {
|
|
249
|
+
args.push('--skills');
|
|
250
|
+
}
|
|
251
|
+
await run('nb', args, {
|
|
252
|
+
stdio: 'inherit',
|
|
253
|
+
env: {
|
|
254
|
+
[NB_SKIP_STARTUP_UPDATE_ENV]: '1',
|
|
255
|
+
},
|
|
256
|
+
errorName: 'nb self update',
|
|
257
|
+
});
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (skillsStatus.updateAvailable === true) {
|
|
261
|
+
await run('nb', ['skills', 'update', '--yes'], {
|
|
262
|
+
stdio: 'inherit',
|
|
263
|
+
env: {
|
|
264
|
+
[NB_SKIP_STARTUP_UPDATE_ENV]: '1',
|
|
265
|
+
},
|
|
266
|
+
errorName: 'nb skills update',
|
|
267
|
+
});
|
|
268
|
+
}
|
|
251
269
|
}
|
|
252
|
-
export async function
|
|
270
|
+
export async function maybeRunStartupUpdate(argv) {
|
|
253
271
|
if (!(await shouldRunStartupUpdateCheck(argv))) {
|
|
254
272
|
return { kind: 'skipped' };
|
|
255
273
|
}
|
|
274
|
+
const policy = await resolveStartupUpdatePolicy(await readState());
|
|
256
275
|
const selfStatus = await inspectSelfStatus();
|
|
257
276
|
const skillsStatus = await inspectSkillsStatus();
|
|
258
277
|
if (!hasPendingUpdates(selfStatus, skillsStatus)) {
|
|
@@ -264,6 +283,11 @@ export async function maybeRunStartupUpdatePrompt(argv) {
|
|
|
264
283
|
await markChecked();
|
|
265
284
|
return { kind: 'warned' };
|
|
266
285
|
}
|
|
286
|
+
if (policy === 'auto') {
|
|
287
|
+
await runStartupUpdates(selfStatus, skillsStatus);
|
|
288
|
+
await markChecked();
|
|
289
|
+
return { kind: 'updated' };
|
|
290
|
+
}
|
|
267
291
|
let answer = false;
|
|
268
292
|
try {
|
|
269
293
|
answer = await confirm({
|
|
@@ -279,7 +303,7 @@ export async function maybeRunStartupUpdatePrompt(argv) {
|
|
|
279
303
|
await markChecked();
|
|
280
304
|
return { kind: 'declined' };
|
|
281
305
|
}
|
|
282
|
-
await runStartupUpdates();
|
|
306
|
+
await runStartupUpdates(selfStatus, skillsStatus);
|
|
283
307
|
await markChecked();
|
|
284
308
|
return { kind: 'updated' };
|
|
285
309
|
}
|
package/dist/lib/ui.js
CHANGED
|
@@ -54,7 +54,10 @@ export function printInfo(message) {
|
|
|
54
54
|
console.log(pc.cyan(message));
|
|
55
55
|
}
|
|
56
56
|
export function announceTargetEnv(envName) {
|
|
57
|
-
|
|
57
|
+
if (process.env.NB_SKIP_TARGET_ENV_LOG === '1') {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
printInfo(`Using env "${envName}".`);
|
|
58
61
|
}
|
|
59
62
|
export function printVerbose(message) {
|
|
60
63
|
if (!verboseMode) {
|
package/dist/locale/en-US.json
CHANGED
|
@@ -34,6 +34,8 @@
|
|
|
34
34
|
"back": "Back",
|
|
35
35
|
"next": "Next",
|
|
36
36
|
"submit": "Submit & continue in terminal",
|
|
37
|
+
"showPassword": "Show password",
|
|
38
|
+
"hidePassword": "Hide password",
|
|
37
39
|
"checking": "Checking...",
|
|
38
40
|
"sending": "Sending...",
|
|
39
41
|
"successTitle": "Success",
|
|
@@ -73,7 +75,8 @@
|
|
|
73
75
|
"timeout": "Timed out connecting to the database at {{host}}:{{port}} after about {{seconds}} seconds.",
|
|
74
76
|
"authenticationFailed": "Failed to sign in to database \"{{database}}\" with user \"{{user}}\". Check the username and password.",
|
|
75
77
|
"databaseNotFound": "Database \"{{database}}\" does not exist or is not accessible with the current connection settings.",
|
|
76
|
-
"connectionFailed": "Database connection check failed. Details: {{details}}"
|
|
78
|
+
"connectionFailed": "Database connection check failed. Details: {{details}}",
|
|
79
|
+
"lowerCaseTableNamesRequiresUnderscored": "MySQL lower_case_table_names=1 requires DB_UNDERSCORED=true."
|
|
77
80
|
}
|
|
78
81
|
},
|
|
79
82
|
"commands": {
|
|
@@ -94,16 +97,28 @@
|
|
|
94
97
|
},
|
|
95
98
|
"authType": {
|
|
96
99
|
"message": "How would you like to sign in?",
|
|
100
|
+
"basicLabel": "Basic login (username + password)",
|
|
101
|
+
"basicHint": "uses your credentials to fetch a token after save",
|
|
97
102
|
"oauthLabel": "OAuth (browser login)",
|
|
98
103
|
"oauthHint": "runs nb env auth after save",
|
|
99
104
|
"tokenLabel": "API token / API key"
|
|
100
105
|
},
|
|
106
|
+
"username": {
|
|
107
|
+
"message": "Enter the username for basic login",
|
|
108
|
+
"placeholder": "admin"
|
|
109
|
+
},
|
|
110
|
+
"password": {
|
|
111
|
+
"message": "Enter the password for basic login"
|
|
112
|
+
},
|
|
101
113
|
"accessToken": {
|
|
102
114
|
"message": "Enter an API token or API key",
|
|
103
115
|
"placeholder": "Enter your API token / API key"
|
|
104
116
|
}
|
|
105
117
|
}
|
|
106
118
|
},
|
|
119
|
+
"shared": {
|
|
120
|
+
"missingCommand": "Couldn't run `{{action}}` because the {{displayName}} executable could not be found. Install {{displayName}} or update `nb config set {{configKey}} <path>` and try again."
|
|
121
|
+
},
|
|
107
122
|
"download": {
|
|
108
123
|
"failures": {
|
|
109
124
|
"dependencyInstall": {
|
|
@@ -206,6 +221,10 @@
|
|
|
206
221
|
}
|
|
207
222
|
},
|
|
208
223
|
"install": {
|
|
224
|
+
"messages": {
|
|
225
|
+
"skipDownloadDockerImageMissing": "Cannot continue with `--skip-download` because Docker image \"{{imageRef}}\" is not available locally. Load or pull the image first, or run the command again without `--skip-download`.",
|
|
226
|
+
"skipDownloadLocalAppMissing": "Cannot continue with `--skip-download` because \"{{projectRoot}}\" is missing or does not contain a package.json file. Point `--app-root-path` to an existing NocoBase app, or run the command again without `--skip-download`."
|
|
227
|
+
},
|
|
209
228
|
"validation": {
|
|
210
229
|
"builtinDbUnsupported": "Built-in database does not support \"{{dialect}}\" yet. Choose PostgreSQL, MySQL, or MariaDB, or turn off built-in database."
|
|
211
230
|
},
|
|
@@ -229,9 +248,6 @@
|
|
|
229
248
|
"message": "Where should uploads and local files be stored?",
|
|
230
249
|
"placeholder": "./<env>/storage/"
|
|
231
250
|
},
|
|
232
|
-
"fetchSource": {
|
|
233
|
-
"message": "Download NocoBase automatically if the app directory is empty?"
|
|
234
|
-
},
|
|
235
251
|
"dbDialect": {
|
|
236
252
|
"message": "Which database would you like to use?"
|
|
237
253
|
},
|
|
@@ -259,6 +275,17 @@
|
|
|
259
275
|
"dbPassword": {
|
|
260
276
|
"message": "What is the database password?"
|
|
261
277
|
},
|
|
278
|
+
"dbSchema": {
|
|
279
|
+
"message": "What is the database schema? (PostgreSQL only, optional)",
|
|
280
|
+
"placeholder": "Leave empty to use the default schema"
|
|
281
|
+
},
|
|
282
|
+
"dbTablePrefix": {
|
|
283
|
+
"message": "What table prefix should be used? (optional)",
|
|
284
|
+
"placeholder": "For example: nb_"
|
|
285
|
+
},
|
|
286
|
+
"dbUnderscored": {
|
|
287
|
+
"message": "Use underscored names for database tables and columns?"
|
|
288
|
+
},
|
|
262
289
|
"rootUsername": {
|
|
263
290
|
"message": "Choose the initial admin username",
|
|
264
291
|
"placeholder": "nocobase"
|
|
@@ -290,7 +317,8 @@
|
|
|
290
317
|
"uiOpening": "A local setup form will open in your browser. That form needs a person to fill it in. If you are using an AI agent, do not stop this process while the CLI waits for the submission.",
|
|
291
318
|
"uiReady": "Local setup form is ready.",
|
|
292
319
|
"uiReadyHelp": "If your browser does not open automatically, copy the URL below into your browser to continue. Keep this terminal session running while the CLI waits for the submission.",
|
|
293
|
-
"uiOpenBrowserFallback": "We could not open your browser automatically. Copy the URL above into your browser to continue setup, and keep this terminal session running. If you are using an AI agent, do not stop the current process."
|
|
320
|
+
"uiOpenBrowserFallback": "We could not open your browser automatically. Copy the URL above into your browser to continue setup, and keep this terminal session running. If you are using an AI agent, do not stop the current process.",
|
|
321
|
+
"skillsSyncRegistryUnavailable": "Couldn't reach the npm registry to sync NocoBase AI coding skills. Skipping skills install and continuing init. Run `nb skills install` later when registry access is available."
|
|
294
322
|
},
|
|
295
323
|
"prompts": {
|
|
296
324
|
"appName": {
|
|
@@ -308,6 +336,9 @@
|
|
|
308
336
|
"apiBaseUrl": {
|
|
309
337
|
"message": "API base URL",
|
|
310
338
|
"placeholder": "https://demo.example.com/api or https://demo.example.com/api/__app/<subapp>"
|
|
339
|
+
},
|
|
340
|
+
"skipDownload": {
|
|
341
|
+
"message": "Skip downloading NocoBase and reuse existing local app files or Docker images"
|
|
311
342
|
}
|
|
312
343
|
},
|
|
313
344
|
"webUi": {
|
|
@@ -339,6 +370,62 @@
|
|
|
339
370
|
"description": "Set up the first admin."
|
|
340
371
|
}
|
|
341
372
|
}
|
|
373
|
+
},
|
|
374
|
+
"env": {
|
|
375
|
+
"messages": {
|
|
376
|
+
"noEnvsConfigured": "No envs configured.",
|
|
377
|
+
"noEnvsConfiguredHelp": "Run `nb init --ui` to create one first."
|
|
378
|
+
}
|
|
342
379
|
}
|
|
380
|
+
},
|
|
381
|
+
"apiCommandCompat": {
|
|
382
|
+
"refusalTitle": "Refusing to run `nb api {{commandId}}` because the current CLI version is {{cliVersion}} while the target app version is {{appVersion}}.",
|
|
383
|
+
"refusalTitleMissingVersion": "Refusing to run `nb api {{commandId}}` because the {{versionLabel}} is unavailable.",
|
|
384
|
+
"refusalTitleGeneric": "Refusing to run `nb api {{commandId}}` because the current version combination is not compatible.",
|
|
385
|
+
"currentVersionsLine": "Current versions: {{versions}}.",
|
|
386
|
+
"refusalBodyWithRequirements": "This API command is blocked when used with {{requirements}}.",
|
|
387
|
+
"refusalBody": "This API command may not be compatible with the current CLI and app version combination.",
|
|
388
|
+
"channel": {
|
|
389
|
+
"stable": "stable",
|
|
390
|
+
"beta": "beta",
|
|
391
|
+
"alpha": "alpha",
|
|
392
|
+
"rc": "rc",
|
|
393
|
+
"unknownPrerelease": "unsupported prerelease"
|
|
394
|
+
},
|
|
395
|
+
"requirement": {
|
|
396
|
+
"cli": "CLI version {{condition}}",
|
|
397
|
+
"app": "app version {{condition}}",
|
|
398
|
+
"skills": "NocoBase AI skills version {{condition}}",
|
|
399
|
+
"appChannel": "{{channelLabel}} app version {{condition}}",
|
|
400
|
+
"appUnknownPrereleaseBlocked": "{{channelLabel}} app versions are blocked"
|
|
401
|
+
},
|
|
402
|
+
"currentVersion": {
|
|
403
|
+
"cli": "CLI {{version}}",
|
|
404
|
+
"app": "app {{version}}",
|
|
405
|
+
"appUnavailable": "app unavailable",
|
|
406
|
+
"skills": "NocoBase AI skills {{version}}",
|
|
407
|
+
"skillsUnavailable": "NocoBase AI skills unavailable"
|
|
408
|
+
},
|
|
409
|
+
"versionLabel": {
|
|
410
|
+
"cli": "CLI version",
|
|
411
|
+
"app": "target app version",
|
|
412
|
+
"skills": "installed NocoBase AI skills version"
|
|
413
|
+
},
|
|
414
|
+
"join": {
|
|
415
|
+
"two": "{{left}} and {{right}}",
|
|
416
|
+
"many": "{{head}}, and {{tail}}"
|
|
417
|
+
},
|
|
418
|
+
"continueTitle": "To continue:",
|
|
419
|
+
"continueUpgradeApp": "- upgrade the app to a compatible version",
|
|
420
|
+
"continueUpgradeAppToVersion": "- upgrade the app to {{suggestedUpgradeTarget}}",
|
|
421
|
+
"continueUseSupportedAppVersion": "- use a supported app version: {{supportedTargets}}",
|
|
422
|
+
"continueRefreshAppVersion": "- refresh the target env runtime so the current app version can be detected, then retry",
|
|
423
|
+
"continueUseCompatibleCli": "- or use a compatible CLI version",
|
|
424
|
+
"continueUseCompatibleCliVersion": "- or use a CLI version {{suggestedCliTarget}}",
|
|
425
|
+
"continueUpdateSkillsToVersion": "- install or update the NocoBase AI coding skills to {{suggestedSkillsUpgradeTarget}}. Run `nb skills update --yes` to refresh the managed skills.",
|
|
426
|
+
"continueUseCompatibleSkillsVersion": "- or use a NocoBase AI skills version {{suggestedSkillsTarget}}",
|
|
427
|
+
"continueInstallOrUpdateSkillsToVersion": "- run `nb skills install --yes` or `nb skills update --yes`, and make sure the managed skills version is {{suggestedSkillsUpgradeTarget}} before retrying",
|
|
428
|
+
"continueInstallOrUpdateSkills": "- run `nb skills install --yes` or `nb skills update --yes`, then retry once the managed skills version is available",
|
|
429
|
+
"supportedAppTarget": "{{channelLabel}} {{target}}"
|
|
343
430
|
}
|
|
344
431
|
}
|