mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { once } from 'lodash-es';
|
|
|
|
import { ModuleScanner } from '../nestjs/scanner';
|
|
import {
|
|
type EventName,
|
|
type EventOptions,
|
|
getEventHandlerMetadata,
|
|
} from './def';
|
|
|
|
@Injectable()
|
|
export class EventHandlerScanner {
|
|
constructor(private readonly scanner: ModuleScanner) {}
|
|
|
|
scan = once(() => {
|
|
const handlers: Array<{
|
|
event: EventName;
|
|
handler: (payload: any) => any;
|
|
opts?: EventOptions;
|
|
}> = [];
|
|
const providers = this.scanner.getAtInjectables();
|
|
|
|
providers.forEach(wrapper => {
|
|
const { instance, name } = wrapper;
|
|
if (!instance || wrapper.isAlias) {
|
|
return;
|
|
}
|
|
|
|
const methods = this.scanner.getAllMethodNames(instance);
|
|
|
|
methods.forEach(method => {
|
|
const fn = instance[method];
|
|
|
|
let defs = getEventHandlerMetadata(instance[method]);
|
|
|
|
if (defs.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const signature = `${name}.${method}`;
|
|
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(`Event handler [${signature}] is not a function.`);
|
|
}
|
|
|
|
if (!wrapper.isDependencyTreeStatic()) {
|
|
throw new Error(
|
|
`Provider [${name}] could not be RequestScoped or TransientScoped injectable if it contains event handlers.`
|
|
);
|
|
}
|
|
|
|
defs.forEach(({ event, opts }) => {
|
|
handlers.push({
|
|
event,
|
|
handler: (payload: any) => {
|
|
// NOTE(@forehalo):
|
|
// we might create spies on the event handlers when testing,
|
|
// avoid reusing `fn` variable to fail the spies or stubs
|
|
return instance[method].bind(instance)(payload);
|
|
},
|
|
opts: {
|
|
name: signature,
|
|
...opts,
|
|
},
|
|
});
|
|
});
|
|
});
|
|
});
|
|
return handlers;
|
|
});
|
|
}
|