tachybase_todo/packages/core/database/src/model-hook.ts
ChengLei Shao b3f3883435
fix: association accessors rebind (#1027)
* chore: test

* chore: test

* fix: association accessors rebind

* fix: test
2022-11-04 09:04:53 +08:00

72 lines
1.7 KiB
TypeScript

import lodash from 'lodash';
import type { SequelizeHooks } from 'sequelize/types/lib/hooks';
import Database from './database';
import { Model } from './model';
const { hooks } = require('sequelize/lib/hooks');
export class ModelHook {
database: Database;
boundEvents = new Set<string>();
constructor(database: Database) {
this.database = database;
}
match(event: string | Symbol): keyof SequelizeHooks | null {
// NOTE: skip Symbol event
if (!lodash.isString(event)) {
return null;
}
const type = event.split('.').pop();
return type in hooks ? <keyof SequelizeHooks>type : null;
}
findModelName(hookArgs) {
for (const arg of hookArgs) {
if (arg?._previousDataValues) {
return (<Model>arg).constructor.name;
}
if (lodash.isPlainObject(arg)) {
if (arg['model']) {
return arg['model'].name;
}
const plural = arg?.name?.plural;
if (this.database.sequelize.isDefined(plural)) {
return plural;
}
const singular = arg?.name?.singular;
if (this.database.sequelize.isDefined(singular)) {
return singular;
}
}
}
return null;
}
bindEvent(type) {
this.boundEvents.add(type);
}
hasBoundEvent(type): boolean {
return this.boundEvents.has(type);
}
buildSequelizeHook(type) {
return async (...args: any[]) => {
const modelName = this.findModelName(args);
if (modelName) {
// emit model event
await this.database.emitAsync(`${modelName}.${type}`, ...args);
}
// emit sequelize global event
await this.database.emitAsync(type, ...args);
};
}
}