From 6ffa3b53e8ab5533f1b8386095466943c74912ad Mon Sep 17 00:00:00 2001 From: chenos Date: Fri, 18 Dec 2020 19:54:53 +0800 Subject: [PATCH] refactor: add plugin manager --- packages/app/src/api/index.ts | 19 ++---- packages/app/src/api/migrate.ts | 17 ++--- .../plugin-collections/src/__tests__/index.ts | 3 +- .../plugin-users/src/__tests__/fields.test.ts | 12 +++- packages/plugin-users/src/__tests__/index.ts | 7 +- packages/server/src/application.ts | 67 ++++++++++++++----- 6 files changed, 81 insertions(+), 44 deletions(-) diff --git a/packages/app/src/api/index.ts b/packages/app/src/api/index.ts index 991de5a46a..757df5a67b 100644 --- a/packages/app/src/api/index.ts +++ b/packages/app/src/api/index.ts @@ -83,7 +83,7 @@ api.resourcer.use(async (ctx: actions.Context, next) => { if (appends.length) { ctx.action.setParam('fields.appends', appends); } - console.log(ctx.action.params.fields); + console.log('ctx.action.params.fields', ctx.action.params.fields, except, appends); } await next(); }); @@ -108,21 +108,16 @@ api.resourcer.use(async (ctx: actions.Context, next) => { } await next(); }); + api.resourcer.use(associated); api.resourcer.registerActionHandlers({...actions.common, ...actions.associate}); +api.registerPlugin('plugin-collections', [path.resolve(__dirname, '../../../plugin-collections'), {}]); +api.registerPlugin('plugin-pages', [path.resolve(__dirname, '../../../plugin-pages'), {}]); +api.registerPlugin('plugin-users', [path.resolve(__dirname, '../../../plugin-users'), {}]); + (async () => { - await api - .plugins([ - [path.resolve(__dirname, '../../../plugin-collections'), {}], - [path.resolve(__dirname, '../../../plugin-pages'), {}], - [path.resolve(__dirname, '../../../plugin-users'), {}], - // [path.resolve(__dirname, '../../../plugin-permissions'), {}], - // [path.resolve(__dirname, '../../../plugin-file-manager'), {}], - ]); - - // await api.database.getModel('collections').load(); - + await api.loadPlugins(); api.listen(process.env.HTTP_PORT, () => { console.log(`http://localhost:${process.env.HTTP_PORT}/`); }); diff --git a/packages/app/src/api/migrate.ts b/packages/app/src/api/migrate.ts index 03f4b7dd9a..cf8276024a 100644 --- a/packages/app/src/api/migrate.ts +++ b/packages/app/src/api/migrate.ts @@ -7,7 +7,7 @@ import associated from '../../../actions/src/middlewares/associated'; console.log(process.argv); -const clean = false; +const clean = true; const sync = { force: clean, @@ -157,18 +157,13 @@ const data = [ } ]; +api.registerPlugin('plugin-collections', [path.resolve(__dirname, '../../../plugin-collections'), {}]); +api.registerPlugin('plugin-pages', [path.resolve(__dirname, '../../../plugin-pages'), {}]); +api.registerPlugin('plugin-users', [path.resolve(__dirname, '../../../plugin-users'), {}]); + (async () => { - await api - .plugins([ - [path.resolve(__dirname, '../../../plugin-collections'), {}], - [path.resolve(__dirname, '../../../plugin-pages'), {}], - // [path.resolve(__dirname, '../../../plugin-permissions'), {}], - [path.resolve(__dirname, '../../../plugin-users'), {}], - // [path.resolve(__dirname, '../../../plugin-file-manager'), {}], - ]); - + await api.loadPlugins(); const database: Database = api.database; - await database.sync({ // tables: ['collections', 'fields', 'actions', 'views', 'tabs'], }); diff --git a/packages/plugin-collections/src/__tests__/index.ts b/packages/plugin-collections/src/__tests__/index.ts index 854ec6117e..3c9e9c581d 100644 --- a/packages/plugin-collections/src/__tests__/index.ts +++ b/packages/plugin-collections/src/__tests__/index.ts @@ -57,7 +57,8 @@ export async function getApp() { }); app.resourcer.use(middlewares.associated); app.resourcer.registerActionHandlers({...actions.associate, ...actions.common}); - await app.plugins([plugin]); + app.registerPlugin('collections', [plugin]); + await app.loadPlugins(); await app.database.sync({ force: true, }); diff --git a/packages/plugin-users/src/__tests__/fields.test.ts b/packages/plugin-users/src/__tests__/fields.test.ts index a9fcad03ba..c6a2a323d0 100644 --- a/packages/plugin-users/src/__tests__/fields.test.ts +++ b/packages/plugin-users/src/__tests__/fields.test.ts @@ -19,7 +19,7 @@ describe('user fields', () => { describe('model definition', () => { it('add model without createdBy/updatedBy field', async () => { const Collection = db.getModel('collections'); - await Collection.create({ name: 'posts' }); + await Collection.create({ name: 'posts', internal: true }); const Post = db.getModel('posts'); const post = await Post.create(); @@ -27,6 +27,16 @@ describe('user fields', () => { expect(post.updated_by_id).toBeUndefined(); }); + it('add model without createdBy/updatedBy field', async () => { + const Collection = db.getModel('collections'); + await Collection.create({ name: 'posts' }); + const Post = db.getModel('posts'); + + const post = await Post.create(); + expect(post.created_by_id).toBeDefined(); + expect(post.updated_by_id).toBeDefined(); + }); + it('add model with named createdBy/updatedBy field', async () => { const Collection = db.getModel('collections'); await Collection.create({ name: 'posts', createdBy: 'author', updatedBy: 'editor' }); diff --git a/packages/plugin-users/src/__tests__/index.ts b/packages/plugin-users/src/__tests__/index.ts index c662d299d3..447e871f07 100644 --- a/packages/plugin-users/src/__tests__/index.ts +++ b/packages/plugin-users/src/__tests__/index.ts @@ -58,10 +58,9 @@ export async function getApp() { }); app.resourcer.use(middlewares.associated); app.resourcer.registerActionHandlers({...actions.associate, ...actions.common}); - await app.plugins([ - [path.resolve(__dirname, '../../../plugin-collections')], - [plugin] - ]); + app.registerPlugin('collections', [path.resolve(__dirname, '../../../plugin-collections')]); + app.registerPlugin('users', [plugin]); + await app.loadPlugins(); await app.database.sync({ force: true, }); diff --git a/packages/server/src/application.ts b/packages/server/src/application.ts index 3c83566278..39e85ba525 100644 --- a/packages/server/src/application.ts +++ b/packages/server/src/application.ts @@ -7,35 +7,72 @@ export interface ApplicationOptions { resourcer: any; } +export class PluginManager { + + protected application: Application; + + protected plugins = new Map(); + + constructor(application: Application) { + this.application = application; + } + + register(key: string | object, plugin?: any) { + if (typeof key === 'object') { + Object.keys(key).forEach((k) => { + this.register(k, key[k]); + }); + } else { + this.plugins.set(key, plugin); + } + } + + async load() { + for (const pluginOptions of this.plugins.values()) { + if (Array.isArray(pluginOptions)) { + const [entry, options = {}] = pluginOptions; + await this.call(entry, options); + } else { + await this.call(pluginOptions); + } + } + } + + async call(entry: string | Function, options: any = {}) { + const main = typeof entry === 'function' + ? entry + : require(`${entry}/${__filename.endsWith('.ts') ? 'src' : 'lib'}/server`).default; + + await main.call(this.application, options); + } +} + export class Application extends Koa { public readonly database: Database; public readonly resourcer: Resourcer; + public readonly pluginManager: PluginManager; + constructor(options: ApplicationOptions) { super(); this.database = new Database(options.database); this.resourcer = new Resourcer(); + this.pluginManager = new PluginManager(this); + // this.runHook('afterInit'); } - async plugins(plugins: any[]) { - for (const pluginOptions of plugins) { - if (Array.isArray(pluginOptions)) { - const [entry, options = {}] = pluginOptions; - await this.plugin(entry, options); - } else { - await this.plugin(pluginOptions); - } - } + registerPlugin(key: string, plugin: any) { + this.pluginManager.register(key, plugin); } - async plugin(entry: string | Function, options: any = {}) { - const main = typeof entry === 'function' - ? entry - : require(`${entry}/${__filename.endsWith('.ts') ? 'src' : 'lib'}/server`).default; - - await main.call(this, options); + registerPlugins(plugins: object) { + this.pluginManager.register(plugins); + } + + async loadPlugins() { + return this.pluginManager.load(); } }