@nocobase/plugin-multi-app-manager 0.7.0-alpha.24 → 0.7.0-alpha.27

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.
@@ -20,6 +20,21 @@ export default defineCollection({
20
20
  'x-read-pretty': true,
21
21
  },
22
22
  },
23
+ {
24
+ type: 'string',
25
+ name: 'status',
26
+ interface: 'radioGroup',
27
+ defaultValue: 'pending',
28
+ uiSchema: {
29
+ type: 'string',
30
+ title: '{{t("Application status")}}',
31
+ 'x-component': 'Radio.Group',
32
+ enum: [
33
+ { label: '创建中', value: 'pending' },
34
+ { label: '运行中', value: 'running' },
35
+ ],
36
+ },
37
+ },
23
38
  {
24
39
  type: 'json',
25
40
  name: 'options',
@@ -1 +1 @@
1
- {"version":3,"file":"applications.js","sourceRoot":"","sources":["../../src/collections/applications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,eAAe,gBAAgB,CAAC;IAC9B,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,KAAK;IAChB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,MAAM;IAChB,eAAe,EAAE,MAAM;IACvB,MAAM,EAAE;QACN;YACE,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,GAAG;YACX,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,2BAA2B;gBAClC,aAAa,EAAE,OAAO;gBACtB,eAAe,EAAE,IAAI;aACtB;SACF;QACD;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,SAAS;SAChB;KACF;CACF,CAAC,CAAC","sourcesContent":["import { defineCollection } from '@nocobase/database';\n\nexport default defineCollection({\n name: 'applications',\n model: 'ApplicationModel',\n autoGenId: false,\n title: '{{t(\"Applications\")}}',\n sortable: 'sort',\n filterTargetKey: 'name',\n fields: [\n {\n type: 'uid',\n name: 'name',\n primaryKey: true,\n prefix: 'a',\n interface: 'input',\n uiSchema: {\n type: 'string',\n title: '{{t(\"Application name\")}}',\n 'x-component': 'Input',\n 'x-read-pretty': true,\n },\n },\n {\n type: 'json',\n name: 'options',\n },\n ],\n});\n"]}
1
+ {"version":3,"file":"applications.js","sourceRoot":"","sources":["../../src/collections/applications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,eAAe,gBAAgB,CAAC;IAC9B,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,KAAK;IAChB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,MAAM;IAChB,eAAe,EAAE,MAAM;IACvB,MAAM,EAAE;QACN;YACE,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,GAAG;YACX,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,2BAA2B;gBAClC,aAAa,EAAE,OAAO;gBACtB,eAAe,EAAE,IAAI;aACtB;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,YAAY;YACvB,YAAY,EAAE,SAAS;YACvB,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,6BAA6B;gBACpC,aAAa,EAAE,aAAa;gBAC5B,IAAI,EAAE;oBACJ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;oBAClC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;iBACnC;aACF;SACF;QACD;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,SAAS;SAChB;KACF;CACF,CAAC,CAAC","sourcesContent":["import { defineCollection } from '@nocobase/database';\n\nexport default defineCollection({\n name: 'applications',\n model: 'ApplicationModel',\n autoGenId: false,\n title: '{{t(\"Applications\")}}',\n sortable: 'sort',\n filterTargetKey: 'name',\n fields: [\n {\n type: 'uid',\n name: 'name',\n primaryKey: true,\n prefix: 'a',\n interface: 'input',\n uiSchema: {\n type: 'string',\n title: '{{t(\"Application name\")}}',\n 'x-component': 'Input',\n 'x-read-pretty': true,\n },\n },\n {\n type: 'string',\n name: 'status',\n interface: 'radioGroup',\n defaultValue: 'pending',\n uiSchema: {\n type: 'string',\n title: '{{t(\"Application status\")}}',\n 'x-component': 'Radio.Group',\n enum: [\n { label: '创建中', value: 'pending' },\n { label: '运行中', value: 'running' },\n ],\n },\n },\n {\n type: 'json',\n name: 'options',\n },\n ],\n});\n"]}
@@ -29,11 +29,12 @@ export class ApplicationModel extends Model {
29
29
  return __awaiter(this, void 0, void 0, function* () {
30
30
  const appName = this.get('name');
31
31
  const appOptions = this.get('options') || {};
32
- const app = mainApp.appManager.createApplication(appName, Object.assign(Object.assign({}, ApplicationModel.initOptions(appName, mainApp)), appOptions));
32
+ const AppModel = this.constructor;
33
+ const app = mainApp.appManager.createApplication(appName, Object.assign(Object.assign({}, AppModel.initOptions(appName, mainApp)), appOptions));
33
34
  // create database before installation if it not exists
34
35
  app.on('beforeInstall', function createDatabase() {
35
36
  return __awaiter(this, void 0, void 0, function* () {
36
- const { host, port, username, password, database, dialect } = ApplicationModel.getDatabaseConfig(app);
37
+ const { host, port, username, password, database, dialect } = AppModel.getDatabaseConfig(app);
37
38
  if (dialect === 'mysql') {
38
39
  const mysql = require('mysql2/promise');
39
40
  const connection = yield mysql.createConnection({ host, port, user: username, password });
@@ -57,11 +58,20 @@ export class ApplicationModel extends Model {
57
58
  }
58
59
  });
59
60
  });
60
- yield ApplicationModel.handleAppStart(app, options);
61
+ yield AppModel.handleAppStart(app, options);
62
+ yield AppModel.update({
63
+ status: 'running',
64
+ }, {
65
+ transaction: options.transaction,
66
+ where: {
67
+ [AppModel.primaryKeyAttribute]: this.get(AppModel.primaryKeyAttribute),
68
+ },
69
+ hooks: false,
70
+ });
61
71
  });
62
72
  }
63
73
  static initOptions(appName, mainApp) {
64
- const rawDatabaseOptions = ApplicationModel.getDatabaseConfig(mainApp);
74
+ const rawDatabaseOptions = this.getDatabaseConfig(mainApp);
65
75
  if (rawDatabaseOptions.dialect === 'sqlite') {
66
76
  const mainAppStorage = rawDatabaseOptions.storage;
67
77
  if (mainAppStorage !== ':memory:') {
@@ -1 +1 @@
1
- {"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/models/application.ts"],"names":[],"mappings":"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","sourcesContent":["import Database, { IDatabaseOptions, Model, TransactionAble } from '@nocobase/database';\nimport { Application } from '@nocobase/server';\nimport lodash from 'lodash';\nimport * as path from 'path';\n\nexport interface registerAppOptions extends TransactionAble {\n skipInstall?: boolean;\n}\n\nexport class ApplicationModel extends Model {\n static getDatabaseConfig(app: Application): IDatabaseOptions {\n return lodash.cloneDeep(\n lodash.isPlainObject(app.options.database)\n ? (app.options.database as IDatabaseOptions)\n : (app.options.database as Database).options,\n );\n }\n\n static async handleAppStart(app: Application, options: registerAppOptions) {\n await app.load();\n\n if (!lodash.get(options, 'skipInstall', false)) {\n await app.install();\n }\n\n await app.start();\n }\n\n async registerToMainApp(mainApp: Application, options: registerAppOptions) {\n const appName = this.get('name') as string;\n const appOptions = (this.get('options') as any) || {};\n\n const app = mainApp.appManager.createApplication(appName, {\n ...ApplicationModel.initOptions(appName, mainApp),\n ...appOptions,\n });\n\n // create database before installation if it not exists\n app.on('beforeInstall', async function createDatabase() {\n const { host, port, username, password, database, dialect } = ApplicationModel.getDatabaseConfig(app);\n\n if (dialect === 'mysql') {\n const mysql = require('mysql2/promise');\n const connection = await mysql.createConnection({ host, port, user: username, password });\n await connection.query(`CREATE DATABASE IF NOT EXISTS \\`${database}\\`;`);\n await connection.close();\n }\n\n if (dialect === 'postgres') {\n const { Client } = require('pg');\n\n const client = new Client({\n user: username,\n host,\n password: password,\n port,\n });\n\n await client.connect();\n\n try {\n await client.query(`CREATE DATABASE \"${database}\"`);\n } catch (e) {}\n\n await client.end();\n }\n });\n\n await ApplicationModel.handleAppStart(app, options);\n }\n\n static initOptions(appName: string, mainApp: Application) {\n const rawDatabaseOptions = ApplicationModel.getDatabaseConfig(mainApp);\n\n if (rawDatabaseOptions.dialect === 'sqlite') {\n const mainAppStorage = rawDatabaseOptions.storage;\n if (mainAppStorage !== ':memory:') {\n const mainStorageDir = path.dirname(mainAppStorage);\n rawDatabaseOptions.storage = path.join(mainStorageDir, `${appName}.sqlite`);\n }\n } else {\n rawDatabaseOptions.database = appName;\n }\n\n return {\n database: rawDatabaseOptions,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/models/application.ts"],"names":[],"mappings":"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","sourcesContent":["import Database, { IDatabaseOptions, Model, TransactionAble } from '@nocobase/database';\nimport { Application } from '@nocobase/server';\nimport lodash from 'lodash';\nimport * as path from 'path';\n\nexport interface registerAppOptions extends TransactionAble {\n skipInstall?: boolean;\n}\n\nexport class ApplicationModel extends Model {\n static getDatabaseConfig(app: Application): IDatabaseOptions {\n return lodash.cloneDeep(\n lodash.isPlainObject(app.options.database)\n ? (app.options.database as IDatabaseOptions)\n : (app.options.database as Database).options,\n );\n }\n\n static async handleAppStart(app: Application, options: registerAppOptions) {\n await app.load();\n\n if (!lodash.get(options, 'skipInstall', false)) {\n await app.install();\n }\n\n await app.start();\n }\n\n async registerToMainApp(mainApp: Application, options: registerAppOptions) {\n const appName = this.get('name') as string;\n const appOptions = (this.get('options') as any) || {};\n\n const AppModel = this.constructor as typeof ApplicationModel;\n\n const app = mainApp.appManager.createApplication(appName, {\n ...AppModel.initOptions(appName, mainApp),\n ...appOptions,\n });\n\n // create database before installation if it not exists\n app.on('beforeInstall', async function createDatabase() {\n const { host, port, username, password, database, dialect } = AppModel.getDatabaseConfig(app);\n\n if (dialect === 'mysql') {\n const mysql = require('mysql2/promise');\n const connection = await mysql.createConnection({ host, port, user: username, password });\n await connection.query(`CREATE DATABASE IF NOT EXISTS \\`${database}\\`;`);\n await connection.close();\n }\n\n if (dialect === 'postgres') {\n const { Client } = require('pg');\n\n const client = new Client({\n user: username,\n host,\n password: password,\n port,\n });\n\n await client.connect();\n\n try {\n await client.query(`CREATE DATABASE \"${database}\"`);\n } catch (e) {}\n\n await client.end();\n }\n });\n\n await AppModel.handleAppStart(app, options);\n\n await AppModel.update(\n {\n status: 'running',\n },\n {\n transaction: options.transaction,\n where: {\n [AppModel.primaryKeyAttribute]: this.get(AppModel.primaryKeyAttribute),\n },\n hooks: false,\n },\n );\n }\n\n static initOptions(appName: string, mainApp: Application) {\n const rawDatabaseOptions = this.getDatabaseConfig(mainApp);\n\n if (rawDatabaseOptions.dialect === 'sqlite') {\n const mainAppStorage = rawDatabaseOptions.storage;\n if (mainAppStorage !== ':memory:') {\n const mainStorageDir = path.dirname(mainAppStorage);\n rawDatabaseOptions.storage = path.join(mainStorageDir, `${appName}.sqlite`);\n }\n } else {\n rawDatabaseOptions.database = appName;\n }\n\n return {\n database: rawDatabaseOptions,\n };\n }\n}\n"]}
package/esm/server.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { Plugin } from '@nocobase/server';
1
+ import { InstallOptions, Plugin } from '@nocobase/server';
2
2
  export declare class PluginMultiAppManager extends Plugin {
3
3
  getName(): string;
4
+ install(options?: InstallOptions): Promise<void>;
4
5
  load(): Promise<void>;
5
6
  }
package/esm/server.js CHANGED
@@ -14,6 +14,14 @@ export class PluginMultiAppManager extends Plugin {
14
14
  getName() {
15
15
  return this.getPackageName(__dirname);
16
16
  }
17
+ install(options) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ const repo = this.db.getRepository('collections');
20
+ if (repo) {
21
+ yield repo.db2cm('applications');
22
+ }
23
+ });
24
+ }
17
25
  load() {
18
26
  return __awaiter(this, void 0, void 0, function* () {
19
27
  this.db.registerModels({
package/esm/server.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,MAAM,OAAO,qBAAsB,SAAQ,MAAM;IAC/C,OAAO;QACL,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAEK,IAAI;;YACR,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC;gBACrB,gBAAgB;aACjB,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;gBACnB,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC;aAC7C,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,0CAA0C,EAAE,CAAO,KAAuB,EAAE,OAAO,EAAE,EAAE;gBAChG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;gBAEhC,MAAM,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;YAC3D,CAAC,CAAA,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAO,KAAuB,EAAE,EAAE;gBACxE,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAW,CAAC,CAAC;YAC3E,CAAC,CAAA,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CACpB,sBAAsB,EACtB,SAAe,mBAAmB,CAAC,EAAE,UAAU,EAAE,IAAI,EAA4C;;oBAC/F,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;wBACtC,MAAM,iBAAiB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;4BACjF,MAAM,EAAE;gCACN,IAAI;6BACL;yBACF,CAAC,CAA4B,CAAC;wBAE/B,IAAI,iBAAiB,EAAE;4BACrB,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;yBAC5E;qBACF;gBACH,CAAC;aAAA,CACF,CAAC;QACJ,CAAC;KAAA;CACF","sourcesContent":["import { Plugin } from '@nocobase/server';\nimport { resolve } from 'path';\nimport { ApplicationModel } from './models/application';\nimport { AppManager } from '@nocobase/server';\n\nexport class PluginMultiAppManager extends Plugin {\n getName(): string {\n return this.getPackageName(__dirname);\n }\n\n async load() {\n this.db.registerModels({\n ApplicationModel,\n });\n\n await this.db.import({\n directory: resolve(__dirname, 'collections'),\n });\n\n this.db.on('applications.afterCreateWithAssociations', async (model: ApplicationModel, options) => {\n const { transaction } = options;\n\n await model.registerToMainApp(this.app, { transaction });\n });\n\n this.db.on('applications.afterDestroy', async (model: ApplicationModel) => {\n await this.app.appManager.removeApplication(model.get('name') as string);\n });\n\n this.app.appManager.on(\n 'beforeGetApplication',\n async function lazyLoadApplication({ appManager, name }: { appManager: AppManager; name: string }) {\n if (!appManager.applications.has(name)) {\n const existsApplication = (await this.app.db.getRepository('applications').findOne({\n filter: {\n name,\n },\n })) as ApplicationModel | null;\n\n if (existsApplication) {\n await existsApplication.registerToMainApp(this.app, { skipInstall: true });\n }\n }\n },\n );\n }\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAA8B,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,OAAO,qBAAsB,SAAQ,MAAM;IAC/C,OAAO;QACL,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAEK,OAAO,CAAC,OAAwB;;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAM,aAAa,CAAC,CAAC;YACvD,IAAI,IAAI,EAAE;gBACR,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;aAClC;QACH,CAAC;KAAA;IAEK,IAAI;;YACR,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC;gBACrB,gBAAgB;aACjB,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;gBACnB,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC;aAC7C,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,0CAA0C,EAAE,CAAO,KAAuB,EAAE,OAAO,EAAE,EAAE;gBAChG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;gBAEhC,MAAM,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;YAC3D,CAAC,CAAA,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAO,KAAuB,EAAE,EAAE;gBACxE,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAW,CAAC,CAAC;YAC3E,CAAC,CAAA,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CACpB,sBAAsB,EACtB,SAAe,mBAAmB,CAAC,EAAE,UAAU,EAAE,IAAI,EAA4C;;oBAC/F,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;wBACtC,MAAM,iBAAiB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;4BACjF,MAAM,EAAE;gCACN,IAAI;6BACL;yBACF,CAAC,CAA4B,CAAC;wBAE/B,IAAI,iBAAiB,EAAE;4BACrB,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;yBAC5E;qBACF;gBACH,CAAC;aAAA,CACF,CAAC;QACJ,CAAC;KAAA;CACF","sourcesContent":["import { AppManager, InstallOptions, Plugin } from '@nocobase/server';\nimport { resolve } from 'path';\nimport { ApplicationModel } from './models/application';\n\nexport class PluginMultiAppManager extends Plugin {\n getName(): string {\n return this.getPackageName(__dirname);\n }\n\n async install(options?: InstallOptions) {\n const repo = this.db.getRepository<any>('collections');\n if (repo) {\n await repo.db2cm('applications');\n }\n }\n\n async load() {\n this.db.registerModels({\n ApplicationModel,\n });\n\n await this.db.import({\n directory: resolve(__dirname, 'collections'),\n });\n\n this.db.on('applications.afterCreateWithAssociations', async (model: ApplicationModel, options) => {\n const { transaction } = options;\n\n await model.registerToMainApp(this.app, { transaction });\n });\n\n this.db.on('applications.afterDestroy', async (model: ApplicationModel) => {\n await this.app.appManager.removeApplication(model.get('name') as string);\n });\n\n this.app.appManager.on(\n 'beforeGetApplication',\n async function lazyLoadApplication({ appManager, name }: { appManager: AppManager; name: string }) {\n if (!appManager.applications.has(name)) {\n const existsApplication = (await this.app.db.getRepository('applications').findOne({\n filter: {\n name,\n },\n })) as ApplicationModel | null;\n\n if (existsApplication) {\n await existsApplication.registerToMainApp(this.app, { skipInstall: true });\n }\n }\n },\n );\n }\n}\n"]}
@@ -22,6 +22,21 @@ exports.default = (0, database_1.defineCollection)({
22
22
  'x-read-pretty': true,
23
23
  },
24
24
  },
25
+ {
26
+ type: 'string',
27
+ name: 'status',
28
+ interface: 'radioGroup',
29
+ defaultValue: 'pending',
30
+ uiSchema: {
31
+ type: 'string',
32
+ title: '{{t("Application status")}}',
33
+ 'x-component': 'Radio.Group',
34
+ enum: [
35
+ { label: '创建中', value: 'pending' },
36
+ { label: '运行中', value: 'running' },
37
+ ],
38
+ },
39
+ },
25
40
  {
26
41
  type: 'json',
27
42
  name: 'options',
@@ -1 +1 @@
1
- {"version":3,"file":"applications.js","sourceRoot":"","sources":["../../src/collections/applications.ts"],"names":[],"mappings":";;AAAA,iDAAsD;AAEtD,kBAAe,IAAA,2BAAgB,EAAC;IAC9B,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,KAAK;IAChB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,MAAM;IAChB,eAAe,EAAE,MAAM;IACvB,MAAM,EAAE;QACN;YACE,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,GAAG;YACX,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,2BAA2B;gBAClC,aAAa,EAAE,OAAO;gBACtB,eAAe,EAAE,IAAI;aACtB;SACF;QACD;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,SAAS;SAChB;KACF;CACF,CAAC,CAAC","sourcesContent":["import { defineCollection } from '@nocobase/database';\n\nexport default defineCollection({\n name: 'applications',\n model: 'ApplicationModel',\n autoGenId: false,\n title: '{{t(\"Applications\")}}',\n sortable: 'sort',\n filterTargetKey: 'name',\n fields: [\n {\n type: 'uid',\n name: 'name',\n primaryKey: true,\n prefix: 'a',\n interface: 'input',\n uiSchema: {\n type: 'string',\n title: '{{t(\"Application name\")}}',\n 'x-component': 'Input',\n 'x-read-pretty': true,\n },\n },\n {\n type: 'json',\n name: 'options',\n },\n ],\n});\n"]}
1
+ {"version":3,"file":"applications.js","sourceRoot":"","sources":["../../src/collections/applications.ts"],"names":[],"mappings":";;AAAA,iDAAsD;AAEtD,kBAAe,IAAA,2BAAgB,EAAC;IAC9B,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,KAAK;IAChB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,MAAM;IAChB,eAAe,EAAE,MAAM;IACvB,MAAM,EAAE;QACN;YACE,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,GAAG;YACX,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,2BAA2B;gBAClC,aAAa,EAAE,OAAO;gBACtB,eAAe,EAAE,IAAI;aACtB;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,YAAY;YACvB,YAAY,EAAE,SAAS;YACvB,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,6BAA6B;gBACpC,aAAa,EAAE,aAAa;gBAC5B,IAAI,EAAE;oBACJ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;oBAClC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;iBACnC;aACF;SACF;QACD;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,SAAS;SAChB;KACF;CACF,CAAC,CAAC","sourcesContent":["import { defineCollection } from '@nocobase/database';\n\nexport default defineCollection({\n name: 'applications',\n model: 'ApplicationModel',\n autoGenId: false,\n title: '{{t(\"Applications\")}}',\n sortable: 'sort',\n filterTargetKey: 'name',\n fields: [\n {\n type: 'uid',\n name: 'name',\n primaryKey: true,\n prefix: 'a',\n interface: 'input',\n uiSchema: {\n type: 'string',\n title: '{{t(\"Application name\")}}',\n 'x-component': 'Input',\n 'x-read-pretty': true,\n },\n },\n {\n type: 'string',\n name: 'status',\n interface: 'radioGroup',\n defaultValue: 'pending',\n uiSchema: {\n type: 'string',\n title: '{{t(\"Application status\")}}',\n 'x-component': 'Radio.Group',\n enum: [\n { label: '创建中', value: 'pending' },\n { label: '运行中', value: 'running' },\n ],\n },\n },\n {\n type: 'json',\n name: 'options',\n },\n ],\n});\n"]}
@@ -54,11 +54,12 @@ class ApplicationModel extends database_1.Model {
54
54
  return __awaiter(this, void 0, void 0, function* () {
55
55
  const appName = this.get('name');
56
56
  const appOptions = this.get('options') || {};
57
- const app = mainApp.appManager.createApplication(appName, Object.assign(Object.assign({}, ApplicationModel.initOptions(appName, mainApp)), appOptions));
57
+ const AppModel = this.constructor;
58
+ const app = mainApp.appManager.createApplication(appName, Object.assign(Object.assign({}, AppModel.initOptions(appName, mainApp)), appOptions));
58
59
  // create database before installation if it not exists
59
60
  app.on('beforeInstall', function createDatabase() {
60
61
  return __awaiter(this, void 0, void 0, function* () {
61
- const { host, port, username, password, database, dialect } = ApplicationModel.getDatabaseConfig(app);
62
+ const { host, port, username, password, database, dialect } = AppModel.getDatabaseConfig(app);
62
63
  if (dialect === 'mysql') {
63
64
  const mysql = require('mysql2/promise');
64
65
  const connection = yield mysql.createConnection({ host, port, user: username, password });
@@ -82,11 +83,20 @@ class ApplicationModel extends database_1.Model {
82
83
  }
83
84
  });
84
85
  });
85
- yield ApplicationModel.handleAppStart(app, options);
86
+ yield AppModel.handleAppStart(app, options);
87
+ yield AppModel.update({
88
+ status: 'running',
89
+ }, {
90
+ transaction: options.transaction,
91
+ where: {
92
+ [AppModel.primaryKeyAttribute]: this.get(AppModel.primaryKeyAttribute),
93
+ },
94
+ hooks: false,
95
+ });
86
96
  });
87
97
  }
88
98
  static initOptions(appName, mainApp) {
89
- const rawDatabaseOptions = ApplicationModel.getDatabaseConfig(mainApp);
99
+ const rawDatabaseOptions = this.getDatabaseConfig(mainApp);
90
100
  if (rawDatabaseOptions.dialect === 'sqlite') {
91
101
  const mainAppStorage = rawDatabaseOptions.storage;
92
102
  if (mainAppStorage !== ':memory:') {
@@ -1 +1 @@
1
- {"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/models/application.ts"],"names":[],"mappings":"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","sourcesContent":["import Database, { IDatabaseOptions, Model, TransactionAble } from '@nocobase/database';\nimport { Application } from '@nocobase/server';\nimport lodash from 'lodash';\nimport * as path from 'path';\n\nexport interface registerAppOptions extends TransactionAble {\n skipInstall?: boolean;\n}\n\nexport class ApplicationModel extends Model {\n static getDatabaseConfig(app: Application): IDatabaseOptions {\n return lodash.cloneDeep(\n lodash.isPlainObject(app.options.database)\n ? (app.options.database as IDatabaseOptions)\n : (app.options.database as Database).options,\n );\n }\n\n static async handleAppStart(app: Application, options: registerAppOptions) {\n await app.load();\n\n if (!lodash.get(options, 'skipInstall', false)) {\n await app.install();\n }\n\n await app.start();\n }\n\n async registerToMainApp(mainApp: Application, options: registerAppOptions) {\n const appName = this.get('name') as string;\n const appOptions = (this.get('options') as any) || {};\n\n const app = mainApp.appManager.createApplication(appName, {\n ...ApplicationModel.initOptions(appName, mainApp),\n ...appOptions,\n });\n\n // create database before installation if it not exists\n app.on('beforeInstall', async function createDatabase() {\n const { host, port, username, password, database, dialect } = ApplicationModel.getDatabaseConfig(app);\n\n if (dialect === 'mysql') {\n const mysql = require('mysql2/promise');\n const connection = await mysql.createConnection({ host, port, user: username, password });\n await connection.query(`CREATE DATABASE IF NOT EXISTS \\`${database}\\`;`);\n await connection.close();\n }\n\n if (dialect === 'postgres') {\n const { Client } = require('pg');\n\n const client = new Client({\n user: username,\n host,\n password: password,\n port,\n });\n\n await client.connect();\n\n try {\n await client.query(`CREATE DATABASE \"${database}\"`);\n } catch (e) {}\n\n await client.end();\n }\n });\n\n await ApplicationModel.handleAppStart(app, options);\n }\n\n static initOptions(appName: string, mainApp: Application) {\n const rawDatabaseOptions = ApplicationModel.getDatabaseConfig(mainApp);\n\n if (rawDatabaseOptions.dialect === 'sqlite') {\n const mainAppStorage = rawDatabaseOptions.storage;\n if (mainAppStorage !== ':memory:') {\n const mainStorageDir = path.dirname(mainAppStorage);\n rawDatabaseOptions.storage = path.join(mainStorageDir, `${appName}.sqlite`);\n }\n } else {\n rawDatabaseOptions.database = appName;\n }\n\n return {\n database: rawDatabaseOptions,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/models/application.ts"],"names":[],"mappings":"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","sourcesContent":["import Database, { IDatabaseOptions, Model, TransactionAble } from '@nocobase/database';\nimport { Application } from '@nocobase/server';\nimport lodash from 'lodash';\nimport * as path from 'path';\n\nexport interface registerAppOptions extends TransactionAble {\n skipInstall?: boolean;\n}\n\nexport class ApplicationModel extends Model {\n static getDatabaseConfig(app: Application): IDatabaseOptions {\n return lodash.cloneDeep(\n lodash.isPlainObject(app.options.database)\n ? (app.options.database as IDatabaseOptions)\n : (app.options.database as Database).options,\n );\n }\n\n static async handleAppStart(app: Application, options: registerAppOptions) {\n await app.load();\n\n if (!lodash.get(options, 'skipInstall', false)) {\n await app.install();\n }\n\n await app.start();\n }\n\n async registerToMainApp(mainApp: Application, options: registerAppOptions) {\n const appName = this.get('name') as string;\n const appOptions = (this.get('options') as any) || {};\n\n const AppModel = this.constructor as typeof ApplicationModel;\n\n const app = mainApp.appManager.createApplication(appName, {\n ...AppModel.initOptions(appName, mainApp),\n ...appOptions,\n });\n\n // create database before installation if it not exists\n app.on('beforeInstall', async function createDatabase() {\n const { host, port, username, password, database, dialect } = AppModel.getDatabaseConfig(app);\n\n if (dialect === 'mysql') {\n const mysql = require('mysql2/promise');\n const connection = await mysql.createConnection({ host, port, user: username, password });\n await connection.query(`CREATE DATABASE IF NOT EXISTS \\`${database}\\`;`);\n await connection.close();\n }\n\n if (dialect === 'postgres') {\n const { Client } = require('pg');\n\n const client = new Client({\n user: username,\n host,\n password: password,\n port,\n });\n\n await client.connect();\n\n try {\n await client.query(`CREATE DATABASE \"${database}\"`);\n } catch (e) {}\n\n await client.end();\n }\n });\n\n await AppModel.handleAppStart(app, options);\n\n await AppModel.update(\n {\n status: 'running',\n },\n {\n transaction: options.transaction,\n where: {\n [AppModel.primaryKeyAttribute]: this.get(AppModel.primaryKeyAttribute),\n },\n hooks: false,\n },\n );\n }\n\n static initOptions(appName: string, mainApp: Application) {\n const rawDatabaseOptions = this.getDatabaseConfig(mainApp);\n\n if (rawDatabaseOptions.dialect === 'sqlite') {\n const mainAppStorage = rawDatabaseOptions.storage;\n if (mainAppStorage !== ':memory:') {\n const mainStorageDir = path.dirname(mainAppStorage);\n rawDatabaseOptions.storage = path.join(mainStorageDir, `${appName}.sqlite`);\n }\n } else {\n rawDatabaseOptions.database = appName;\n }\n\n return {\n database: rawDatabaseOptions,\n };\n }\n}\n"]}
package/lib/server.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { Plugin } from '@nocobase/server';
1
+ import { InstallOptions, Plugin } from '@nocobase/server';
2
2
  export declare class PluginMultiAppManager extends Plugin {
3
3
  getName(): string;
4
+ install(options?: InstallOptions): Promise<void>;
4
5
  load(): Promise<void>;
5
6
  }
package/lib/server.js CHANGED
@@ -17,6 +17,14 @@ class PluginMultiAppManager extends server_1.Plugin {
17
17
  getName() {
18
18
  return this.getPackageName(__dirname);
19
19
  }
20
+ install(options) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const repo = this.db.getRepository('collections');
23
+ if (repo) {
24
+ yield repo.db2cm('applications');
25
+ }
26
+ });
27
+ }
20
28
  load() {
21
29
  return __awaiter(this, void 0, void 0, function* () {
22
30
  this.db.registerModels({
package/lib/server.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA0C;AAC1C,+BAA+B;AAC/B,sDAAwD;AAGxD,MAAa,qBAAsB,SAAQ,eAAM;IAC/C,OAAO;QACL,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAEK,IAAI;;YACR,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC;gBACrB,gBAAgB,EAAhB,8BAAgB;aACjB,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;gBACnB,SAAS,EAAE,IAAA,cAAO,EAAC,SAAS,EAAE,aAAa,CAAC;aAC7C,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,0CAA0C,EAAE,CAAO,KAAuB,EAAE,OAAO,EAAE,EAAE;gBAChG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;gBAEhC,MAAM,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;YAC3D,CAAC,CAAA,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAO,KAAuB,EAAE,EAAE;gBACxE,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAW,CAAC,CAAC;YAC3E,CAAC,CAAA,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CACpB,sBAAsB,EACtB,SAAe,mBAAmB,CAAC,EAAE,UAAU,EAAE,IAAI,EAA4C;;oBAC/F,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;wBACtC,MAAM,iBAAiB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;4BACjF,MAAM,EAAE;gCACN,IAAI;6BACL;yBACF,CAAC,CAA4B,CAAC;wBAE/B,IAAI,iBAAiB,EAAE;4BACrB,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;yBAC5E;qBACF;gBACH,CAAC;aAAA,CACF,CAAC;QACJ,CAAC;KAAA;CACF;AAzCD,sDAyCC","sourcesContent":["import { Plugin } from '@nocobase/server';\nimport { resolve } from 'path';\nimport { ApplicationModel } from './models/application';\nimport { AppManager } from '@nocobase/server';\n\nexport class PluginMultiAppManager extends Plugin {\n getName(): string {\n return this.getPackageName(__dirname);\n }\n\n async load() {\n this.db.registerModels({\n ApplicationModel,\n });\n\n await this.db.import({\n directory: resolve(__dirname, 'collections'),\n });\n\n this.db.on('applications.afterCreateWithAssociations', async (model: ApplicationModel, options) => {\n const { transaction } = options;\n\n await model.registerToMainApp(this.app, { transaction });\n });\n\n this.db.on('applications.afterDestroy', async (model: ApplicationModel) => {\n await this.app.appManager.removeApplication(model.get('name') as string);\n });\n\n this.app.appManager.on(\n 'beforeGetApplication',\n async function lazyLoadApplication({ appManager, name }: { appManager: AppManager; name: string }) {\n if (!appManager.applications.has(name)) {\n const existsApplication = (await this.app.db.getRepository('applications').findOne({\n filter: {\n name,\n },\n })) as ApplicationModel | null;\n\n if (existsApplication) {\n await existsApplication.registerToMainApp(this.app, { skipInstall: true });\n }\n }\n },\n );\n }\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAAsE;AACtE,+BAA+B;AAC/B,sDAAwD;AAExD,MAAa,qBAAsB,SAAQ,eAAM;IAC/C,OAAO;QACL,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAEK,OAAO,CAAC,OAAwB;;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAM,aAAa,CAAC,CAAC;YACvD,IAAI,IAAI,EAAE;gBACR,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;aAClC;QACH,CAAC;KAAA;IAEK,IAAI;;YACR,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC;gBACrB,gBAAgB,EAAhB,8BAAgB;aACjB,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;gBACnB,SAAS,EAAE,IAAA,cAAO,EAAC,SAAS,EAAE,aAAa,CAAC;aAC7C,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,0CAA0C,EAAE,CAAO,KAAuB,EAAE,OAAO,EAAE,EAAE;gBAChG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;gBAEhC,MAAM,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;YAC3D,CAAC,CAAA,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAO,KAAuB,EAAE,EAAE;gBACxE,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAW,CAAC,CAAC;YAC3E,CAAC,CAAA,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CACpB,sBAAsB,EACtB,SAAe,mBAAmB,CAAC,EAAE,UAAU,EAAE,IAAI,EAA4C;;oBAC/F,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;wBACtC,MAAM,iBAAiB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;4BACjF,MAAM,EAAE;gCACN,IAAI;6BACL;yBACF,CAAC,CAA4B,CAAC;wBAE/B,IAAI,iBAAiB,EAAE;4BACrB,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;yBAC5E;qBACF;gBACH,CAAC;aAAA,CACF,CAAC;QACJ,CAAC;KAAA;CACF;AAhDD,sDAgDC","sourcesContent":["import { AppManager, InstallOptions, Plugin } from '@nocobase/server';\nimport { resolve } from 'path';\nimport { ApplicationModel } from './models/application';\n\nexport class PluginMultiAppManager extends Plugin {\n getName(): string {\n return this.getPackageName(__dirname);\n }\n\n async install(options?: InstallOptions) {\n const repo = this.db.getRepository<any>('collections');\n if (repo) {\n await repo.db2cm('applications');\n }\n }\n\n async load() {\n this.db.registerModels({\n ApplicationModel,\n });\n\n await this.db.import({\n directory: resolve(__dirname, 'collections'),\n });\n\n this.db.on('applications.afterCreateWithAssociations', async (model: ApplicationModel, options) => {\n const { transaction } = options;\n\n await model.registerToMainApp(this.app, { transaction });\n });\n\n this.db.on('applications.afterDestroy', async (model: ApplicationModel) => {\n await this.app.appManager.removeApplication(model.get('name') as string);\n });\n\n this.app.appManager.on(\n 'beforeGetApplication',\n async function lazyLoadApplication({ appManager, name }: { appManager: AppManager; name: string }) {\n if (!appManager.applications.has(name)) {\n const existsApplication = (await this.app.db.getRepository('applications').findOne({\n filter: {\n name,\n },\n })) as ApplicationModel | null;\n\n if (existsApplication) {\n await existsApplication.registerToMainApp(this.app, { skipInstall: true });\n }\n }\n },\n );\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/plugin-multi-app-manager",
3
- "version": "0.7.0-alpha.24",
3
+ "version": "0.7.0-alpha.27",
4
4
  "main": "lib/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "licenses": [
@@ -15,7 +15,7 @@
15
15
  "build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
16
16
  },
17
17
  "dependencies": {
18
- "@nocobase/server": "0.7.0-alpha.24"
18
+ "@nocobase/server": "0.7.0-alpha.27"
19
19
  },
20
- "gitHead": "1fb2dd884c4f2d2167f5dde40a15012a752e53ab"
20
+ "gitHead": "ebfe11ff09bf50b4b2322cbbad65b4ea936fdb71"
21
21
  }