@nocobase/cli-v1 2.1.0-beta.43 → 2.1.0-beta.45
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/nocobase.conf.tpl +9 -1
- package/package.json +5 -5
- package/src/commands/client.js +56 -25
- package/src/commands/create-nginx-conf.js +8 -4
- package/src/util.js +25 -1
package/nocobase.conf.tpl
CHANGED
|
@@ -58,6 +58,14 @@ server {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
location ^~ {{distPath}} {
|
|
62
|
+
alias {{cwd}}/storage/dist-client/;
|
|
63
|
+
expires 365d;
|
|
64
|
+
add_header Cache-Control "public";
|
|
65
|
+
access_log off;
|
|
66
|
+
autoindex off;
|
|
67
|
+
}
|
|
68
|
+
|
|
61
69
|
location {{publicPath}}static/plugins/ {
|
|
62
70
|
alias {{cwd}}/node_modules/;
|
|
63
71
|
expires 365d;
|
|
@@ -91,7 +99,7 @@ server {
|
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
location {{v2PublicPath}}assets/ {
|
|
94
|
-
alias {{cwd}}/node_modules/@nocobase/app/dist/client/
|
|
102
|
+
alias {{cwd}}/node_modules/@nocobase/app/dist/client/v/assets/;
|
|
95
103
|
expires 365d;
|
|
96
104
|
add_header Cache-Control "public";
|
|
97
105
|
access_log off;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli-v1",
|
|
3
|
-
"version": "2.1.0-beta.
|
|
3
|
+
"version": "2.1.0-beta.45",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
"nocobase-v1": "./bin/index.js"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@nocobase/cli": "2.1.0-beta.
|
|
11
|
+
"@nocobase/cli": "2.1.0-beta.45",
|
|
12
12
|
"@nocobase/license-kit": "^0.3.8",
|
|
13
|
-
"@nocobase/utils": "2.1.0-beta.
|
|
13
|
+
"@nocobase/utils": "2.1.0-beta.45",
|
|
14
14
|
"chalk": "^4.1.1",
|
|
15
15
|
"commander": "^9.2.0",
|
|
16
16
|
"deepmerge": "^4.3.1",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"tree-kill": "^1.2.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@nocobase/devtools": "2.1.0-beta.
|
|
28
|
+
"@nocobase/devtools": "2.1.0-beta.45",
|
|
29
29
|
"@types/fs-extra": "^11.0.1"
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
34
34
|
"directory": "packages/core/cli"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "42587115fc34c3eb01ef2b2549f1c998e5708318"
|
|
37
37
|
}
|
package/src/commands/client.js
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const chalk = require('chalk');
|
|
11
|
-
const { Command } = require('commander');
|
|
12
11
|
const fs = require('fs-extra');
|
|
13
12
|
const { resolve } = require('path');
|
|
13
|
+
const { discoverPluginPackages } = require('@nocobase/utils/plugin-package');
|
|
14
14
|
const { storagePathJoin } = require('../util');
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -20,39 +20,47 @@ const { storagePathJoin } = require('../util');
|
|
|
20
20
|
*/
|
|
21
21
|
async function copyMainClient(source, target) {
|
|
22
22
|
if (!(await fs.exists(source))) {
|
|
23
|
-
console.
|
|
24
|
-
return;
|
|
23
|
+
console.warn(chalk.yellow(`Source directory does not exist: ${source}`));
|
|
24
|
+
return false;
|
|
25
25
|
}
|
|
26
26
|
// 确保目标目录存在且为空
|
|
27
27
|
await fs.ensureDir(target);
|
|
28
28
|
await fs.emptyDir(target);
|
|
29
29
|
await fs.copy(source, target, { recursive: true });
|
|
30
|
-
|
|
30
|
+
return true;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* 复制插件客户端文件
|
|
35
|
-
* @param {string}
|
|
36
|
-
* @param {string} namespace - 命名空间(如 '@nocobase' 或 '@nocobase-example')
|
|
35
|
+
* @param {Array<{ packageName: string, resolvedPath: string }>} plugins - 插件清单
|
|
37
36
|
* @param {string} target - 目标目录
|
|
38
37
|
*/
|
|
39
|
-
async function copyPluginClients(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
await fs.mkdir(resolve(pluginTarget, '..'), { recursive: true });
|
|
50
|
-
await fs.copy(pluginDistClient, pluginTarget, { recursive: true });
|
|
51
|
-
console.log(chalk.green(`Copied ${namespace}/${pluginName} ${lane} files`));
|
|
52
|
-
}
|
|
38
|
+
async function copyPluginClients(plugins, target) {
|
|
39
|
+
let copiedCount = 0;
|
|
40
|
+
for (const plugin of plugins) {
|
|
41
|
+
for (const lane of ['client', 'client-v2']) {
|
|
42
|
+
const pluginDistClient = resolve(plugin.resolvedPath, `dist/${lane}`);
|
|
43
|
+
if (await fs.exists(pluginDistClient)) {
|
|
44
|
+
const pluginTarget = resolve(target, 'static/plugins', plugin.packageName, 'dist', lane);
|
|
45
|
+
await fs.mkdir(resolve(pluginTarget, '..'), { recursive: true });
|
|
46
|
+
await fs.copy(pluginDistClient, pluginTarget, { recursive: true });
|
|
47
|
+
copiedCount++;
|
|
53
48
|
}
|
|
54
49
|
}
|
|
55
50
|
}
|
|
51
|
+
return copiedCount;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function writeActiveVersion(version) {
|
|
55
|
+
const distClientRoot = storagePathJoin('dist-client');
|
|
56
|
+
const activeVersionFile = resolve(distClientRoot, 'active-version');
|
|
57
|
+
const tempFile = resolve(distClientRoot, `.active-version.${process.pid}.${Date.now()}.tmp`);
|
|
58
|
+
|
|
59
|
+
await fs.ensureDir(distClientRoot);
|
|
60
|
+
await fs.writeFile(tempFile, `${version}\n`, 'utf8');
|
|
61
|
+
await fs.move(tempFile, activeVersionFile, { overwrite: true });
|
|
62
|
+
|
|
63
|
+
return activeVersionFile;
|
|
56
64
|
}
|
|
57
65
|
|
|
58
66
|
/**
|
|
@@ -108,15 +116,38 @@ async function uploadDirectoryToOSS(client, localDir, ossPrefix = '') {
|
|
|
108
116
|
module.exports = (cli) => {
|
|
109
117
|
cli
|
|
110
118
|
.command('client:extract')
|
|
119
|
+
.option('--json', 'Output machine-readable JSON')
|
|
111
120
|
.allowUnknownOption()
|
|
112
|
-
.action(async ()
|
|
121
|
+
.action(async function () {
|
|
122
|
+
const json = this.opts().json === true;
|
|
113
123
|
const version = require('../../package.json').version;
|
|
114
124
|
const target = storagePathJoin('dist-client', version);
|
|
115
125
|
const mainClientSource = resolve(process.cwd(), 'node_modules/@nocobase/app/dist/client');
|
|
116
|
-
await
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
await
|
|
126
|
+
const plugins = await discoverPluginPackages({
|
|
127
|
+
nodeModulesPath: resolve(process.cwd(), 'node_modules'),
|
|
128
|
+
});
|
|
129
|
+
const copiedMainClient = await copyMainClient(mainClientSource, target);
|
|
130
|
+
const copiedPluginBundles = await copyPluginClients(plugins, target);
|
|
131
|
+
const activeVersionFile = await writeActiveVersion(version);
|
|
132
|
+
|
|
133
|
+
if (json) {
|
|
134
|
+
process.stdout.write(
|
|
135
|
+
JSON.stringify({
|
|
136
|
+
version,
|
|
137
|
+
target,
|
|
138
|
+
activeVersionFile,
|
|
139
|
+
}),
|
|
140
|
+
);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.log(
|
|
145
|
+
chalk.green(
|
|
146
|
+
`Extracted client assets ${version} to ${target} (main client: ${
|
|
147
|
+
copiedMainClient ? 'yes' : 'no'
|
|
148
|
+
}, plugin bundles: ${copiedPluginBundles}).`,
|
|
149
|
+
),
|
|
150
|
+
);
|
|
120
151
|
});
|
|
121
152
|
|
|
122
153
|
cli
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const { resolve, posix } = require('path');
|
|
11
|
-
const { storagePathJoin, resolvePublicPath, resolveV2PublicPath } = require('../util');
|
|
12
|
-
const { Command } = require('commander');
|
|
11
|
+
const { storagePathJoin, resolvePublicPath, resolveV2PublicPath, normalizeModernClientPrefix } = require('../util');
|
|
13
12
|
const { readFileSync, writeFileSync } = require('fs');
|
|
14
13
|
|
|
15
14
|
/**
|
|
@@ -20,18 +19,22 @@ module.exports = (cli) => {
|
|
|
20
19
|
cli.command('create-nginx-conf').action(async (name, options) => {
|
|
21
20
|
const rawAppPublicPath = process.env.APP_PUBLIC_PATH || '/';
|
|
22
21
|
const appPublicPath = resolvePublicPath(rawAppPublicPath);
|
|
22
|
+
const distPath = `${appPublicPath.replace(/\/$/, '')}/dist/`;
|
|
23
23
|
const v2PublicPath = resolveV2PublicPath(rawAppPublicPath);
|
|
24
|
+
const modernClientPrefix = normalizeModernClientPrefix(process.env.APP_MODERN_CLIENT_PREFIX);
|
|
24
25
|
const appPublicPathWithoutTrailingSlash = appPublicPath.replace(/\/$/, '');
|
|
25
26
|
const v2PublicPathWithoutTrailingSlash = v2PublicPath.replace(/\/$/, '');
|
|
26
27
|
const file = resolve(__dirname, '../../nocobase.conf.tpl');
|
|
27
28
|
const data = readFileSync(file, 'utf-8');
|
|
28
29
|
let otherLocation = '';
|
|
29
30
|
if (appPublicPath !== '/') {
|
|
30
|
-
|
|
31
|
+
// When the app is mounted under a sub-path, redirect the root-level
|
|
32
|
+
// `/<prefix>` and `/<prefix>/` to the real (sub-path-prefixed) location.
|
|
33
|
+
otherLocation = `location = /${modernClientPrefix} {
|
|
31
34
|
return 302 ${v2PublicPath}$is_args$args;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
location /
|
|
37
|
+
location /${modernClientPrefix}/ {
|
|
35
38
|
return 302 ${appPublicPathWithoutTrailingSlash}$uri$is_args$args;
|
|
36
39
|
}
|
|
37
40
|
|
|
@@ -43,6 +46,7 @@ module.exports = (cli) => {
|
|
|
43
46
|
const replaced = data
|
|
44
47
|
.replace(/\{\{cwd\}\}/g, posix.resolve(process.cwd()))
|
|
45
48
|
.replace(/\{\{publicPath\}\}/g, appPublicPath)
|
|
49
|
+
.replace(/\{\{distPath\}\}/g, distPath)
|
|
46
50
|
.replace(/\{\{v2PublicPath\}\}/g, v2PublicPath)
|
|
47
51
|
.replace(/\{\{v2PublicPathNoTrailingSlash\}\}/g, v2PublicPathWithoutTrailingSlash)
|
|
48
52
|
.replace(/\{\{apiPort\}\}/g, process.env.APP_PORT)
|
package/src/util.js
CHANGED
|
@@ -367,9 +367,32 @@ function resolvePublicPath(appPublicPath = '/') {
|
|
|
367
367
|
|
|
368
368
|
exports.resolvePublicPath = resolvePublicPath;
|
|
369
369
|
|
|
370
|
+
// Default URL segment under which the modern (v2) client is served.
|
|
371
|
+
// Kept local here so the CLI bootstrap (bin/index.js -> initEnv) stays lightweight
|
|
372
|
+
// and does not have to require heavier packages. A second copy of the fixed
|
|
373
|
+
// build-output directory name lives in:
|
|
374
|
+
// - packages/core/app/client-v2/rsbuild.config.ts (output.distPath)
|
|
375
|
+
// - packages/core/server/src/gateway/index.ts (MODERN_CLIENT_DIST_DIR)
|
|
376
|
+
// Keep them in sync. See docs/adr/0001-modern-client-prefix.md.
|
|
377
|
+
const DEFAULT_MODERN_CLIENT_PREFIX = 'v';
|
|
378
|
+
|
|
379
|
+
exports.DEFAULT_MODERN_CLIENT_PREFIX = DEFAULT_MODERN_CLIENT_PREFIX;
|
|
380
|
+
|
|
381
|
+
// Normalize APP_MODERN_CLIENT_PREFIX (accepts `v`, `/v`, `/v/`)
|
|
382
|
+
// down to a bare segment like `v`.
|
|
383
|
+
function normalizeModernClientPrefix(value) {
|
|
384
|
+
const segment = String(value || '')
|
|
385
|
+
.trim()
|
|
386
|
+
.replace(/^\/+|\/+$/g, '');
|
|
387
|
+
return segment || DEFAULT_MODERN_CLIENT_PREFIX;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
exports.normalizeModernClientPrefix = normalizeModernClientPrefix;
|
|
391
|
+
|
|
370
392
|
function resolveV2PublicPath(appPublicPath = '/') {
|
|
371
393
|
const publicPath = resolvePublicPath(appPublicPath);
|
|
372
|
-
|
|
394
|
+
const prefix = normalizeModernClientPrefix(process.env.APP_MODERN_CLIENT_PREFIX);
|
|
395
|
+
return `${publicPath.replace(/\/$/, '')}/${prefix}/`;
|
|
373
396
|
}
|
|
374
397
|
|
|
375
398
|
exports.resolveV2PublicPath = resolveV2PublicPath;
|
|
@@ -533,6 +556,7 @@ exports.initEnv = function initEnv() {
|
|
|
533
556
|
APP_BASE_URL: '',
|
|
534
557
|
CDN_BASE_URL: '',
|
|
535
558
|
APP_PUBLIC_PATH: '/',
|
|
559
|
+
APP_MODERN_CLIENT_PREFIX: DEFAULT_MODERN_CLIENT_PREFIX,
|
|
536
560
|
ESM_CDN_BASE_URL: 'https://esm.sh',
|
|
537
561
|
ESM_CDN_SUFFIX: '',
|
|
538
562
|
};
|