@nocobase/server 0.19.0-alpha.2 → 0.19.0-alpha.4

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.
@@ -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 && ["install", "upgrade", "pm.add", "pm.update", "pm.enable", "pm.disable", "pm.remove", "restore"].includes(
217
- maintainingStatus.command.name
218
- ) && !startOptions.recover) {
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
  });
@@ -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
- this.log.debug("stop app...", { method: "stop" });
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
- this.log.warn(`app is stopped`, { method: "stop" });
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
- this.log.info(`close db`, { method: "stop" });
520
+ log.info(`close db`, { method: "stop" });
511
521
  await this.db.close();
512
522
  }
513
523
  } catch (e) {
514
- this.log.error(e.message, { method: "stop", err: e.stack });
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
- this.log.info(`app has stopped`, { method: "stop" });
534
+ log.info(`app has stopped`, { method: "stop" });
525
535
  this._started = false;
526
536
  }
527
537
  async destroy(options = {}) {
@@ -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");
@@ -22,7 +22,7 @@ __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
26
  await app.install(options);
27
27
  const reinstall = options.clean || options.force;
28
28
  app.log.info(`app ${reinstall ? "reinstalled" : "installed"} successfully [v${app.getVersion()}]`);
@@ -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").ipc().arguments("plugin").action(async (plugin) => {
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").ipc().preload().arguments("<plugins...>").action(async (plugins) => {
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,3 @@
1
+ import Application from '../application';
2
+ declare const _default: (app: Application) => void;
3
+ export default _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");
@@ -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 {};
@@ -266,7 +266,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
266
266
  if (ipcClient) {
267
267
  const response = await ipcClient.write({ type: "passCliArgv", payload: { argv: process.argv } });
268
268
  ipcClient.close();
269
- if (response.type !== "error" || response.payload.message !== "Not handle by ipc server") {
269
+ if (!["error", "not_found"].includes(response.type)) {
270
270
  return;
271
271
  }
272
272
  }
@@ -275,16 +275,20 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
275
275
  await (0, import_plugin_symlink.createStoragePluginsSymlink)();
276
276
  }
277
277
  const mainApp = import_app_supervisor.AppSupervisor.getInstance().bootMainApp(options.mainAppOptions);
278
- await mainApp.load();
279
278
  mainApp.runAsCLI(process.argv, {
280
279
  throwError: true,
281
280
  from: "node"
282
281
  }).then(async () => {
283
282
  if (!await mainApp.isStarted()) {
284
- 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 });
285
291
  }
286
- }).catch((e) => {
287
- console.error(e);
288
292
  });
289
293
  }
