tachybase_todo/packages/plugin-ui-schema-storage/src/server-hooks/index.ts

144 lines
3.6 KiB
TypeScript
Raw Normal View History

2022-02-08 20:58:57 +08:00
import { Database } from '@nocobase/database';
2022-02-09 20:24:25 +08:00
import { ServerHookModel } from './model';
2022-02-10 13:58:26 +08:00
import { hooks } from './hooks';
2022-02-08 20:58:57 +08:00
2022-02-09 20:24:25 +08:00
export type HookType =
2022-02-09 21:11:29 +08:00
| 'onSelfDestroy'
2022-02-09 20:24:25 +08:00
| 'onCollectionDestroy'
| 'onCollectionFieldDestroy'
| 'onAnyCollectionFieldDestroy'
| 'onSelfCreate';
2022-02-08 20:58:57 +08:00
export class ServerHooks {
hooks = new Map<HookType, Map<string, any>>();
constructor(protected db: Database) {
this.listen();
2022-02-10 13:58:26 +08:00
this.registerHooks();
}
registerHooks() {
hooks.forEach((hook) => this.register(hook.hookType, hook.hookName, hook.hookFunc));
2022-02-08 20:58:57 +08:00
}
listen() {
this.db.on('fields.afterDestroy', async (model, options) => {
2022-02-09 20:24:25 +08:00
await this.onCollectionFieldDestroy(model, options);
2022-02-09 20:30:00 +08:00
await this.onAnyCollectionFieldDestroy(model, options);
2022-02-08 20:58:57 +08:00
});
this.db.on('collections.afterDestroy', async (model, options) => {
2022-02-09 20:24:25 +08:00
await this.onCollectionDestroy(model, options);
});
2022-02-09 20:24:25 +08:00
this.db.on('ui_schemas.afterCreateWithAssociations', async (model, options) => {
await this.onUiSchemaCreate(model, options);
});
}
2022-02-09 20:24:25 +08:00
protected async onCollectionDestroy(collectionModel, options) {
const { transaction } = options;
2022-02-09 20:24:25 +08:00
await this.findHooksAndCall(
{
type: 'onCollectionDestroy',
collection: collectionModel.get('name'),
},
{
2022-02-09 20:51:29 +08:00
collectionInstance: collectionModel,
2022-02-09 09:50:36 +08:00
options,
2022-02-09 20:24:25 +08:00
},
transaction,
);
}
2022-02-09 20:30:00 +08:00
protected async onAnyCollectionFieldDestroy(fieldModel, options) {
const { transaction } = options;
const collectionName = fieldModel.get('collectionName');
await this.findHooksAndCall(
{
type: 'onAnyCollectionFieldDestroy',
collection: collectionName,
},
{
2022-02-09 20:51:29 +08:00
collectionFieldInstance: fieldModel,
2022-02-09 20:30:00 +08:00
options,
},
transaction,
);
}
2022-02-09 20:24:25 +08:00
protected async onCollectionFieldDestroy(fieldModel, options) {
const { transaction } = options;
2022-02-09 20:24:25 +08:00
const collectionName = fieldModel.get('collectionName');
const fieldName = fieldModel.get('name');
await this.findHooksAndCall(
{
type: 'onCollectionFieldDestroy',
collection: collectionName,
2022-02-10 19:11:43 +08:00
field: fieldName,
2022-02-09 20:24:25 +08:00
},
{
2022-02-09 20:51:29 +08:00
collectionFieldInstance: fieldModel,
2022-02-09 20:24:25 +08:00
options,
},
transaction,
2022-02-09 20:24:25 +08:00
);
2022-02-08 20:58:57 +08:00
}
2022-02-09 21:11:29 +08:00
protected async onUiSchemaCreate(schemaInstance, options) {
2022-02-08 20:58:57 +08:00
const { transaction } = options;
2022-02-09 20:24:25 +08:00
await this.findHooksAndCall(
{
type: 'onSelfCreate',
2022-02-09 21:11:29 +08:00
uid: schemaInstance.schema['x-uid'],
2022-02-09 20:24:25 +08:00
},
{
2022-02-09 21:11:29 +08:00
schemaInstance,
2022-02-09 20:24:25 +08:00
options,
2022-02-08 20:58:57 +08:00
},
transaction,
2022-02-09 20:24:25 +08:00
);
}
protected async findHooksAndCall(hooksFilter, hooksArgs, transaction) {
const hooks = (await this.db.getRepository('uiSchemaServerHooks').find({
filter: hooksFilter,
appends: ['uiSchema'],
transaction,
})) as ServerHookModel[];
for (const hookRecord of hooks) {
const hoodMethodName = hookRecord.get('method') as string;
const hookFunc = this.hooks.get(hookRecord.get('type') as HookType)?.get(hoodMethodName);
if (hookFunc) {
2022-02-10 20:28:27 +08:00
await hookFunc({
...hooksArgs,
schemaInstance: (<any>hookRecord).uiSchema,
db: this.db,
params: hookRecord.get('params'),
});
2022-02-08 20:58:57 +08:00
}
}
}
/**
* register a server hook function
* @param type type of server hook
* @param name name of server hook
* @param hookFunc server hook function
*/
register(type: HookType, name: string, hookFunc: any) {
if (!this.hooks.has(type)) {
this.hooks.set(type, new Map());
}
const hookTypeMap = this.hooks.get(type);
hookTypeMap.set(name, hookFunc);
}
}