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-08 20:58:57 +08:00
|
|
|
|
2022-02-09 20:24:25 +08:00
|
|
|
export type HookType =
|
|
|
|
| 'onSchemaDestroy'
|
|
|
|
| '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();
|
|
|
|
}
|
|
|
|
|
|
|
|
listen() {
|
|
|
|
this.db.on('fields.afterDestroy', async (model, options) => {
|
2022-02-09 20:24:25 +08:00
|
|
|
await this.onCollectionFieldDestroy(model, options);
|
2022-02-08 20:58:57 +08:00
|
|
|
});
|
2022-02-08 21:43:30 +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-08 21:43:30 +08:00
|
|
|
});
|
|
|
|
|
2022-02-09 20:24:25 +08:00
|
|
|
this.db.on('ui_schemas.afterCreateWithAssociations', async (model, options) => {
|
|
|
|
await this.onUiSchemaCreate(model, options);
|
2022-02-08 21:43:30 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-02-09 20:24:25 +08:00
|
|
|
protected async onCollectionDestroy(collectionModel, options) {
|
2022-02-08 21:43:30 +08:00
|
|
|
const { transaction } = options;
|
|
|
|
|
2022-02-09 20:24:25 +08:00
|
|
|
await this.findHooksAndCall(
|
|
|
|
{
|
|
|
|
type: 'onCollectionDestroy',
|
|
|
|
collection: collectionModel.get('name'),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
collectionModel,
|
2022-02-09 09:50:36 +08:00
|
|
|
options,
|
2022-02-09 20:24:25 +08:00
|
|
|
},
|
|
|
|
transaction,
|
|
|
|
);
|
2022-02-08 21:43:30 +08:00
|
|
|
}
|
|
|
|
|
2022-02-09 20:24:25 +08:00
|
|
|
protected async onCollectionFieldDestroy(fieldModel, options) {
|
2022-02-08 21:43:30 +08:00
|
|
|
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,
|
|
|
|
'fields.$anyOf': [fieldName],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
fieldInstance: fieldModel,
|
|
|
|
options,
|
2022-02-08 21:43:30 +08:00
|
|
|
},
|
|
|
|
transaction,
|
2022-02-09 20:24:25 +08:00
|
|
|
);
|
2022-02-08 20:58:57 +08:00
|
|
|
}
|
|
|
|
|
2022-02-09 20:24:25 +08:00
|
|
|
protected async onUiSchemaCreate(uiSchemaModel, 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',
|
|
|
|
uid: uiSchemaModel.schema['x-uid'],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
uiSchemaModel,
|
|
|
|
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) {
|
|
|
|
await hookFunc({ ...hooksArgs, schemaInstance: (<any>hookRecord).uiSchema });
|
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);
|
|
|
|
}
|
|
|
|
}
|