n8n/packages/cli/src/ExternalHooks.ts
Iván Ovejero 027dfb2f0a
Enable esModuleInterop compiler option and upgrade to TypeScript 4.6 (#3106)
*  Enable `esModuleInterop` for /core

*  Adjust imports in /core

*  Enable `esModuleInterop` for /cli

*  Adjust imports in /cli

*  Enable `esModuleInterop` for /nodes-base

*  Adjust imports in /nodes-base

*  Make imports consistent

* ⬆️ Upgrade TypeScript to 4.6 (#3109)

* ⬆️ Upgrade TypeScript to 4.6

* 📦 Update package-lock.json

* 🔧 Avoid erroring on untyped errors

* 📘 Fix type error

Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2022-04-08 23:32:08 +02:00

110 lines
3.1 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable import/no-dynamic-require */
/* eslint-disable no-restricted-syntax */
// eslint-disable-next-line import/no-cycle
import { Db, IExternalHooksClass, IExternalHooksFileData, IExternalHooksFunctions } from '.';
import config from '../config';
class ExternalHooksClass implements IExternalHooksClass {
externalHooks: {
[key: string]: Array<() => {}>;
} = {};
initDidRun = false;
async init(): Promise<void> {
if (this.initDidRun) {
return;
}
await this.loadHooksFiles();
this.initDidRun = true;
}
async reload(externalHooks?: IExternalHooksFileData) {
this.externalHooks = {};
if (externalHooks === undefined) {
await this.loadHooksFiles(true);
} else {
this.loadHooks(externalHooks);
}
}
async loadHooksFiles(reload = false) {
const externalHookFiles = config.getEnv('externalHookFiles').split(':');
// Load all the provided hook-files
for (let hookFilePath of externalHookFiles) {
hookFilePath = hookFilePath.trim();
if (hookFilePath !== '') {
try {
if (reload) {
delete require.cache[require.resolve(hookFilePath)];
}
// eslint-disable-next-line import/no-dynamic-require
// eslint-disable-next-line global-require
const hookFile = require(hookFilePath) as IExternalHooksFileData;
this.loadHooks(hookFile);
} catch (error) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-member-access
throw new Error(`Problem loading external hook file "${hookFilePath}": ${error.message}`);
}
}
}
}
loadHooks(hookFileData: IExternalHooksFileData) {
for (const resource of Object.keys(hookFileData)) {
for (const operation of Object.keys(hookFileData[resource])) {
// Save all the hook functions directly under their string
// format in an array
const hookString = `${resource}.${operation}`;
if (this.externalHooks[hookString] === undefined) {
this.externalHooks[hookString] = [];
}
// eslint-disable-next-line prefer-spread
this.externalHooks[hookString].push.apply(
this.externalHooks[hookString],
hookFileData[resource][operation],
);
}
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async run(hookName: string, hookParameters?: any[]): Promise<void> {
const externalHookFunctions: IExternalHooksFunctions = {
dbCollections: Db.collections,
};
if (this.externalHooks[hookName] === undefined) {
return;
}
for (const externalHookFunction of this.externalHooks[hookName]) {
// eslint-disable-next-line no-await-in-loop
await externalHookFunction.apply(externalHookFunctions, hookParameters);
}
}
exists(hookName: string): boolean {
return !!this.externalHooks[hookName];
}
}
let externalHooksInstance: ExternalHooksClass | undefined;
// eslint-disable-next-line @typescript-eslint/naming-convention
export function ExternalHooks(): ExternalHooksClass {
if (externalHooksInstance === undefined) {
externalHooksInstance = new ExternalHooksClass();
}
return externalHooksInstance;
}