@nocobase/server 0.19.0-alpha.1 → 0.19.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/lib/app-supervisor.js +11 -3
- package/lib/application.js +15 -5
- package/lib/commands/index.js +2 -0
- package/lib/commands/install.js +4 -1
- package/lib/commands/pm.js +4 -4
- package/lib/commands/refresh.d.ts +3 -0
- package/lib/commands/refresh.js +31 -0
- package/lib/gateway/index.d.ts +1 -0
- package/lib/gateway/index.js +20 -9
- package/lib/gateway/ipc-socket-client.d.ts +2 -2
- package/lib/gateway/ipc-socket-client.js +6 -3
- package/lib/gateway/ipc-socket-server.d.ts +1 -1
- package/lib/gateway/ipc-socket-server.js +27 -8
- package/lib/middlewares/data-wrapping.js +21 -18
- package/lib/migrations/20230912193824-package-name-unique.js +14 -7
- package/lib/plugin-manager/plugin-manager.d.ts +8 -2
- package/lib/plugin-manager/plugin-manager.js +104 -35
- package/lib/plugin.d.ts +3 -1
- package/lib/plugin.js +28 -7
- package/package.json +13 -13
package/lib/app-supervisor.js
CHANGED
|
@@ -213,9 +213,17 @@ const _AppSupervisor = class _AppSupervisor extends import_events.EventEmitter {
|
|
|
213
213
|
});
|
|
214
214
|
app.on("__started", async (_app, options) => {
|
|
215
215
|
const { maintainingStatus, options: startOptions } = options;
|
|
216
|
-
if (maintainingStatus && [
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
if (maintainingStatus && [
|
|
217
|
+
"install",
|
|
218
|
+
"upgrade",
|
|
219
|
+
"refresh",
|
|
220
|
+
"restore",
|
|
221
|
+
"pm.add",
|
|
222
|
+
"pm.update",
|
|
223
|
+
"pm.enable",
|
|
224
|
+
"pm.disable",
|
|
225
|
+
"pm.remove"
|
|
226
|
+
].includes(maintainingStatus.command.name) && !startOptions.recover) {
|
|
219
227
|
this.setAppStatus(app.name, "running", {
|
|
220
228
|
refresh: true
|
|
221
229
|
});
|
package/lib/application.js
CHANGED
|
@@ -498,20 +498,30 @@ const _Application = class _Application extends import_koa.default {
|
|
|
498
498
|
this.emit("__restarted", this, options);
|
|
499
499
|
}
|
|
500
500
|
async stop(options = {}) {
|
|
501
|
-
|
|
501
|
+
const log = options.logging === false ? {
|
|
502
|
+
debug() {
|
|
503
|
+
},
|
|
504
|
+
warn() {
|
|
505
|
+
},
|
|
506
|
+
info() {
|
|
507
|
+
},
|
|
508
|
+
error() {
|
|
509
|
+
}
|
|
510
|
+
} : this.log;
|
|
511
|
+
log.debug("stop app...", { method: "stop" });
|
|
502
512
|
this.setMaintainingMessage("stopping app...");
|
|
503
513
|
if (this.stopped) {
|
|
504
|
-
|
|
514
|
+
log.warn(`app is stopped`, { method: "stop" });
|
|
505
515
|
return;
|
|
506
516
|
}
|
|
507
517
|
await this.emitAsync("beforeStop", this, options);
|
|
508
518
|
try {
|
|
509
519
|
if (!this.db.closed()) {
|
|
510
|
-
|
|
520
|
+
log.info(`close db`, { method: "stop" });
|
|
511
521
|
await this.db.close();
|
|
512
522
|
}
|
|
513
523
|
} catch (e) {
|
|
514
|
-
|
|
524
|
+
log.error(e.message, { method: "stop", err: e.stack });
|
|
515
525
|
}
|
|
516
526
|
if (this.cacheManager) {
|
|
517
527
|
await this.cacheManager.close();
|
|
@@ -521,7 +531,7 @@ const _Application = class _Application extends import_koa.default {
|
|
|
521
531
|
}
|
|
522
532
|
await this.emitAsync("afterStop", this, options);
|
|
523
533
|
this.stopped = true;
|
|
524
|
-
|
|
534
|
+
log.info(`app has stopped`, { method: "stop" });
|
|
525
535
|
this._started = false;
|
|
526
536
|
}
|
|
527
537
|
async destroy(options = {}) {
|
package/lib/commands/index.js
CHANGED
|
@@ -38,6 +38,7 @@ var import_db_sync = __toESM(require("./db-sync"));
|
|
|
38
38
|
var import_destroy = __toESM(require("./destroy"));
|
|
39
39
|
var import_install = __toESM(require("./install"));
|
|
40
40
|
var import_pm = __toESM(require("./pm"));
|
|
41
|
+
var import_refresh = __toESM(require("./refresh"));
|
|
41
42
|
var import_restart = __toESM(require("./restart"));
|
|
42
43
|
var import_start = __toESM(require("./start"));
|
|
43
44
|
var import_stop = __toESM(require("./stop"));
|
|
@@ -54,6 +55,7 @@ function registerCli(app) {
|
|
|
54
55
|
(0, import_stop.default)(app);
|
|
55
56
|
(0, import_destroy.default)(app);
|
|
56
57
|
(0, import_start.default)(app);
|
|
58
|
+
(0, import_refresh.default)(app);
|
|
57
59
|
app.command("build").argument("[packages...]");
|
|
58
60
|
app.command("clean");
|
|
59
61
|
app.command("dev").usage("[options]").option("-p, --port [port]").option("--client").option("--server");
|
package/lib/commands/install.js
CHANGED
|
@@ -22,7 +22,10 @@ __export(install_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(install_exports);
|
|
24
24
|
var install_default = /* @__PURE__ */ __name((app) => {
|
|
25
|
-
app.command("install").ipc().auth().option("-f, --force").option("-c, --clean").action(async (options) => {
|
|
25
|
+
app.command("install").ipc().auth().option("-f, --force").option("-c, --clean").option("--lang <lang>").action(async (options) => {
|
|
26
|
+
if (options.lang) {
|
|
27
|
+
process.env.INIT_APP_LANG = options.lang;
|
|
28
|
+
}
|
|
26
29
|
await app.install(options);
|
|
27
30
|
const reinstall = options.clean || options.force;
|
|
28
31
|
app.log.info(`app ${reinstall ? "reinstalled" : "installed"} successfully [v${app.getVersion()}]`);
|
package/lib/commands/pm.js
CHANGED
|
@@ -35,8 +35,8 @@ var import_lodash = __toESM(require("lodash"));
|
|
|
35
35
|
var import_plugin_command_error = require("../errors/plugin-command-error");
|
|
36
36
|
var pm_default = /* @__PURE__ */ __name((app) => {
|
|
37
37
|
const pm = app.command("pm");
|
|
38
|
-
pm.command("create").
|
|
39
|
-
await app.pm.create(plugin);
|
|
38
|
+
pm.command("create").arguments("plugin").option("--force-recreate").action(async (plugin, options) => {
|
|
39
|
+
await app.pm.create(plugin, options);
|
|
40
40
|
});
|
|
41
41
|
pm.command("add").ipc().preload().argument("<pkg>").option("--registry [registry]").option("--auth-token [authToken]").option("--version [version]").action(async (name, options, cli) => {
|
|
42
42
|
try {
|
|
@@ -69,7 +69,7 @@ var pm_default = /* @__PURE__ */ __name((app) => {
|
|
|
69
69
|
throw new import_plugin_command_error.PluginCommandError(`Failed to disable plugin: ${error.message}`);
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
|
-
pm.command("remove").
|
|
73
|
-
await app.pm.remove(plugins);
|
|
72
|
+
pm.command("remove").auth().arguments("<plugins...>").option("--force").option("--remove-dir").action(async (plugins, options) => {
|
|
73
|
+
await app.pm.remove(plugins, options);
|
|
74
74
|
});
|
|
75
75
|
}, "default");
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var refresh_exports = {};
|
|
20
|
+
__export(refresh_exports, {
|
|
21
|
+
default: () => refresh_default
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(refresh_exports);
|
|
24
|
+
var refresh_default = /* @__PURE__ */ __name((app) => {
|
|
25
|
+
app.command("refresh").ipc().action(async (cliArgs) => {
|
|
26
|
+
await app.restart({
|
|
27
|
+
cliArgs
|
|
28
|
+
});
|
|
29
|
+
app.log.info("refreshing...");
|
|
30
|
+
});
|
|
31
|
+
}, "default");
|
package/lib/gateway/index.d.ts
CHANGED
|
@@ -66,5 +66,6 @@ export declare class Gateway extends EventEmitter {
|
|
|
66
66
|
tryConnectToIPCServer(): Promise<false | IPCSocketClient>;
|
|
67
67
|
getIPCSocketClient(): Promise<IPCSocketClient>;
|
|
68
68
|
close(): void;
|
|
69
|
+
static getIPCSocketClient(): Promise<false | IPCSocketClient>;
|
|
69
70
|
}
|
|
70
71
|
export {};
|
package/lib/gateway/index.js
CHANGED
|
@@ -51,7 +51,6 @@ var import_path = require("path");
|
|
|
51
51
|
var import_qs = __toESM(require("qs"));
|
|
52
52
|
var import_serve_handler = __toESM(require("serve-handler"));
|
|
53
53
|
var import_url = require("url");
|
|
54
|
-
var import_xpipe = __toESM(require("xpipe"));
|
|
55
54
|
var import_app_supervisor = require("../app-supervisor");
|
|
56
55
|
var import_plugin_manager = require("../plugin-manager");
|
|
57
56
|
var import_errors = require("./errors");
|
|
@@ -69,13 +68,13 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
69
68
|
port = process.env.APP_PORT ? parseInt(process.env.APP_PORT) : null;
|
|
70
69
|
host = "0.0.0.0";
|
|
71
70
|
wsServer;
|
|
72
|
-
socketPath =
|
|
71
|
+
socketPath = (0, import_path.resolve)(process.cwd(), "storage", "gateway.sock");
|
|
73
72
|
loggers = new import_utils.Registry();
|
|
74
73
|
constructor() {
|
|
75
74
|
super();
|
|
76
75
|
this.reset();
|
|
77
76
|
if (process.env.SOCKET_PATH) {
|
|
78
|
-
this.socketPath =
|
|
77
|
+
this.socketPath = (0, import_path.resolve)(process.cwd(), process.env.SOCKET_PATH);
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
80
|
static getInstance(options = {}) {
|
|
@@ -267,7 +266,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
267
266
|
if (ipcClient) {
|
|
268
267
|
const response = await ipcClient.write({ type: "passCliArgv", payload: { argv: process.argv } });
|
|
269
268
|
ipcClient.close();
|
|
270
|
-
if (
|
|
269
|
+
if (!["error", "not_found"].includes(response.type)) {
|
|
271
270
|
return;
|
|
272
271
|
}
|
|
273
272
|
}
|
|
@@ -276,16 +275,20 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
276
275
|
await (0, import_plugin_symlink.createStoragePluginsSymlink)();
|
|
277
276
|
}
|
|
278
277
|
const mainApp = import_app_supervisor.AppSupervisor.getInstance().bootMainApp(options.mainAppOptions);
|
|
279
|
-
await mainApp.load();
|
|
280
278
|
mainApp.runAsCLI(process.argv, {
|
|
281
279
|
throwError: true,
|
|
282
280
|
from: "node"
|
|
283
281
|
}).then(async () => {
|
|
284
282
|
if (!await mainApp.isStarted()) {
|
|
285
|
-
await mainApp.stop();
|
|
283
|
+
await mainApp.stop({ logging: false });
|
|
284
|
+
}
|
|
285
|
+
}).catch(async (e) => {
|
|
286
|
+
if (e.code !== "commander.helpDisplayed") {
|
|
287
|
+
mainApp.log.error(e);
|
|
288
|
+
}
|
|
289
|
+
if (!await mainApp.isStarted()) {
|
|
290
|
+
await mainApp.stop({ logging: false });
|
|
286
291
|
}
|
|
287
|
-
}).catch((e) => {
|
|
288
|
-
console.error(e);
|
|
289
292
|
});
|
|
290
293
|
}
|
|
291
294
|
isStart() {
|
|
@@ -325,7 +328,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
325
328
|
this.wsServer = new import_ws_server.WSServer();
|
|
326
329
|
this.server.on("upgrade", (request, socket, head) => {
|
|
327
330
|
const { pathname } = (0, import_url.parse)(request.url);
|
|
328
|
-
if (pathname ===
|
|
331
|
+
if (pathname === process.env.WS_PATH) {
|
|
329
332
|
this.wsServer.wss.handleUpgrade(request, socket, head, (ws) => {
|
|
330
333
|
this.wsServer.wss.emit("connection", ws, request);
|
|
331
334
|
});
|
|
@@ -356,6 +359,14 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
|
|
|
356
359
|
(_a = this.server) == null ? void 0 : _a.close();
|
|
357
360
|
(_b = this.wsServer) == null ? void 0 : _b.close();
|
|
358
361
|
}
|
|
362
|
+
static async getIPCSocketClient() {
|
|
363
|
+
const socketPath = (0, import_path.resolve)(process.cwd(), process.env.SOCKET_PATH || "storage/gateway.sock");
|
|
364
|
+
try {
|
|
365
|
+
return await import_ipc_socket_client.IPCSocketClient.getConnection(socketPath);
|
|
366
|
+
} catch (error) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
359
370
|
};
|
|
360
371
|
__name(_Gateway, "Gateway");
|
|
361
372
|
__publicField(_Gateway, "instance");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
import net from 'net';
|
|
4
|
-
import * as events from 'events';
|
|
5
3
|
import { Logger } from '@nocobase/logger';
|
|
4
|
+
import * as events from 'events';
|
|
5
|
+
import net from 'net';
|
|
6
6
|
export declare const writeJSON: (socket: net.Socket, data: object) => void;
|
|
7
7
|
export declare class IPCSocketClient extends events.EventEmitter {
|
|
8
8
|
client: net.Socket;
|
|
@@ -32,9 +32,10 @@ __export(ipc_socket_client_exports, {
|
|
|
32
32
|
writeJSON: () => writeJSON
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(ipc_socket_client_exports);
|
|
35
|
-
var import_net = __toESM(require("net"));
|
|
36
|
-
var events = __toESM(require("events"));
|
|
37
35
|
var import_logger = require("@nocobase/logger");
|
|
36
|
+
var events = __toESM(require("events"));
|
|
37
|
+
var import_net = __toESM(require("net"));
|
|
38
|
+
var import_xpipe = __toESM(require("xpipe"));
|
|
38
39
|
const writeJSON = /* @__PURE__ */ __name((socket, data) => {
|
|
39
40
|
socket.write(JSON.stringify(data) + "\n", "utf8");
|
|
40
41
|
}, "writeJSON");
|
|
@@ -59,7 +60,7 @@ const _IPCSocketClient = class _IPCSocketClient extends events.EventEmitter {
|
|
|
59
60
|
}
|
|
60
61
|
static async getConnection(serverPath) {
|
|
61
62
|
return new Promise((resolve, reject) => {
|
|
62
|
-
const client = import_net.default.createConnection({ path: serverPath }, () => {
|
|
63
|
+
const client = import_net.default.createConnection({ path: import_xpipe.default.eq(serverPath) }, () => {
|
|
63
64
|
resolve(new _IPCSocketClient(client));
|
|
64
65
|
});
|
|
65
66
|
client.on("error", (err) => {
|
|
@@ -69,6 +70,8 @@ const _IPCSocketClient = class _IPCSocketClient extends events.EventEmitter {
|
|
|
69
70
|
}
|
|
70
71
|
async handleServerMessage({ reqId, type, payload }) {
|
|
71
72
|
switch (type) {
|
|
73
|
+
case "not_found":
|
|
74
|
+
break;
|
|
72
75
|
case "error":
|
|
73
76
|
this.logger.error({ reqId, message: `${payload.message}|${payload.stack}` });
|
|
74
77
|
break;
|
|
@@ -31,12 +31,13 @@ __export(ipc_socket_server_exports, {
|
|
|
31
31
|
IPCSocketServer: () => IPCSocketServer
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(ipc_socket_server_exports);
|
|
34
|
-
var
|
|
34
|
+
var import_crypto = require("crypto");
|
|
35
35
|
var import_fs = __toESM(require("fs"));
|
|
36
|
+
var import_net = __toESM(require("net"));
|
|
36
37
|
var import_path = __toESM(require("path"));
|
|
38
|
+
var import_xpipe = __toESM(require("xpipe"));
|
|
37
39
|
var import_app_supervisor = require("../app-supervisor");
|
|
38
40
|
var import_ipc_socket_client = require("./ipc-socket-client");
|
|
39
|
-
var import_crypto = require("crypto");
|
|
40
41
|
const _IPCSocketServer = class _IPCSocketServer {
|
|
41
42
|
socketServer;
|
|
42
43
|
constructor(server) {
|
|
@@ -64,10 +65,10 @@ const _IPCSocketServer = class _IPCSocketServer {
|
|
|
64
65
|
}
|
|
65
66
|
const reqId = (0, import_crypto.randomUUID)();
|
|
66
67
|
const dataObj = JSON.parse(message);
|
|
67
|
-
_IPCSocketServer.handleClientMessage({ reqId, ...dataObj }).then(() => {
|
|
68
|
+
_IPCSocketServer.handleClientMessage({ reqId, ...dataObj }).then((result) => {
|
|
68
69
|
(0, import_ipc_socket_client.writeJSON)(c, {
|
|
69
70
|
reqId,
|
|
70
|
-
type: "success"
|
|
71
|
+
type: result === false ? "not_found" : "success"
|
|
71
72
|
});
|
|
72
73
|
}).catch((err) => {
|
|
73
74
|
(0, import_ipc_socket_client.writeJSON)(c, {
|
|
@@ -82,25 +83,43 @@ const _IPCSocketServer = class _IPCSocketServer {
|
|
|
82
83
|
}
|
|
83
84
|
});
|
|
84
85
|
});
|
|
85
|
-
socketServer.listen(socketPath, () => {
|
|
86
|
+
socketServer.listen(import_xpipe.default.eq(socketPath), () => {
|
|
86
87
|
console.log(`Gateway IPC Server running at ${socketPath}`);
|
|
87
88
|
});
|
|
88
89
|
return new _IPCSocketServer(socketServer);
|
|
89
90
|
}
|
|
90
91
|
static async handleClientMessage({ reqId, type, payload }) {
|
|
91
|
-
|
|
92
|
+
if (type === "appReady") {
|
|
93
|
+
const status = await new Promise((resolve, reject) => {
|
|
94
|
+
let status2;
|
|
95
|
+
const max = 300;
|
|
96
|
+
let count = 0;
|
|
97
|
+
const timer = setInterval(async () => {
|
|
98
|
+
status2 = import_app_supervisor.AppSupervisor.getInstance().getAppStatus("main");
|
|
99
|
+
if (status2 === "running") {
|
|
100
|
+
clearInterval(timer);
|
|
101
|
+
resolve(status2);
|
|
102
|
+
}
|
|
103
|
+
if (count++ > max) {
|
|
104
|
+
reject("error");
|
|
105
|
+
}
|
|
106
|
+
}, 500);
|
|
107
|
+
});
|
|
108
|
+
console.log("status", status);
|
|
109
|
+
return status;
|
|
110
|
+
}
|
|
92
111
|
if (type === "passCliArgv") {
|
|
93
112
|
const argv = payload.argv;
|
|
94
113
|
const mainApp = await import_app_supervisor.AppSupervisor.getInstance().getApp("main");
|
|
95
114
|
if (!mainApp.cli.hasCommand(argv[2])) {
|
|
96
|
-
console.log("passCliArgv", argv[2]);
|
|
97
115
|
await mainApp.pm.loadCommands();
|
|
98
116
|
}
|
|
99
117
|
const cli = mainApp.cli;
|
|
100
118
|
if (!cli.parseHandleByIPCServer(argv, {
|
|
101
119
|
from: "node"
|
|
102
120
|
})) {
|
|
103
|
-
|
|
121
|
+
mainApp.log.debug("Not handle by ipc server");
|
|
122
|
+
return false;
|
|
104
123
|
}
|
|
105
124
|
return mainApp.runAsCLI(argv, {
|
|
106
125
|
reqId,
|
|
@@ -35,7 +35,7 @@ module.exports = __toCommonJS(data_wrapping_exports);
|
|
|
35
35
|
var import_stream = __toESM(require("stream"));
|
|
36
36
|
function dataWrapping() {
|
|
37
37
|
return /* @__PURE__ */ __name(async function dataWrapping2(ctx, next) {
|
|
38
|
-
var _a;
|
|
38
|
+
var _a, _b;
|
|
39
39
|
await next();
|
|
40
40
|
if (ctx.withoutDataWrapping) {
|
|
41
41
|
return;
|
|
@@ -55,27 +55,30 @@ function dataWrapping() {
|
|
|
55
55
|
ctx.body = {
|
|
56
56
|
data: ctx.body
|
|
57
57
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
58
|
+
} else {
|
|
59
|
+
if (ctx.body) {
|
|
60
|
+
const { rows, ...meta } = ctx.body;
|
|
61
|
+
if (rows) {
|
|
62
|
+
ctx.body = {
|
|
63
|
+
data: rows,
|
|
64
|
+
meta
|
|
65
|
+
};
|
|
66
|
+
} else {
|
|
67
|
+
ctx.body = {
|
|
68
|
+
data: ctx.body
|
|
69
|
+
};
|
|
70
|
+
if (ctx.bodyMeta) {
|
|
71
|
+
ctx.body.meta = ctx.bodyMeta;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} else if (ctx.action) {
|
|
68
75
|
ctx.body = {
|
|
69
76
|
data: ctx.body
|
|
70
77
|
};
|
|
71
|
-
if (ctx.bodyMeta) {
|
|
72
|
-
ctx.body.meta = ctx.bodyMeta;
|
|
73
|
-
}
|
|
74
78
|
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
};
|
|
79
|
+
}
|
|
80
|
+
if (ctx.body && ((_b = ctx.state.messages) == null ? void 0 : _b.length)) {
|
|
81
|
+
ctx.body.messages = ctx.state.messages;
|
|
79
82
|
}
|
|
80
83
|
}, "dataWrapping");
|
|
81
84
|
}
|
|
@@ -29,13 +29,20 @@ const _package_name_unique_default = class _package_name_unique_default extends
|
|
|
29
29
|
async up() {
|
|
30
30
|
const tableNameWithSchema = this.pm.collection.getTableNameWithSchema();
|
|
31
31
|
const field = this.pm.collection.getField("packageName");
|
|
32
|
-
await
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
const exists = await field.existsInDb();
|
|
33
|
+
if (exists) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
await this.db.sequelize.getQueryInterface().addColumn(tableNameWithSchema, field.columnName(), {
|
|
38
|
+
type: import_database.DataTypes.STRING
|
|
39
|
+
});
|
|
40
|
+
await this.db.sequelize.getQueryInterface().addConstraint(tableNameWithSchema, {
|
|
41
|
+
type: "unique",
|
|
42
|
+
fields: [field.columnName()]
|
|
43
|
+
});
|
|
44
|
+
} catch (error) {
|
|
45
|
+
}
|
|
39
46
|
}
|
|
40
47
|
};
|
|
41
48
|
__name(_package_name_unique_default, "default");
|
|
@@ -5,6 +5,7 @@ import Application from '../application';
|
|
|
5
5
|
import { Plugin } from '../plugin';
|
|
6
6
|
import { PluginManagerRepository } from './plugin-manager-repository';
|
|
7
7
|
import { PluginData } from './types';
|
|
8
|
+
export declare const sleep: (timeout?: number) => Promise<unknown>;
|
|
8
9
|
export interface PluginManagerOptions {
|
|
9
10
|
app: Application;
|
|
10
11
|
plugins?: any[];
|
|
@@ -39,7 +40,9 @@ export declare class PluginManager {
|
|
|
39
40
|
get(name: string | typeof Plugin): Plugin<any>;
|
|
40
41
|
has(name: string | typeof Plugin): boolean;
|
|
41
42
|
del(name: string | typeof Plugin): void;
|
|
42
|
-
create(pluginName: string
|
|
43
|
+
create(pluginName: string, options?: {
|
|
44
|
+
forceRecreate?: boolean;
|
|
45
|
+
}): Promise<void>;
|
|
43
46
|
add(plugin?: any, options?: any, insert?: boolean, isUpgrade?: boolean): Promise<void>;
|
|
44
47
|
initPlugins(): Promise<void>;
|
|
45
48
|
loadCommands(): Promise<void>;
|
|
@@ -47,7 +50,10 @@ export declare class PluginManager {
|
|
|
47
50
|
install(options?: InstallOptions): Promise<void>;
|
|
48
51
|
enable(name: string | string[]): Promise<void>;
|
|
49
52
|
disable(name: string | string[]): Promise<void>;
|
|
50
|
-
remove(name: string | string[]
|
|
53
|
+
remove(name: string | string[], options?: {
|
|
54
|
+
removeDir?: boolean;
|
|
55
|
+
force?: boolean;
|
|
56
|
+
}): Promise<void>;
|
|
51
57
|
loadOne(plugin: Plugin): Promise<void>;
|
|
52
58
|
addViaCLI(urlOrName: string, options?: PluginData): Promise<void>;
|
|
53
59
|
addByNpm(options: {
|
|
@@ -30,7 +30,8 @@ var plugin_manager_exports = {};
|
|
|
30
30
|
__export(plugin_manager_exports, {
|
|
31
31
|
AddPresetError: () => AddPresetError,
|
|
32
32
|
PluginManager: () => PluginManager,
|
|
33
|
-
default: () => plugin_manager_default
|
|
33
|
+
default: () => plugin_manager_default,
|
|
34
|
+
sleep: () => sleep
|
|
34
35
|
});
|
|
35
36
|
module.exports = __toCommonJS(plugin_manager_exports);
|
|
36
37
|
var import_utils = require("@nocobase/utils");
|
|
@@ -46,6 +47,11 @@ var import_collection = __toESM(require("./options/collection"));
|
|
|
46
47
|
var import_resource = __toESM(require("./options/resource"));
|
|
47
48
|
var import_plugin_manager_repository = require("./plugin-manager-repository");
|
|
48
49
|
var import_utils2 = require("./utils");
|
|
50
|
+
const sleep = /* @__PURE__ */ __name(async (timeout = 0) => {
|
|
51
|
+
return new Promise((resolve2) => {
|
|
52
|
+
setTimeout(resolve2, timeout);
|
|
53
|
+
});
|
|
54
|
+
}, "sleep");
|
|
49
55
|
const _AddPresetError = class _AddPresetError extends Error {
|
|
50
56
|
};
|
|
51
57
|
__name(_AddPresetError, "AddPresetError");
|
|
@@ -177,12 +183,15 @@ const _PluginManager = class _PluginManager {
|
|
|
177
183
|
this.app.pm.pluginInstances.delete(instance.constructor);
|
|
178
184
|
}
|
|
179
185
|
}
|
|
180
|
-
async create(pluginName) {
|
|
181
|
-
console.log("creating...");
|
|
186
|
+
async create(pluginName, options) {
|
|
182
187
|
const createPlugin = /* @__PURE__ */ __name(async (name) => {
|
|
188
|
+
const pluginDir = (0, import_path.resolve)(process.cwd(), "packages/plugins", name);
|
|
189
|
+
if (options == null ? void 0 : options.forceRecreate) {
|
|
190
|
+
await import_fs.default.promises.rm(pluginDir, { recursive: true, force: true });
|
|
191
|
+
}
|
|
183
192
|
const { PluginGenerator } = require("@nocobase/cli/src/plugin-generator");
|
|
184
193
|
const generator = new PluginGenerator({
|
|
185
|
-
cwd:
|
|
194
|
+
cwd: process.cwd(),
|
|
186
195
|
args: {},
|
|
187
196
|
context: {
|
|
188
197
|
name
|
|
@@ -191,13 +200,38 @@ const _PluginManager = class _PluginManager {
|
|
|
191
200
|
await generator.run();
|
|
192
201
|
}, "createPlugin");
|
|
193
202
|
await createPlugin(pluginName);
|
|
194
|
-
|
|
203
|
+
try {
|
|
204
|
+
await this.app.db.auth({ retry: 1 });
|
|
205
|
+
const installed = await this.app.isInstalled();
|
|
206
|
+
if (!installed) {
|
|
207
|
+
console.log(`yarn pm add ${pluginName}`);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
} catch (error) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
this.app.log.info("attempt to add the plugin to the app");
|
|
214
|
+
let packageName;
|
|
215
|
+
try {
|
|
216
|
+
packageName = await _PluginManager.getPackageName(pluginName);
|
|
217
|
+
} catch (error) {
|
|
218
|
+
packageName = pluginName;
|
|
219
|
+
}
|
|
220
|
+
const json = await _PluginManager.getPackageJson(packageName);
|
|
221
|
+
this.app.log.info(`add plugin [${packageName}]`, {
|
|
222
|
+
name: pluginName,
|
|
223
|
+
packageName,
|
|
224
|
+
version: json.version
|
|
225
|
+
});
|
|
226
|
+
await this.repository.updateOrCreate({
|
|
195
227
|
values: {
|
|
196
228
|
name: pluginName,
|
|
197
|
-
packageName
|
|
198
|
-
version:
|
|
199
|
-
}
|
|
229
|
+
packageName,
|
|
230
|
+
version: json.version
|
|
231
|
+
},
|
|
232
|
+
filterKeys: ["name"]
|
|
200
233
|
});
|
|
234
|
+
await sleep(1e3);
|
|
201
235
|
await (0, import_helper.tsxRerunning)();
|
|
202
236
|
}
|
|
203
237
|
async add(plugin, options = {}, insert = false, isUpgrade = false) {
|
|
@@ -254,7 +288,7 @@ const _PluginManager = class _PluginManager {
|
|
|
254
288
|
await this.initOtherPlugins();
|
|
255
289
|
}
|
|
256
290
|
async loadCommands() {
|
|
257
|
-
this.app.log.
|
|
291
|
+
this.app.log.debug("load commands");
|
|
258
292
|
const items = await this.repository.find({
|
|
259
293
|
filter: {
|
|
260
294
|
enabled: true
|
|
@@ -486,37 +520,70 @@ const _PluginManager = class _PluginManager {
|
|
|
486
520
|
throw error;
|
|
487
521
|
}
|
|
488
522
|
}
|
|
489
|
-
async remove(name) {
|
|
523
|
+
async remove(name, options) {
|
|
490
524
|
const pluginNames = import_lodash.default.castArray(name);
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
|
|
525
|
+
const records = pluginNames.map((name2) => {
|
|
526
|
+
return {
|
|
527
|
+
name: name2,
|
|
528
|
+
packageName: name2
|
|
529
|
+
};
|
|
530
|
+
});
|
|
531
|
+
const removeDir = /* @__PURE__ */ __name(async () => {
|
|
532
|
+
await Promise.all(
|
|
533
|
+
records.map(async (plugin) => {
|
|
534
|
+
const dir = (0, import_path.resolve)(process.env.NODE_MODULES_PATH, plugin.packageName);
|
|
535
|
+
try {
|
|
536
|
+
const realDir = await import_fs.default.promises.realpath(dir);
|
|
537
|
+
this.app.log.debug(`rm -rf ${realDir}`);
|
|
538
|
+
return import_fs.default.promises.rm(realDir, { force: true, recursive: true });
|
|
539
|
+
} catch (error) {
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
})
|
|
543
|
+
);
|
|
544
|
+
await (0, import_execa.default)("yarn", ["nocobase", "postinstall"]);
|
|
545
|
+
}, "removeDir");
|
|
546
|
+
if (options == null ? void 0 : options.force) {
|
|
547
|
+
await this.repository.destroy({
|
|
548
|
+
filter: {
|
|
549
|
+
name: pluginNames
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
} else {
|
|
553
|
+
await this.app.load();
|
|
554
|
+
for (const pluginName of pluginNames) {
|
|
555
|
+
const plugin = this.get(pluginName);
|
|
556
|
+
if (!plugin) {
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
if (plugin.enabled) {
|
|
560
|
+
throw new Error(`plugin is enabled [${pluginName}]`);
|
|
561
|
+
}
|
|
562
|
+
await plugin.beforeRemove();
|
|
498
563
|
}
|
|
499
|
-
await
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
564
|
+
await this.repository.destroy({
|
|
565
|
+
filter: {
|
|
566
|
+
name: pluginNames
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
const plugins = [];
|
|
570
|
+
for (const pluginName of pluginNames) {
|
|
571
|
+
const plugin = this.get(pluginName);
|
|
572
|
+
if (!plugin) {
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
plugins.push(plugin);
|
|
576
|
+
this.del(pluginName);
|
|
577
|
+
await plugin.afterRemove();
|
|
504
578
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
for (const pluginName of pluginNames) {
|
|
508
|
-
const plugin = this.get(pluginName);
|
|
509
|
-
if (!plugin) {
|
|
510
|
-
continue;
|
|
579
|
+
if (await this.app.isStarted()) {
|
|
580
|
+
await this.app.tryReloadOrRestart();
|
|
511
581
|
}
|
|
512
|
-
plugins.push(plugin);
|
|
513
|
-
this.del(pluginName);
|
|
514
582
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
await plugin.afterRemove();
|
|
583
|
+
if (options == null ? void 0 : options.removeDir) {
|
|
584
|
+
await removeDir();
|
|
518
585
|
}
|
|
519
|
-
await
|
|
586
|
+
await (0, import_execa.default)("yarn", ["nocobase", "refresh"]);
|
|
520
587
|
}
|
|
521
588
|
async loadOne(plugin) {
|
|
522
589
|
this.app.setMaintainingMessage(`loading plugin ${plugin.name}...`);
|
|
@@ -572,6 +639,7 @@ const _PluginManager = class _PluginManager {
|
|
|
572
639
|
await this.add(opts["name"] || urlOrName, opts, true);
|
|
573
640
|
}
|
|
574
641
|
await this.app.emitStartedEvent();
|
|
642
|
+
await (0, import_execa.default)("yarn", ["nocobase", "postinstall"]);
|
|
575
643
|
}
|
|
576
644
|
async addByNpm(options) {
|
|
577
645
|
let { name = "", registry, packageName, authToken } = options;
|
|
@@ -823,5 +891,6 @@ var plugin_manager_default = PluginManager;
|
|
|
823
891
|
// Annotate the CommonJS export names for ESM import in node:
|
|
824
892
|
0 && (module.exports = {
|
|
825
893
|
AddPresetError,
|
|
826
|
-
PluginManager
|
|
894
|
+
PluginManager,
|
|
895
|
+
sleep
|
|
827
896
|
});
|
package/lib/plugin.d.ts
CHANGED
|
@@ -37,7 +37,8 @@ export declare abstract class Plugin<O = any> implements PluginInterface {
|
|
|
37
37
|
setOptions(options: any): void;
|
|
38
38
|
getName(): any;
|
|
39
39
|
createLogger(options: LoggerOptions): import("winston").Logger;
|
|
40
|
-
|
|
40
|
+
protected _sourceDir: string;
|
|
41
|
+
protected getSourceDir(): Promise<string>;
|
|
41
42
|
loadCommands(): Promise<void>;
|
|
42
43
|
loadMigrations(): Promise<{
|
|
43
44
|
beforeLoad: any[];
|
|
@@ -59,6 +60,7 @@ export declare abstract class Plugin<O = any> implements PluginInterface {
|
|
|
59
60
|
loadCollections(): Promise<void>;
|
|
60
61
|
requiredPlugins(): any[];
|
|
61
62
|
t(text: TFuncKey | TFuncKey[], options?: TOptions): import("i18next").TFunctionDetailedResult<object>;
|
|
63
|
+
protected isDev(): Promise<boolean>;
|
|
62
64
|
toJSON(options?: any): Promise<any>;
|
|
63
65
|
}
|
|
64
66
|
export default Plugin;
|
package/lib/plugin.js
CHANGED
|
@@ -86,18 +86,25 @@ const _Plugin = class _Plugin {
|
|
|
86
86
|
createLogger(options) {
|
|
87
87
|
return this.app.createLogger(options);
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
_sourceDir;
|
|
90
|
+
async getSourceDir() {
|
|
91
|
+
if (this._sourceDir) {
|
|
92
|
+
return this._sourceDir;
|
|
93
|
+
}
|
|
94
|
+
if (await this.isDev()) {
|
|
95
|
+
return this._sourceDir = "src";
|
|
96
|
+
}
|
|
90
97
|
if ((0, import_path.basename)(__dirname) === "src") {
|
|
91
|
-
return "src";
|
|
98
|
+
return this._sourceDir = "src";
|
|
92
99
|
}
|
|
93
|
-
return this.isPreset ? "lib" : "dist";
|
|
100
|
+
return this._sourceDir = this.isPreset ? "lib" : "dist";
|
|
94
101
|
}
|
|
95
102
|
async loadCommands() {
|
|
96
103
|
const extensions = ["js", "ts"];
|
|
97
104
|
const directory = (0, import_path.resolve)(
|
|
98
105
|
process.env.NODE_MODULES_PATH,
|
|
99
106
|
this.options.packageName,
|
|
100
|
-
this.
|
|
107
|
+
await this.getSourceDir(),
|
|
101
108
|
"server/commands"
|
|
102
109
|
);
|
|
103
110
|
const patten = `${directory}/*.{${extensions.join(",")}}`;
|
|
@@ -122,7 +129,7 @@ const _Plugin = class _Plugin {
|
|
|
122
129
|
const directory = (0, import_path.resolve)(
|
|
123
130
|
process.env.NODE_MODULES_PATH,
|
|
124
131
|
this.options.packageName,
|
|
125
|
-
this.
|
|
132
|
+
await this.getSourceDir(),
|
|
126
133
|
"server/migrations"
|
|
127
134
|
);
|
|
128
135
|
return await this.app.loadMigrations({
|
|
@@ -164,7 +171,7 @@ const _Plugin = class _Plugin {
|
|
|
164
171
|
const directory = (0, import_path.resolve)(
|
|
165
172
|
process.env.NODE_MODULES_PATH,
|
|
166
173
|
this.options.packageName,
|
|
167
|
-
this.
|
|
174
|
+
await this.getSourceDir(),
|
|
168
175
|
"server/collections"
|
|
169
176
|
);
|
|
170
177
|
if (await (0, import_utils.fsExists)(directory)) {
|
|
@@ -180,6 +187,18 @@ const _Plugin = class _Plugin {
|
|
|
180
187
|
t(text, options = {}) {
|
|
181
188
|
return this.app.i18n.t(text, { ns: this.options["packageName"], ...options });
|
|
182
189
|
}
|
|
190
|
+
async isDev() {
|
|
191
|
+
if (!this.options.packageName) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
const file = await import_fs.default.promises.realpath(
|
|
195
|
+
(0, import_path.resolve)(process.env.NODE_MODULES_PATH || (0, import_path.resolve)(process.cwd(), "node_modules"), this.options.packageName)
|
|
196
|
+
);
|
|
197
|
+
if (file.startsWith((0, import_path.resolve)(process.cwd(), "packages"))) {
|
|
198
|
+
return !!process.env.IS_DEV_CMD;
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
183
202
|
async toJSON(options = {}) {
|
|
184
203
|
const { locale = "en-US" } = options;
|
|
185
204
|
const { name, packageName, packageJson } = this.options;
|
|
@@ -190,10 +209,12 @@ const _Plugin = class _Plugin {
|
|
|
190
209
|
}
|
|
191
210
|
const results = {
|
|
192
211
|
...this.options,
|
|
212
|
+
keywords: packageJson.keywords,
|
|
193
213
|
readmeUrl: (0, import_plugin_manager.getExposeReadmeUrl)(packageName, locale),
|
|
194
214
|
changelogUrl: (0, import_plugin_manager.getExposeChangelogUrl)(packageName),
|
|
195
215
|
displayName: packageJson[`displayName.${locale}`] || packageJson.displayName || name,
|
|
196
|
-
description: packageJson[`description.${locale}`] || packageJson.description
|
|
216
|
+
description: packageJson[`description.${locale}`] || packageJson.description,
|
|
217
|
+
homepage: packageJson[`homepage.${locale}`] || packageJson.homepage
|
|
197
218
|
};
|
|
198
219
|
if (!options.withOutOpenFile) {
|
|
199
220
|
const file = await import_fs.default.promises.realpath(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/server",
|
|
3
|
-
"version": "0.19.0-alpha.
|
|
3
|
+
"version": "0.19.0-alpha.10",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "./lib/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -10,17 +10,17 @@
|
|
|
10
10
|
"@koa/cors": "^3.1.0",
|
|
11
11
|
"@koa/multer": "^3.0.2",
|
|
12
12
|
"@koa/router": "^9.4.0",
|
|
13
|
-
"@nocobase/acl": "0.19.0-alpha.
|
|
14
|
-
"@nocobase/actions": "0.19.0-alpha.
|
|
15
|
-
"@nocobase/auth": "0.19.0-alpha.
|
|
16
|
-
"@nocobase/cache": "0.19.0-alpha.
|
|
17
|
-
"@nocobase/database": "0.19.0-alpha.
|
|
18
|
-
"@nocobase/evaluators": "0.19.0-alpha.
|
|
19
|
-
"@nocobase/logger": "0.19.0-alpha.
|
|
20
|
-
"@nocobase/resourcer": "0.19.0-alpha.
|
|
21
|
-
"@nocobase/sdk": "0.19.0-alpha.
|
|
22
|
-
"@nocobase/telemetry": "0.19.0-alpha.
|
|
23
|
-
"@nocobase/utils": "0.19.0-alpha.
|
|
13
|
+
"@nocobase/acl": "0.19.0-alpha.10",
|
|
14
|
+
"@nocobase/actions": "0.19.0-alpha.10",
|
|
15
|
+
"@nocobase/auth": "0.19.0-alpha.10",
|
|
16
|
+
"@nocobase/cache": "0.19.0-alpha.10",
|
|
17
|
+
"@nocobase/database": "0.19.0-alpha.10",
|
|
18
|
+
"@nocobase/evaluators": "0.19.0-alpha.10",
|
|
19
|
+
"@nocobase/logger": "0.19.0-alpha.10",
|
|
20
|
+
"@nocobase/resourcer": "0.19.0-alpha.10",
|
|
21
|
+
"@nocobase/sdk": "0.19.0-alpha.10",
|
|
22
|
+
"@nocobase/telemetry": "0.19.0-alpha.10",
|
|
23
|
+
"@nocobase/utils": "0.19.0-alpha.10",
|
|
24
24
|
"@types/decompress": "4.2.4",
|
|
25
25
|
"@types/ini": "^1.3.31",
|
|
26
26
|
"@types/koa-send": "^4.1.3",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"@types/serve-handler": "^6.1.1",
|
|
54
54
|
"@types/ws": "^8.5.5"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "d09d81eba67339da36bcec27939a85b35d180770"
|
|
57
57
|
}
|