@nocobase/server 2.1.0-alpha.4 → 2.1.0-alpha.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/LICENSE +201 -661
- package/README.md +79 -10
- package/lib/acl/available-action.js +1 -1
- package/lib/aes-encryptor.js +3 -2
- package/lib/app-supervisor/app-options-factory.d.ts +1 -0
- package/lib/app-supervisor/index.d.ts +13 -5
- package/lib/app-supervisor/index.js +48 -13
- package/lib/app-supervisor/main-only-adapter.d.ts +4 -1
- package/lib/app-supervisor/main-only-adapter.js +24 -12
- package/lib/app-supervisor/types.d.ts +18 -3
- package/lib/application.d.ts +1 -2
- package/lib/application.js +3 -24
- package/lib/audit-manager/index.d.ts +2 -0
- package/lib/audit-manager/index.js +5 -2
- package/lib/commands/ai.js +1 -6
- package/lib/commands/create-migration.js +1 -1
- package/lib/commands/install.js +0 -2
- package/lib/commands/pm.js +7 -0
- package/lib/commands/start.js +2 -5
- package/lib/commands/upgrade.js +0 -2
- package/lib/{ai/create-docs-index.d.ts → constants.d.ts} +1 -5
- package/lib/constants.js +36 -0
- package/lib/event-queue.js +1 -1
- package/lib/gateway/index.d.ts +15 -3
- package/lib/gateway/index.js +161 -20
- package/lib/gateway/static-file-security.d.ts +10 -0
- package/lib/gateway/static-file-security.js +69 -0
- package/lib/gateway/utils.d.ts +17 -0
- package/lib/gateway/utils.js +115 -0
- package/lib/helper.js +33 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.js +5 -4
- package/lib/locale/locale.d.ts +24 -0
- package/lib/locale/locale.js +29 -5
- package/lib/main-data-source.js +12 -5
- package/lib/plugin-manager/deps.js +3 -2
- package/lib/plugin-manager/findPackageNames.js +4 -2
- package/lib/plugin-manager/options/resource.d.ts +12 -1
- package/lib/plugin-manager/options/resource.js +212 -53
- package/lib/plugin-manager/plugin-manager.d.ts +7 -2
- package/lib/plugin-manager/plugin-manager.js +65 -56
- package/lib/plugin-manager/utils.d.ts +9 -1
- package/lib/plugin-manager/utils.js +68 -10
- package/lib/plugin.js +46 -2
- package/lib/pub-sub-manager/handler-manager.d.ts +1 -0
- package/lib/pub-sub-manager/handler-manager.js +11 -0
- package/lib/pub-sub-manager/pub-sub-manager.js +2 -1
- package/lib/swagger/app.d.ts +102 -0
- package/lib/swagger/app.js +124 -0
- package/lib/swagger/base.d.ts +244 -0
- package/lib/swagger/base.js +292 -0
- package/lib/swagger/collections.d.ts +996 -0
- package/lib/swagger/collections.js +1264 -0
- package/lib/swagger/index.d.ts +1774 -0
- package/lib/swagger/index.js +70 -0
- package/lib/swagger/pm.d.ts +462 -0
- package/lib/swagger/pm.js +422 -0
- package/lib/sync-message-manager.js +8 -1
- package/lib/worker-mode.d.ts +19 -0
- package/lib/worker-mode.js +67 -0
- package/package.json +19 -19
- package/lib/ai/create-docs-index.js +0 -892
- package/lib/swagger/index.json +0 -1569
package/lib/commands/pm.js
CHANGED
|
@@ -32,9 +32,16 @@ __export(pm_exports, {
|
|
|
32
32
|
module.exports = __toCommonJS(pm_exports);
|
|
33
33
|
var import_app_supervisor = require("../app-supervisor");
|
|
34
34
|
var import_plugin_command_error = require("../errors/plugin-command-error");
|
|
35
|
+
var import_utils = require("../plugin-manager/utils");
|
|
35
36
|
/* istanbul ignore file -- @preserve */
|
|
36
37
|
var pm_default = /* @__PURE__ */ __name((app) => {
|
|
37
38
|
const pm = app.command("pm");
|
|
39
|
+
pm.command("list").action(async () => {
|
|
40
|
+
const items = await (0, import_utils.pmListSummary)(app);
|
|
41
|
+
console.log("--- BEGIN_PLUGIN_LIST_JSON ---");
|
|
42
|
+
console.log(JSON.stringify(items));
|
|
43
|
+
console.log("--- END_PLUGIN_LIST_JSON ---");
|
|
44
|
+
});
|
|
38
45
|
pm.command("create").argument("plugin").option("--force-recreate").action(async (plugin, options) => {
|
|
39
46
|
await app.pm.create(plugin, options);
|
|
40
47
|
});
|
package/lib/commands/start.js
CHANGED
|
@@ -41,19 +41,17 @@ __export(start_exports, {
|
|
|
41
41
|
});
|
|
42
42
|
module.exports = __toCommonJS(start_exports);
|
|
43
43
|
var import_fs_extra = __toESM(require("fs-extra"));
|
|
44
|
-
var
|
|
45
|
-
var import_create_docs_index = require("../ai/create-docs-index");
|
|
44
|
+
var import_utils = require("@nocobase/utils");
|
|
46
45
|
var import_application_not_install = require("../errors/application-not-install");
|
|
47
46
|
/* istanbul ignore file -- @preserve */
|
|
48
47
|
var start_default = /* @__PURE__ */ __name((app) => {
|
|
49
48
|
app.command("start").auth().option("--db-sync").option("--quickstart").action(async (...cliArgs) => {
|
|
50
49
|
const [options] = cliArgs;
|
|
51
|
-
const file = (0,
|
|
50
|
+
const file = (0, import_utils.storagePathJoin)(".upgrading");
|
|
52
51
|
const upgrading = await import_fs_extra.default.exists(file);
|
|
53
52
|
if (upgrading) {
|
|
54
53
|
if (!process.env.VITEST) {
|
|
55
54
|
if (await app.isInstalled()) {
|
|
56
|
-
await (0, import_create_docs_index.createDocsIndex)(app);
|
|
57
55
|
await app.upgrade();
|
|
58
56
|
}
|
|
59
57
|
}
|
|
@@ -62,7 +60,6 @@ var start_default = /* @__PURE__ */ __name((app) => {
|
|
|
62
60
|
} catch (error) {
|
|
63
61
|
}
|
|
64
62
|
} else if (options.quickstart) {
|
|
65
|
-
await (0, import_create_docs_index.createDocsIndex)(app);
|
|
66
63
|
if (await app.isInstalled()) {
|
|
67
64
|
await app.upgrade({ quickstart: true });
|
|
68
65
|
} else {
|
package/lib/commands/upgrade.js
CHANGED
|
@@ -30,11 +30,9 @@ __export(upgrade_exports, {
|
|
|
30
30
|
default: () => upgrade_default
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(upgrade_exports);
|
|
33
|
-
var import_create_docs_index = require("../ai/create-docs-index");
|
|
34
33
|
/* istanbul ignore file -- @preserve */
|
|
35
34
|
var upgrade_default = /* @__PURE__ */ __name((app) => {
|
|
36
35
|
app.command("upgrade").ipc().auth().action(async (options) => {
|
|
37
|
-
await (0, import_create_docs_index.createDocsIndex)(app);
|
|
38
36
|
await app.upgrade(options);
|
|
39
37
|
app.log.info(`\u2728 NocoBase has been upgraded to v${app.getVersion()}`);
|
|
40
38
|
});
|
|
@@ -6,8 +6,4 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
export type DocsIndexOptions = {
|
|
11
|
-
pkg?: string | string[];
|
|
12
|
-
};
|
|
13
|
-
export declare function createDocsIndex(app: Application, options?: DocsIndexOptions): Promise<void>;
|
|
9
|
+
export declare const OFFICIAL_PLUGIN_PREFIX = "@nocobase/plugin-";
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var constants_exports = {};
|
|
28
|
+
__export(constants_exports, {
|
|
29
|
+
OFFICIAL_PLUGIN_PREFIX: () => OFFICIAL_PLUGIN_PREFIX
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(constants_exports);
|
|
32
|
+
const OFFICIAL_PLUGIN_PREFIX = "@nocobase/plugin-";
|
|
33
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
34
|
+
0 && (module.exports = {
|
|
35
|
+
OFFICIAL_PLUGIN_PREFIX
|
|
36
|
+
});
|
package/lib/event-queue.js
CHANGED
|
@@ -71,7 +71,7 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
71
71
|
return null;
|
|
72
72
|
}
|
|
73
73
|
get storagePath() {
|
|
74
|
-
return
|
|
74
|
+
return (0, import_utils.storagePathJoin)("apps", this.options.appName, "event-queue.json");
|
|
75
75
|
}
|
|
76
76
|
listen = /* @__PURE__ */ __name((channel) => {
|
|
77
77
|
if (!this.connected) {
|
package/lib/gateway/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { IPCSocketClient } from './ipc-socket-client';
|
|
|
19
19
|
import { IPCSocketServer } from './ipc-socket-server';
|
|
20
20
|
import { WSServer } from './ws-server';
|
|
21
21
|
import { Duplex } from 'node:stream';
|
|
22
|
+
export { getHost, getHostname } from './utils';
|
|
22
23
|
export interface IncomingRequest {
|
|
23
24
|
url: string;
|
|
24
25
|
headers: any;
|
|
@@ -40,7 +41,7 @@ interface RunOptions {
|
|
|
40
41
|
mainAppOptions: ApplicationOptions;
|
|
41
42
|
}
|
|
42
43
|
export interface AppSelectorMiddlewareContext {
|
|
43
|
-
req: IncomingRequest;
|
|
44
|
+
req: IncomingMessage | IncomingRequest;
|
|
44
45
|
resolvedAppName: string | null;
|
|
45
46
|
}
|
|
46
47
|
export declare class Gateway extends EventEmitter {
|
|
@@ -57,7 +58,10 @@ export declare class Gateway extends EventEmitter {
|
|
|
57
58
|
private port;
|
|
58
59
|
private host;
|
|
59
60
|
private socketPath;
|
|
61
|
+
private v2IndexTemplateCache;
|
|
60
62
|
private terminating;
|
|
63
|
+
private getOriginalRequestUrl;
|
|
64
|
+
private proxyRequestToSubApp;
|
|
61
65
|
private onTerminate;
|
|
62
66
|
private constructor();
|
|
63
67
|
static getInstance(options?: any): Gateway;
|
|
@@ -74,9 +78,18 @@ export declare class Gateway extends EventEmitter {
|
|
|
74
78
|
code: string;
|
|
75
79
|
}): void;
|
|
76
80
|
responseErrorWithCode(code: any, res: any, options: any): void;
|
|
81
|
+
private getV2PublicPath;
|
|
82
|
+
private getAppPublicPath;
|
|
83
|
+
private isV2Request;
|
|
84
|
+
private isV2IndexRequest;
|
|
85
|
+
private getV2RuntimeConfig;
|
|
86
|
+
private getV2RuntimeConfigScript;
|
|
87
|
+
private getV2AssetPublicPath;
|
|
88
|
+
private getV2IndexTemplate;
|
|
89
|
+
private renderV2IndexHtml;
|
|
77
90
|
requestHandler(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
78
91
|
getAppSelectorMiddlewares(): Toposort<AppSelectorMiddleware>;
|
|
79
|
-
getRequestHandleAppName(req: IncomingRequest): Promise<string>;
|
|
92
|
+
getRequestHandleAppName(req: IncomingMessage | IncomingRequest): Promise<string>;
|
|
80
93
|
getCallback(): any;
|
|
81
94
|
watch(): Promise<void>;
|
|
82
95
|
run(options: RunOptions): Promise<void>;
|
|
@@ -96,4 +109,3 @@ export declare class Gateway extends EventEmitter {
|
|
|
96
109
|
static registerWsHandler(wsServer: (req: IncomingMessage, socket: Duplex, head: Buffer, app: Application) => boolean | void): void;
|
|
97
110
|
static unregisterWsHandler(wsServer: (req: IncomingMessage, socket: Duplex, head: Buffer, app: Application) => boolean | void): void;
|
|
98
111
|
}
|
|
99
|
-
export {};
|
package/lib/gateway/index.js
CHANGED
|
@@ -39,7 +39,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
39
39
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
40
40
|
var gateway_exports = {};
|
|
41
41
|
__export(gateway_exports, {
|
|
42
|
-
Gateway: () => Gateway
|
|
42
|
+
Gateway: () => Gateway,
|
|
43
|
+
getHost: () => import_utils4.getHost,
|
|
44
|
+
getHostname: () => import_utils4.getHostname
|
|
43
45
|
});
|
|
44
46
|
module.exports = __toCommonJS(gateway_exports);
|
|
45
47
|
var import_logger = require("@nocobase/logger");
|
|
@@ -54,6 +56,7 @@ var import_fs = __toESM(require("fs"));
|
|
|
54
56
|
var import_http = __toESM(require("http"));
|
|
55
57
|
var import_koa_compose = __toESM(require("koa-compose"));
|
|
56
58
|
var import_node_util = require("node:util");
|
|
59
|
+
var import_node_os = require("node:os");
|
|
57
60
|
var import_path = require("path");
|
|
58
61
|
var import_qs = __toESM(require("qs"));
|
|
59
62
|
var import_serve_handler = __toESM(require("serve-handler"));
|
|
@@ -63,16 +66,27 @@ var import_plugin_manager = require("../plugin-manager");
|
|
|
63
66
|
var import_errors = require("./errors");
|
|
64
67
|
var import_ipc_socket_client = require("./ipc-socket-client");
|
|
65
68
|
var import_ipc_socket_server = require("./ipc-socket-server");
|
|
69
|
+
var import_static_file_security = require("./static-file-security");
|
|
70
|
+
var import_utils3 = require("./utils");
|
|
66
71
|
var import_ws_server = require("./ws-server");
|
|
67
72
|
var import_node_worker_threads = require("node:worker_threads");
|
|
68
73
|
var import_node_process = __toESM(require("node:process"));
|
|
74
|
+
var import_utils4 = require("./utils");
|
|
69
75
|
const compress = (0, import_node_util.promisify)((0, import_compression.default)());
|
|
76
|
+
function normalizeBasePath(path = "") {
|
|
77
|
+
const normalized = path.replace(/\/+/g, "/").replace(/\/$/, "");
|
|
78
|
+
return normalized || "/";
|
|
79
|
+
}
|
|
80
|
+
__name(normalizeBasePath, "normalizeBasePath");
|
|
70
81
|
function getSocketPath() {
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
73
|
-
return
|
|
82
|
+
const socketPath = import_node_process.default.env.SOCKET_PATH;
|
|
83
|
+
if (socketPath) {
|
|
84
|
+
return (0, import_path.isAbsolute)(socketPath) ? socketPath : (0, import_path.resolve)(import_node_process.default.cwd(), socketPath);
|
|
85
|
+
}
|
|
86
|
+
if (import_node_process.default.env.NOCOBASE_RUNNING_IN_DOCKER === "true") {
|
|
87
|
+
return (0, import_path.resolve)((0, import_node_os.homedir)(), ".nocobase", "gateway.sock");
|
|
74
88
|
}
|
|
75
|
-
return (0,
|
|
89
|
+
return (0, import_utils.storagePathJoin)("gateway.sock");
|
|
76
90
|
}
|
|
77
91
|
__name(getSocketPath, "getSocketPath");
|
|
78
92
|
const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
@@ -87,8 +101,21 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
87
101
|
loggers = new import_utils.Registry();
|
|
88
102
|
port = import_node_process.default.env.APP_PORT ? parseInt(import_node_process.default.env.APP_PORT) : null;
|
|
89
103
|
host = "0.0.0.0";
|
|
90
|
-
socketPath = (
|
|
104
|
+
socketPath = getSocketPath();
|
|
105
|
+
v2IndexTemplateCache = null;
|
|
91
106
|
terminating = false;
|
|
107
|
+
getOriginalRequestUrl(req) {
|
|
108
|
+
return req.originalUrl || req.url;
|
|
109
|
+
}
|
|
110
|
+
async proxyRequestToSubApp(supervisor, appName, req, res) {
|
|
111
|
+
const internalUrl = req.url;
|
|
112
|
+
req.url = this.getOriginalRequestUrl(req);
|
|
113
|
+
try {
|
|
114
|
+
return await supervisor.proxyWeb(appName, req, res);
|
|
115
|
+
} finally {
|
|
116
|
+
req.url = internalUrl;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
92
119
|
onTerminate = /* @__PURE__ */ __name(async (signal) => {
|
|
93
120
|
var _a;
|
|
94
121
|
if (this.terminating) {
|
|
@@ -119,7 +146,6 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
119
146
|
constructor() {
|
|
120
147
|
super();
|
|
121
148
|
this.reset();
|
|
122
|
-
this.socketPath = getSocketPath();
|
|
123
149
|
import_node_process.default.once("SIGTERM", this.onTerminate);
|
|
124
150
|
import_node_process.default.once("SIGINT", this.onTerminate);
|
|
125
151
|
}
|
|
@@ -151,14 +177,30 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
151
177
|
this.selectorMiddlewares = new import_utils.Toposort();
|
|
152
178
|
this.addAppSelectorMiddleware(
|
|
153
179
|
async (ctx, next) => {
|
|
154
|
-
var _a;
|
|
180
|
+
var _a, _b;
|
|
155
181
|
const { req } = ctx;
|
|
156
|
-
const
|
|
182
|
+
const parsedUrl = (0, import_url.parse)(req.url);
|
|
183
|
+
const appName = (_a = import_qs.default.parse(parsedUrl.query)) == null ? void 0 : _a.__appName;
|
|
184
|
+
const apiBasePath = normalizeBasePath(import_node_process.default.env.API_BASE_PATH || "/api");
|
|
185
|
+
const appPathPrefix = `${apiBasePath}/__app/`;
|
|
186
|
+
if (req.headers["x-app"]) {
|
|
187
|
+
ctx.resolvedAppName = req.headers["x-app"];
|
|
188
|
+
}
|
|
157
189
|
if (appName) {
|
|
158
190
|
ctx.resolvedAppName = appName;
|
|
159
191
|
}
|
|
160
|
-
if (
|
|
161
|
-
|
|
192
|
+
if ((_b = parsedUrl.pathname) == null ? void 0 : _b.startsWith(appPathPrefix)) {
|
|
193
|
+
const restPath = parsedUrl.pathname.slice(appPathPrefix.length);
|
|
194
|
+
const [pathAppName, ...segments] = restPath.split("/");
|
|
195
|
+
if (pathAppName) {
|
|
196
|
+
ctx.resolvedAppName = pathAppName;
|
|
197
|
+
const rewrittenPath = `${apiBasePath}${segments.length ? `/${segments.join("/")}` : ""}`;
|
|
198
|
+
const rewrittenUrl = `${rewrittenPath}${parsedUrl.search || ""}`;
|
|
199
|
+
if (!req.originalUrl) {
|
|
200
|
+
req.originalUrl = req.url;
|
|
201
|
+
}
|
|
202
|
+
req.url = rewrittenUrl;
|
|
203
|
+
}
|
|
162
204
|
}
|
|
163
205
|
await next();
|
|
164
206
|
},
|
|
@@ -222,9 +264,81 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
222
264
|
});
|
|
223
265
|
this.responseError(res, error);
|
|
224
266
|
}
|
|
267
|
+
getV2PublicPath() {
|
|
268
|
+
return (0, import_utils3.resolveV2PublicPath)(import_node_process.default.env.APP_PUBLIC_PATH || "/");
|
|
269
|
+
}
|
|
270
|
+
getAppPublicPath() {
|
|
271
|
+
return (0, import_utils3.resolvePublicPath)(import_node_process.default.env.APP_PUBLIC_PATH || "/");
|
|
272
|
+
}
|
|
273
|
+
isV2Request(pathname) {
|
|
274
|
+
const v2PublicPath = this.getV2PublicPath();
|
|
275
|
+
return pathname === v2PublicPath.slice(0, -1) || pathname.startsWith(v2PublicPath);
|
|
276
|
+
}
|
|
277
|
+
isV2IndexRequest(pathname) {
|
|
278
|
+
if (!this.isV2Request(pathname)) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
const v2PublicPath = this.getV2PublicPath();
|
|
282
|
+
if (pathname === v2PublicPath || pathname === v2PublicPath.slice(0, -1) || pathname === `${v2PublicPath}index.html`) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
return !(0, import_path.extname)(pathname);
|
|
286
|
+
}
|
|
287
|
+
getV2RuntimeConfig() {
|
|
288
|
+
return {
|
|
289
|
+
__nocobase_public_path__: this.getV2PublicPath(),
|
|
290
|
+
__webpack_public_path__: import_node_process.default.env.CDN_BASE_URL ? `${import_node_process.default.env.CDN_BASE_URL.replace(/\/+$/, "")}/` : "",
|
|
291
|
+
__nocobase_api_base_url__: import_node_process.default.env.API_BASE_URL || import_node_process.default.env.API_BASE_PATH,
|
|
292
|
+
__nocobase_api_client_storage_prefix__: import_node_process.default.env.API_CLIENT_STORAGE_PREFIX,
|
|
293
|
+
__nocobase_api_client_storage_type__: import_node_process.default.env.API_CLIENT_STORAGE_TYPE,
|
|
294
|
+
__nocobase_api_client_share_token__: import_node_process.default.env.API_CLIENT_SHARE_TOKEN === "true",
|
|
295
|
+
__nocobase_ws_url__: import_node_process.default.env.WEBSOCKET_URL || "",
|
|
296
|
+
__nocobase_ws_path__: import_node_process.default.env.WS_PATH,
|
|
297
|
+
__nocobase_app_dev__: import_node_process.default.env.NOCOBASE_APP_DEV === "true",
|
|
298
|
+
__esm_cdn_base_url__: import_node_process.default.env.ESM_CDN_BASE_URL || "https://esm.sh",
|
|
299
|
+
__esm_cdn_suffix__: import_node_process.default.env.ESM_CDN_SUFFIX || ""
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
getV2RuntimeConfigScript() {
|
|
303
|
+
const runtimeConfig = this.getV2RuntimeConfig();
|
|
304
|
+
const scriptContent = Object.entries(runtimeConfig).map(([key, value]) => `window['${key}'] = ${JSON.stringify(value)};`).join("\n");
|
|
305
|
+
return `<script>${scriptContent}</script>`;
|
|
306
|
+
}
|
|
307
|
+
getV2AssetPublicPath() {
|
|
308
|
+
if (import_node_process.default.env.CDN_BASE_URL) {
|
|
309
|
+
return `${import_node_process.default.env.CDN_BASE_URL.replace(/\/+$/, "")}/v2/`;
|
|
310
|
+
}
|
|
311
|
+
return this.getV2PublicPath();
|
|
312
|
+
}
|
|
313
|
+
getV2IndexTemplate() {
|
|
314
|
+
const file = `${import_node_process.default.env.APP_PACKAGE_ROOT}/dist/client/v2/index.html`;
|
|
315
|
+
if (!import_fs.default.existsSync(file)) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
const stat = import_fs.default.statSync(file);
|
|
319
|
+
if (this.v2IndexTemplateCache && this.v2IndexTemplateCache.file === file && this.v2IndexTemplateCache.mtimeMs === stat.mtimeMs) {
|
|
320
|
+
return this.v2IndexTemplateCache.html;
|
|
321
|
+
}
|
|
322
|
+
const html = import_fs.default.readFileSync(file, "utf-8");
|
|
323
|
+
this.v2IndexTemplateCache = {
|
|
324
|
+
file,
|
|
325
|
+
mtimeMs: stat.mtimeMs,
|
|
326
|
+
html
|
|
327
|
+
};
|
|
328
|
+
return html;
|
|
329
|
+
}
|
|
330
|
+
renderV2IndexHtml() {
|
|
331
|
+
const template = this.getV2IndexTemplate();
|
|
332
|
+
if (!template) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
const html = (0, import_utils3.rewriteV2AssetPublicPath)(template, this.getV2AssetPublicPath());
|
|
336
|
+
return (0, import_utils3.injectRuntimeScript)(html, this.getV2RuntimeConfigScript());
|
|
337
|
+
}
|
|
225
338
|
async requestHandler(req, res) {
|
|
226
339
|
const { pathname } = (0, import_url.parse)(req.url);
|
|
227
|
-
const { PLUGIN_STATICS_PATH
|
|
340
|
+
const { PLUGIN_STATICS_PATH } = import_node_process.default.env;
|
|
341
|
+
const APP_PUBLIC_PATH = this.getAppPublicPath();
|
|
228
342
|
if (pathname.endsWith("/__umi/api/bundle-status")) {
|
|
229
343
|
res.statusCode = 200;
|
|
230
344
|
res.end("ok");
|
|
@@ -241,21 +355,25 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
241
355
|
}
|
|
242
356
|
if (pathname.startsWith(APP_PUBLIC_PATH + "storage/uploads/")) {
|
|
243
357
|
if (handleApp !== "main") {
|
|
244
|
-
const isProxy = await
|
|
358
|
+
const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
|
|
245
359
|
if (isProxy) {
|
|
246
360
|
return;
|
|
247
361
|
}
|
|
248
362
|
}
|
|
249
|
-
|
|
363
|
+
const headers = (0, import_static_file_security.getStorageUploadSecurityHeaders)(pathname);
|
|
364
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
365
|
+
res.setHeader(key, value);
|
|
366
|
+
}
|
|
367
|
+
req.url = req.url.substring(APP_PUBLIC_PATH.length + "storage".length);
|
|
250
368
|
await compress(req, res);
|
|
251
369
|
return (0, import_serve_handler.default)(req, res, {
|
|
252
|
-
public: (0,
|
|
370
|
+
public: (0, import_utils.resolveStorageRoot)(),
|
|
253
371
|
directoryListing: false
|
|
254
372
|
});
|
|
255
373
|
}
|
|
256
374
|
if (pathname.startsWith(PLUGIN_STATICS_PATH) && !pathname.includes("/server/")) {
|
|
257
375
|
if (handleApp !== "main") {
|
|
258
|
-
const isProxy = await
|
|
376
|
+
const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
|
|
259
377
|
if (isProxy) {
|
|
260
378
|
return;
|
|
261
379
|
}
|
|
@@ -275,8 +393,29 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
275
393
|
});
|
|
276
394
|
}
|
|
277
395
|
if (!pathname.startsWith(import_node_process.default.env.API_BASE_PATH)) {
|
|
396
|
+
if (this.isV2Request(pathname)) {
|
|
397
|
+
if (handleApp !== "main") {
|
|
398
|
+
const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
|
|
399
|
+
if (isProxy) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (this.isV2IndexRequest(pathname)) {
|
|
404
|
+
const v2Html = this.renderV2IndexHtml();
|
|
405
|
+
if (v2Html) {
|
|
406
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
407
|
+
res.end(v2Html);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
req.url = req.url.substring(APP_PUBLIC_PATH.length - 1);
|
|
412
|
+
await compress(req, res);
|
|
413
|
+
return (0, import_serve_handler.default)(req, res, {
|
|
414
|
+
public: `${import_node_process.default.env.APP_PACKAGE_ROOT}/dist/client`
|
|
415
|
+
});
|
|
416
|
+
}
|
|
278
417
|
if (handleApp !== "main") {
|
|
279
|
-
const isProxy = await
|
|
418
|
+
const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
|
|
280
419
|
if (isProxy) {
|
|
281
420
|
return;
|
|
282
421
|
}
|
|
@@ -289,7 +428,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
289
428
|
});
|
|
290
429
|
}
|
|
291
430
|
if (handleApp !== "main") {
|
|
292
|
-
const isProxy = await
|
|
431
|
+
const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
|
|
293
432
|
if (isProxy) {
|
|
294
433
|
return;
|
|
295
434
|
}
|
|
@@ -399,7 +538,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
399
538
|
}
|
|
400
539
|
}
|
|
401
540
|
if (isStart || !ipcClient) {
|
|
402
|
-
await (0, import_plugin_symlink.
|
|
541
|
+
await (0, import_plugin_symlink.syncPluginSymlinks)();
|
|
403
542
|
}
|
|
404
543
|
const mainApp = import_app_supervisor.AppSupervisor.getInstance().bootMainApp(options.mainAppOptions);
|
|
405
544
|
mainApp.setMaxListeners(50);
|
|
@@ -541,5 +680,7 @@ __publicField(_Gateway, "wsServers", []);
|
|
|
541
680
|
let Gateway = _Gateway;
|
|
542
681
|
// Annotate the CommonJS export names for ESM import in node:
|
|
543
682
|
0 && (module.exports = {
|
|
544
|
-
Gateway
|
|
683
|
+
Gateway,
|
|
684
|
+
getHost,
|
|
685
|
+
getHostname
|
|
545
686
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
export declare function hasActiveContentExtension(pathname?: string): boolean;
|
|
10
|
+
export declare function getStorageUploadSecurityHeaders(pathname?: string): Record<string, string>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
17
|
+
var __export = (target, all) => {
|
|
18
|
+
for (var name in all)
|
|
19
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
20
|
+
};
|
|
21
|
+
var __copyProps = (to, from, except, desc) => {
|
|
22
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
23
|
+
for (let key of __getOwnPropNames(from))
|
|
24
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
25
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
26
|
+
}
|
|
27
|
+
return to;
|
|
28
|
+
};
|
|
29
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
30
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
31
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
32
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
33
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
34
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
35
|
+
mod
|
|
36
|
+
));
|
|
37
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
|
+
var static_file_security_exports = {};
|
|
39
|
+
__export(static_file_security_exports, {
|
|
40
|
+
getStorageUploadSecurityHeaders: () => getStorageUploadSecurityHeaders,
|
|
41
|
+
hasActiveContentExtension: () => hasActiveContentExtension
|
|
42
|
+
});
|
|
43
|
+
module.exports = __toCommonJS(static_file_security_exports);
|
|
44
|
+
var import_node_path = __toESM(require("node:path"));
|
|
45
|
+
const ACTIVE_CONTENT_EXTENSIONS = /* @__PURE__ */ new Set([".htm", ".html", ".pdf", ".svg", ".svgz", ".xhtml"]);
|
|
46
|
+
function stripQueryAndHash(pathname = "") {
|
|
47
|
+
return pathname.split("?")[0].split("#")[0];
|
|
48
|
+
}
|
|
49
|
+
__name(stripQueryAndHash, "stripQueryAndHash");
|
|
50
|
+
function hasActiveContentExtension(pathname = "") {
|
|
51
|
+
const ext = import_node_path.default.extname(stripQueryAndHash(pathname)).toLowerCase();
|
|
52
|
+
return ACTIVE_CONTENT_EXTENSIONS.has(ext);
|
|
53
|
+
}
|
|
54
|
+
__name(hasActiveContentExtension, "hasActiveContentExtension");
|
|
55
|
+
function getStorageUploadSecurityHeaders(pathname = "") {
|
|
56
|
+
const headers = {
|
|
57
|
+
"X-Content-Type-Options": "nosniff"
|
|
58
|
+
};
|
|
59
|
+
if (hasActiveContentExtension(pathname)) {
|
|
60
|
+
headers["Content-Disposition"] = "attachment";
|
|
61
|
+
}
|
|
62
|
+
return headers;
|
|
63
|
+
}
|
|
64
|
+
__name(getStorageUploadSecurityHeaders, "getStorageUploadSecurityHeaders");
|
|
65
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
66
|
+
0 && (module.exports = {
|
|
67
|
+
getStorageUploadSecurityHeaders,
|
|
68
|
+
hasActiveContentExtension
|
|
69
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
/// <reference types="node" />
|
|
10
|
+
import { IncomingMessage } from 'http';
|
|
11
|
+
import { IncomingRequest } from '.';
|
|
12
|
+
export declare function resolvePublicPath(appPublicPath?: string): string;
|
|
13
|
+
export declare function resolveV2PublicPath(appPublicPath?: string): string;
|
|
14
|
+
export declare function rewriteV2AssetPublicPath(html: string, assetPublicPath: string): string;
|
|
15
|
+
export declare function injectRuntimeScript(html: string, runtimeScript: string): string;
|
|
16
|
+
export declare function getHost(req: IncomingMessage | IncomingRequest): any;
|
|
17
|
+
export declare function getHostname(req: IncomingMessage | IncomingRequest): any;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var utils_exports = {};
|
|
29
|
+
__export(utils_exports, {
|
|
30
|
+
getHost: () => getHost,
|
|
31
|
+
getHostname: () => getHostname,
|
|
32
|
+
injectRuntimeScript: () => injectRuntimeScript,
|
|
33
|
+
resolvePublicPath: () => resolvePublicPath,
|
|
34
|
+
resolveV2PublicPath: () => resolveV2PublicPath,
|
|
35
|
+
rewriteV2AssetPublicPath: () => rewriteV2AssetPublicPath
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(utils_exports);
|
|
38
|
+
function resolvePublicPath(appPublicPath = "/") {
|
|
39
|
+
const normalized = String(appPublicPath || "/").trim() || "/";
|
|
40
|
+
const withLeadingSlash = normalized.startsWith("/") ? normalized : `/${normalized}`;
|
|
41
|
+
return withLeadingSlash.endsWith("/") ? withLeadingSlash : `${withLeadingSlash}/`;
|
|
42
|
+
}
|
|
43
|
+
__name(resolvePublicPath, "resolvePublicPath");
|
|
44
|
+
function resolveV2PublicPath(appPublicPath = "/") {
|
|
45
|
+
const publicPath = resolvePublicPath(appPublicPath);
|
|
46
|
+
return `${publicPath.replace(/\/$/, "")}/v2/`;
|
|
47
|
+
}
|
|
48
|
+
__name(resolveV2PublicPath, "resolveV2PublicPath");
|
|
49
|
+
function ensureTrailingSlash(value) {
|
|
50
|
+
return value.endsWith("/") ? value : `${value}/`;
|
|
51
|
+
}
|
|
52
|
+
__name(ensureTrailingSlash, "ensureTrailingSlash");
|
|
53
|
+
function rewriteV2AssetPublicPath(html, assetPublicPath) {
|
|
54
|
+
const normalizedAssetPublicPath = ensureTrailingSlash(assetPublicPath);
|
|
55
|
+
if (normalizedAssetPublicPath === "/v2/") {
|
|
56
|
+
return html;
|
|
57
|
+
}
|
|
58
|
+
return html.replace(/((?:src|href)=["'])\/v2\//g, `$1${normalizedAssetPublicPath}`);
|
|
59
|
+
}
|
|
60
|
+
__name(rewriteV2AssetPublicPath, "rewriteV2AssetPublicPath");
|
|
61
|
+
function injectRuntimeScript(html, runtimeScript) {
|
|
62
|
+
const browserCheckerScriptMatch = html.match(/<script\b[^>]*browser-checker\.js[^>]*><\/script>/i);
|
|
63
|
+
if (browserCheckerScriptMatch == null ? void 0 : browserCheckerScriptMatch[0]) {
|
|
64
|
+
return html.replace(browserCheckerScriptMatch[0], `${runtimeScript}
|
|
65
|
+
${browserCheckerScriptMatch[0]}`);
|
|
66
|
+
}
|
|
67
|
+
const moduleScriptMatch = html.match(/<script\b[^>]*type=["']module["'][^>]*>/i);
|
|
68
|
+
if (moduleScriptMatch == null ? void 0 : moduleScriptMatch[0]) {
|
|
69
|
+
return html.replace(moduleScriptMatch[0], `${runtimeScript}
|
|
70
|
+
${moduleScriptMatch[0]}`);
|
|
71
|
+
}
|
|
72
|
+
if (html.includes("</head>")) {
|
|
73
|
+
return html.replace("</head>", `${runtimeScript}
|
|
74
|
+
</head>`);
|
|
75
|
+
}
|
|
76
|
+
return `${runtimeScript}
|
|
77
|
+
${html}`;
|
|
78
|
+
}
|
|
79
|
+
__name(injectRuntimeScript, "injectRuntimeScript");
|
|
80
|
+
function splitCommaSeparatedValues(value, limit) {
|
|
81
|
+
return value.split(",", limit).map((v) => v.trim());
|
|
82
|
+
}
|
|
83
|
+
__name(splitCommaSeparatedValues, "splitCommaSeparatedValues");
|
|
84
|
+
function getHost(req) {
|
|
85
|
+
let host = req.headers["x-forwarded-host"];
|
|
86
|
+
if (!host) {
|
|
87
|
+
host = req.headers[":authority"] || req.headers["host"];
|
|
88
|
+
}
|
|
89
|
+
if (!host) return "";
|
|
90
|
+
host = splitCommaSeparatedValues(host, 1)[0];
|
|
91
|
+
if (host.includes("@")) {
|
|
92
|
+
try {
|
|
93
|
+
host = new URL(`http://${host}`).host;
|
|
94
|
+
} catch (e) {
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return host;
|
|
99
|
+
}
|
|
100
|
+
__name(getHost, "getHost");
|
|
101
|
+
function getHostname(req) {
|
|
102
|
+
const host = getHost(req);
|
|
103
|
+
if (!host) return "";
|
|
104
|
+
return host.split(":", 1)[0];
|
|
105
|
+
}
|
|
106
|
+
__name(getHostname, "getHostname");
|
|
107
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
108
|
+
0 && (module.exports = {
|
|
109
|
+
getHost,
|
|
110
|
+
getHostname,
|
|
111
|
+
injectRuntimeScript,
|
|
112
|
+
resolvePublicPath,
|
|
113
|
+
resolveV2PublicPath,
|
|
114
|
+
rewriteV2AssetPublicPath
|
|
115
|
+
});
|