refactor: add plugin manager

This commit is contained in:
chenos 2020-12-18 19:54:53 +08:00
parent 7e9b4a8f45
commit 6ffa3b53e8
6 changed files with 81 additions and 44 deletions

View File

@ -83,7 +83,7 @@ api.resourcer.use(async (ctx: actions.Context, next) => {
if (appends.length) { if (appends.length) {
ctx.action.setParam('fields.appends', appends); 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(); await next();
}); });
@ -108,21 +108,16 @@ api.resourcer.use(async (ctx: actions.Context, next) => {
} }
await next(); await next();
}); });
api.resourcer.use(associated); api.resourcer.use(associated);
api.resourcer.registerActionHandlers({...actions.common, ...actions.associate}); 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 () => { (async () => {
await api await api.loadPlugins();
.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();
api.listen(process.env.HTTP_PORT, () => { api.listen(process.env.HTTP_PORT, () => {
console.log(`http://localhost:${process.env.HTTP_PORT}/`); console.log(`http://localhost:${process.env.HTTP_PORT}/`);
}); });

View File

@ -7,7 +7,7 @@ import associated from '../../../actions/src/middlewares/associated';
console.log(process.argv); console.log(process.argv);
const clean = false; const clean = true;
const sync = { const sync = {
force: clean, 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 () => { (async () => {
await api await api.loadPlugins();
.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'), {}],
]);
const database: Database = api.database; const database: Database = api.database;
await database.sync({ await database.sync({
// tables: ['collections', 'fields', 'actions', 'views', 'tabs'], // tables: ['collections', 'fields', 'actions', 'views', 'tabs'],
}); });

View File

@ -57,7 +57,8 @@ export async function getApp() {
}); });
app.resourcer.use(middlewares.associated); app.resourcer.use(middlewares.associated);
app.resourcer.registerActionHandlers({...actions.associate, ...actions.common}); app.resourcer.registerActionHandlers({...actions.associate, ...actions.common});
await app.plugins([plugin]); app.registerPlugin('collections', [plugin]);
await app.loadPlugins();
await app.database.sync({ await app.database.sync({
force: true, force: true,
}); });

View File

@ -19,7 +19,7 @@ describe('user fields', () => {
describe('model definition', () => { describe('model definition', () => {
it('add model without createdBy/updatedBy field', async () => { it('add model without createdBy/updatedBy field', async () => {
const Collection = db.getModel('collections'); const Collection = db.getModel('collections');
await Collection.create({ name: 'posts' }); await Collection.create({ name: 'posts', internal: true });
const Post = db.getModel('posts'); const Post = db.getModel('posts');
const post = await Post.create(); const post = await Post.create();
@ -27,6 +27,16 @@ describe('user fields', () => {
expect(post.updated_by_id).toBeUndefined(); 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 () => { it('add model with named createdBy/updatedBy field', async () => {
const Collection = db.getModel('collections'); const Collection = db.getModel('collections');
await Collection.create({ name: 'posts', createdBy: 'author', updatedBy: 'editor' }); await Collection.create({ name: 'posts', createdBy: 'author', updatedBy: 'editor' });

View File

@ -58,10 +58,9 @@ export async function getApp() {
}); });
app.resourcer.use(middlewares.associated); app.resourcer.use(middlewares.associated);
app.resourcer.registerActionHandlers({...actions.associate, ...actions.common}); app.resourcer.registerActionHandlers({...actions.associate, ...actions.common});
await app.plugins([ app.registerPlugin('collections', [path.resolve(__dirname, '../../../plugin-collections')]);
[path.resolve(__dirname, '../../../plugin-collections')], app.registerPlugin('users', [plugin]);
[plugin] await app.loadPlugins();
]);
await app.database.sync({ await app.database.sync({
force: true, force: true,
}); });

View File

@ -7,35 +7,72 @@ export interface ApplicationOptions {
resourcer: any; resourcer: any;
} }
export class PluginManager {
protected application: Application;
protected plugins = new Map<string, any>();
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 { export class Application extends Koa {
public readonly database: Database; public readonly database: Database;
public readonly resourcer: Resourcer; public readonly resourcer: Resourcer;
public readonly pluginManager: PluginManager;
constructor(options: ApplicationOptions) { constructor(options: ApplicationOptions) {
super(); super();
this.database = new Database(options.database); this.database = new Database(options.database);
this.resourcer = new Resourcer(); this.resourcer = new Resourcer();
this.pluginManager = new PluginManager(this);
// this.runHook('afterInit');
} }
async plugins(plugins: any[]) { registerPlugin(key: string, plugin: any) {
for (const pluginOptions of plugins) { this.pluginManager.register(key, plugin);
if (Array.isArray(pluginOptions)) {
const [entry, options = {}] = pluginOptions;
await this.plugin(entry, options);
} else {
await this.plugin(pluginOptions);
}
}
} }
async plugin(entry: string | Function, options: any = {}) { registerPlugins(plugins: object) {
const main = typeof entry === 'function' this.pluginManager.register(plugins);
? entry }
: require(`${entry}/${__filename.endsWith('.ts') ? 'src' : 'lib'}/server`).default;
await main.call(this, options); async loadPlugins() {
return this.pluginManager.load();
} }
} }