@nocobase/cli 2.2.0-beta.8 → 2.2.0-beta.9
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/app.conf.tpl +23 -0
- package/assets/env-proxy/nginx/nocobase.conf.tpl +5 -0
- package/assets/env-proxy/nginx/snippets/dist-location.conf +5 -0
- package/assets/env-proxy/nginx/snippets/gzip.conf +17 -0
- package/assets/env-proxy/nginx/snippets/log-format-http.conf +13 -0
- package/assets/env-proxy/nginx/snippets/maps-http.conf +14 -0
- package/assets/env-proxy/nginx/snippets/mime-types.conf +98 -0
- package/assets/env-proxy/nginx/snippets/proxy-location.conf +18 -0
- package/assets/env-proxy/nginx/snippets/spa-location.conf +6 -0
- package/assets/env-proxy/nginx/snippets/uploads-location.conf +21 -0
- package/dist/commands/app/start.js +4 -1
- package/dist/commands/install.js +53 -128
- 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/source/download.js +16 -12
- package/dist/lib/app-managed-resources.js +3 -2
- package/dist/lib/auth-store.js +68 -0
- package/dist/lib/cli-config.js +52 -1
- package/dist/lib/docker-image.js +94 -6
- package/dist/lib/env-config.js +5 -0
- package/dist/lib/env-proxy-config.js +48 -0
- package/dist/lib/env-proxy.js +164 -58
- package/dist/lib/proxy-caddy.js +77 -9
- package/dist/lib/proxy-nginx.js +71 -11
- package/dist/locale/en-US.json +1 -1
- package/dist/locale/zh-CN.json +1 -1
- package/package.json +3 -2
package/dist/lib/proxy-caddy.js
CHANGED
|
@@ -9,14 +9,17 @@
|
|
|
9
9
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import { dockerContainerExists, dockerContainerIsRunning, startDockerContainer, stopDockerContainer, } from './app-runtime.js';
|
|
12
|
+
import { loadAuthConfig } from './auth-store.js';
|
|
12
13
|
import { CADDY_PROXY_DRIVER_OPTIONS, DEFAULT_CADDY_PROXY_DRIVER, getCliConfigValue, normalizeCaddyProxyDriver, resolveDockerContainerPrefix, setCliConfigValue, } from './cli-config.js';
|
|
13
14
|
import { resolveCliHomeRoot } from './cli-home.js';
|
|
14
|
-
import { applyEnvProxyAppEntryOptions, buildEnvProxyCaddyBundle, buildEnvProxyMainConfig, mapProxyPathFromCliRoot, resolveEnvProxyMainOutputPath, } from './env-proxy.js';
|
|
15
|
-
import {
|
|
15
|
+
import { applyEnvProxyAppEntryOptions, buildManualEnvProxyCaddyBundle, buildEnvProxyCaddyBundle, buildEnvProxyMainConfig, mapProxyPathFromCliRoot, resolveEnvProxyMainOutputPath, } from './env-proxy.js';
|
|
16
|
+
import { normalizeEnvProxyConfig } from './env-proxy-config.js';
|
|
17
|
+
import { commandOutput, run } from './run-npm.js';
|
|
16
18
|
const DOCKER_CADDY_PROXY_CONTAINER_SUFFIX = 'caddy-proxy';
|
|
17
19
|
const DOCKER_CADDY_PROXY_IMAGE = 'caddy:latest';
|
|
18
20
|
const DOCKER_CADDY_PROXY_RUNTIME_ROOT = '/apps';
|
|
19
21
|
const DOCKER_CADDY_PROXY_CONF_DESTINATION = '/etc/caddy/Caddyfile';
|
|
22
|
+
const DEFAULT_DOCKER_CADDY_PROXY_PUBLISHED_PORTS = [80, 443];
|
|
20
23
|
async function readOptionalTextFile(filePath) {
|
|
21
24
|
try {
|
|
22
25
|
return await readFile(filePath, 'utf8');
|
|
@@ -62,8 +65,9 @@ export async function resolveCaddyProxyRuntimeContext(options) {
|
|
|
62
65
|
upstreamHost: resolveCaddyProxyUpstreamHost(driver),
|
|
63
66
|
};
|
|
64
67
|
}
|
|
65
|
-
export async function writeCaddyProxyBundle(runtime, appEntryOptions, runtimeContext) {
|
|
68
|
+
export async function writeCaddyProxyBundle(runtime, appEntryOptions, runtimeContext, options) {
|
|
66
69
|
const bundle = await buildEnvProxyCaddyBundle(runtime, {
|
|
70
|
+
cdnBaseUrl: options?.cdnBaseUrl,
|
|
67
71
|
runtimeCliRoot: runtimeContext.runtimeCliRoot,
|
|
68
72
|
upstreamHost: runtimeContext.upstreamHost,
|
|
69
73
|
});
|
|
@@ -82,6 +86,27 @@ export async function writeCaddyProxyBundle(runtime, appEntryOptions, runtimeCon
|
|
|
82
86
|
status,
|
|
83
87
|
};
|
|
84
88
|
}
|
|
89
|
+
export async function writeManualCaddyProxyBundle(input, appEntryOptions, runtimeContext, options) {
|
|
90
|
+
const bundle = await buildManualEnvProxyCaddyBundle(input, {
|
|
91
|
+
cdnBaseUrl: options?.cdnBaseUrl,
|
|
92
|
+
runtimeCliRoot: runtimeContext.runtimeCliRoot,
|
|
93
|
+
upstreamHost: input.upstreamHost || runtimeContext.upstreamHost,
|
|
94
|
+
});
|
|
95
|
+
const currentAppConfigContent = await readOptionalTextFile(bundle.appConfigPath);
|
|
96
|
+
const nextAppConfigContent = applyEnvProxyAppEntryOptions(bundle.appConfigContent, 'caddy', appEntryOptions);
|
|
97
|
+
const status = currentAppConfigContent ? 'updated' : 'created';
|
|
98
|
+
await Promise.all([mkdir(bundle.entryDir, { recursive: true }), mkdir(bundle.publicDir, { recursive: true })]);
|
|
99
|
+
await Promise.all([
|
|
100
|
+
writeFile(bundle.appConfigPath, nextAppConfigContent, 'utf8'),
|
|
101
|
+
writeFile(bundle.indexV1Path, bundle.indexV1Content, 'utf8'),
|
|
102
|
+
writeFile(bundle.indexV2Path, bundle.indexV2Content, 'utf8'),
|
|
103
|
+
writeFile(bundle.mainConfigPath, bundle.mainConfigContent, 'utf8'),
|
|
104
|
+
]);
|
|
105
|
+
return {
|
|
106
|
+
bundle,
|
|
107
|
+
status,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
85
110
|
function resolveLocalCaddyPidFilePath() {
|
|
86
111
|
return path.join(path.dirname(resolveEnvProxyMainOutputPath({ provider: 'caddy' })), 'caddy.pid');
|
|
87
112
|
}
|
|
@@ -149,11 +174,16 @@ async function reloadLocalCaddyProxy(runtimeContext) {
|
|
|
149
174
|
}
|
|
150
175
|
async function ensureDockerCaddyProxyContainer(runtimeContext) {
|
|
151
176
|
const containerName = await resolveCaddyProxyContainerName();
|
|
177
|
+
const mainConfigPath = await ensureCaddyProxyMainConfig(runtimeContext);
|
|
178
|
+
const publishedPorts = await resolveDockerCaddyPublishedPorts();
|
|
152
179
|
if (await dockerContainerExists(containerName)) {
|
|
153
|
-
|
|
180
|
+
if (await dockerCaddyProxyContainerMatchesPublishedPorts(containerName, publishedPorts)) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
await removeDockerCaddyProxyContainer(containerName);
|
|
154
184
|
}
|
|
155
185
|
const hostCliRoot = String(process.env.NB_CLI_ROOT ?? resolveCliHomeRoot()).trim() || resolveCliHomeRoot();
|
|
156
|
-
const
|
|
186
|
+
const dockerPortArgs = publishedPorts.flatMap((port) => ['-p', `${port}:${port}`]);
|
|
157
187
|
await run('docker', [
|
|
158
188
|
'run',
|
|
159
189
|
'-d',
|
|
@@ -161,8 +191,7 @@ async function ensureDockerCaddyProxyContainer(runtimeContext) {
|
|
|
161
191
|
containerName,
|
|
162
192
|
'--add-host',
|
|
163
193
|
'host.docker.internal:host-gateway',
|
|
164
|
-
|
|
165
|
-
'80:80',
|
|
194
|
+
...dockerPortArgs,
|
|
166
195
|
'-v',
|
|
167
196
|
`${hostCliRoot}:${DOCKER_CADDY_PROXY_RUNTIME_ROOT}`,
|
|
168
197
|
'-v',
|
|
@@ -173,14 +202,53 @@ async function ensureDockerCaddyProxyContainer(runtimeContext) {
|
|
|
173
202
|
stdio: 'ignore',
|
|
174
203
|
});
|
|
175
204
|
}
|
|
205
|
+
async function resolveDockerCaddyPublishedPorts() {
|
|
206
|
+
const config = await loadAuthConfig();
|
|
207
|
+
const ports = new Set(DEFAULT_DOCKER_CADDY_PROXY_PUBLISHED_PORTS);
|
|
208
|
+
for (const envConfig of Object.values(config.envs)) {
|
|
209
|
+
const port = normalizeEnvProxyConfig(envConfig.proxy)?.port;
|
|
210
|
+
if (port !== undefined) {
|
|
211
|
+
ports.add(port);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return Array.from(ports).sort((left, right) => left - right);
|
|
215
|
+
}
|
|
216
|
+
async function readDockerCaddyPublishedPorts(containerName) {
|
|
217
|
+
const output = await commandOutput('docker', ['inspect', '--format', '{{json .HostConfig.PortBindings}}', containerName], { errorName: 'docker inspect' });
|
|
218
|
+
const parsed = JSON.parse(output.trim() || '{}');
|
|
219
|
+
const ports = new Set();
|
|
220
|
+
for (const bindings of Object.values(parsed)) {
|
|
221
|
+
if (!Array.isArray(bindings)) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
for (const binding of bindings) {
|
|
225
|
+
const port = Number.parseInt(String(binding?.HostPort ?? '').trim(), 10);
|
|
226
|
+
if (Number.isInteger(port) && port > 0) {
|
|
227
|
+
ports.add(port);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return Array.from(ports).sort((left, right) => left - right);
|
|
232
|
+
}
|
|
233
|
+
async function dockerCaddyProxyContainerMatchesPublishedPorts(containerName, expectedPorts) {
|
|
234
|
+
const currentPorts = await readDockerCaddyPublishedPorts(containerName);
|
|
235
|
+
return currentPorts.length === expectedPorts.length && currentPorts.every((port, index) => port === expectedPorts[index]);
|
|
236
|
+
}
|
|
237
|
+
async function removeDockerCaddyProxyContainer(containerName) {
|
|
238
|
+
await run('docker', ['rm', '-f', containerName], {
|
|
239
|
+
errorName: 'docker rm',
|
|
240
|
+
stdio: 'ignore',
|
|
241
|
+
});
|
|
242
|
+
}
|
|
176
243
|
async function startDockerCaddyProxy(runtimeContext) {
|
|
177
244
|
const containerName = await resolveCaddyProxyContainerName();
|
|
178
245
|
await ensureCaddyProxyMainConfig(runtimeContext);
|
|
179
|
-
|
|
246
|
+
const existedBeforeEnsure = await dockerContainerExists(containerName);
|
|
247
|
+
await ensureDockerCaddyProxyContainer(runtimeContext);
|
|
248
|
+
if (existedBeforeEnsure && (await dockerContainerExists(containerName))) {
|
|
180
249
|
const state = await startDockerContainer(containerName, { stdio: 'ignore' });
|
|
181
250
|
return state === 'already-running' ? 'already-running' : 'started';
|
|
182
251
|
}
|
|
183
|
-
await ensureDockerCaddyProxyContainer(runtimeContext);
|
|
184
252
|
return 'started';
|
|
185
253
|
}
|
|
186
254
|
async function stopDockerCaddyProxy() {
|
package/dist/lib/proxy-nginx.js
CHANGED
|
@@ -9,14 +9,17 @@
|
|
|
9
9
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import { dockerContainerExists, dockerContainerIsRunning, startDockerContainer, stopDockerContainer, } from './app-runtime.js';
|
|
12
|
+
import { loadAuthConfig } from './auth-store.js';
|
|
12
13
|
import { DEFAULT_NGINX_PROXY_DRIVER, getCliConfigValue, NGINX_PROXY_DRIVER_OPTIONS, normalizeNginxProxyDriver, resolveDockerContainerPrefix, setCliConfigValue, } from './cli-config.js';
|
|
13
14
|
import { resolveCliHomeRoot } from './cli-home.js';
|
|
14
|
-
import { applyEnvProxyAppEntryOptions, appConfigHasManagedNginxBlock, buildEnvProxyMainConfig, buildEnvProxyNginxBundle, extractManagedNginxConfigBlock, installEnvProxyProvider, mapProxyPathFromCliRoot, reloadEnvProxyProvider, resolveEnvProxyMainOutputPath, replaceManagedNginxConfigBlock, syncEnvProxyNginxSnippets, } from './env-proxy.js';
|
|
15
|
-
import {
|
|
15
|
+
import { applyEnvProxyAppEntryOptions, appConfigHasManagedNginxBlock, buildManualEnvProxyNginxBundle, buildEnvProxyMainConfig, buildEnvProxyNginxBundle, extractManagedNginxConfigBlock, installEnvProxyProvider, mapProxyPathFromCliRoot, reloadEnvProxyProvider, resolveEnvProxyMainOutputPath, replaceManagedNginxConfigBlock, syncEnvProxyNginxSnippets, } from './env-proxy.js';
|
|
16
|
+
import { normalizeEnvProxyConfig } from './env-proxy-config.js';
|
|
17
|
+
import { commandOutput, run } from './run-npm.js';
|
|
16
18
|
const DOCKER_NGINX_PROXY_CONTAINER_SUFFIX = 'nginx-proxy';
|
|
17
19
|
const DOCKER_NGINX_PROXY_IMAGE = 'nginx:latest';
|
|
18
20
|
const DOCKER_NGINX_PROXY_RUNTIME_ROOT = '/apps';
|
|
19
21
|
const DOCKER_NGINX_PROXY_CONF_DESTINATION = '/etc/nginx/conf.d/default.conf';
|
|
22
|
+
const DEFAULT_DOCKER_NGINX_PROXY_PUBLISHED_PORTS = [80, 443];
|
|
20
23
|
async function readOptionalTextFile(filePath) {
|
|
21
24
|
try {
|
|
22
25
|
return await readFile(filePath, 'utf8');
|
|
@@ -66,11 +69,23 @@ function buildNginxManagedBlockMissingMessage(appConfigPath) {
|
|
|
66
69
|
return (`The editable nginx app entry config at ${appConfigPath} does not contain the NocoBase managed block. ` +
|
|
67
70
|
'Restore the managed block or delete the file and regenerate the proxy config.');
|
|
68
71
|
}
|
|
69
|
-
export async function writeNginxProxyBundle(runtime, appEntryOptions, runtimeContext) {
|
|
72
|
+
export async function writeNginxProxyBundle(runtime, appEntryOptions, runtimeContext, options) {
|
|
70
73
|
const bundle = await buildEnvProxyNginxBundle(runtime, {
|
|
74
|
+
cdnBaseUrl: options?.cdnBaseUrl,
|
|
71
75
|
runtimeCliRoot: runtimeContext.runtimeCliRoot,
|
|
72
76
|
upstreamHost: runtimeContext.upstreamHost,
|
|
73
77
|
});
|
|
78
|
+
return await writeResolvedNginxProxyBundle(bundle, appEntryOptions, options);
|
|
79
|
+
}
|
|
80
|
+
export async function writeManualNginxProxyBundle(input, appEntryOptions, runtimeContext, options) {
|
|
81
|
+
const bundle = await buildManualEnvProxyNginxBundle(input, {
|
|
82
|
+
cdnBaseUrl: options?.cdnBaseUrl,
|
|
83
|
+
runtimeCliRoot: runtimeContext.runtimeCliRoot,
|
|
84
|
+
upstreamHost: runtimeContext.upstreamHost,
|
|
85
|
+
});
|
|
86
|
+
return await writeResolvedNginxProxyBundle(bundle, appEntryOptions, options);
|
|
87
|
+
}
|
|
88
|
+
async function writeResolvedNginxProxyBundle(bundle, appEntryOptions, options) {
|
|
74
89
|
const managedConfigBlock = extractManagedNginxConfigBlock(bundle.appConfigContent);
|
|
75
90
|
if (!managedConfigBlock) {
|
|
76
91
|
throw new Error('Failed to render the managed nginx config block.');
|
|
@@ -79,10 +94,12 @@ export async function writeNginxProxyBundle(runtime, appEntryOptions, runtimeCon
|
|
|
79
94
|
let nextAppConfigContent = applyEnvProxyAppEntryOptions(bundle.appConfigContent, 'nginx', appEntryOptions);
|
|
80
95
|
let status = 'created';
|
|
81
96
|
if (currentAppConfigContent) {
|
|
82
|
-
if (!appConfigHasManagedNginxBlock(currentAppConfigContent)) {
|
|
97
|
+
if (!appConfigHasManagedNginxBlock(currentAppConfigContent) && !options?.force) {
|
|
83
98
|
throw new Error(buildNginxManagedBlockMissingMessage(bundle.appConfigPath));
|
|
84
99
|
}
|
|
85
|
-
nextAppConfigContent =
|
|
100
|
+
nextAppConfigContent = appConfigHasManagedNginxBlock(currentAppConfigContent)
|
|
101
|
+
? applyEnvProxyAppEntryOptions(replaceManagedNginxConfigBlock(currentAppConfigContent, managedConfigBlock), 'nginx', appEntryOptions)
|
|
102
|
+
: applyEnvProxyAppEntryOptions(bundle.appConfigContent, 'nginx', appEntryOptions);
|
|
86
103
|
status = 'updated';
|
|
87
104
|
}
|
|
88
105
|
await Promise.all([mkdir(bundle.entryDir, { recursive: true }), mkdir(bundle.publicDir, { recursive: true })]);
|
|
@@ -217,11 +234,16 @@ async function reloadLocalNginxProxy(runtimeContext) {
|
|
|
217
234
|
}
|
|
218
235
|
async function ensureDockerNginxProxyContainer(runtimeContext) {
|
|
219
236
|
const containerName = await resolveNginxProxyContainerName();
|
|
237
|
+
const mainConfigPath = await ensureNginxProxyMainConfig(runtimeContext);
|
|
238
|
+
const publishedPorts = await resolveDockerNginxPublishedPorts();
|
|
220
239
|
if (await dockerContainerExists(containerName)) {
|
|
221
|
-
|
|
240
|
+
if (await dockerNginxProxyContainerMatchesPublishedPorts(containerName, publishedPorts)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
await removeDockerNginxProxyContainer(containerName);
|
|
222
244
|
}
|
|
223
245
|
const hostCliRoot = String(process.env.NB_CLI_ROOT ?? resolveCliHomeRoot()).trim() || resolveCliHomeRoot();
|
|
224
|
-
const
|
|
246
|
+
const dockerPortArgs = publishedPorts.flatMap((port) => ['-p', `${port}:${port}`]);
|
|
225
247
|
await run('docker', [
|
|
226
248
|
'run',
|
|
227
249
|
'-d',
|
|
@@ -229,8 +251,7 @@ async function ensureDockerNginxProxyContainer(runtimeContext) {
|
|
|
229
251
|
containerName,
|
|
230
252
|
'--add-host',
|
|
231
253
|
'host.docker.internal:host-gateway',
|
|
232
|
-
|
|
233
|
-
'80:80',
|
|
254
|
+
...dockerPortArgs,
|
|
234
255
|
'-v',
|
|
235
256
|
`${hostCliRoot}:${DOCKER_NGINX_PROXY_RUNTIME_ROOT}`,
|
|
236
257
|
'-v',
|
|
@@ -241,14 +262,53 @@ async function ensureDockerNginxProxyContainer(runtimeContext) {
|
|
|
241
262
|
stdio: 'ignore',
|
|
242
263
|
});
|
|
243
264
|
}
|
|
265
|
+
async function resolveDockerNginxPublishedPorts() {
|
|
266
|
+
const config = await loadAuthConfig();
|
|
267
|
+
const ports = new Set(DEFAULT_DOCKER_NGINX_PROXY_PUBLISHED_PORTS);
|
|
268
|
+
for (const envConfig of Object.values(config.envs)) {
|
|
269
|
+
const port = normalizeEnvProxyConfig(envConfig.proxy)?.port;
|
|
270
|
+
if (port !== undefined) {
|
|
271
|
+
ports.add(port);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return Array.from(ports).sort((left, right) => left - right);
|
|
275
|
+
}
|
|
276
|
+
async function readDockerNginxPublishedPorts(containerName) {
|
|
277
|
+
const output = await commandOutput('docker', ['inspect', '--format', '{{json .HostConfig.PortBindings}}', containerName], { errorName: 'docker inspect' });
|
|
278
|
+
const parsed = JSON.parse(output.trim() || '{}');
|
|
279
|
+
const ports = new Set();
|
|
280
|
+
for (const bindings of Object.values(parsed)) {
|
|
281
|
+
if (!Array.isArray(bindings)) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
for (const binding of bindings) {
|
|
285
|
+
const port = Number.parseInt(String(binding?.HostPort ?? '').trim(), 10);
|
|
286
|
+
if (Number.isInteger(port) && port > 0) {
|
|
287
|
+
ports.add(port);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return Array.from(ports).sort((left, right) => left - right);
|
|
292
|
+
}
|
|
293
|
+
async function dockerNginxProxyContainerMatchesPublishedPorts(containerName, expectedPorts) {
|
|
294
|
+
const currentPorts = await readDockerNginxPublishedPorts(containerName);
|
|
295
|
+
return currentPorts.length === expectedPorts.length && currentPorts.every((port, index) => port === expectedPorts[index]);
|
|
296
|
+
}
|
|
297
|
+
async function removeDockerNginxProxyContainer(containerName) {
|
|
298
|
+
await run('docker', ['rm', '-f', containerName], {
|
|
299
|
+
errorName: 'docker rm',
|
|
300
|
+
stdio: 'ignore',
|
|
301
|
+
});
|
|
302
|
+
}
|
|
244
303
|
async function startDockerNginxProxy(runtimeContext) {
|
|
245
304
|
const containerName = await resolveNginxProxyContainerName();
|
|
246
305
|
await ensureNginxProxyMainConfig(runtimeContext);
|
|
247
|
-
|
|
306
|
+
const existedBeforeEnsure = await dockerContainerExists(containerName);
|
|
307
|
+
await ensureDockerNginxProxyContainer(runtimeContext);
|
|
308
|
+
if (existedBeforeEnsure && (await dockerContainerExists(containerName))) {
|
|
248
309
|
const state = await startDockerContainer(containerName, { stdio: 'ignore' });
|
|
249
310
|
return state === 'already-running' ? 'already-running' : 'started';
|
|
250
311
|
}
|
|
251
|
-
await ensureDockerNginxProxyContainer(runtimeContext);
|
|
252
312
|
return 'started';
|
|
253
313
|
}
|
|
254
314
|
async function stopDockerNginxProxy() {
|
package/dist/locale/en-US.json
CHANGED
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
"version": {
|
|
264
264
|
"message": "Which version would you like to use?",
|
|
265
265
|
"latestLabel": "latest",
|
|
266
|
-
"latestHint": "Stable release. Best for production use and the most predictable experience.
|
|
266
|
+
"latestHint": "Stable release. Best for production use and the most predictable experience.",
|
|
267
267
|
"betaLabel": "beta",
|
|
268
268
|
"betaHint": "Preview release. Good for trying upcoming features before general release.",
|
|
269
269
|
"alphaLabel": "alpha",
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
"version": {
|
|
264
264
|
"message": "你想使用哪个版本?",
|
|
265
265
|
"latestLabel": "latest",
|
|
266
|
-
"latestHint": "
|
|
266
|
+
"latestHint": "稳定版。适合生产环境和希望获得稳定体验的场景。",
|
|
267
267
|
"betaLabel": "beta",
|
|
268
268
|
"betaHint": "测试版。包含即将发布的新功能,适合提前体验和反馈。",
|
|
269
269
|
"alphaLabel": "alpha",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli",
|
|
3
|
-
"version": "2.2.0-beta.
|
|
3
|
+
"version": "2.2.0-beta.9",
|
|
4
4
|
"description": "NocoBase Command Line Tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/generated/command-registry.js",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "Apache-2.0",
|
|
15
15
|
"files": [
|
|
16
|
+
"assets",
|
|
16
17
|
"bin",
|
|
17
18
|
"dist",
|
|
18
19
|
"nocobase-ctl.config.json"
|
|
@@ -143,5 +144,5 @@
|
|
|
143
144
|
"type": "git",
|
|
144
145
|
"url": "git+https://github.com/nocobase/nocobase.git"
|
|
145
146
|
},
|
|
146
|
-
"gitHead": "
|
|
147
|
+
"gitHead": "60e3d7abbaa0c7cead76f71a4f3d5eedb6b8acdb"
|
|
147
148
|
}
|