@nocobase/cli 2.1.0-beta.44.test.3 → 2.1.0-beta.44.test.4
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/bin/run.js +40 -3
- package/dist/commands/app/destroy.js +13 -6
- package/dist/commands/app/restart.js +11 -2
- package/dist/commands/app/shared.js +3 -2
- package/dist/commands/app/start.js +10 -2
- package/dist/commands/app/upgrade.js +6 -4
- package/dist/commands/config/delete.js +2 -0
- package/dist/commands/config/get.js +2 -0
- package/dist/commands/config/set.js +2 -0
- package/dist/commands/env/add.js +5 -5
- package/dist/commands/init.js +117 -7
- package/dist/commands/install.js +50 -13
- package/dist/commands/source/download.js +1 -1
- package/dist/commands/source/test.js +13 -14
- package/dist/locale/en-US.json +13 -5
- package/dist/locale/zh-CN.json +13 -5
- package/package.json +1 -7
- package/scripts/build.mjs +34 -0
- package/scripts/clean.mjs +9 -0
- package/tsconfig.json +19 -0
- package/dist/lib/api-client.js +0 -335
- package/dist/lib/api-command-compat.js +0 -641
- package/dist/lib/app-health.js +0 -139
- package/dist/lib/app-managed-resources.js +0 -321
- package/dist/lib/app-public-path.js +0 -80
- package/dist/lib/app-runtime.js +0 -189
- package/dist/lib/auth-store.js +0 -498
- package/dist/lib/backup.js +0 -171
- package/dist/lib/bootstrap.js +0 -409
- package/dist/lib/build-config.js +0 -18
- package/dist/lib/builtin-db.js +0 -86
- package/dist/lib/cli-config.js +0 -398
- package/dist/lib/cli-entry-error.js +0 -44
- package/dist/lib/cli-home.js +0 -47
- package/dist/lib/cli-locale.js +0 -141
- package/dist/lib/command-discovery.js +0 -39
- package/dist/lib/db-connection-check.js +0 -219
- package/dist/lib/docker-env-file.js +0 -60
- package/dist/lib/docker-image.js +0 -37
- package/dist/lib/docker-log-stream.js +0 -45
- package/dist/lib/env-auth.js +0 -960
- package/dist/lib/env-command-config.js +0 -45
- package/dist/lib/env-config.js +0 -100
- package/dist/lib/env-guard.js +0 -61
- package/dist/lib/env-paths.js +0 -101
- package/dist/lib/env-proxy.js +0 -1295
- package/dist/lib/generated-command.js +0 -203
- package/dist/lib/http-request.js +0 -49
- package/dist/lib/inquirer-theme.js +0 -17
- package/dist/lib/inquirer.js +0 -243
- package/dist/lib/managed-env-file.js +0 -98
- package/dist/lib/naming.js +0 -70
- package/dist/lib/object-utils.js +0 -76
- package/dist/lib/openapi.js +0 -62
- package/dist/lib/plugin-import.js +0 -279
- package/dist/lib/plugin-storage.js +0 -64
- package/dist/lib/post-processors.js +0 -23
- package/dist/lib/prompt-catalog-core.js +0 -185
- package/dist/lib/prompt-catalog-terminal.js +0 -375
- package/dist/lib/prompt-catalog.js +0 -10
- package/dist/lib/prompt-validators.js +0 -258
- package/dist/lib/prompt-web-ui.js +0 -2227
- package/dist/lib/resource-command.js +0 -357
- package/dist/lib/resource-request.js +0 -104
- package/dist/lib/run-npm.js +0 -393
- package/dist/lib/runtime-env-vars.js +0 -32
- package/dist/lib/runtime-generator.js +0 -498
- package/dist/lib/runtime-store.js +0 -56
- package/dist/lib/self-manager.js +0 -301
- package/dist/lib/session-id.js +0 -17
- package/dist/lib/session-integration.js +0 -703
- package/dist/lib/session-store.js +0 -118
- package/dist/lib/skills-manager.js +0 -438
- package/dist/lib/source-publish.js +0 -326
- package/dist/lib/source-registry.js +0 -188
- package/dist/lib/startup-update.js +0 -309
- package/dist/lib/ui.js +0 -159
package/dist/commands/install.js
CHANGED
|
@@ -16,12 +16,12 @@ import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
|
16
16
|
import { applyCliLocale, localeText, resolveCliLocale, translateCli } from "../lib/cli-locale.js";
|
|
17
17
|
import { resolveConfiguredEnvPath, resolveDefaultConfigScope, resolveEnvRoot, resolveEnvRelativePath, } from '../lib/cli-home.js';
|
|
18
18
|
import { defaultDockerContainerPrefix, defaultDockerNetworkName } from '../lib/app-runtime.js';
|
|
19
|
-
import { resolveDockerContainerPrefix, resolveDockerNetworkName } from '../lib/cli-config.js';
|
|
19
|
+
import { resolveDefaultApiHost, resolveDockerContainerPrefix, resolveDockerNetworkName } from '../lib/cli-config.js';
|
|
20
20
|
import { DEFAULT_DOCKER_VERSION, resolveDockerImageRef } from "../lib/docker-image.js";
|
|
21
|
-
import { findAvailableTcpPort, validateAvailableTcpPort, validateTcpPort, validateEnvKey, } from "../lib/prompt-validators.js";
|
|
21
|
+
import { findAvailableTcpPort, validateAppPublicPath, validateAvailableTcpPort, validateTcpPort, validateEnvKey, } from "../lib/prompt-validators.js";
|
|
22
22
|
import { validateExternalDbConfig, validateMysqlLowerCaseTableNamesCompatibility } from "../lib/db-connection-check.js";
|
|
23
23
|
import { formatMissingManagedAppEnvMessage } from '../lib/app-runtime.js';
|
|
24
|
-
import { commandOutput, commandSucceeds, run, runNocoBaseCommand } from '../lib/run-npm.js';
|
|
24
|
+
import { commandOutput, commandSucceeds, ensureDockerDaemonRunning, run, runNocoBaseCommand } from '../lib/run-npm.js';
|
|
25
25
|
import { printInfo, printStage, printVerbose, printWarning, setVerboseMode } from '../lib/ui.js';
|
|
26
26
|
import { omitKeys, upperFirst } from "../lib/object-utils.js";
|
|
27
27
|
import { clearEnvRootSetup, getEnv, setCurrentEnv, upsertEnv } from '../lib/auth-store.js';
|
|
@@ -31,6 +31,7 @@ import { startDockerLogFollower } from '../lib/docker-log-stream.js';
|
|
|
31
31
|
import { areConfiguredPathsEquivalent, deriveConfiguredSourcePath, deriveConfiguredStoragePath, inferConfiguredAppPathFromLegacyConfig, } from '../lib/env-paths.js';
|
|
32
32
|
import Download, { defaultDockerRegistryForLang } from './download.js';
|
|
33
33
|
import EnvAdd from "./env/add.js";
|
|
34
|
+
import { resolveAppUrlFromApiBaseUrl } from "./env/shared.js";
|
|
34
35
|
const DEFAULT_INSTALL_ENV_NAME = 'local';
|
|
35
36
|
const DEFAULT_INSTALL_LANG = 'en-US';
|
|
36
37
|
const DEFAULT_INSTALL_APP_PORT = '13000';
|
|
@@ -61,10 +62,19 @@ const DEFAULT_INSTALL_ROOT_USERNAME = 'nocobase';
|
|
|
61
62
|
const DEFAULT_INSTALL_ROOT_EMAIL = 'admin@nocobase.com';
|
|
62
63
|
const DEFAULT_INSTALL_ROOT_PASSWORD = 'admin123';
|
|
63
64
|
const DEFAULT_INSTALL_ROOT_NICKNAME = 'Super Admin';
|
|
65
|
+
const DEFAULT_INSTALL_API_HOST = '127.0.0.1';
|
|
64
66
|
function toOptionalPromptString(value) {
|
|
65
67
|
const text = String(value ?? '').trim();
|
|
66
68
|
return text || undefined;
|
|
67
69
|
}
|
|
70
|
+
function buildInstallApiBaseUrl(appResults, defaultApiHost = DEFAULT_INSTALL_API_HOST) {
|
|
71
|
+
const appPort = String(appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT;
|
|
72
|
+
const appPublicPath = String(appResults.appPublicPath ?? '').trim();
|
|
73
|
+
return `http://${defaultApiHost}:${appPort}${appendAppPublicPath(appPublicPath, 'api', { trailingSlash: false })}`;
|
|
74
|
+
}
|
|
75
|
+
function formatInstallDisplayUrl(apiBaseUrl) {
|
|
76
|
+
return resolveAppUrlFromApiBaseUrl(apiBaseUrl) || apiBaseUrl.replace(/\/api\/?$/, '');
|
|
77
|
+
}
|
|
68
78
|
const APP_HEALTH_CHECK_INTERVAL_MS = 2_000;
|
|
69
79
|
const APP_HEALTH_CHECK_TIMEOUT_MS = 600_000;
|
|
70
80
|
const APP_HEALTH_CHECK_REQUEST_TIMEOUT_MS = 5_000;
|
|
@@ -268,6 +278,15 @@ function optionalEnvBoolean(value) {
|
|
|
268
278
|
}
|
|
269
279
|
return Boolean(value);
|
|
270
280
|
}
|
|
281
|
+
function resolveExtractClientAssetsDefaultEnabled(value) {
|
|
282
|
+
const text = String(value ?? '')
|
|
283
|
+
.trim()
|
|
284
|
+
.toLowerCase();
|
|
285
|
+
if (!text) {
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
return !['0', 'false', 'no', 'off'].includes(text);
|
|
289
|
+
}
|
|
271
290
|
function pushOptionalEnvArg(args, key, value) {
|
|
272
291
|
if (typeof value === 'string') {
|
|
273
292
|
if (!value) {
|
|
@@ -490,8 +509,11 @@ export default class Install extends Command {
|
|
|
490
509
|
},
|
|
491
510
|
appPublicPath: {
|
|
492
511
|
type: 'text',
|
|
493
|
-
message: '',
|
|
494
|
-
|
|
512
|
+
message: installText('prompts.appPublicPath.message'),
|
|
513
|
+
placeholder: installText('prompts.appPublicPath.placeholder'),
|
|
514
|
+
initialValue: '/',
|
|
515
|
+
yesInitialValue: '/',
|
|
516
|
+
validate: validateAppPublicPath,
|
|
495
517
|
},
|
|
496
518
|
};
|
|
497
519
|
}
|
|
@@ -1068,6 +1090,7 @@ export default class Install extends Command {
|
|
|
1068
1090
|
const appPort = Install.toOptionalPromptString(config.appPort);
|
|
1069
1091
|
const storagePath = Install.toOptionalPromptString(config.storagePath);
|
|
1070
1092
|
const appPublicPath = Install.toOptionalPromptString(config.appPublicPath);
|
|
1093
|
+
const apiBaseUrl = Install.toOptionalPromptString(config.apiBaseUrl);
|
|
1071
1094
|
const downloadVersion = Install.toOptionalPromptString(config.downloadVersion);
|
|
1072
1095
|
const dockerRegistry = Install.toOptionalPromptString(config.dockerRegistry);
|
|
1073
1096
|
const dockerPlatform = Install.toOptionalPromptString(config.dockerPlatform);
|
|
@@ -1132,6 +1155,9 @@ export default class Install extends Command {
|
|
|
1132
1155
|
...(rootNickname ? { rootNickname } : {}),
|
|
1133
1156
|
};
|
|
1134
1157
|
const envAddPreset = {};
|
|
1158
|
+
if (apiBaseUrl) {
|
|
1159
|
+
envAddPreset.apiBaseUrl = apiBaseUrl;
|
|
1160
|
+
}
|
|
1135
1161
|
if (savedAuthType === 'token') {
|
|
1136
1162
|
envAddPreset.authType = 'token';
|
|
1137
1163
|
if (Install.toOptionalPromptString(auth.accessToken)) {
|
|
@@ -1613,6 +1639,7 @@ export default class Install extends Command {
|
|
|
1613
1639
|
if (this.ensuredDockerNetworks.has(name)) {
|
|
1614
1640
|
return;
|
|
1615
1641
|
}
|
|
1642
|
+
await ensureDockerDaemonRunning('prepare Docker resources for this environment');
|
|
1616
1643
|
printVerbose(`Checking Docker network: ${name}`);
|
|
1617
1644
|
const exists = await commandSucceeds('docker', ['network', 'inspect', name]);
|
|
1618
1645
|
if (exists) {
|
|
@@ -1751,7 +1778,7 @@ export default class Install extends Command {
|
|
|
1751
1778
|
const dbSchema = optionalEnvString(params.dbResults.dbSchema);
|
|
1752
1779
|
const dbTablePrefix = optionalEnvString(params.dbResults.dbTablePrefix);
|
|
1753
1780
|
const dbUnderscored = optionalEnvBoolean(params.dbResults.dbUnderscored);
|
|
1754
|
-
const extractClientAssets =
|
|
1781
|
+
const extractClientAssets = resolveExtractClientAssetsDefaultEnabled(process.env.NOCOBASE_EXTRACT_CLIENT_ASSETS);
|
|
1755
1782
|
const appKey = Install.resolveManagedAppKey(params.appResults.appKey);
|
|
1756
1783
|
const appPublicPath = Install.toOptionalPromptString(params.appResults.appPublicPath);
|
|
1757
1784
|
const timeZone = Install.resolveManagedTimeZone(params.appResults.timeZone);
|
|
@@ -2059,10 +2086,8 @@ export default class Install extends Command {
|
|
|
2059
2086
|
};
|
|
2060
2087
|
}
|
|
2061
2088
|
static resolveApiBaseUrl(params) {
|
|
2062
|
-
const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT;
|
|
2063
|
-
const appPublicPath = String(params.appResults.appPublicPath ?? '').trim();
|
|
2064
2089
|
return (String(params.envAddResults.apiBaseUrl ?? '').trim() ||
|
|
2065
|
-
|
|
2090
|
+
buildInstallApiBaseUrl(params.appResults, params.defaultApiHost));
|
|
2066
2091
|
}
|
|
2067
2092
|
static buildHealthCheckUrl(apiBaseUrl) {
|
|
2068
2093
|
return `${apiBaseUrl.replace(/\/+$/, '')}/__health_check`;
|
|
@@ -2154,7 +2179,10 @@ export default class Install extends Command {
|
|
|
2154
2179
|
}
|
|
2155
2180
|
}
|
|
2156
2181
|
async saveInstalledEnv(params) {
|
|
2157
|
-
|
|
2182
|
+
const defaultApiHost = await resolveDefaultApiHost();
|
|
2183
|
+
await upsertEnv(params.envName, Install.buildSavedEnvConfig(params, { defaultApiHost }), {
|
|
2184
|
+
scope: resolveDefaultConfigScope(),
|
|
2185
|
+
});
|
|
2158
2186
|
await setCurrentEnv(params.envName, { scope: resolveDefaultConfigScope() });
|
|
2159
2187
|
}
|
|
2160
2188
|
async syncInstalledEnvConnection(params) {
|
|
@@ -2183,7 +2211,7 @@ export default class Install extends Command {
|
|
|
2183
2211
|
}
|
|
2184
2212
|
await this.config.runCommand('env:update', [params.envName]);
|
|
2185
2213
|
}
|
|
2186
|
-
static buildSavedEnvConfig(params) {
|
|
2214
|
+
static buildSavedEnvConfig(params, options = {}) {
|
|
2187
2215
|
const appPath = resolveConfiguredAppPathValue(params.appResults);
|
|
2188
2216
|
const appRootPath = Install.toOptionalPromptString(params.appResults.appRootPath);
|
|
2189
2217
|
const storagePath = Install.toOptionalPromptString(params.appResults.storagePath);
|
|
@@ -2195,6 +2223,7 @@ export default class Install extends Command {
|
|
|
2195
2223
|
const apiBaseUrl = Install.resolveApiBaseUrl({
|
|
2196
2224
|
appResults: params.appResults,
|
|
2197
2225
|
envAddResults: params.envAddResults,
|
|
2226
|
+
defaultApiHost: options.defaultApiHost,
|
|
2198
2227
|
});
|
|
2199
2228
|
const authType = String(params.envAddResults.authType ?? 'oauth').trim() || 'oauth';
|
|
2200
2229
|
const authUsername = authType === 'basic' ? String(params.envAddResults.username ?? params.rootResults.rootUsername ?? '').trim() : '';
|
|
@@ -2239,6 +2268,7 @@ export default class Install extends Command {
|
|
|
2239
2268
|
}
|
|
2240
2269
|
async collectPromptResults(parsed, yes) {
|
|
2241
2270
|
const commandArgv = this.argv ?? process.argv.slice(2);
|
|
2271
|
+
const defaultApiHost = await resolveDefaultApiHost();
|
|
2242
2272
|
const resumePreset = await this.resolveResumePresetValues(parsed, yes);
|
|
2243
2273
|
const envPreset = {
|
|
2244
2274
|
...(resumePreset?.envPreset ?? {}),
|
|
@@ -2334,7 +2364,7 @@ export default class Install extends Command {
|
|
|
2334
2364
|
};
|
|
2335
2365
|
const resolvedEnvAddAuthType = String(envAddPreset.authType ?? '').trim();
|
|
2336
2366
|
const envAddInitialValues = {
|
|
2337
|
-
apiBaseUrl:
|
|
2367
|
+
apiBaseUrl: buildInstallApiBaseUrl(appResults, defaultApiHost),
|
|
2338
2368
|
...envAddResumePreset,
|
|
2339
2369
|
...(!parsed['skip-auth'] && resolvedEnvAddAuthType === 'basic'
|
|
2340
2370
|
? {
|
|
@@ -2381,6 +2411,7 @@ export default class Install extends Command {
|
|
|
2381
2411
|
const parsed = {
|
|
2382
2412
|
...flags,
|
|
2383
2413
|
};
|
|
2414
|
+
const defaultApiHost = await resolveDefaultApiHost();
|
|
2384
2415
|
if (parsed['skip-auth'] && (parsed['access-token'] !== undefined || parsed.token !== undefined)) {
|
|
2385
2416
|
this.error('--skip-auth cannot be used with --access-token or --token.');
|
|
2386
2417
|
}
|
|
@@ -2518,11 +2549,17 @@ export default class Install extends Command {
|
|
|
2518
2549
|
await this.waitForAppHealthCheck(Install.resolveApiBaseUrl({
|
|
2519
2550
|
appResults,
|
|
2520
2551
|
envAddResults,
|
|
2552
|
+
defaultApiHost,
|
|
2521
2553
|
}), {
|
|
2522
2554
|
containerName: dockerAppPlan?.containerName,
|
|
2523
2555
|
verbose: parsed.verbose,
|
|
2524
2556
|
});
|
|
2525
|
-
|
|
2557
|
+
const displayApiBaseUrl = Install.resolveApiBaseUrl({
|
|
2558
|
+
appResults,
|
|
2559
|
+
envAddResults,
|
|
2560
|
+
defaultApiHost,
|
|
2561
|
+
});
|
|
2562
|
+
printInfo(`NocoBase is ready at ${formatInstallDisplayUrl(displayApiBaseUrl)}`);
|
|
2526
2563
|
}
|
|
2527
2564
|
if (dockerAppPlan || localAppPlan || builtinDbPlan) {
|
|
2528
2565
|
await this.saveInstalledEnv({
|
|
@@ -276,7 +276,7 @@ export default class SourceDownload extends Command {
|
|
|
276
276
|
value: 'latest',
|
|
277
277
|
label: downloadText('prompts.version.latestLabel'),
|
|
278
278
|
hint: downloadText('prompts.version.latestHint'),
|
|
279
|
-
disabled: true,
|
|
279
|
+
// disabled: true,
|
|
280
280
|
},
|
|
281
281
|
{
|
|
282
282
|
value: 'beta',
|
|
@@ -14,7 +14,7 @@ import Install from '../install.js';
|
|
|
14
14
|
import { defaultWorkspaceName } from '../../lib/app-runtime.js';
|
|
15
15
|
import { resolveCliLocale } from '../../lib/cli-locale.js';
|
|
16
16
|
import { findAvailableTcpPort, validateAvailableTcpPort } from '../../lib/prompt-validators.js';
|
|
17
|
-
import { commandSucceeds, resolveProjectCwd, run, runNocoBaseCommand } from '../../lib/run-npm.js';
|
|
17
|
+
import { commandSucceeds, ensureDockerDaemonRunning, resolveProjectCwd, run, runNocoBaseCommand, } from '../../lib/run-npm.js';
|
|
18
18
|
import { failTask, printInfo, setVerboseMode, startTask, succeedTask } from '../../lib/ui.js';
|
|
19
19
|
const DEFAULT_DB_HOST = '127.0.0.1';
|
|
20
20
|
const DEFAULT_DB_DATABASE = 'nocobase-test';
|
|
@@ -48,11 +48,11 @@ const DEFAULT_DB_PORTS = {
|
|
|
48
48
|
};
|
|
49
49
|
const TCP_PORT_READY_SCRIPT = [
|
|
50
50
|
"const net = require('node:net');",
|
|
51
|
-
|
|
51
|
+
'const port = Number(process.argv.at(-1));',
|
|
52
52
|
"const socket = net.createConnection({ host: '127.0.0.1', port });",
|
|
53
53
|
"socket.once('connect', () => { socket.end(); process.exit(0); });",
|
|
54
54
|
"socket.once('error', () => process.exit(1));",
|
|
55
|
-
|
|
55
|
+
'setTimeout(() => { socket.destroy(); process.exit(1); }, 200).unref();',
|
|
56
56
|
].join('\n');
|
|
57
57
|
function inferTestEnv(paths) {
|
|
58
58
|
const first = String(paths[0] ?? '').trim();
|
|
@@ -60,9 +60,7 @@ function inferTestEnv(paths) {
|
|
|
60
60
|
return undefined;
|
|
61
61
|
}
|
|
62
62
|
const normalized = first.split('\\').join('/');
|
|
63
|
-
if (normalized.includes('/client/')
|
|
64
|
-
|| normalized.includes('/client-v2/')
|
|
65
|
-
|| normalized.includes('/flow-engine/')) {
|
|
63
|
+
if (normalized.includes('/client/') || normalized.includes('/client-v2/') || normalized.includes('/flow-engine/')) {
|
|
66
64
|
return 'client-side';
|
|
67
65
|
}
|
|
68
66
|
return 'server-side';
|
|
@@ -77,9 +75,7 @@ function defaultTestDbPort(dbDialect) {
|
|
|
77
75
|
return String(DEFAULT_DB_PORTS[dbDialect] ?? DEFAULT_DB_PORTS.postgres);
|
|
78
76
|
}
|
|
79
77
|
function defaultTestDbImage(dbDialect) {
|
|
80
|
-
const defaults = resolveCliLocale(process.env.NB_LOCALE) === 'zh-CN'
|
|
81
|
-
? DEFAULT_TEST_DB_IMAGES_ZH_CN
|
|
82
|
-
: DEFAULT_TEST_DB_IMAGES;
|
|
78
|
+
const defaults = resolveCliLocale(process.env.NB_LOCALE) === 'zh-CN' ? DEFAULT_TEST_DB_IMAGES_ZH_CN : DEFAULT_TEST_DB_IMAGES;
|
|
83
79
|
return defaults[dbDialect] ?? defaults.postgres;
|
|
84
80
|
}
|
|
85
81
|
function delay(ms) {
|
|
@@ -174,9 +170,11 @@ async function startTestDbDistributor(params) {
|
|
|
174
170
|
if (code === 0) {
|
|
175
171
|
return;
|
|
176
172
|
}
|
|
177
|
-
childError =
|
|
178
|
-
|
|
179
|
-
|
|
173
|
+
childError =
|
|
174
|
+
childError ??
|
|
175
|
+
new Error(signal
|
|
176
|
+
? `test DB distributor exited due to signal ${signal}`
|
|
177
|
+
: `test DB distributor exited with code ${code ?? 'unknown'}`);
|
|
180
178
|
});
|
|
181
179
|
try {
|
|
182
180
|
await waitForTcpPortReady(port);
|
|
@@ -194,6 +192,7 @@ async function startTestDbDistributor(params) {
|
|
|
194
192
|
};
|
|
195
193
|
}
|
|
196
194
|
async function ensureDockerNetwork(networkName, options) {
|
|
195
|
+
await ensureDockerDaemonRunning('prepare Docker resources for the built-in test database');
|
|
197
196
|
if (await commandSucceeds('docker', ['network', 'inspect', networkName])) {
|
|
198
197
|
return;
|
|
199
198
|
}
|
|
@@ -440,8 +439,8 @@ export default class SourceTest extends Command {
|
|
|
440
439
|
server: flags.server,
|
|
441
440
|
client: flags.client,
|
|
442
441
|
paths: args.paths ?? [],
|
|
443
|
-
})
|
|
444
|
-
|
|
442
|
+
}) &&
|
|
443
|
+
supportsTestDbDistributor(testDbConfig.env.DB_DIALECT)) {
|
|
445
444
|
testDbDistributor = await startTestDbDistributor({
|
|
446
445
|
cwd,
|
|
447
446
|
env: testDbConfig.env,
|
package/dist/locale/en-US.json
CHANGED
|
@@ -63,6 +63,9 @@
|
|
|
63
63
|
"envKey": {
|
|
64
64
|
"invalid": "Use letters and numbers only."
|
|
65
65
|
},
|
|
66
|
+
"appPublicPath": {
|
|
67
|
+
"invalid": "Use / or a slash-separated path like /nocobase/ or /foo-bar/baz_2/. Each path segment may contain letters, numbers, hyphens, and underscores only."
|
|
68
|
+
},
|
|
66
69
|
"tcpPort": {
|
|
67
70
|
"invalid": "Enter a valid TCP port between 1 and 65535, for example {{example}}.",
|
|
68
71
|
"allocateFailed": "Failed to allocate an available TCP port.",
|
|
@@ -96,10 +99,10 @@
|
|
|
96
99
|
"placeholder": "https://demo.example.com/api or https://demo.example.com/api/__app/<subapp>"
|
|
97
100
|
},
|
|
98
101
|
"authType": {
|
|
99
|
-
"message": "
|
|
100
|
-
"basicLabel": "Basic
|
|
102
|
+
"message": "Which authentication method would you like to use?",
|
|
103
|
+
"basicLabel": "Basic authentication (username + password)",
|
|
101
104
|
"basicHint": "uses your credentials to fetch a token after save",
|
|
102
|
-
"oauthLabel": "OAuth (browser
|
|
105
|
+
"oauthLabel": "OAuth (browser authentication)",
|
|
103
106
|
"oauthHint": "runs nb env auth after save",
|
|
104
107
|
"tokenLabel": "API token / API key"
|
|
105
108
|
},
|
|
@@ -151,6 +154,7 @@
|
|
|
151
154
|
},
|
|
152
155
|
"shared": {
|
|
153
156
|
"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.",
|
|
157
|
+
"dockerDaemonUnavailable": "Couldn't run `{{action}}` because Docker is installed but the Docker daemon is not running. Start Docker Desktop or the Docker daemon service, then try again. Details: {{details}}",
|
|
154
158
|
"targetEnv": "Using env \"{{envName}}\".",
|
|
155
159
|
"crossEnv": {
|
|
156
160
|
"prompt": "Current env is \"{{currentEnv}}\", but this command targets \"{{requestedEnv}}\" via --env. Continue without switching the current env?",
|
|
@@ -326,6 +330,10 @@
|
|
|
326
330
|
"message": "Which port should this app use?",
|
|
327
331
|
"placeholder": "13000"
|
|
328
332
|
},
|
|
333
|
+
"appPublicPath": {
|
|
334
|
+
"message": "What is the app subpath? (for example, /nocobase/)",
|
|
335
|
+
"placeholder": "/ or /nocobase/"
|
|
336
|
+
},
|
|
329
337
|
"storagePath": {
|
|
330
338
|
"message": "Where should uploads and local files be stored?",
|
|
331
339
|
"placeholder": "./<env>/storage/"
|
|
@@ -436,8 +444,8 @@
|
|
|
436
444
|
"description": "Choose whether to install a new app, manage a local app, or connect a remote app."
|
|
437
445
|
},
|
|
438
446
|
"connectExistingApp": {
|
|
439
|
-
"title": "
|
|
440
|
-
"description": "
|
|
447
|
+
"title": "Connection & authentication",
|
|
448
|
+
"description": "Enter the app access URL and choose an authentication method."
|
|
441
449
|
},
|
|
442
450
|
"createNewApp": {
|
|
443
451
|
"title": "App environment",
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -63,6 +63,9 @@
|
|
|
63
63
|
"envKey": {
|
|
64
64
|
"invalid": "仅支持字母和数字。"
|
|
65
65
|
},
|
|
66
|
+
"appPublicPath": {
|
|
67
|
+
"invalid": "请输入 /,或类似 /nocobase/、/foo-bar/baz_2/ 这样的路径。每个路径段仅支持字母、数字、中划线和下划线。"
|
|
68
|
+
},
|
|
66
69
|
"tcpPort": {
|
|
67
70
|
"invalid": "请输入 1 到 65535 之间的有效 TCP 端口,例如 {{example}}。",
|
|
68
71
|
"allocateFailed": "分配可用 TCP 端口失败。",
|
|
@@ -96,10 +99,10 @@
|
|
|
96
99
|
"placeholder": "https://demo.example.com/api 或 https://demo.example.com/api/__app/<subapp>"
|
|
97
100
|
},
|
|
98
101
|
"authType": {
|
|
99
|
-
"message": "
|
|
100
|
-
"basicLabel": "Basic
|
|
102
|
+
"message": "你想使用哪种认证方式?",
|
|
103
|
+
"basicLabel": "Basic 认证(用户名 + 密码)",
|
|
101
104
|
"basicHint": "保存后会用用户名和密码换取 Token",
|
|
102
|
-
"oauthLabel": "OAuth
|
|
105
|
+
"oauthLabel": "OAuth(浏览器认证)",
|
|
103
106
|
"oauthHint": "保存后会自动执行 nb env auth",
|
|
104
107
|
"tokenLabel": "API Token / API Key"
|
|
105
108
|
},
|
|
@@ -151,6 +154,7 @@
|
|
|
151
154
|
},
|
|
152
155
|
"shared": {
|
|
153
156
|
"missingCommand": "无法执行 `{{action}}`,因为找不到 {{displayName}} 可执行文件。请先安装 {{displayName}},或更新 `nb config set {{configKey}} <path>` 后重试。",
|
|
157
|
+
"dockerDaemonUnavailable": "无法执行 `{{action}}`,因为 Docker 已安装,但 Docker daemon 尚未运行。请先启动 Docker Desktop 或 Docker daemon 服务,然后重试。详情:{{details}}",
|
|
154
158
|
"targetEnv": "正在使用 env \"{{envName}}\"。",
|
|
155
159
|
"crossEnv": {
|
|
156
160
|
"prompt": "当前 env 是 \"{{currentEnv}}\",但该命令通过 --env 指向了 \"{{requestedEnv}}\"。要在不切换当前 env 的情况下继续吗?",
|
|
@@ -326,6 +330,10 @@
|
|
|
326
330
|
"message": "应用要使用哪个端口?",
|
|
327
331
|
"placeholder": "13000"
|
|
328
332
|
},
|
|
333
|
+
"appPublicPath": {
|
|
334
|
+
"message": "应用的子路径是什么?(例如 /nocobase/)",
|
|
335
|
+
"placeholder": "/ 或 /nocobase/"
|
|
336
|
+
},
|
|
329
337
|
"storagePath": {
|
|
330
338
|
"message": "上传文件和本地存储目录要放到哪里?",
|
|
331
339
|
"placeholder": "./<env>/storage/"
|
|
@@ -436,8 +444,8 @@
|
|
|
436
444
|
"description": "选择新安装、本机接管,或远程连接。"
|
|
437
445
|
},
|
|
438
446
|
"connectExistingApp": {
|
|
439
|
-
"title": "
|
|
440
|
-
"description": "
|
|
447
|
+
"title": "连接与认证",
|
|
448
|
+
"description": "填写应用访问地址并选择认证方式。"
|
|
441
449
|
},
|
|
442
450
|
"createNewApp": {
|
|
443
451
|
"title": "应用环境信息",
|
package/package.json
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli",
|
|
3
|
-
"version": "2.1.0-beta.44.test.
|
|
3
|
+
"version": "2.1.0-beta.44.test.4",
|
|
4
4
|
"description": "NocoBase Command Line Tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/generated/command-registry.js",
|
|
7
|
-
"files": [
|
|
8
|
-
"assets",
|
|
9
|
-
"bin",
|
|
10
|
-
"dist",
|
|
11
|
-
"nocobase-ctl.config.json"
|
|
12
|
-
],
|
|
13
7
|
"scripts": {
|
|
14
8
|
"clean": "node ./scripts/clean.mjs",
|
|
15
9
|
"build": "node ./scripts/build.mjs",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { copyFileSync, mkdirSync, readdirSync, rmSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
const scriptsDir = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const packageRoot = path.resolve(scriptsDir, '..');
|
|
10
|
+
const distDir = path.join(packageRoot, 'dist');
|
|
11
|
+
const srcLocaleDir = path.join(packageRoot, 'src', 'locale');
|
|
12
|
+
const distLocaleDir = path.join(distDir, 'locale');
|
|
13
|
+
const tscBin = require.resolve('typescript/bin/tsc');
|
|
14
|
+
|
|
15
|
+
rmSync(distDir, { recursive: true, force: true });
|
|
16
|
+
|
|
17
|
+
const compile = spawnSync(process.execPath, [tscBin, '-p', path.join(packageRoot, 'tsconfig.json')], {
|
|
18
|
+
cwd: packageRoot,
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (compile.status !== 0) {
|
|
23
|
+
process.exit(compile.status ?? 1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
mkdirSync(distLocaleDir, { recursive: true });
|
|
27
|
+
|
|
28
|
+
for (const entry of readdirSync(srcLocaleDir, { withFileTypes: true })) {
|
|
29
|
+
if (!entry.isFile() || !entry.name.endsWith('.json')) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
copyFileSync(path.join(srcLocaleDir, entry.name), path.join(distLocaleDir, entry.name));
|
|
34
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { rmSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const scriptsDir = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const packageRoot = path.resolve(scriptsDir, '..');
|
|
7
|
+
const distDir = path.join(packageRoot, 'dist');
|
|
8
|
+
|
|
9
|
+
rmSync(distDir, { recursive: true, force: true });
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"rewriteRelativeImportExtensions": true,
|
|
7
|
+
"rootDir": "src",
|
|
8
|
+
"outDir": "dist",
|
|
9
|
+
"declaration": false,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"allowSyntheticDefaultImports": true,
|
|
13
|
+
"types": ["node"],
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"strict": false
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*.ts"],
|
|
18
|
+
"exclude": ["src/**/__tests__/**"]
|
|
19
|
+
}
|