@nocobase/server 1.6.0-alpha.7 → 1.6.0-alpha.8
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/lib/application.d.ts +2 -0
- package/lib/application.js +6 -1
- package/lib/gateway/index.js +81 -23
- package/lib/gateway/ws-server.d.ts +16 -2
- package/lib/gateway/ws-server.js +45 -7
- package/lib/plugin-manager/plugin-manager.js +2 -2
- package/lib/service-container.d.ts +5 -0
- package/lib/service-container.js +50 -0
- package/package.json +15 -15
package/lib/application.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { Plugin } from './plugin';
|
|
|
31
31
|
import { InstallOptions, PluginManager } from './plugin-manager';
|
|
32
32
|
import { PubSubManager, PubSubManagerOptions } from './pub-sub-manager';
|
|
33
33
|
import { SyncMessageManager } from './sync-message-manager';
|
|
34
|
+
import { ServiceContainer } from './service-container';
|
|
34
35
|
import { AuditManager } from './audit-manager';
|
|
35
36
|
export type PluginType = string | typeof Plugin;
|
|
36
37
|
export type PluginConfiguration = PluginType | [PluginType, any];
|
|
@@ -169,6 +170,7 @@ export declare class Application<StateT = DefaultState, ContextT = DefaultContex
|
|
|
169
170
|
private _maintainingCommandStatus;
|
|
170
171
|
private _maintainingStatusBeforeCommand;
|
|
171
172
|
private _actionCommand;
|
|
173
|
+
container: ServiceContainer;
|
|
172
174
|
lockManager: LockManager;
|
|
173
175
|
constructor(options: ApplicationOptions);
|
|
174
176
|
private static staticCommands;
|
package/lib/application.js
CHANGED
|
@@ -76,6 +76,7 @@ var import_plugin_manager = require("./plugin-manager");
|
|
|
76
76
|
var import_pub_sub_manager = require("./pub-sub-manager");
|
|
77
77
|
var import_sync_message_manager = require("./sync-message-manager");
|
|
78
78
|
var import_package = __toESM(require("../package.json"));
|
|
79
|
+
var import_service_container = require("./service-container");
|
|
79
80
|
var import_available_action = require("./acl/available-action");
|
|
80
81
|
var import_audit_manager = require("./audit-manager");
|
|
81
82
|
const _Application = class _Application extends import_koa.default {
|
|
@@ -126,6 +127,7 @@ const _Application = class _Application extends import_koa.default {
|
|
|
126
127
|
_maintainingCommandStatus;
|
|
127
128
|
_maintainingStatusBeforeCommand;
|
|
128
129
|
_actionCommand;
|
|
130
|
+
container = new import_service_container.ServiceContainer();
|
|
129
131
|
lockManager;
|
|
130
132
|
static addCommand(callback) {
|
|
131
133
|
this.staticCommands.push(callback);
|
|
@@ -371,7 +373,10 @@ const _Application = class _Application extends import_koa.default {
|
|
|
371
373
|
this._loaded = false;
|
|
372
374
|
}
|
|
373
375
|
async createCacheManager() {
|
|
374
|
-
this._cacheManager = await (0, import_cache2.createCacheManager)(this,
|
|
376
|
+
this._cacheManager = await (0, import_cache2.createCacheManager)(this, {
|
|
377
|
+
prefix: this.name,
|
|
378
|
+
...this.options.cacheManager
|
|
379
|
+
});
|
|
375
380
|
return this._cacheManager;
|
|
376
381
|
}
|
|
377
382
|
async load(options) {
|
package/lib/gateway/index.js
CHANGED
|
@@ -63,6 +63,8 @@ var import_errors = require("./errors");
|
|
|
63
63
|
var import_ipc_socket_client = require("./ipc-socket-client");
|
|
64
64
|
var import_ipc_socket_server = require("./ipc-socket-server");
|
|
65
65
|
var import_ws_server = require("./ws-server");
|
|
66
|
+
var import_node_worker_threads = require("node:worker_threads");
|
|
67
|
+
var import_node_process = __toESM(require("node:process"));
|
|
66
68
|
const compress = (0, import_node_util.promisify)((0, import_compression.default)());
|
|
67
69
|
const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
68
70
|
/**
|
|
@@ -72,15 +74,15 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
72
74
|
server = null;
|
|
73
75
|
ipcSocketServer = null;
|
|
74
76
|
loggers = new import_utils.Registry();
|
|
75
|
-
port =
|
|
77
|
+
port = import_node_process.default.env.APP_PORT ? parseInt(import_node_process.default.env.APP_PORT) : null;
|
|
76
78
|
host = "0.0.0.0";
|
|
77
79
|
wsServer;
|
|
78
|
-
socketPath = (0, import_path.resolve)(
|
|
80
|
+
socketPath = (0, import_path.resolve)(import_node_process.default.cwd(), "storage", "gateway.sock");
|
|
79
81
|
constructor() {
|
|
80
82
|
super();
|
|
81
83
|
this.reset();
|
|
82
|
-
if (
|
|
83
|
-
this.socketPath = (0, import_path.resolve)(
|
|
84
|
+
if (import_node_process.default.env.SOCKET_PATH) {
|
|
85
|
+
this.socketPath = (0, import_path.resolve)(import_node_process.default.cwd(), import_node_process.default.env.SOCKET_PATH);
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
static getInstance(options = {}) {
|
|
@@ -90,7 +92,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
90
92
|
return _Gateway.instance;
|
|
91
93
|
}
|
|
92
94
|
static async getIPCSocketClient() {
|
|
93
|
-
const socketPath = (0, import_path.resolve)(
|
|
95
|
+
const socketPath = (0, import_path.resolve)(import_node_process.default.cwd(), import_node_process.default.env.SOCKET_PATH || "storage/gateway.sock");
|
|
94
96
|
try {
|
|
95
97
|
return await import_ipc_socket_client.IPCSocketClient.getConnection(socketPath);
|
|
96
98
|
} catch (error) {
|
|
@@ -166,7 +168,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
166
168
|
}
|
|
167
169
|
async requestHandler(req, res) {
|
|
168
170
|
const { pathname } = (0, import_url.parse)(req.url);
|
|
169
|
-
const { PLUGIN_STATICS_PATH, APP_PUBLIC_PATH } =
|
|
171
|
+
const { PLUGIN_STATICS_PATH, APP_PUBLIC_PATH } = import_node_process.default.env;
|
|
170
172
|
if (pathname.endsWith("/__umi/api/bundle-status")) {
|
|
171
173
|
res.statusCode = 200;
|
|
172
174
|
res.end("ok");
|
|
@@ -176,7 +178,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
176
178
|
req.url = req.url.substring(APP_PUBLIC_PATH.length - 1);
|
|
177
179
|
await compress(req, res);
|
|
178
180
|
return (0, import_serve_handler.default)(req, res, {
|
|
179
|
-
public: (0, import_path.resolve)(
|
|
181
|
+
public: (0, import_path.resolve)(import_node_process.default.cwd()),
|
|
180
182
|
directoryListing: false
|
|
181
183
|
});
|
|
182
184
|
}
|
|
@@ -195,15 +197,22 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
195
197
|
]
|
|
196
198
|
});
|
|
197
199
|
}
|
|
198
|
-
if (!pathname.startsWith(
|
|
200
|
+
if (!pathname.startsWith(import_node_process.default.env.API_BASE_PATH)) {
|
|
199
201
|
req.url = req.url.substring(APP_PUBLIC_PATH.length - 1);
|
|
200
202
|
await compress(req, res);
|
|
201
203
|
return (0, import_serve_handler.default)(req, res, {
|
|
202
|
-
public: `${
|
|
204
|
+
public: `${import_node_process.default.env.APP_PACKAGE_ROOT}/dist/client`,
|
|
203
205
|
rewrites: [{ source: "/**", destination: "/index.html" }]
|
|
204
206
|
});
|
|
205
207
|
}
|
|
206
|
-
|
|
208
|
+
let handleApp = "main";
|
|
209
|
+
try {
|
|
210
|
+
handleApp = await this.getRequestHandleAppName(req);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.log(error);
|
|
213
|
+
this.responseErrorWithCode("APP_INITIALIZING", res, { appName: handleApp });
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
207
216
|
const hasApp = import_app_supervisor.AppSupervisor.getInstance().hasApp(handleApp);
|
|
208
217
|
if (!hasApp) {
|
|
209
218
|
void import_app_supervisor.AppSupervisor.getInstance().bootStrapApp(handleApp);
|
|
@@ -257,10 +266,10 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
257
266
|
}
|
|
258
267
|
/* istanbul ignore next -- @preserve */
|
|
259
268
|
async watch() {
|
|
260
|
-
if (!
|
|
269
|
+
if (!import_node_process.default.env.IS_DEV_CMD) {
|
|
261
270
|
return;
|
|
262
271
|
}
|
|
263
|
-
const file =
|
|
272
|
+
const file = import_node_process.default.env.WATCH_FILE;
|
|
264
273
|
if (!import_fs.default.existsSync(file)) {
|
|
265
274
|
await import_fs.default.promises.writeFile(file, `export const watchId = '${(0, import_utils.uid)()}';`, "utf-8");
|
|
266
275
|
}
|
|
@@ -273,8 +282,8 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
273
282
|
if (isStart) {
|
|
274
283
|
await this.watch();
|
|
275
284
|
const startOptions = this.getStartOptions();
|
|
276
|
-
const port = startOptions.port ||
|
|
277
|
-
const host = startOptions.host ||
|
|
285
|
+
const port = startOptions.port || import_node_process.default.env.APP_PORT || 13e3;
|
|
286
|
+
const host = startOptions.host || import_node_process.default.env.APP_HOST || "0.0.0.0";
|
|
278
287
|
this.start({
|
|
279
288
|
port,
|
|
280
289
|
host
|
|
@@ -282,7 +291,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
282
291
|
} else if (!this.isHelp()) {
|
|
283
292
|
ipcClient = await this.tryConnectToIPCServer();
|
|
284
293
|
if (ipcClient) {
|
|
285
|
-
const response = await ipcClient.write({ type: "passCliArgv", payload: { argv:
|
|
294
|
+
const response = await ipcClient.write({ type: "passCliArgv", payload: { argv: import_node_process.default.argv } });
|
|
286
295
|
ipcClient.close();
|
|
287
296
|
if (!["error", "not_found"].includes(response.type)) {
|
|
288
297
|
return;
|
|
@@ -293,15 +302,19 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
293
302
|
await (0, import_plugin_symlink.createStoragePluginsSymlink)();
|
|
294
303
|
}
|
|
295
304
|
const mainApp = import_app_supervisor.AppSupervisor.getInstance().bootMainApp(options.mainAppOptions);
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
from: "
|
|
299
|
-
}
|
|
305
|
+
let runArgs = [import_node_process.default.argv, { throwError: true, from: "node" }];
|
|
306
|
+
if (!import_node_worker_threads.isMainThread) {
|
|
307
|
+
runArgs = [import_node_worker_threads.workerData.argv, { throwError: true, from: "user" }];
|
|
308
|
+
}
|
|
309
|
+
mainApp.runAsCLI(...runArgs).then(async () => {
|
|
300
310
|
if (!isStart && !await mainApp.isStarted()) {
|
|
301
311
|
await mainApp.stop({ logging: false });
|
|
302
312
|
}
|
|
303
313
|
}).catch(async (e) => {
|
|
304
314
|
if (e.code !== "commander.helpDisplayed") {
|
|
315
|
+
if (!import_node_worker_threads.isMainThread) {
|
|
316
|
+
throw e;
|
|
317
|
+
}
|
|
305
318
|
mainApp.log.error(e);
|
|
306
319
|
}
|
|
307
320
|
if (!isStart && !await mainApp.isStarted()) {
|
|
@@ -310,16 +323,16 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
310
323
|
});
|
|
311
324
|
}
|
|
312
325
|
isStart() {
|
|
313
|
-
const argv =
|
|
326
|
+
const argv = import_node_process.default.argv;
|
|
314
327
|
return argv[2] === "start";
|
|
315
328
|
}
|
|
316
329
|
isHelp() {
|
|
317
|
-
const argv =
|
|
330
|
+
const argv = import_node_process.default.argv;
|
|
318
331
|
return argv[2] === "help";
|
|
319
332
|
}
|
|
320
333
|
getStartOptions() {
|
|
321
334
|
const program = new import_commander.Command();
|
|
322
|
-
program.allowUnknownOption().option("-s, --silent").option("-p, --port [post]").option("-h, --host [host]").option("--db-sync").parse(
|
|
335
|
+
program.allowUnknownOption().option("-s, --silent").option("-p, --port [post]").option("-h, --host [host]").option("--db-sync").parse(import_node_process.default.argv);
|
|
323
336
|
return program.opts();
|
|
324
337
|
}
|
|
325
338
|
start(options) {
|
|
@@ -342,9 +355,54 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
342
355
|
}
|
|
343
356
|
this.server = import_http.default.createServer(this.getCallback());
|
|
344
357
|
this.wsServer = new import_ws_server.WSServer();
|
|
358
|
+
this.wsServer.on("message", async ({ client, message }) => {
|
|
359
|
+
const app = await import_app_supervisor.AppSupervisor.getInstance().getApp(client.app);
|
|
360
|
+
if (!app) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const parsedMessage = JSON.parse(message.toString());
|
|
364
|
+
if (!parsedMessage.type) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (!app.listenerCount(`ws:setTag`)) {
|
|
368
|
+
app.on("ws:setTag", ({ clientId, tagKey, tagValue }) => {
|
|
369
|
+
this.wsServer.setClientTag(clientId, tagKey, tagValue);
|
|
370
|
+
});
|
|
371
|
+
app.on("ws:removeTag", ({ clientId, tagKey }) => {
|
|
372
|
+
this.wsServer.removeClientTag(clientId, tagKey);
|
|
373
|
+
});
|
|
374
|
+
app.on("ws:sendToTag", ({ tagKey, tagValue, message: message2 }) => {
|
|
375
|
+
this.wsServer.sendToConnectionsByTags(
|
|
376
|
+
[
|
|
377
|
+
{ tagName: tagKey, tagValue },
|
|
378
|
+
{ tagName: "app", tagValue: app.name }
|
|
379
|
+
],
|
|
380
|
+
message2
|
|
381
|
+
);
|
|
382
|
+
});
|
|
383
|
+
app.on("ws:sendToTags", ({ tags, message: message2 }) => {
|
|
384
|
+
this.wsServer.sendToConnectionsByTags(tags, message2);
|
|
385
|
+
});
|
|
386
|
+
app.on("ws:authorized", ({ clientId, userId }) => {
|
|
387
|
+
this.wsServer.sendToConnectionsByTags(
|
|
388
|
+
[
|
|
389
|
+
{ tagName: "userId", tagValue: userId },
|
|
390
|
+
{ tagName: "app", tagValue: app.name }
|
|
391
|
+
],
|
|
392
|
+
{ type: "authorized" }
|
|
393
|
+
);
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
const eventName = `ws:message:${parsedMessage.type}`;
|
|
397
|
+
app.emit(eventName, {
|
|
398
|
+
clientId: client.id,
|
|
399
|
+
tags: [...client.tags],
|
|
400
|
+
payload: parsedMessage.payload
|
|
401
|
+
});
|
|
402
|
+
});
|
|
345
403
|
this.server.on("upgrade", (request, socket, head) => {
|
|
346
404
|
const { pathname } = (0, import_url.parse)(request.url);
|
|
347
|
-
if (pathname ===
|
|
405
|
+
if (pathname === import_node_process.default.env.WS_PATH) {
|
|
348
406
|
this.wsServer.wss.handleUpgrade(request, socket, head, (ws) => {
|
|
349
407
|
this.wsServer.wss.emit("connection", ws, request);
|
|
350
408
|
});
|
|
@@ -7,29 +7,43 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
/// <reference types="node" />
|
|
10
|
+
/// <reference types="node" />
|
|
10
11
|
import WebSocket from 'ws';
|
|
11
12
|
import { IncomingMessage } from 'http';
|
|
12
13
|
import { Logger } from '@nocobase/logger';
|
|
14
|
+
import EventEmitter from 'events';
|
|
13
15
|
declare class WebSocketWithId extends WebSocket {
|
|
14
16
|
id: string;
|
|
15
17
|
}
|
|
16
18
|
interface WebSocketClient {
|
|
17
19
|
ws: WebSocketWithId;
|
|
18
|
-
tags: string
|
|
20
|
+
tags: Set<string>;
|
|
19
21
|
url: string;
|
|
20
22
|
headers: any;
|
|
21
23
|
app?: string;
|
|
24
|
+
id: string;
|
|
22
25
|
}
|
|
23
|
-
export declare class WSServer {
|
|
26
|
+
export declare class WSServer extends EventEmitter {
|
|
24
27
|
wss: WebSocket.Server;
|
|
25
28
|
webSocketClients: Map<string, WebSocketClient>;
|
|
26
29
|
logger: Logger;
|
|
27
30
|
constructor();
|
|
28
31
|
addNewConnection(ws: WebSocketWithId, request: IncomingMessage): WebSocketClient;
|
|
32
|
+
setClientTag(clientId: string, tagKey: string, tagValue: string): void;
|
|
33
|
+
removeClientTag(clientId: string, tagKey: string): void;
|
|
29
34
|
setClientApp(client: WebSocketClient): Promise<void>;
|
|
30
35
|
removeConnection(id: string): void;
|
|
31
36
|
sendMessageToConnection(client: WebSocketClient, sendMessage: object): void;
|
|
32
37
|
sendToConnectionsByTag(tagName: string, tagValue: string, sendMessage: object): void;
|
|
38
|
+
/**
|
|
39
|
+
* Send message to clients that match all the given tag conditions
|
|
40
|
+
* @param tags Array of tag conditions, each condition is an object with tagName and tagValue
|
|
41
|
+
* @param sendMessage Message to be sent
|
|
42
|
+
*/
|
|
43
|
+
sendToConnectionsByTags(tags: Array<{
|
|
44
|
+
tagName: string;
|
|
45
|
+
tagValue: string;
|
|
46
|
+
}>, sendMessage: object): void;
|
|
33
47
|
loopThroughConnections(callback: (client: WebSocketClient) => void): void;
|
|
34
48
|
close(): void;
|
|
35
49
|
}
|
package/lib/gateway/ws-server.js
CHANGED
|
@@ -46,16 +46,18 @@ var import_nanoid = require("nanoid");
|
|
|
46
46
|
var import_app_supervisor = require("../app-supervisor");
|
|
47
47
|
var import_errors = require("./errors");
|
|
48
48
|
var import_lodash = __toESM(require("lodash"));
|
|
49
|
+
var import_events = __toESM(require("events"));
|
|
49
50
|
function getPayloadByErrorCode(code, options) {
|
|
50
51
|
const error = (0, import_errors.getErrorWithCode)(code);
|
|
51
52
|
return import_lodash.default.omit((0, import_errors.applyErrorWithArgs)(error, options), ["status", "maintaining"]);
|
|
52
53
|
}
|
|
53
54
|
__name(getPayloadByErrorCode, "getPayloadByErrorCode");
|
|
54
|
-
const _WSServer = class _WSServer {
|
|
55
|
+
const _WSServer = class _WSServer extends import_events.default {
|
|
55
56
|
wss;
|
|
56
57
|
webSocketClients = /* @__PURE__ */ new Map();
|
|
57
58
|
logger;
|
|
58
59
|
constructor() {
|
|
60
|
+
super();
|
|
59
61
|
this.wss = new import_ws.WebSocketServer({ noServer: true });
|
|
60
62
|
this.wss.on("connection", (ws, request) => {
|
|
61
63
|
const client = this.addNewConnection(ws, request);
|
|
@@ -66,6 +68,15 @@ const _WSServer = class _WSServer {
|
|
|
66
68
|
ws.on("close", () => {
|
|
67
69
|
this.removeConnection(ws.id);
|
|
68
70
|
});
|
|
71
|
+
ws.on("message", (message) => {
|
|
72
|
+
if (message.toString() === "ping") {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.emit("message", {
|
|
76
|
+
client,
|
|
77
|
+
message
|
|
78
|
+
});
|
|
79
|
+
});
|
|
69
80
|
});
|
|
70
81
|
import_gateway.Gateway.getInstance().on("appSelectorChanged", () => {
|
|
71
82
|
this.loopThroughConnections(async (client) => {
|
|
@@ -73,8 +84,12 @@ const _WSServer = class _WSServer {
|
|
|
73
84
|
url: client.url,
|
|
74
85
|
headers: client.headers
|
|
75
86
|
});
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
for (const tag of client.tags) {
|
|
88
|
+
if (tag.startsWith("app#")) {
|
|
89
|
+
client.tags.delete(tag);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
client.tags.add(`app#${handleAppName}`);
|
|
78
93
|
import_app_supervisor.AppSupervisor.getInstance().bootStrapApp(handleAppName);
|
|
79
94
|
});
|
|
80
95
|
});
|
|
@@ -124,13 +139,27 @@ const _WSServer = class _WSServer {
|
|
|
124
139
|
ws.id = id;
|
|
125
140
|
this.webSocketClients.set(id, {
|
|
126
141
|
ws,
|
|
127
|
-
tags:
|
|
142
|
+
tags: /* @__PURE__ */ new Set(),
|
|
128
143
|
url: request.url,
|
|
129
|
-
headers: request.headers
|
|
144
|
+
headers: request.headers,
|
|
145
|
+
id
|
|
130
146
|
});
|
|
131
147
|
this.setClientApp(this.webSocketClients.get(id));
|
|
132
148
|
return this.webSocketClients.get(id);
|
|
133
149
|
}
|
|
150
|
+
setClientTag(clientId, tagKey, tagValue) {
|
|
151
|
+
const client = this.webSocketClients.get(clientId);
|
|
152
|
+
client.tags.add(`${tagKey}#${tagValue}`);
|
|
153
|
+
console.log(`client tags: ${Array.from(client.tags)}`);
|
|
154
|
+
}
|
|
155
|
+
removeClientTag(clientId, tagKey) {
|
|
156
|
+
const client = this.webSocketClients.get(clientId);
|
|
157
|
+
client.tags.forEach((tag) => {
|
|
158
|
+
if (tag.startsWith(tagKey)) {
|
|
159
|
+
client.tags.delete(tag);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
134
163
|
async setClientApp(client) {
|
|
135
164
|
const req = {
|
|
136
165
|
url: client.url,
|
|
@@ -139,7 +168,7 @@ const _WSServer = class _WSServer {
|
|
|
139
168
|
const handleAppName = await import_gateway.Gateway.getInstance().getRequestHandleAppName(req);
|
|
140
169
|
client.app = handleAppName;
|
|
141
170
|
console.log(`client tags: app#${handleAppName}`);
|
|
142
|
-
client.tags.
|
|
171
|
+
client.tags.add(`app#${handleAppName}`);
|
|
143
172
|
const hasApp = import_app_supervisor.AppSupervisor.getInstance().hasApp(handleAppName);
|
|
144
173
|
if (!hasApp) {
|
|
145
174
|
import_app_supervisor.AppSupervisor.getInstance().bootStrapApp(handleAppName);
|
|
@@ -173,8 +202,17 @@ const _WSServer = class _WSServer {
|
|
|
173
202
|
client.ws.send(JSON.stringify(sendMessage));
|
|
174
203
|
}
|
|
175
204
|
sendToConnectionsByTag(tagName, tagValue, sendMessage) {
|
|
205
|
+
this.sendToConnectionsByTags([{ tagName, tagValue }], sendMessage);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Send message to clients that match all the given tag conditions
|
|
209
|
+
* @param tags Array of tag conditions, each condition is an object with tagName and tagValue
|
|
210
|
+
* @param sendMessage Message to be sent
|
|
211
|
+
*/
|
|
212
|
+
sendToConnectionsByTags(tags, sendMessage) {
|
|
176
213
|
this.loopThroughConnections((client) => {
|
|
177
|
-
|
|
214
|
+
const allTagsMatch = tags.every(({ tagName, tagValue }) => client.tags.has(`${tagName}#${tagValue}`));
|
|
215
|
+
if (allTagsMatch) {
|
|
178
216
|
this.sendMessageToConnection(client, sendMessage);
|
|
179
217
|
}
|
|
180
218
|
});
|
|
@@ -372,14 +372,14 @@ const _PluginManager = class _PluginManager {
|
|
|
372
372
|
const source = [];
|
|
373
373
|
for (const packageName of packageNames) {
|
|
374
374
|
const dirname = await (0, import_utils2.getPluginBasePath)(packageName);
|
|
375
|
-
const directory = (0, import_path.join)(dirname, "server/commands/*." + ((0, import_path.basename)(dirname) === "src" ? "ts" : "js"));
|
|
375
|
+
const directory = (0, import_path.join)(dirname, "server/commands/*." + ((0, import_path.basename)(dirname) === "src" ? "{ts,js}" : "js"));
|
|
376
376
|
source.push(directory.replaceAll(import_path.sep, "/"));
|
|
377
377
|
}
|
|
378
378
|
for (const plugin of this.options.plugins || []) {
|
|
379
379
|
if (typeof plugin === "string") {
|
|
380
380
|
const { packageName } = await _PluginManager.parseName(plugin);
|
|
381
381
|
const dirname = await (0, import_utils2.getPluginBasePath)(packageName);
|
|
382
|
-
const directory = (0, import_path.join)(dirname, "server/commands/*." + ((0, import_path.basename)(dirname) === "src" ? "ts" : "js"));
|
|
382
|
+
const directory = (0, import_path.join)(dirname, "server/commands/*." + ((0, import_path.basename)(dirname) === "src" ? "{ts,js}" : "js"));
|
|
383
383
|
source.push(directory.replaceAll(import_path.sep, "/"));
|
|
384
384
|
}
|
|
385
385
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
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 service_container_exports = {};
|
|
29
|
+
__export(service_container_exports, {
|
|
30
|
+
ServiceContainer: () => ServiceContainer
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(service_container_exports);
|
|
33
|
+
const _ServiceContainer = class _ServiceContainer {
|
|
34
|
+
services = /* @__PURE__ */ new Map();
|
|
35
|
+
register(name, service) {
|
|
36
|
+
if (typeof service === "function") {
|
|
37
|
+
service = service();
|
|
38
|
+
}
|
|
39
|
+
this.services.set(name, service);
|
|
40
|
+
}
|
|
41
|
+
get(name) {
|
|
42
|
+
return this.services.get(name);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
__name(_ServiceContainer, "ServiceContainer");
|
|
46
|
+
let ServiceContainer = _ServiceContainer;
|
|
47
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
48
|
+
0 && (module.exports = {
|
|
49
|
+
ServiceContainer
|
|
50
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/server",
|
|
3
|
-
"version": "1.6.0-alpha.
|
|
3
|
+
"version": "1.6.0-alpha.8",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "./lib/index.d.ts",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -10,19 +10,19 @@
|
|
|
10
10
|
"@koa/cors": "^3.1.0",
|
|
11
11
|
"@koa/multer": "^3.0.2",
|
|
12
12
|
"@koa/router": "^9.4.0",
|
|
13
|
-
"@nocobase/acl": "1.6.0-alpha.
|
|
14
|
-
"@nocobase/actions": "1.6.0-alpha.
|
|
15
|
-
"@nocobase/auth": "1.6.0-alpha.
|
|
16
|
-
"@nocobase/cache": "1.6.0-alpha.
|
|
17
|
-
"@nocobase/data-source-manager": "1.6.0-alpha.
|
|
18
|
-
"@nocobase/database": "1.6.0-alpha.
|
|
19
|
-
"@nocobase/evaluators": "1.6.0-alpha.
|
|
20
|
-
"@nocobase/lock-manager": "1.6.0-alpha.
|
|
21
|
-
"@nocobase/logger": "1.6.0-alpha.
|
|
22
|
-
"@nocobase/resourcer": "1.6.0-alpha.
|
|
23
|
-
"@nocobase/sdk": "1.6.0-alpha.
|
|
24
|
-
"@nocobase/telemetry": "1.6.0-alpha.
|
|
25
|
-
"@nocobase/utils": "1.6.0-alpha.
|
|
13
|
+
"@nocobase/acl": "1.6.0-alpha.8",
|
|
14
|
+
"@nocobase/actions": "1.6.0-alpha.8",
|
|
15
|
+
"@nocobase/auth": "1.6.0-alpha.8",
|
|
16
|
+
"@nocobase/cache": "1.6.0-alpha.8",
|
|
17
|
+
"@nocobase/data-source-manager": "1.6.0-alpha.8",
|
|
18
|
+
"@nocobase/database": "1.6.0-alpha.8",
|
|
19
|
+
"@nocobase/evaluators": "1.6.0-alpha.8",
|
|
20
|
+
"@nocobase/lock-manager": "1.6.0-alpha.8",
|
|
21
|
+
"@nocobase/logger": "1.6.0-alpha.8",
|
|
22
|
+
"@nocobase/resourcer": "1.6.0-alpha.8",
|
|
23
|
+
"@nocobase/sdk": "1.6.0-alpha.8",
|
|
24
|
+
"@nocobase/telemetry": "1.6.0-alpha.8",
|
|
25
|
+
"@nocobase/utils": "1.6.0-alpha.8",
|
|
26
26
|
"@types/decompress": "4.2.7",
|
|
27
27
|
"@types/ini": "^1.3.31",
|
|
28
28
|
"@types/koa-send": "^4.1.3",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"@types/serve-handler": "^6.1.1",
|
|
57
57
|
"@types/ws": "^8.5.5"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "f7ab757a5d7fb723c96bc9c1340291e4deec03ea"
|
|
60
60
|
}
|