@nocobase/server 0.12.0-alpha.5 → 0.13.0-alpha.2

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.
Files changed (52) hide show
  1. package/lib/app-supervisor.d.ts +59 -0
  2. package/lib/app-supervisor.js +268 -0
  3. package/lib/application.d.ts +65 -52
  4. package/lib/application.js +369 -269
  5. package/lib/commands/db-sync.js +0 -3
  6. package/lib/commands/destroy.d.ts +3 -0
  7. package/lib/commands/destroy.js +16 -0
  8. package/lib/commands/index.js +3 -0
  9. package/lib/commands/install.js +1 -37
  10. package/lib/commands/pm.js +53 -13
  11. package/lib/commands/restart.d.ts +3 -0
  12. package/lib/commands/restart.js +16 -0
  13. package/lib/commands/start.js +10 -10
  14. package/lib/commands/stop.d.ts +3 -0
  15. package/lib/commands/stop.js +16 -0
  16. package/lib/commands/upgrade.js +0 -3
  17. package/lib/errors/application-not-install.d.ts +4 -0
  18. package/lib/errors/application-not-install.js +14 -0
  19. package/lib/gateway/errors.d.ts +22 -0
  20. package/lib/gateway/errors.js +146 -0
  21. package/lib/gateway/handle-plugin-static-file.d.ts +3 -0
  22. package/lib/gateway/handle-plugin-static-file.js +91 -0
  23. package/lib/gateway/index.d.ts +59 -0
  24. package/lib/gateway/index.js +327 -0
  25. package/lib/gateway/ipc-socket-client.d.ts +9 -0
  26. package/lib/gateway/ipc-socket-client.js +48 -0
  27. package/lib/gateway/ipc-socket-server.d.ts +12 -0
  28. package/lib/gateway/ipc-socket-server.js +86 -0
  29. package/lib/gateway/ws-server.d.ts +26 -0
  30. package/lib/gateway/ws-server.js +198 -0
  31. package/lib/helper.d.ts +3 -0
  32. package/lib/helper.js +32 -1
  33. package/lib/helpers/application-version.d.ts +10 -0
  34. package/lib/helpers/application-version.js +78 -0
  35. package/lib/index.d.ts +2 -1
  36. package/lib/index.js +24 -8
  37. package/lib/locale/locale.d.ts +1 -1
  38. package/lib/locale/locale.js +26 -17
  39. package/lib/locale/resource.js +8 -0
  40. package/lib/plugin-manager/clientStaticMiddleware.d.ts +0 -8
  41. package/lib/plugin-manager/clientStaticMiddleware.js +2 -95
  42. package/lib/plugin-manager/options/resource.js +12 -3
  43. package/lib/plugin-manager/plugin-manager-repository.d.ts +2 -1
  44. package/lib/plugin-manager/plugin-manager-repository.js +53 -18
  45. package/lib/plugin-manager/plugin-manager.d.ts +21 -18
  46. package/lib/plugin-manager/plugin-manager.js +394 -332
  47. package/lib/plugin.d.ts +10 -2
  48. package/lib/plugin.js +21 -3
  49. package/lib/swagger/index.json +1565 -0
  50. package/package.json +18 -13
  51. package/lib/app-manager.d.ts +0 -21
  52. package/lib/app-manager.js +0 -138
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.ApplicationVersion = exports.Application = void 0;
6
+ exports.default = exports.Application = void 0;
7
7
  function _actions() {
8
8
  const data = require("@nocobase/actions");
9
9
  _actions = function _actions() {
@@ -74,27 +74,25 @@ function _koaCompose() {
74
74
  };
75
75
  return data;
76
76
  }
77
- function _semver() {
78
- const data = _interopRequireDefault(require("semver"));
79
- _semver = function _semver() {
80
- return data;
81
- };
82
- return data;
83
- }
84
- function _util() {
85
- const data = require("util");
86
- _util = function _util() {
77
+ function _lodash() {
78
+ const data = _interopRequireDefault(require("lodash"));
79
+ _lodash = function _lodash() {
87
80
  return data;
88
81
  };
89
82
  return data;
90
83
  }
91
84
  var _acl = require("./acl");
92
- var _appManager = require("./app-manager");
85
+ var _appSupervisor = require("./app-supervisor");
93
86
  var _commands = require("./commands");
87
+ var _applicationNotInstall = require("./errors/application-not-install");
94
88
  var _helper = require("./helper");
89
+ var _applicationVersion = require("./helpers/application-version");
95
90
  var _locale = require("./locale");
96
91
  var _pluginManager = require("./plugin-manager");
97
92
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
93
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
94
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
95
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
98
96
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
99
97
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
100
98
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -103,72 +101,25 @@ function _toPrimitive(input, hint) { if (typeof input !== "object" || input ===
103
101
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
104
102
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
105
103
  const packageJson = require('../package.json');
106
- class ApplicationVersion {
107
- constructor(app) {
108
- this.app = void 0;
109
- this.collection = void 0;
110
- this.app = app;
111
- if (!app.db.hasCollection('applicationVersion')) {
112
- app.db.collection({
113
- name: 'applicationVersion',
114
- namespace: 'core.applicationVersion',
115
- duplicator: 'required',
116
- timestamps: false,
117
- fields: [{
118
- name: 'value',
119
- type: 'string'
120
- }]
121
- });
122
- }
123
- this.collection = this.app.db.getCollection('applicationVersion');
124
- }
125
- get() {
126
- var _this = this;
127
- return _asyncToGenerator(function* () {
128
- if (yield _this.app.db.collectionExistsInDb('applicationVersion')) {
129
- const model = yield _this.collection.model.findOne();
130
- if (!model) {
131
- return null;
132
- }
133
- return model.get('value');
134
- }
135
- return null;
136
- })();
137
- }
138
- update() {
139
- var _this2 = this;
140
- return _asyncToGenerator(function* () {
141
- yield _this2.collection.sync();
142
- yield _this2.collection.model.destroy({
143
- truncate: true
144
- });
145
- yield _this2.collection.model.create({
146
- value: _this2.app.getVersion()
147
- });
148
- })();
149
- }
150
- satisfies(range) {
151
- var _this3 = this;
152
- return _asyncToGenerator(function* () {
153
- if (yield _this3.app.db.collectionExistsInDb('applicationVersion')) {
154
- const model = yield _this3.collection.model.findOne();
155
- const version = model === null || model === void 0 ? void 0 : model.value;
156
- if (!version) {
157
- return true;
158
- }
159
- return _semver().default.satisfies(version, range, {
160
- includePrerelease: true
161
- });
162
- }
163
- return true;
164
- })();
165
- }
166
- }
167
- exports.ApplicationVersion = ApplicationVersion;
168
104
  class Application extends _koa().default {
169
105
  constructor(options) {
170
106
  super();
171
107
  this.options = void 0;
108
+ this.listenServer = void 0;
109
+ this.stopped = false;
110
+ this.ready = false;
111
+ this.rawOptions = void 0;
112
+ this.activatedCommand = null;
113
+ this.running = false;
114
+ this.plugins = new Map();
115
+ this._appSupervisor = _appSupervisor.AppSupervisor.getInstance();
116
+ this._started = void 0;
117
+ this._authenticated = false;
118
+ this._maintaining = false;
119
+ this._maintainingCommandStatus = void 0;
120
+ this._maintainingStatusBeforeCommand = void 0;
121
+ this._loaded = void 0;
122
+ this._maintainingMessage = void 0;
172
123
  this._db = void 0;
173
124
  this._logger = void 0;
174
125
  this._resourcer = void 0;
@@ -177,140 +128,87 @@ class Application extends _koa().default {
177
128
  this._i18n = void 0;
178
129
  this._pm = void 0;
179
130
  this._acl = void 0;
180
- this._appManager = void 0;
181
131
  this._authManager = void 0;
182
132
  this._locales = void 0;
183
133
  this._version = void 0;
184
- this.plugins = new Map();
185
- this.listenServer = void 0;
186
- this.stopped = false;
187
134
  this.options = options;
135
+ this.rawOptions = this.name == 'main' ? _lodash().default.cloneDeep(options) : {};
188
136
  this.init();
137
+ this._appSupervisor.addApp(this);
138
+ }
139
+ get loaded() {
140
+ return this._loaded;
141
+ }
142
+ get maintainingMessage() {
143
+ return this._maintainingMessage;
189
144
  }
190
145
  get db() {
191
146
  return this._db;
192
147
  }
193
- get cache() {
194
- return this._cache;
148
+ get logger() {
149
+ return this._logger;
195
150
  }
196
151
  get resourcer() {
197
152
  return this._resourcer;
198
153
  }
154
+ get cache() {
155
+ return this._cache;
156
+ }
199
157
  get cli() {
200
158
  return this._cli;
201
159
  }
202
- get acl() {
203
- return this._acl;
204
- }
205
160
  get i18n() {
206
161
  return this._i18n;
207
162
  }
208
163
  get pm() {
209
164
  return this._pm;
210
165
  }
211
- get version() {
212
- return this._version;
213
- }
214
- get appManager() {
215
- return this._appManager;
166
+ get acl() {
167
+ return this._acl;
216
168
  }
217
169
  get authManager() {
218
170
  return this._authManager;
219
171
  }
220
- get logger() {
221
- return this._logger;
172
+ get locales() {
173
+ return this._locales;
174
+ }
175
+ get version() {
176
+ return this._version;
222
177
  }
223
178
  get log() {
224
179
  return this._logger;
225
180
  }
226
- get locales() {
227
- return this._locales;
228
- }
229
181
  get name() {
230
182
  return this.options.name || 'main';
231
183
  }
232
- init() {
233
- const options = this.options;
234
- const logger = (0, _logger().createAppLogger)(options.logger);
235
- this._logger = logger.instance;
236
- // @ts-ignore
237
- this._events = [];
238
- // @ts-ignore
239
- this._eventsCount = [];
240
- this.removeAllListeners();
241
- this.middleware = new (_utils().Toposort)();
242
- this.plugins = new Map();
243
- this._acl = (0, _acl.createACL)();
244
- this.use(logger.middleware, {
245
- tag: 'logger'
246
- });
247
- if (this._db) {
248
- // MaxListenersExceededWarning
249
- this._db.removeAllListeners();
250
- }
251
- this._db = this.createDatabase(options);
252
- this._resourcer = (0, _helper.createResourcer)(options);
253
- this._cli = new (_commander().Command)('nocobase').usage('[command] [options]');
254
- this._i18n = (0, _helper.createI18n)(options);
255
- this._cache = (0, _cache().createCache)(options.cache);
256
- this.context.db = this._db;
257
- this.context.logger = this._logger;
258
- this.context.resourcer = this._resourcer;
259
- this.context.cache = this._cache;
260
- if (this._pm) {
261
- this._pm = this._pm.clone();
262
- } else {
263
- this._pm = new _pluginManager.PluginManager({
264
- app: this,
265
- plugins: options.plugins
266
- });
267
- }
268
- if (this._appManager) {
269
- this._appManager.bindMainApplication(this);
270
- } else {
271
- this._appManager = new _appManager.AppManager(this);
272
- }
273
- this._authManager = new (_auth().AuthManager)({
274
- authKey: 'X-Authenticator',
275
- default: 'basic'
276
- });
277
- this.resource({
278
- name: 'auth',
279
- actions: _auth().actions
280
- });
281
- this._resourcer.use(this._authManager.middleware(), {
282
- tag: 'auth'
283
- });
284
- if (this.options.acl !== false) {
285
- this._resourcer.use(this._acl.middleware(), {
286
- tag: 'acl',
287
- after: ['auth']
288
- });
289
- }
290
- this._locales = new _locale.Locale(this);
291
- (0, _helper.registerMiddlewares)(this, options);
292
- if (options.registerActions !== false) {
293
- (0, _actions().registerActions)(this);
184
+ isMaintaining() {
185
+ return this._maintaining;
186
+ }
187
+ getMaintaining() {
188
+ return this._maintainingCommandStatus;
189
+ }
190
+ setMaintaining(_maintainingCommandStatus) {
191
+ this._maintainingCommandStatus = _maintainingCommandStatus;
192
+ this.emit('maintaining', _maintainingCommandStatus);
193
+ if (_maintainingCommandStatus.status == 'command_end') {
194
+ this._maintaining = false;
195
+ return;
294
196
  }
295
- (0, _commands.registerCli)(this);
296
- this._version = new ApplicationVersion(this);
197
+ this._maintaining = true;
297
198
  }
298
- createDatabase(options) {
299
- const db = new (_database().default)(_objectSpread(_objectSpread({}, options.database instanceof _database().default ? options.database.options : options.database), {}, {
300
- migrator: {
301
- context: {
302
- app: this
303
- }
304
- }
305
- }));
306
- db.setLogger(this._logger);
307
- return db;
199
+ setMaintainingMessage(message) {
200
+ this._maintainingMessage = message;
201
+ this.emit('maintainingMessageChanged', {
202
+ message: this._maintainingMessage,
203
+ maintainingStatus: this._maintainingCommandStatus
204
+ });
308
205
  }
309
206
  getVersion() {
310
207
  return packageJson.version;
311
208
  }
312
209
  plugin(pluginClass, options) {
313
- return this.pm.addStatic(pluginClass, options);
210
+ this.log.debug(`add plugin ${pluginClass.name}`);
211
+ this.pm.addPreset(pluginClass, options);
314
212
  }
315
213
  // @ts-ignore
316
214
  use(middleware, options) {
@@ -320,12 +218,11 @@ class Application extends _koa().default {
320
218
  callback() {
321
219
  const fn = (0, _koaCompose().default)(this.middleware.nodes);
322
220
  if (!this.listenerCount('error')) this.on('error', this.onerror);
323
- const handleRequest = (req, res) => {
221
+ return (req, res) => {
324
222
  const ctx = this.createContext(req, res);
325
223
  // @ts-ignore
326
224
  return this.handleRequest(ctx, fn);
327
225
  };
328
- return handleRequest;
329
226
  }
330
227
  collection(options) {
331
228
  return this.db.collection(options);
@@ -343,139 +240,227 @@ class Application extends _koa().default {
343
240
  return this.cli._findCommand(name);
344
241
  }
345
242
  load(options) {
346
- var _this4 = this;
243
+ var _this = this;
347
244
  return _asyncToGenerator(function* () {
245
+ if (_this._loaded) {
246
+ return;
247
+ }
348
248
  if (options !== null && options !== void 0 && options.reload) {
349
- console.log(`Reload the ${_this4.name} application configuration`);
350
- const oldDb = _this4._db;
351
- _this4.init();
249
+ _this.setMaintainingMessage('app reload');
250
+ _this.log.info(`app.reload()`);
251
+ const oldDb = _this._db;
252
+ _this.init();
352
253
  yield oldDb.close();
353
254
  }
354
- yield _this4.emitAsync('beforeLoad', _this4, options);
355
- yield _this4.pm.load(options);
356
- yield _this4.emitAsync('afterLoad', _this4, options);
255
+ _this.setMaintainingMessage('init plugins');
256
+ yield _this.pm.initPlugins();
257
+ _this.setMaintainingMessage('start load');
258
+ _this.setMaintainingMessage('emit beforeLoad');
259
+ yield _this.emitAsync('beforeLoad', _this, options);
260
+ yield _this.pm.load(options);
261
+ _this.setMaintainingMessage('emit afterLoad');
262
+ yield _this.emitAsync('afterLoad', _this, options);
263
+ _this._loaded = true;
357
264
  })();
358
265
  }
359
266
  reload(options) {
360
- var _this5 = this;
267
+ var _this2 = this;
361
268
  return _asyncToGenerator(function* () {
362
- yield _this5.load(_objectSpread(_objectSpread({}, options), {}, {
269
+ _this2.log.debug(`start reload`);
270
+ _this2._loaded = false;
271
+ yield _this2.load(_objectSpread(_objectSpread({}, options), {}, {
363
272
  reload: true
364
273
  }));
365
- yield _this5.emitAsync('afterReload', _this5, options);
274
+ _this2.log.debug('emit afterReload');
275
+ _this2.setMaintainingMessage('emit afterReload');
276
+ yield _this2.emitAsync('afterReload', _this2, options);
277
+ _this2.log.debug(`finish reload`);
366
278
  })();
367
279
  }
368
280
  getPlugin(name) {
369
281
  return this.pm.get(name);
370
282
  }
371
283
  parse(argv = process.argv) {
372
- var _this6 = this;
284
+ var _this3 = this;
373
285
  return _asyncToGenerator(function* () {
374
- return _this6.runAsCLI(argv);
286
+ return _this3.runAsCLI(argv);
375
287
  })();
376
288
  }
289
+ authenticate() {
290
+ var _this4 = this;
291
+ return _asyncToGenerator(function* () {
292
+ if (_this4._authenticated) {
293
+ return;
294
+ }
295
+ _this4._authenticated = true;
296
+ yield _this4.db.auth({
297
+ retry: 30
298
+ });
299
+ yield _this4.dbVersionCheck({
300
+ exit: true
301
+ });
302
+ yield _this4.db.prepare();
303
+ })();
304
+ }
305
+ runCommand(command, ...args) {
306
+ var _this5 = this;
307
+ return _asyncToGenerator(function* () {
308
+ return yield _this5.runAsCLI([command, ...args], {
309
+ from: 'user'
310
+ });
311
+ })();
312
+ }
313
+ createCli() {
314
+ var _this6 = this;
315
+ return new (_commander().Command)('nocobase').usage('[command] [options]').hook('preAction', /*#__PURE__*/function () {
316
+ var _ref = _asyncToGenerator(function* (_, actionCommand) {
317
+ _this6.activatedCommand = {
318
+ name: (0, _helper.getCommandFullName)(actionCommand)
319
+ };
320
+ _this6.setMaintaining({
321
+ status: 'command_begin',
322
+ command: _this6.activatedCommand
323
+ });
324
+ _this6.setMaintaining({
325
+ status: 'command_running',
326
+ command: _this6.activatedCommand
327
+ });
328
+ yield _this6.authenticate();
329
+ yield _this6.load();
330
+ });
331
+ return function (_x, _x2) {
332
+ return _ref.apply(this, arguments);
333
+ };
334
+ }()).hook('postAction', /*#__PURE__*/function () {
335
+ var _ref2 = _asyncToGenerator(function* (_, actionCommand) {
336
+ var _this6$_maintainingSt;
337
+ if ((_this6$_maintainingSt = _this6._maintainingStatusBeforeCommand) !== null && _this6$_maintainingSt !== void 0 && _this6$_maintainingSt.error && _this6._started) {
338
+ yield _this6.restart();
339
+ }
340
+ });
341
+ return function (_x3, _x4) {
342
+ return _ref2.apply(this, arguments);
343
+ };
344
+ }());
345
+ }
377
346
  runAsCLI(argv = process.argv, options) {
378
347
  var _this7 = this;
379
348
  return _asyncToGenerator(function* () {
349
+ if (_this7.activatedCommand) {
350
+ return;
351
+ }
352
+ _this7._maintainingStatusBeforeCommand = _this7._maintainingCommandStatus;
380
353
  try {
381
- yield _this7.db.auth({
382
- retry: 30
354
+ const command = yield _this7.cli.parseAsync(argv, options);
355
+ _this7.setMaintaining({
356
+ status: 'command_end',
357
+ command: _this7.activatedCommand
383
358
  });
359
+ return command;
384
360
  } catch (error) {
385
- console.log(_chalk().default.red(error.message));
386
- process.exit(1);
387
- }
388
- yield _this7.dbVersionCheck({
389
- exit: true
390
- });
391
- yield _this7.db.prepare();
392
- if ((argv === null || argv === void 0 ? void 0 : argv[2]) !== 'upgrade') {
393
- yield _this7.load({
394
- method: argv === null || argv === void 0 ? void 0 : argv[2]
361
+ console.log(`run command ${_this7.activatedCommand.name} error:`, error);
362
+ _this7.setMaintaining({
363
+ status: 'command_error',
364
+ command: _this7.activatedCommand,
365
+ error
395
366
  });
367
+ } finally {
368
+ _this7.activatedCommand = null;
396
369
  }
397
- return _this7.cli.parseAsync(argv, options);
398
370
  })();
399
371
  }
400
372
  start(options = {}) {
401
373
  var _this8 = this;
402
374
  return _asyncToGenerator(function* () {
403
- var _options$listen;
375
+ if (_this8._started) {
376
+ return;
377
+ }
378
+ _this8._started = true;
379
+ if (options.checkInstall && !(yield _this8.isInstalled())) {
380
+ throw new _applicationNotInstall.ApplicationNotInstall(`Application ${_this8.name} is not installed, Please run 'yarn nocobase install' command first`);
381
+ }
382
+ _this8.setMaintainingMessage('starting app...');
404
383
  if (_this8.db.closed()) {
405
384
  yield _this8.db.reconnect();
406
385
  }
407
- if (options.dbSync) {
408
- console.log('db sync...');
409
- yield _this8.db.sync();
410
- }
386
+ _this8.setMaintainingMessage('emit beforeStart');
411
387
  yield _this8.emitAsync('beforeStart', _this8, options);
412
- if (options !== null && options !== void 0 && (_options$listen = options.listen) !== null && _options$listen !== void 0 && _options$listen.port) {
413
- const pmServer = yield _this8.pm.listen();
414
- const listen = () => new Promise((resolve, reject) => {
415
- const Server = _this8.listen(options === null || options === void 0 ? void 0 : options.listen, () => {
416
- resolve(Server);
417
- });
418
- Server.on('error', err => {
419
- reject(err);
420
- });
421
- Server.on('close', () => {
422
- pmServer.close();
423
- });
424
- });
425
- try {
426
- //@ts-ignore
427
- _this8.listenServer = yield listen();
428
- } catch (e) {
429
- console.error(e);
430
- process.exit(1);
431
- }
432
- }
388
+ _this8.setMaintainingMessage('emit afterStart');
433
389
  yield _this8.emitAsync('afterStart', _this8, options);
390
+ yield _this8.emitAsync('__started', _this8, options);
434
391
  _this8.stopped = false;
435
392
  })();
436
393
  }
437
- listen(...args) {
438
- return this.appManager.listen(...args);
439
- }
440
- stop(options = {}) {
394
+ isStarted() {
441
395
  var _this9 = this;
442
396
  return _asyncToGenerator(function* () {
443
- if (_this9.stopped) {
444
- _this9.log.warn(`Application ${_this9.name} already stopped`);
397
+ return _this9._started;
398
+ })();
399
+ }
400
+ tryReloadOrRestart() {
401
+ var _this10 = this;
402
+ return _asyncToGenerator(function* () {
403
+ if (_this10._started) {
404
+ yield _this10.restart();
405
+ } else {
406
+ yield _this10.reload();
407
+ }
408
+ })();
409
+ }
410
+ restart(options = {}) {
411
+ var _this11 = this;
412
+ return _asyncToGenerator(function* () {
413
+ if (!_this11._started) {
445
414
  return;
446
415
  }
447
- yield _this9.emitAsync('beforeStop', _this9, options);
448
- // close http server
449
- if (_this9.listenServer) {
450
- yield (0, _util().promisify)(_this9.listenServer.close).call(_this9.listenServer);
451
- _this9.listenServer = null;
416
+ _this11._started = false;
417
+ yield _this11.reload(options);
418
+ yield _this11.start(options);
419
+ _this11.emit('__restarted', _this11, options);
420
+ })();
421
+ }
422
+ stop(options = {}) {
423
+ var _this12 = this;
424
+ return _asyncToGenerator(function* () {
425
+ _this12.log.debug('stop app...');
426
+ _this12.setMaintainingMessage('stopping app...');
427
+ if (_this12.stopped) {
428
+ _this12.log.warn(`Application ${_this12.name} already stopped`);
429
+ return;
452
430
  }
431
+ yield _this12.emitAsync('beforeStop', _this12, options);
453
432
  try {
454
433
  // close database connection
455
434
  // silent if database already closed
456
- if (!_this9.db.closed()) {
457
- yield _this9.db.close();
435
+ if (!_this12.db.closed()) {
436
+ _this12.logger.info(`close db`);
437
+ yield _this12.db.close();
458
438
  }
459
439
  } catch (e) {
460
- console.log(e);
440
+ _this12.log.error(e);
461
441
  }
462
- yield _this9.emitAsync('afterStop', _this9, options);
463
- _this9.stopped = true;
464
- console.log(`${_this9.name} is stopped`);
442
+ yield _this12.emitAsync('afterStop', _this12, options);
443
+ _this12.stopped = true;
444
+ _this12.log.info(`${_this12.name} is stopped`);
445
+ _this12._started = false;
465
446
  })();
466
447
  }
467
448
  destroy(options = {}) {
468
- var _this10 = this;
449
+ var _this13 = this;
469
450
  return _asyncToGenerator(function* () {
470
- yield _this10.emitAsync('beforeDestroy', _this10, options);
471
- yield _this10.stop(options);
472
- yield _this10.emitAsync('afterDestroy', _this10, options);
451
+ _this13.logger.debug('start destroy app');
452
+ _this13.setMaintainingMessage('destroying app...');
453
+ yield _this13.emitAsync('beforeDestroy', _this13, options);
454
+ yield _this13.stop(options);
455
+ _this13.logger.debug('emit afterDestroy');
456
+ yield _this13.emitAsync('afterDestroy', _this13, options);
457
+ _this13.logger.debug('finish destroy app');
473
458
  })();
474
459
  }
475
460
  dbVersionCheck(options) {
476
- var _this11 = this;
461
+ var _this14 = this;
477
462
  return _asyncToGenerator(function* () {
478
- const r = yield _this11.db.version.satisfies({
463
+ const r = yield _this14.db.version.satisfies({
479
464
  mysql: '>=8.0.17',
480
465
  sqlite: '3.x',
481
466
  postgres: '>=10'
@@ -487,11 +472,11 @@ class Application extends _koa().default {
487
472
  }
488
473
  return false;
489
474
  }
490
- if (_this11.db.inDialect('mysql')) {
491
- const result = yield _this11.db.sequelize.query(`SHOW VARIABLES LIKE 'lower_case_table_names'`, {
475
+ if (_this14.db.inDialect('mysql')) {
476
+ const result = yield _this14.db.sequelize.query(`SHOW VARIABLES LIKE 'lower_case_table_names'`, {
492
477
  plain: true
493
478
  });
494
- if ((result === null || result === void 0 ? void 0 : result.Value) === '1' && !_this11.db.options.underscored) {
479
+ if ((result === null || result === void 0 ? void 0 : result.Value) === '1' && !_this14.db.options.underscored) {
495
480
  console.log(`Your database lower_case_table_names=1, please add ${_chalk().default.yellow('DB_UNDERSCORED=true')} to the .env file`);
496
481
  if (options !== null && options !== void 0 && options.exit) {
497
482
  process.exit();
@@ -503,53 +488,168 @@ class Application extends _koa().default {
503
488
  })();
504
489
  }
505
490
  isInstalled() {
506
- var _this12 = this;
491
+ var _this15 = this;
507
492
  return _asyncToGenerator(function* () {
508
- return (yield _this12.db.collectionExistsInDb('applicationVersion')) || (yield _this12.db.collectionExistsInDb('collections'));
493
+ return (yield _this15.db.collectionExistsInDb('applicationVersion')) || (yield _this15.db.collectionExistsInDb('collections'));
509
494
  })();
510
495
  }
511
496
  install(options = {}) {
512
- var _this13 = this;
497
+ var _this16 = this;
513
498
  return _asyncToGenerator(function* () {
514
- var _options$sync;
515
- console.log('Database dialect: ' + _this13.db.sequelize.getDialect());
499
+ var _options$sync, _this16$_maintainingS;
500
+ _this16.setMaintainingMessage('installing app...');
501
+ _this16.log.debug('Database dialect: ' + _this16.db.sequelize.getDialect());
516
502
  if (options !== null && options !== void 0 && options.clean || options !== null && options !== void 0 && (_options$sync = options.sync) !== null && _options$sync !== void 0 && _options$sync.force) {
517
- console.log('Truncate database and reload app configuration');
518
- yield _this13.db.clean({
503
+ _this16.log.debug('truncate database');
504
+ yield _this16.db.clean({
519
505
  drop: true
520
506
  });
521
- yield _this13.reload({
522
- method: 'install'
523
- });
507
+ _this16.log.debug('app reloading');
508
+ yield _this16.reload();
509
+ } else if (yield _this16.isInstalled()) {
510
+ _this16.log.warn('app is installed');
511
+ return;
512
+ }
513
+ _this16.log.debug('emit beforeInstall');
514
+ _this16.setMaintainingMessage('call beforeInstall hook...');
515
+ yield _this16.emitAsync('beforeInstall', _this16, options);
516
+ _this16.log.debug('start install plugins');
517
+ yield _this16.pm.install(options);
518
+ _this16.log.debug('update version');
519
+ yield _this16.version.update();
520
+ _this16.log.debug('emit afterInstall');
521
+ _this16.setMaintainingMessage('call afterInstall hook...');
522
+ yield _this16.emitAsync('afterInstall', _this16, options);
523
+ if ((_this16$_maintainingS = _this16._maintainingStatusBeforeCommand) !== null && _this16$_maintainingS !== void 0 && _this16$_maintainingS.error) {
524
+ return;
525
+ }
526
+ if (_this16._started) {
527
+ yield _this16.restart();
524
528
  }
525
- yield _this13.emitAsync('beforeInstall', _this13, options);
526
- yield _this13.db.sync();
527
- yield _this13.pm.install(options);
528
- yield _this13.version.update();
529
- yield _this13.emitAsync('afterInstall', _this13, options);
530
529
  })();
531
530
  }
532
531
  upgrade(options = {}) {
533
- var _this14 = this;
532
+ var _this17 = this;
534
533
  return _asyncToGenerator(function* () {
535
- yield _this14.emitAsync('beforeUpgrade', _this14, options);
534
+ yield _this17.emitAsync('beforeUpgrade', _this17, options);
536
535
  const force = false;
537
- yield _this14.db.migrator.up();
538
- yield _this14.db.sync({
536
+ yield _this17.db.migrator.up();
537
+ yield _this17.db.sync({
539
538
  force,
540
539
  alter: {
541
540
  drop: force
542
541
  }
543
542
  });
544
- yield _this14.version.update();
545
- yield _this14.emitAsync('afterUpgrade', _this14, options);
543
+ yield _this17.version.update();
544
+ yield _this17.emitAsync('afterUpgrade', _this17, options);
545
+ _this17.log.debug(_chalk().default.green(`✨ NocoBase has been upgraded to v${_this17.getVersion()}`));
546
+ if (_this17._started) {
547
+ yield _this17.restart();
548
+ }
546
549
  })();
547
550
  }
548
551
  toJSON() {
549
552
  return {
550
- appName: this.name
553
+ appName: this.name,
554
+ name: this.name
551
555
  };
552
556
  }
557
+ reInitEvents() {
558
+ var _iterator = _createForOfIteratorHelper(this.eventNames()),
559
+ _step;
560
+ try {
561
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
562
+ const eventName = _step.value;
563
+ var _iterator2 = _createForOfIteratorHelper(this.listeners(eventName)),
564
+ _step2;
565
+ try {
566
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
567
+ const listener = _step2.value;
568
+ if (listener['_reinitializable']) {
569
+ this.removeListener(eventName, listener);
570
+ }
571
+ }
572
+ } catch (err) {
573
+ _iterator2.e(err);
574
+ } finally {
575
+ _iterator2.f();
576
+ }
577
+ }
578
+ } catch (err) {
579
+ _iterator.e(err);
580
+ } finally {
581
+ _iterator.f();
582
+ }
583
+ }
584
+ init() {
585
+ const options = this.options;
586
+ const logger = (0, _logger().createAppLogger)(_objectSpread(_objectSpread({}, options.logger), {}, {
587
+ defaultMeta: {
588
+ app: this.name
589
+ }
590
+ }));
591
+ this._logger = logger.instance;
592
+ this.reInitEvents();
593
+ this.middleware = new (_utils().Toposort)();
594
+ this.plugins = new Map();
595
+ this._acl = (0, _acl.createACL)();
596
+ this.use(logger.middleware, {
597
+ tag: 'logger'
598
+ });
599
+ if (this._db) {
600
+ // MaxListenersExceededWarning
601
+ this._db.removeAllListeners();
602
+ }
603
+ this._db = this.createDatabase(options);
604
+ this._resourcer = (0, _helper.createResourcer)(options);
605
+ this._cli = this.createCli();
606
+ this._i18n = (0, _helper.createI18n)(options);
607
+ this._cache = (0, _cache().createCache)(options.cache);
608
+ this.context.db = this._db;
609
+ this.context.logger = this._logger;
610
+ this.context.resourcer = this._resourcer;
611
+ this.context.cache = this._cache;
612
+ const plugins = this._pm ? this._pm.options.plugins : options.plugins;
613
+ this._pm = new _pluginManager.PluginManager({
614
+ app: this,
615
+ plugins: plugins || []
616
+ });
617
+ this._authManager = new (_auth().AuthManager)({
618
+ authKey: 'X-Authenticator',
619
+ default: 'basic'
620
+ });
621
+ this.resource({
622
+ name: 'auth',
623
+ actions: _auth().actions
624
+ });
625
+ this._resourcer.use(this._authManager.middleware(), {
626
+ tag: 'auth'
627
+ });
628
+ if (this.options.acl !== false) {
629
+ this._resourcer.use(this._acl.middleware(), {
630
+ tag: 'acl',
631
+ after: ['auth']
632
+ });
633
+ }
634
+ this._locales = new _locale.Locale((0, _helper.createAppProxy)(this));
635
+ (0, _helper.registerMiddlewares)(this, options);
636
+ if (options.registerActions !== false) {
637
+ (0, _actions().registerActions)(this);
638
+ }
639
+ (0, _commands.registerCli)(this);
640
+ this._version = new _applicationVersion.ApplicationVersion(this);
641
+ }
642
+ createDatabase(options) {
643
+ const db = new (_database().default)(_objectSpread(_objectSpread({}, options.database instanceof _database().default ? options.database.options : options.database), {}, {
644
+ migrator: {
645
+ context: {
646
+ app: this
647
+ }
648
+ }
649
+ }));
650
+ db.setLogger(this._logger);
651
+ return db;
652
+ }
553
653
  }
554
654
  exports.Application = Application;
555
655
  (0, _utils().applyMixins)(Application, [_utils().AsyncEmitter]);