@nocobase/app 2.1.31 → 2.2.0-alpha.10
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/client/public/browser-checker.js +58 -0
- package/client/rsbuild.config.ts +21 -0
- package/client-v2/rsbuild.config.ts +66 -0
- package/dist/client/assets/{index-6426e795.js → index-baf26099.js} +507 -378
- package/dist/client/assets/{vendor-antd-a0dccf46.js → vendor-antd-f421fb70.js} +8 -8
- package/dist/client/assets/{vendor-diagram-686f3f07.js → vendor-diagram-c90b5083.js} +2 -2
- package/dist/client/assets/{vendor-lodash-97b39f5f.js → vendor-lodash-c512d103.js} +2 -2
- package/dist/client/assets/{vendor-misc-c30c528b.js → vendor-misc-47bbd442.js} +3 -3
- package/dist/client/browser-checker.js +58 -0
- package/dist/client/index.html +3 -1
- package/dist/client/index.html.tpl +3 -1
- package/dist/client/v/assets/{8384-4b58de2e.js → 8384-1634db4d.js} +2 -2
- package/dist/client/v/assets/index-372e693c.js +1843 -0
- package/dist/client/v/assets/{vendor-antd-f8c3ace1.js → vendor-antd-155a4c9b.js} +8 -8
- package/dist/client/v/index.html +1 -1
- package/package.json +7 -7
- package/dist/client/v/assets/index-17b108fa.js +0 -1714
- /package/dist/client/assets/{index-6426e795.js.LICENSE.txt → index-baf26099.js.LICENSE.txt} +0 -0
- /package/dist/client/assets/{vendor-diagram-686f3f07.js.LICENSE.txt → vendor-diagram-c90b5083.js.LICENSE.txt} +0 -0
- /package/dist/client/assets/{vendor-lodash-97b39f5f.js.LICENSE.txt → vendor-lodash-c512d103.js.LICENSE.txt} +0 -0
- /package/dist/client/assets/{vendor-misc-c30c528b.js.LICENSE.txt → vendor-misc-47bbd442.js.LICENSE.txt} +0 -0
- /package/dist/client/v/assets/{8384-4b58de2e.js.LICENSE.txt → 8384-1634db4d.js.LICENSE.txt} +0 -0
- /package/dist/client/v/assets/{index-17b108fa.js.LICENSE.txt → index-372e693c.js.LICENSE.txt} +0 -0
|
@@ -17,9 +17,31 @@ function normalizePublicPath(value) {
|
|
|
17
17
|
return ensureTrailingSlash(normalized);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function trimTrailingSlash(value) {
|
|
21
|
+
return value === '/' ? value : value.replace(/\/+$/g, '');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function normalizePathname(value) {
|
|
25
|
+
const normalized = ensureLeadingSlash(String(value || '/').trim() || '/').replace(/\/{2,}/g, '/');
|
|
26
|
+
if (normalized !== '/' && normalized.endsWith('/')) {
|
|
27
|
+
return normalized.replace(/\/+$/g, '');
|
|
28
|
+
}
|
|
29
|
+
return normalized;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function isClientDocumentEntryPath(pathname) {
|
|
33
|
+
const normalized = normalizePathname(pathname);
|
|
34
|
+
return normalized === '/' || normalized === '/index.html' || !/\.[^/]+$/.test(normalized);
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
const basename = normalizePublicPath(window['__nocobase_public_path__'] || '/');
|
|
21
38
|
const currentPath = ensureLeadingSlash(String(window.location.pathname || '/').trim() || '/').replace(/\/{2,}/g, '/');
|
|
22
39
|
const basenameWithoutTrailingSlash = basename === '/' ? '/' : basename.replace(/\/+$/, '');
|
|
40
|
+
const modernClientPrefix =
|
|
41
|
+
String(window['__nocobase_modern_client_prefix__'] || 'v')
|
|
42
|
+
.trim()
|
|
43
|
+
.replace(/^\/+|\/+$/g, '') || 'v';
|
|
44
|
+
const appClientEntryMode = window['__nocobase_app_client_entry_mode__'];
|
|
23
45
|
|
|
24
46
|
if (basename !== '/' && currentPath === basenameWithoutTrailingSlash) {
|
|
25
47
|
const newUrl = `${window.location.origin}${basename}${window.location.search}${window.location.hash}`;
|
|
@@ -28,6 +50,42 @@ if (basename !== '/' && currentPath === basenameWithoutTrailingSlash) {
|
|
|
28
50
|
const newPath = currentPath === '/' ? basename : `${basenameWithoutTrailingSlash}${currentPath}`;
|
|
29
51
|
let newUrl = window.location.origin + newPath + window.location.search + window.location.hash;
|
|
30
52
|
window.location.replace(newUrl);
|
|
53
|
+
} else {
|
|
54
|
+
// This client-side redirect is still needed because legacy `index.html` is
|
|
55
|
+
// not always served through the node gateway. In nginx/static delivery paths
|
|
56
|
+
// the browser may already be running the legacy shell by the time entry-mode
|
|
57
|
+
// logic is evaluated, so the last hop into the modern entry has to be
|
|
58
|
+
// recoverable in the browser as well.
|
|
59
|
+
const normalizedPath = normalizePathname(currentPath);
|
|
60
|
+
const relativePath =
|
|
61
|
+
basename === '/'
|
|
62
|
+
? normalizedPath
|
|
63
|
+
: normalizedPath === basenameWithoutTrailingSlash
|
|
64
|
+
? '/'
|
|
65
|
+
: normalizedPath.startsWith(basename)
|
|
66
|
+
? normalizePathname(normalizedPath.slice(basename.length - 1))
|
|
67
|
+
: null;
|
|
68
|
+
const modernBase = `${trimTrailingSlash(basename)}/${modernClientPrefix}/`.replace(/\/{2,}/g, '/');
|
|
69
|
+
const isModernDefault = appClientEntryMode === 'modern-default';
|
|
70
|
+
const isModernOnly = appClientEntryMode === 'modern-only';
|
|
71
|
+
if (
|
|
72
|
+
relativePath &&
|
|
73
|
+
isClientDocumentEntryPath(relativePath) &&
|
|
74
|
+
(isModernDefault || isModernOnly) &&
|
|
75
|
+
!normalizedPath.startsWith(modernBase)
|
|
76
|
+
) {
|
|
77
|
+
const targetPath = isModernDefault
|
|
78
|
+
? relativePath === '/' || relativePath === '/index.html'
|
|
79
|
+
? relativePath === '/index.html'
|
|
80
|
+
? `${modernBase}index.html`
|
|
81
|
+
: modernBase
|
|
82
|
+
: null
|
|
83
|
+
: `${trimTrailingSlash(modernBase)}${relativePath}`;
|
|
84
|
+
if (targetPath && targetPath !== currentPath) {
|
|
85
|
+
const newUrl = window.location.origin + targetPath + window.location.search + window.location.hash;
|
|
86
|
+
window.location.replace(newUrl);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
31
89
|
}
|
|
32
90
|
let showLog = true;
|
|
33
91
|
function log(m) {
|
package/client/rsbuild.config.ts
CHANGED
|
@@ -47,9 +47,16 @@ function toDefineLiteral(value: string | undefined) {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
function createRuntimeHeadScript(appPublicPath: string, isBuild: boolean) {
|
|
50
|
+
const modernClientPrefix =
|
|
51
|
+
String(process.env.APP_MODERN_CLIENT_PREFIX || 'v')
|
|
52
|
+
.trim()
|
|
53
|
+
.replace(/^\/+|\/+$/g, '') || 'v';
|
|
54
|
+
const appClientEntryMode = process.env.APP_CLIENT_ENTRY_MODE;
|
|
50
55
|
if (!isBuild) {
|
|
51
56
|
return [
|
|
52
57
|
`window['__nocobase_public_path__'] = ${JSON.stringify(appPublicPath)};`,
|
|
58
|
+
`window['__nocobase_modern_client_prefix__'] = ${JSON.stringify(modernClientPrefix)};`,
|
|
59
|
+
`window['__nocobase_app_client_entry_mode__'] = ${JSON.stringify(appClientEntryMode)};`,
|
|
53
60
|
`window['__nocobase_dev_public_path__'] = "/";`,
|
|
54
61
|
`window['__nocobase_app_dev__'] = ${JSON.stringify(process.env.NOCOBASE_APP_DEV === 'true')};`,
|
|
55
62
|
`window['__esm_cdn_base_url__'] = ${JSON.stringify(process.env.ESM_CDN_BASE_URL || '')};`,
|
|
@@ -60,6 +67,8 @@ function createRuntimeHeadScript(appPublicPath: string, isBuild: boolean) {
|
|
|
60
67
|
return [
|
|
61
68
|
`window['__webpack_public_path__'] = '{{env.CDN_BASE_URL}}';`,
|
|
62
69
|
`window['__nocobase_public_path__'] = '${appPublicPath}';`,
|
|
70
|
+
`window['__nocobase_modern_client_prefix__'] = '{{env.APP_MODERN_CLIENT_PREFIX}}';`,
|
|
71
|
+
`window['__nocobase_app_client_entry_mode__'] = '{{env.APP_CLIENT_ENTRY_MODE}}';`,
|
|
63
72
|
`window['__nocobase_api_base_url__'] = '{{env.API_BASE_URL}}';`,
|
|
64
73
|
`window['__nocobase_api_client_storage_prefix__'] = '{{env.API_CLIENT_STORAGE_PREFIX}}';`,
|
|
65
74
|
`window['__nocobase_api_client_storage_type__'] = '{{env.API_CLIENT_STORAGE_TYPE}}';`,
|
|
@@ -96,6 +105,7 @@ export default defineConfig(({ command }) => {
|
|
|
96
105
|
const appPublicPath = isBuild ? APP_PUBLIC_PATH_TEMPLATE : resolvedAppPublicPath;
|
|
97
106
|
const htmlPublicPath = isDev ? '/' : appPublicPath;
|
|
98
107
|
const apiBasePath = ensurePublicPath(process.env.API_BASE_PATH, '/api/');
|
|
108
|
+
const fileBasePath = ensurePublicPath(`${resolvedAppPublicPath}files/`, '/files/');
|
|
99
109
|
const localStorageBasePath = ensurePublicPath(`${resolvedAppPublicPath}storage/uploads/`, '/storage/uploads/');
|
|
100
110
|
const staticBasePath = ensurePublicPath(`${resolvedAppPublicPath}static/`, '/static/');
|
|
101
111
|
const wsBasePath = ensurePublicPath(process.env.WS_PATH, '/ws/');
|
|
@@ -107,6 +117,7 @@ export default defineConfig(({ command }) => {
|
|
|
107
117
|
`${resolvedAppPublicPath.replace(/\/$/, '')}/${modernClientPrefix}/`,
|
|
108
118
|
`/${modernClientPrefix}/`,
|
|
109
119
|
);
|
|
120
|
+
const portalBasePath = ensurePublicPath(`${resolvedAppPublicPath.replace(/\/$/, '')}/x/`, '/x/');
|
|
110
121
|
const clientPort = toNumber(process.env.APP_PORT, 13001);
|
|
111
122
|
const v2Port = toNumber(process.env.APP_V2_PORT, clientPort + 2);
|
|
112
123
|
const hmrPath = `${resolvedAppPublicPath.replace(/\/$/, '')}/__rspack_hmr`;
|
|
@@ -220,6 +231,10 @@ export default defineConfig(({ command }) => {
|
|
|
220
231
|
target: proxyTargetUrl,
|
|
221
232
|
changeOrigin: true,
|
|
222
233
|
},
|
|
234
|
+
[fileBasePath]: {
|
|
235
|
+
target: proxyTargetUrl,
|
|
236
|
+
changeOrigin: true,
|
|
237
|
+
},
|
|
223
238
|
[staticBasePath]: {
|
|
224
239
|
target: proxyTargetUrl,
|
|
225
240
|
changeOrigin: true,
|
|
@@ -239,6 +254,12 @@ export default defineConfig(({ command }) => {
|
|
|
239
254
|
},
|
|
240
255
|
xfwd: true,
|
|
241
256
|
},
|
|
257
|
+
[portalBasePath]: {
|
|
258
|
+
target: proxyTargetUrl,
|
|
259
|
+
changeOrigin: true,
|
|
260
|
+
ws: true,
|
|
261
|
+
xfwd: true,
|
|
262
|
+
},
|
|
242
263
|
},
|
|
243
264
|
historyApiFallback: {
|
|
244
265
|
disableDotRule: true,
|
|
@@ -52,6 +52,27 @@ function toNumber(value: string | undefined, fallback: number) {
|
|
|
52
52
|
return Number.isFinite(parsed) ? parsed : fallback;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
function normalizePathname(value: string | undefined) {
|
|
56
|
+
let normalized = value || '/';
|
|
57
|
+
if (!normalized.startsWith('/')) {
|
|
58
|
+
normalized = `/${normalized}`;
|
|
59
|
+
}
|
|
60
|
+
normalized = normalized.replace(/\/{2,}/g, '/');
|
|
61
|
+
if (normalized !== '/' && normalized.endsWith('/')) {
|
|
62
|
+
return normalized.replace(/\/+$/g, '');
|
|
63
|
+
}
|
|
64
|
+
return normalized || '/';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isClientDocumentEntryPath(pathname: string) {
|
|
68
|
+
return pathname === '/' || pathname === '/index.html' || !/\.[^/]+$/.test(pathname);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function isWithinBasePath(pathname: string, basePath: string) {
|
|
72
|
+
const normalizedBasePath = normalizePathname(basePath);
|
|
73
|
+
return pathname === normalizedBasePath || pathname.startsWith(`${normalizedBasePath}/`);
|
|
74
|
+
}
|
|
75
|
+
|
|
55
76
|
function createRuntimeHeadScript(v2PublicPath: string, isBuild: boolean, modernClientPrefix: string) {
|
|
56
77
|
if (!isBuild) {
|
|
57
78
|
return [
|
|
@@ -123,8 +144,10 @@ export default defineConfig(({ command }) => {
|
|
|
123
144
|
const isBuild = command === 'build';
|
|
124
145
|
const appPublicPath = ensurePublicPath(process.env.APP_PUBLIC_PATH || '/');
|
|
125
146
|
const apiBasePath = ensurePublicPath(process.env.API_BASE_PATH || '/api/');
|
|
147
|
+
const fileBasePath = ensurePublicPath(`${appPublicPath.replace(/\/$/, '')}/files/`);
|
|
126
148
|
const localStorageBasePath = ensurePublicPath(`${appPublicPath.replace(/\/$/, '')}/storage/uploads/`);
|
|
127
149
|
const staticBasePath = ensurePublicPath(`${appPublicPath.replace(/\/$/, '')}/static/`);
|
|
150
|
+
const portalBasePath = ensurePublicPath(`${appPublicPath.replace(/\/$/, '')}/x/`);
|
|
128
151
|
const modernClientPrefix = normalizeModernClientPrefix(process.env.APP_MODERN_CLIENT_PREFIX);
|
|
129
152
|
// Build bakes the FIXED dist-dir segment (`/v/`) as a sentinel that the
|
|
130
153
|
// server rewrites to the runtime prefix per request. Dev serves under the
|
|
@@ -132,6 +155,7 @@ export default defineConfig(({ command }) => {
|
|
|
132
155
|
const modernClientDistPath = ensurePublicPath(`${appPublicPath.replace(/\/$/, '')}/${MODERN_CLIENT_DIST_DIR}/`);
|
|
133
156
|
const modernClientPublicPath = ensurePublicPath(`${appPublicPath.replace(/\/$/, '')}/${modernClientPrefix}/`);
|
|
134
157
|
const v2PublicPath = isBuild ? modernClientDistPath : modernClientPublicPath;
|
|
158
|
+
const appClientEntryMode = process.env.APP_CLIENT_ENTRY_MODE;
|
|
135
159
|
const wsBasePath = ensurePublicPath(process.env.WS_PATH || '/ws/');
|
|
136
160
|
const hmrPath = `${v2PublicPath.replace(/\/$/, '')}/__rspack_hmr`;
|
|
137
161
|
const v2Port = toNumber(process.env.APP_V2_PORT, 13002);
|
|
@@ -256,10 +280,20 @@ export default defineConfig(({ command }) => {
|
|
|
256
280
|
target: proxyTargetUrl,
|
|
257
281
|
changeOrigin: true,
|
|
258
282
|
},
|
|
283
|
+
[fileBasePath]: {
|
|
284
|
+
target: proxyTargetUrl,
|
|
285
|
+
changeOrigin: true,
|
|
286
|
+
},
|
|
259
287
|
[staticBasePath]: {
|
|
260
288
|
target: proxyTargetUrl,
|
|
261
289
|
changeOrigin: true,
|
|
262
290
|
},
|
|
291
|
+
[portalBasePath]: {
|
|
292
|
+
target: proxyTargetUrl,
|
|
293
|
+
changeOrigin: true,
|
|
294
|
+
ws: true,
|
|
295
|
+
xfwd: true,
|
|
296
|
+
},
|
|
263
297
|
[wsBasePath]: {
|
|
264
298
|
target: proxyTargetUrl,
|
|
265
299
|
changeOrigin: true,
|
|
@@ -275,6 +309,38 @@ export default defineConfig(({ command }) => {
|
|
|
275
309
|
dev: {
|
|
276
310
|
assetPrefix: v2PublicPath,
|
|
277
311
|
lazyCompilation: false,
|
|
312
|
+
setupMiddlewares: [
|
|
313
|
+
(middlewares) => {
|
|
314
|
+
if (appClientEntryMode !== 'modern-only') {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
middlewares.unshift((req, res, next) => {
|
|
319
|
+
const [rawPathname = '/', query = ''] = String(req.url || '/').split('?');
|
|
320
|
+
const pathname = normalizePathname(rawPathname);
|
|
321
|
+
if (
|
|
322
|
+
!isClientDocumentEntryPath(pathname) ||
|
|
323
|
+
pathname.startsWith('/.well-known/') ||
|
|
324
|
+
pathname.startsWith(apiBasePath) ||
|
|
325
|
+
pathname.startsWith(wsBasePath) ||
|
|
326
|
+
pathname.startsWith(localStorageBasePath) ||
|
|
327
|
+
pathname.startsWith(portalBasePath) ||
|
|
328
|
+
pathname.startsWith(staticBasePath)
|
|
329
|
+
) {
|
|
330
|
+
next();
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (!isWithinBasePath(pathname, v2PublicPath)) {
|
|
334
|
+
const target = pathname === '/' ? v2PublicPath : `${v2PublicPath.replace(/\/$/, '')}${pathname}`;
|
|
335
|
+
res.statusCode = 302;
|
|
336
|
+
res.setHeader('Location', `${target}${query ? `?${query}` : ''}`);
|
|
337
|
+
res.end();
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
next();
|
|
341
|
+
});
|
|
342
|
+
},
|
|
343
|
+
],
|
|
278
344
|
client: {
|
|
279
345
|
overlay: false,
|
|
280
346
|
protocol: 'ws',
|