From b1086ee728e305b4affe6f9deaf8b8e1e020e5f1 Mon Sep 17 00:00:00 2001 From: ChengLei Shao Date: Sun, 24 Apr 2022 20:22:50 +0800 Subject: [PATCH] Fix multiple apps (#316) * chore: multiple apps * fix: multiple apps with application options * fix: multiple apps AppSelector type * chore: multiple apps with plugin config * chore: rename multiple-apps to multiple-apps-manager * chore: application association * chore: plugin multi-app manager --- packages/core/server/src/app-manager.ts | 4 +- .../.npmignore | 0 .../package.json | 2 +- .../src/__tests__/mock-get-schema.test.ts | 42 ++++++++----------- .../src/__tests__/multiple-apps.test.ts | 27 ++++++------ .../src/collections/applications.ts | 19 +++++---- .../plugins/multi-app-manager/src/index.ts | 1 + .../src/models/application.ts | 17 +++----- .../src/server.ts | 2 +- .../tsconfig.build.json | 0 .../tsconfig.json | 0 .../src/collections/application-plugins.ts | 17 -------- publish.js | 2 +- 13 files changed, 55 insertions(+), 78 deletions(-) rename packages/plugins/{multiple-apps => multi-app-manager}/.npmignore (100%) rename packages/plugins/{multiple-apps => multi-app-manager}/package.json (88%) rename packages/plugins/{multiple-apps => multi-app-manager}/src/__tests__/mock-get-schema.test.ts (76%) rename packages/plugins/{multiple-apps => multi-app-manager}/src/__tests__/multiple-apps.test.ts (79%) rename packages/plugins/{multiple-apps => multi-app-manager}/src/collections/applications.ts (50%) create mode 100644 packages/plugins/multi-app-manager/src/index.ts rename packages/plugins/{multiple-apps => multi-app-manager}/src/models/application.ts (83%) rename packages/plugins/{multiple-apps => multi-app-manager}/src/server.ts (96%) rename packages/plugins/{multiple-apps => multi-app-manager}/tsconfig.build.json (100%) rename packages/plugins/{multiple-apps => multi-app-manager}/tsconfig.json (100%) delete mode 100644 packages/plugins/multiple-apps/src/collections/application-plugins.ts diff --git a/packages/core/server/src/app-manager.ts b/packages/core/server/src/app-manager.ts index a0e6033b9..26f3c7194 100644 --- a/packages/core/server/src/app-manager.ts +++ b/packages/core/server/src/app-manager.ts @@ -3,7 +3,7 @@ import http, { IncomingMessage } from 'http'; import EventEmitter from 'events'; import { applyMixins, AsyncEmitter } from '@nocobase/utils'; -type AppSelector = (ctx) => Application | string; +type AppSelector = (req: IncomingMessage) => Application | string | undefined | null; export class AppManager extends EventEmitter { public applications: Map = new Map(); @@ -63,7 +63,7 @@ export class AppManager extends EventEmitter { callback() { return async (req, res) => { - let handleApp = this.appSelector(req); + let handleApp = this.appSelector(req) || this.app; if (typeof handleApp === 'string') { handleApp = (await this.getApplication(handleApp)) || this.app; diff --git a/packages/plugins/multiple-apps/.npmignore b/packages/plugins/multi-app-manager/.npmignore similarity index 100% rename from packages/plugins/multiple-apps/.npmignore rename to packages/plugins/multi-app-manager/.npmignore diff --git a/packages/plugins/multiple-apps/package.json b/packages/plugins/multi-app-manager/package.json similarity index 88% rename from packages/plugins/multiple-apps/package.json rename to packages/plugins/multi-app-manager/package.json index 346eaf677..7fff72896 100644 --- a/packages/plugins/multiple-apps/package.json +++ b/packages/plugins/multi-app-manager/package.json @@ -1,5 +1,5 @@ { - "name": "@nocobase/plugin-multiple-apps", + "name": "@nocobase/plugin-multi-app-manager", "version": "0.6.2-alpha.12", "main": "lib/index.js", "license": "MIT", diff --git a/packages/plugins/multiple-apps/src/__tests__/mock-get-schema.test.ts b/packages/plugins/multi-app-manager/src/__tests__/mock-get-schema.test.ts similarity index 76% rename from packages/plugins/multiple-apps/src/__tests__/mock-get-schema.test.ts rename to packages/plugins/multi-app-manager/src/__tests__/mock-get-schema.test.ts index dc2015c6d..e20175539 100644 --- a/packages/plugins/multiple-apps/src/__tests__/mock-get-schema.test.ts +++ b/packages/plugins/multi-app-manager/src/__tests__/mock-get-schema.test.ts @@ -1,7 +1,6 @@ -import { Plugin } from '@nocobase/server'; -import { ApplicationModel } from '../models/application'; +import { Plugin, PluginManager } from '@nocobase/server'; import { mockServer } from '@nocobase/test'; -import { PluginMultipleApps } from '../server'; +import { PluginMultiAppManager } from '../server'; describe('test with start', () => { it('should load subApp on create', async () => { @@ -24,11 +23,12 @@ describe('test with start', () => { const mockGetPluginByName = jest.fn(); mockGetPluginByName.mockReturnValue(TestPlugin); - ApplicationModel.getPluginByName = mockGetPluginByName; + PluginManager.resolvePlugin = mockGetPluginByName; const app = mockServer(); await app.cleanDb(); - app.plugin(PluginMultipleApps); + + app.plugin(PluginMultiAppManager); await app.loadAndInstall(); await app.start(); @@ -38,11 +38,9 @@ describe('test with start', () => { await db.getRepository('applications').create({ values: { name: 'sub1', - plugins: [ - { - name: 'test-package', - }, - ], + options: { + plugins: ['test-package'], + }, }, }); @@ -55,7 +53,7 @@ describe('test with start', () => { it('should install into difference database', async () => { const app = mockServer(); await app.cleanDb(); - app.plugin(PluginMultipleApps); + app.plugin(PluginMultiAppManager); await app.loadAndInstall(); await app.start(); @@ -65,11 +63,9 @@ describe('test with start', () => { await db.getRepository('applications').create({ values: { name: 'sub1', - plugins: [ - { - name: '@nocobase/plugin-ui-schema-storage', - }, - ], + options: { + plugins: ['@nocobase/plugin-ui-schema-storage'], + }, }, }); await app.destroy(); @@ -84,7 +80,7 @@ describe('test with start', () => { let app = mockServer(); await app.cleanDb(); - app.plugin(PluginMultipleApps); + app.plugin(PluginMultiAppManager); await app.loadAndInstall(); await app.start(); @@ -93,16 +89,14 @@ describe('test with start', () => { const mockGetPluginByName = jest.fn(); mockGetPluginByName.mockReturnValue(TestPlugin); - ApplicationModel.getPluginByName = mockGetPluginByName; + PluginManager.resolvePlugin = mockGetPluginByName; await db.getRepository('applications').create({ values: { name: 'sub1', - plugins: [ - { - name: 'test-package', - }, - ], + options: { + plugins: ['test-package'], + }, }, }); @@ -114,7 +108,7 @@ describe('test with start', () => { database: app.db, }); - newApp.plugin(PluginMultipleApps); + newApp.plugin(PluginMultiAppManager); await newApp.db.reconnect(); await newApp.load(); diff --git a/packages/plugins/multiple-apps/src/__tests__/multiple-apps.test.ts b/packages/plugins/multi-app-manager/src/__tests__/multiple-apps.test.ts similarity index 79% rename from packages/plugins/multiple-apps/src/__tests__/multiple-apps.test.ts rename to packages/plugins/multi-app-manager/src/__tests__/multiple-apps.test.ts index 790a46989..d91e86706 100644 --- a/packages/plugins/multiple-apps/src/__tests__/multiple-apps.test.ts +++ b/packages/plugins/multi-app-manager/src/__tests__/multiple-apps.test.ts @@ -1,6 +1,6 @@ import { mockServer, MockServer } from '@nocobase/test'; import { Database } from '@nocobase/database'; -import { PluginMultipleApps } from '../server'; +import { PluginMultiAppManager } from '../server'; describe('multiple apps create', () => { let app: MockServer; @@ -10,7 +10,7 @@ describe('multiple apps create', () => { app = mockServer({}); db = app.db; await app.cleanDb(); - app.plugin(PluginMultipleApps); + app.plugin(PluginMultiAppManager); await app.loadAndInstall(); }); @@ -51,29 +51,30 @@ describe('multiple apps create', () => { await db.getRepository('applications').create({ values: { name: 'miniApp', - plugins: [ - { - name: '@nocobase/plugin-ui-schema-storage', - }, - ], + options: { + plugins: [['@nocobase/plugin-ui-schema-storage', { test: 'B' }]], + }, }, }); const miniApp = app.appManager.applications.get('miniApp'); expect(miniApp).toBeDefined(); - expect(miniApp.pm.get('@nocobase/plugin-ui-schema-storage')).toBeDefined(); + const plugin = miniApp.pm.get('@nocobase/plugin-ui-schema-storage'); + + expect(plugin).toBeDefined(); + expect(plugin.options).toEqual({ + test: 'B', + }); }); it('should lazy load applications', async () => { await db.getRepository('applications').create({ values: { name: 'miniApp', - plugins: [ - { - name: '@nocobase/plugin-ui-schema-storage', - }, - ], + options: { + plugins: ['@nocobase/plugin-ui-schema-storage'], + }, }, }); diff --git a/packages/plugins/multiple-apps/src/collections/applications.ts b/packages/plugins/multi-app-manager/src/collections/applications.ts similarity index 50% rename from packages/plugins/multiple-apps/src/collections/applications.ts rename to packages/plugins/multi-app-manager/src/collections/applications.ts index 82800773c..cd8efcae7 100644 --- a/packages/plugins/multiple-apps/src/collections/applications.ts +++ b/packages/plugins/multi-app-manager/src/collections/applications.ts @@ -4,21 +4,26 @@ export default defineCollection({ name: 'applications', model: 'ApplicationModel', autoGenId: false, + title: '{{t("Applications")}}', + sortable: 'sort', + createdBy: true, fields: [ { - type: 'string', + type: 'uid', name: 'name', primaryKey: true, + prefix: 'a', + interface: 'input', + uiSchema: { + type: 'string', + title: '{{t("Application name")}}', + 'x-component': 'Input', + 'x-read-pretty': true, + }, }, { type: 'json', name: 'options', }, - { - type: 'hasMany', - name: 'plugins', - target: 'applicationPlugins', - foreignKey: 'applicationName', - }, ], }); diff --git a/packages/plugins/multi-app-manager/src/index.ts b/packages/plugins/multi-app-manager/src/index.ts new file mode 100644 index 000000000..72e55c742 --- /dev/null +++ b/packages/plugins/multi-app-manager/src/index.ts @@ -0,0 +1 @@ +export { PluginMultiAppManager as default } from './server'; diff --git a/packages/plugins/multiple-apps/src/models/application.ts b/packages/plugins/multi-app-manager/src/models/application.ts similarity index 83% rename from packages/plugins/multiple-apps/src/models/application.ts rename to packages/plugins/multi-app-manager/src/models/application.ts index 73f9f65da..d939bd689 100644 --- a/packages/plugins/multiple-apps/src/models/application.ts +++ b/packages/plugins/multi-app-manager/src/models/application.ts @@ -8,10 +8,6 @@ interface registerAppOptions extends TransactionAble { } export class ApplicationModel extends Model { - static getPluginByName(pluginName: string) { - return require(pluginName).default; - } - static getDatabaseConfig(app: Application): IDatabaseOptions { return lodash.cloneDeep( lodash.isPlainObject(app.options.database) @@ -23,15 +19,12 @@ export class ApplicationModel extends Model { async registerToMainApp(mainApp: Application, options: registerAppOptions) { const { transaction } = options; const appName = this.get('name') as string; - const app = mainApp.appManager.createApplication(appName, ApplicationModel.initOptions(appName, mainApp)); + const appOptions = (this.get('options') as any) || {}; - // @ts-ignore - const plugins = await this.getPlugins({ transaction }); - - for (const pluginInstance of plugins) { - const plugin = ApplicationModel.getPluginByName(pluginInstance.get('name') as string); - app.plugin(plugin); - } + const app = mainApp.appManager.createApplication(appName, { + ...ApplicationModel.initOptions(appName, mainApp), + ...appOptions, + }); app.on('beforeInstall', async function createDatabase() { const { host, port, username, password, database, dialect } = ApplicationModel.getDatabaseConfig(app); diff --git a/packages/plugins/multiple-apps/src/server.ts b/packages/plugins/multi-app-manager/src/server.ts similarity index 96% rename from packages/plugins/multiple-apps/src/server.ts rename to packages/plugins/multi-app-manager/src/server.ts index ecc711d01..1fed0fd0d 100644 --- a/packages/plugins/multiple-apps/src/server.ts +++ b/packages/plugins/multi-app-manager/src/server.ts @@ -3,7 +3,7 @@ import { resolve } from 'path'; import { ApplicationModel } from './models/application'; import { AppManager } from '@nocobase/server'; -export class PluginMultipleApps extends Plugin { +export class PluginMultiAppManager extends Plugin { getName(): string { return this.getPackageName(__dirname); } diff --git a/packages/plugins/multiple-apps/tsconfig.build.json b/packages/plugins/multi-app-manager/tsconfig.build.json similarity index 100% rename from packages/plugins/multiple-apps/tsconfig.build.json rename to packages/plugins/multi-app-manager/tsconfig.build.json diff --git a/packages/plugins/multiple-apps/tsconfig.json b/packages/plugins/multi-app-manager/tsconfig.json similarity index 100% rename from packages/plugins/multiple-apps/tsconfig.json rename to packages/plugins/multi-app-manager/tsconfig.json diff --git a/packages/plugins/multiple-apps/src/collections/application-plugins.ts b/packages/plugins/multiple-apps/src/collections/application-plugins.ts deleted file mode 100644 index 8dff18c56..000000000 --- a/packages/plugins/multiple-apps/src/collections/application-plugins.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { defineCollection } from '@nocobase/database'; - -export default defineCollection({ - name: 'applicationPlugins', - timestamps: false, - fields: [ - { - type: 'string', - name: 'name', - }, - { - type: 'belongsTo', - name: 'application', - foreignKey: 'applicationName', - }, - ], -}); diff --git a/publish.js b/publish.js index 4177bb45c..50bfffe70 100644 --- a/publish.js +++ b/publish.js @@ -14,7 +14,7 @@ Promise.all(packageDirs.map((d) => getDirectories(d))) .then((res) => res.flat()) .then((res) => res.forEach((d) => { - exec(`cd ${d} && npm unpublish -f && npm publish`, (error, stdout, stderr) => { + exec(`cd ${d} && npm unpublish -f; npm publish`, (error, stdout, stderr) => { if (error) { console.log(`error: ${error.message}`); return;