290
294
  isStart() {
@@ -324,7 +328,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
324
328
  this.wsServer = new import_ws_server.WSServer();
325
329
  this.server.on("upgrade", (request, socket, head) => {
326
330
  const { pathname } = (0, import_url.parse)(request.url);
327
- if (pathname === "/ws") {
331
+ if (pathname === process.env.WS_PATH) {
328
332
  this.wsServer.wss.handleUpgrade(request, socket, head, (ws) => {
329
333
  this.wsServer.wss.emit("connection", ws, request);
330
334
  });
@@ -355,6 +359,14 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
355
359
  (_a = this.server) == null ? void 0 : _a.close();
356
360
  (_b = this.wsServer) == null ? void 0 : _b.close();
357
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
+ }
358
370
  };
359
371
  __name(_Gateway, "Gateway");
360
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,10 +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"));
35
+ var import_logger = require("@nocobase/logger");
36
36
  var events = __toESM(require("events"));
37
+ var import_net = __toESM(require("net"));
37
38
  var import_xpipe = __toESM(require("xpipe"));
38
- var import_logger = require("@nocobase/logger");
39
39
  const writeJSON = /* @__PURE__ */ __name((socket, data) => {
40
40
  socket.write(JSON.stringify(data) + "\n", "utf8");
41
41
  }, "writeJSON");
@@ -70,6 +70,8 @@ const _IPCSocketClient = class _IPCSocketClient extends events.EventEmitter {
70
70
  }
71
71
  async handleServerMessage({ reqId, type, payload }) {
72
72
  switch (type) {
73
+ case "not_found":
74
+ break;
73
75
  case "error":
74
76
  this.logger.error({ reqId, message: `${payload.message}|${payload.stack}` });
75
77
  break;
@@ -8,6 +8,6 @@ export declare class IPCSocketServer {
8
8
  reqId: any;
9
9
  type: any;
10
10
  payload: any;
11
- }): Promise<import("../app-command").AppCommand>;
11
+ }): Promise<string | false | import("../app-command").AppCommand>;
12
12
  close(): void;
13
13
  }
@@ -31,13 +31,13 @@ __export(ipc_socket_server_exports, {
31
31
  IPCSocketServer: () => IPCSocketServer
32
32
  });
33
33
  module.exports = __toCommonJS(ipc_socket_server_exports);
34
- var import_net = __toESM(require("net"));
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"));
37
38
  var import_xpipe = __toESM(require("xpipe"));
38
39
  var import_app_supervisor = require("../app-supervisor");
39
40
  var import_ipc_socket_client = require("./ipc-socket-client");
40
- var import_crypto = require("crypto");
41
41
  const _IPCSocketServer = class _IPCSocketServer {
42
42
  socketServer;
43
43
  constructor(server) {
@@ -65,10 +65,10 @@ const _IPCSocketServer = class _IPCSocketServer {
65
65
  }
66
66
  const reqId = (0, import_crypto.randomUUID)();
67
67
  const dataObj = JSON.parse(message);
68
- _IPCSocketServer.handleClientMessage({ reqId, ...dataObj }).then(() => {
68
+ _IPCSocketServer.handleClientMessage({ reqId, ...dataObj }).then((result) => {
69
69
  (0, import_ipc_socket_client.writeJSON)(c, {
70
70
  reqId,
71
- type: "success"
71
+ type: result === false ? "not_found" : "success"
72
72
  });
73
73
  }).catch((err) => {
74
74
  (0, import_ipc_socket_client.writeJSON)(c, {
@@ -89,19 +89,37 @@ const _IPCSocketServer = class _IPCSocketServer {
89
89
  return new _IPCSocketServer(socketServer);
90
90
  }
91
91
  static async handleClientMessage({ reqId, type, payload }) {
92
- console.log(`cli received message ${type}`);
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
+ }
93
111
  if (type === "passCliArgv") {
94
112
  const argv = payload.argv;
95
113
  const mainApp = await import_app_supervisor.AppSupervisor.getInstance().getApp("main");
96
114
  if (!mainApp.cli.hasCommand(argv[2])) {
97
- console.log("passCliArgv", argv[2]);
98
115
  await mainApp.pm.loadCommands();
99
116
  }
100
117
  const cli = mainApp.cli;
101
118
  if (!cli.parseHandleByIPCServer(argv, {
102
119
  from: "node"
103
120
  })) {
104
- throw new Error("Not handle by ipc server");
121
+ mainApp.log.debug("Not handle by ipc server");
122
+ return false;
105
123
  }
106
124
  return mainApp.runAsCLI(argv, {
107
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;
@@ -77,6 +77,9 @@ function dataWrapping() {
77
77
  data: ctx.body
78
78
  };
79
79
  }
80
+ if (ctx.body && ((_b = ctx.state.messages) == null ? void 0 : _b.length)) {
81
+ ctx.body.messages = ctx.state.messages;
82
+ }
80
83
  }, "dataWrapping");
81
84
  }
82
85
  __name(dataWrapping, "dataWrapping");
@@ -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 this.db.sequelize.getQueryInterface().addColumn(tableNameWithSchema, field.columnName(), {
33
- type: import_database.DataTypes.STRING
34
- });
35
- await this.db.sequelize.getQueryInterface().addConstraint(tableNameWithSchema, {
36
- type: "unique",
37
- fields: [field.columnName()]
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): Promise<void>;
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[]): Promise<void>;
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: (0, import_path.resolve)(process.cwd(), name),
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
- await this.repository.create({
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: pluginName,
198
- version: "0.1.0"
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.info("load commands");
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
- for (const pluginName of pluginNames) {
492
- const plugin = this.get(pluginName);
493
- if (!plugin) {
494
- continue;
495
- }
496
- if (plugin.enabled) {
497
- throw new Error(`${pluginName} plugin is enabled`);
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 plugin.beforeRemove();
500
- }
501
- await this.repository.destroy({
502
- filter: {
503
- name: pluginNames
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
- const plugins = [];
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
- await this.app.reload();
516
- for (const plugin of plugins) {
517
- await plugin.afterRemove();
583
+ if (options == null ? void 0 : options.removeDir) {
584
+ await removeDir();
518
585
  }
519
- await this.app.emitStartedEvent();
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/server",
3
- "version": "0.19.0-alpha.2",
3
+ "version": "0.19.0-alpha.4",
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.2",
14
- "@nocobase/actions": "0.19.0-alpha.2",
15
- "@nocobase/auth": "0.19.0-alpha.2",
16
- "@nocobase/cache": "0.19.0-alpha.2",
17
- "@nocobase/database": "0.19.0-alpha.2",
18
- "@nocobase/evaluators": "0.19.0-alpha.2",
19
- "@nocobase/logger": "0.19.0-alpha.2",
20
- "@nocobase/resourcer": "0.19.0-alpha.2",
21
- "@nocobase/sdk": "0.19.0-alpha.2",
22
- "@nocobase/telemetry": "0.19.0-alpha.2",
23
- "@nocobase/utils": "0.19.0-alpha.2",
13
+ "@nocobase/acl": "0.19.0-alpha.4",
14
+ "@nocobase/actions": "0.19.0-alpha.4",
15
+ "@nocobase/auth": "0.19.0-alpha.4",
16
+ "@nocobase/cache": "0.19.0-alpha.4",
17
+ "@nocobase/database": "0.19.0-alpha.4",
18
+ "@nocobase/evaluators": "0.19.0-alpha.4",
19
+ "@nocobase/logger": "0.19.0-alpha.4",
20
+ "@nocobase/resourcer": "0.19.0-alpha.4",
21
+ "@nocobase/sdk": "0.19.0-alpha.4",
22
+ "@nocobase/telemetry": "0.19.0-alpha.4",
23
+ "@nocobase/utils": "0.19.0-alpha.4",
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": "cff5b77ecf12ccdb450d50d505b3aa44a68478c8"
56
+ "gitHead": "9583023f7bea828da5192384a5c002782c341b65"
57
57
  }