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
|
|
|
});
|
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'),
|
|
|
|
},
|
|
|
|
{
|
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-08 21:43:30 +08:00
|
|
|
}
|
|
|
|
|
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) {
|
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],
|
|
|
|
},
|
|
|
|
{
|
2022-02-09 20:51:29 +08:00
|
|
|
collectionFieldInstance: fieldModel,
|
2022-02-09 20:24:25 +08:00
|
|
|
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 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-09 23:39:50 +08:00
|
|
|
await hookFunc({ ...hooksArgs, schemaInstance: (<any>hookRecord).uiSchema, db: this.db });
|
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);
|
|
|
|
}
|
|
|
|
}
|