feat: plugin install (#211)

* feat: plugin install

* fix: install options
This commit is contained in:
ChengLei Shao 2022-02-28 21:49:50 +08:00 committed by GitHub
parent 78f75f5a2f
commit 5e51973b21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 200 additions and 196 deletions

View File

@ -238,7 +238,7 @@ export class PluginACL extends Plugin {
await this.writeRolesToACL();
});
this.app.on('installing.beforeUsersPlugin', async () => {
this.app.on('afterInstallUsersPlugin', async () => {
const repository = this.app.db.getRepository('roles');
await repository.createMany({
records: [

View File

@ -3,11 +3,8 @@ import { areas, cities, provinces } from 'china-division';
import { resolve } from 'path';
export class ChinaRegionPlugin extends Plugin {
async beforeLoad() {
this.app.on('installing', async () => {
async install() {
await this.importData();
});
}
async load() {

View File

@ -9,8 +9,7 @@ export default class PluginFileManager extends Plugin {
return process.env.DEFAULT_STORAGE_TYPE;
}
async beforeLoad() {
this.app.on('installing', async () => {
async install() {
const defaultStorageConfig = getStorageConfig(this.storageType());
if (defaultStorageConfig) {
const Storage = this.db.getCollection('storages');
@ -22,7 +21,6 @@ export default class PluginFileManager extends Plugin {
},
});
}
});
}
async load() {

View File

@ -3,8 +3,7 @@ import { Plugin } from '@nocobase/server';
import { resolve } from 'path';
export class SystemSettingsPlugin extends Plugin {
async beforeLoad() {
this.app.on('installing', async () => {
async install() {
await this.db.getRepository('systemSettings').create({
values: {
title: 'NocoBase',
@ -17,7 +16,6 @@ export class SystemSettingsPlugin extends Plugin {
},
},
});
});
}
async load() {

View File

@ -5,8 +5,7 @@ import { resolve } from 'path';
import { getAccessible } from './actions/getAccessible';
export class UiRoutesStoragePlugin extends Plugin {
beforeLoad() {
this.app.on('installing', async () => {
async install() {
const repository = this.app.db.getRepository('uiRoutes');
const routes = [
{
@ -139,7 +138,6 @@ export class UiRoutesStoragePlugin extends Plugin {
values,
});
}
});
}
async load() {

View File

@ -8,6 +8,7 @@ describe('role', () => {
beforeEach(async () => {
api = mockServer();
await api.cleanDb();
api.plugin(require('../server').default);
api.plugin(PluginACL);
await api.loadAndInstall();

View File

@ -5,31 +5,28 @@ import * as actions from './actions/users';
import * as middlewares from './middlewares';
export default class UsersPlugin extends Plugin {
async beforeLoad() {
async install() {
const {
adminNickname = 'Super Admin',
adminEmail = 'admin@nocobase.com',
adminPassword = 'admin123',
} = this.options;
this.app.on('installing', async (...args) => {
// TODO 暂时先这么写着,理想状态应该由 app.emitAsync('installing') 内部处理
await this.app.emitAsync('installing.beforeUsersPlugin', ...args);
const User = this.db.getCollection('users');
await User.repository.create({
values: {
nickname: adminNickname,
email: adminEmail,
password: adminPassword,
roles: ['admin'],
},
});
await this.app.emitAsync('installing.afterUsersPlugin', ...args);
});
}
async beforeLoad() {
this.db.on('users.afterCreateWithAssociations', async (model, options) => {
const { transaction } = options;
if (this.app.db.getCollection('roles')) {
const defaultRole = await this.app.db.getRepository('roles').findOne({
filter: {
default: true,
@ -40,6 +37,7 @@ export default class UsersPlugin extends Plugin {
if (defaultRole && (await model.countRoles({ transaction })) == 0) {
await model.addRoles(defaultRole, { transaction });
}
}
});
this.db.on('afterDefineCollection', (collection: Collection) => {

View File

@ -11,7 +11,7 @@ import { isBoolean } from 'lodash';
import { createACL } from './acl';
import { createCli, createDatabase, createI18n, createResourcer, registerMiddlewares } from './helper';
import { Plugin } from './plugin';
import { PluginManager } from './plugin-manager';
import { PluginManager, InstallOptions } from './plugin-manager';
export interface ResourcerOptions {
prefix?: string;
@ -71,12 +71,6 @@ interface StartOptions {
listen?: ListenOptions;
}
interface InstallOptions {
cliArgs?: any[];
clean?: CleanOptions | boolean;
sync?: SyncOptions;
}
export class Application<StateT = DefaultState, ContextT = DefaultContext> extends Koa implements AsyncEmitter {
public readonly db: Database;
@ -214,11 +208,13 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
async install(options?: InstallOptions) {
await this.emitAsync('beforeInstall', this, options);
if (options?.clean) {
await this.db.clean(isBoolean(options.clean) ? { drop: options.clean } : options.clean);
}
await this.db.sync(options?.sync);
await this.emitAsync('installing', this, options);
await this.pm.install(options);
await this.emitAsync('afterInstall', this, options);
}

View File

@ -1,10 +1,17 @@
import Application from './application';
import { Plugin } from './plugin';
import { CleanOptions, SyncOptions } from '@nocobase/database';
interface PluginManagerOptions {
app: Application;
}
export interface InstallOptions {
cliArgs?: any[];
clean?: CleanOptions | boolean;
sync?: SyncOptions;
}
export class PluginManager {
app: Application;
protected plugins = new Map<string, Plugin>();
@ -46,4 +53,12 @@ export class PluginManager {
await this.app.emitAsync('afterLoadAll');
}
async install(options?: InstallOptions) {
for (const [name, plugin] of this.plugins) {
await this.app.emitAsync('beforeInstallPlugin', plugin, options);
await plugin.install(options);
await this.app.emitAsync('afterInstallPlugin', plugin, options);
}
}
}

View File

@ -1,6 +1,7 @@
import { Database } from '@nocobase/database';
import { Application } from './application';
import path from 'path';
import { InstallOptions } from './plugin-manager';
export interface PluginInterface {
beforeLoad?: () => void;
@ -42,6 +43,8 @@ export abstract class Plugin<O = any> implements PluginInterface {
beforeLoad() {}
async install(options?: InstallOptions) {}
async load() {
const collectionPath = this.collectionPath();
if (collectionPath) {