mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 05:17:28 -08:00
⚡ Add first basic code for external hooks
This commit is contained in:
parent
582ff76799
commit
a380a9a394
|
@ -12,6 +12,7 @@ import {
|
|||
ActiveWorkflowRunner,
|
||||
CredentialTypes,
|
||||
Db,
|
||||
ExternalHooks,
|
||||
GenericHelpers,
|
||||
LoadNodesAndCredentials,
|
||||
NodeTypes,
|
||||
|
@ -108,6 +109,12 @@ export class Start extends Command {
|
|||
const loadNodesAndCredentials = LoadNodesAndCredentials();
|
||||
await loadNodesAndCredentials.init();
|
||||
|
||||
// Load all external hooks
|
||||
const externalHooks = ExternalHooks();
|
||||
await externalHooks.init();
|
||||
|
||||
// await externalHooks.run('credentials.new');
|
||||
|
||||
// Add the found types to an instance other parts of the application can use
|
||||
const nodeTypes = NodeTypes();
|
||||
await nodeTypes.init(loadNodesAndCredentials.nodeTypes);
|
||||
|
|
|
@ -252,6 +252,13 @@ const config = convict({
|
|||
},
|
||||
},
|
||||
|
||||
externalHookFiles: {
|
||||
doc: 'Files containing external hooks',
|
||||
format: String,
|
||||
default: '',
|
||||
env: 'EXTERNAL_HOOK_FILES'
|
||||
},
|
||||
|
||||
nodes: {
|
||||
exclude: {
|
||||
doc: 'Nodes not to load',
|
||||
|
|
89
packages/cli/src/ExternalHooks.ts
Normal file
89
packages/cli/src/ExternalHooks.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
import {
|
||||
Db,
|
||||
IDatabaseCollections,
|
||||
IExternalHooks,
|
||||
} from "./";
|
||||
|
||||
import * as config from '../config';
|
||||
// import {
|
||||
// access as fsAccess,
|
||||
// readdir as fsReaddir,
|
||||
// readFile as fsReadFile,
|
||||
// stat as fsStat,
|
||||
// } from 'fs';
|
||||
|
||||
// TODO: Give different name
|
||||
interface IHookData {
|
||||
DbCollections: IDatabaseCollections;
|
||||
}
|
||||
|
||||
// export EXTERNAL_HOOK_FILES=/data/packages/cli/dist/src/externalHooksTemp/test-hooks.js
|
||||
|
||||
class ExternalHooksClass implements IExternalHooks {
|
||||
|
||||
externalHooks: {
|
||||
[key: string]: Array<() => {}>
|
||||
} = {};
|
||||
|
||||
|
||||
async init(): Promise<void> {
|
||||
console.log('ExternalHooks.init');
|
||||
|
||||
const externalHookFiles = config.get('externalHookFiles').split(',');
|
||||
|
||||
console.log('externalHookFiles');
|
||||
console.log(externalHookFiles);
|
||||
|
||||
for (let hookFilePath of externalHookFiles) {
|
||||
hookFilePath = hookFilePath.trim();
|
||||
if (hookFilePath !== '') {
|
||||
console.log(' --- load: ' + hookFilePath);
|
||||
const hookFile = require(hookFilePath);
|
||||
|
||||
for (const resource of Object.keys(hookFile)) {
|
||||
// if (this.externalHooks[resource] === undefined) {
|
||||
// this.externalHooks[resource] = {};
|
||||
// }
|
||||
|
||||
for (const operation of Object.keys(hookFile[resource])) {
|
||||
const hookString = `${resource}.${operation}`;
|
||||
if (this.externalHooks[hookString] === undefined) {
|
||||
this.externalHooks[hookString] = [];
|
||||
}
|
||||
|
||||
this.externalHooks[hookString].push.apply(this.externalHooks[hookString], hookFile[resource][operation]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async run(hookName: string): Promise<void> {
|
||||
console.log('RUN NOW: ' + hookName);
|
||||
|
||||
const hookData: IHookData = {
|
||||
DbCollections: Db.collections,
|
||||
};
|
||||
|
||||
if (this.externalHooks[hookName] === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(const externalHookFunction of this.externalHooks[hookName]) {
|
||||
externalHookFunction.call(hookData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
let externalHooksInstance: ExternalHooksClass | undefined;
|
||||
|
||||
export function ExternalHooks(): ExternalHooksClass {
|
||||
if (externalHooksInstance === undefined) {
|
||||
externalHooksInstance = new ExternalHooksClass();
|
||||
}
|
||||
|
||||
return externalHooksInstance;
|
||||
}
|
|
@ -188,6 +188,11 @@ export interface IExecutingWorkflowData {
|
|||
workflowExecution?: PCancelable<IRun>;
|
||||
}
|
||||
|
||||
export interface IExternalHooks {
|
||||
init(): Promise<void>;
|
||||
run(hookName: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IN8nConfig {
|
||||
database: IN8nConfigDatabase;
|
||||
endpoints: IN8nConfigEndpoints;
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
ActiveWorkflowRunner,
|
||||
CredentialTypes,
|
||||
Db,
|
||||
ExternalHooks,
|
||||
IActivationError,
|
||||
ICustomRequest,
|
||||
ICredentialsDb,
|
||||
|
@ -33,6 +34,7 @@ import {
|
|||
IExecutionsListResponse,
|
||||
IExecutionsStopData,
|
||||
IExecutionsSummary,
|
||||
IExternalHooks,
|
||||
IN8nUISettings,
|
||||
IPackageVersions,
|
||||
IWorkflowBase,
|
||||
|
@ -93,6 +95,7 @@ class App {
|
|||
testWebhooks: TestWebhooks.TestWebhooks;
|
||||
endpointWebhook: string;
|
||||
endpointWebhookTest: string;
|
||||
externalHooks: IExternalHooks;
|
||||
saveDataErrorExecution: string;
|
||||
saveDataSuccessExecution: string;
|
||||
saveManualExecutions: boolean;
|
||||
|
@ -124,6 +127,8 @@ class App {
|
|||
this.protocol = config.get('protocol');
|
||||
this.sslKey = config.get('ssl_key');
|
||||
this.sslCert = config.get('ssl_cert');
|
||||
|
||||
this.externalHooks = ExternalHooks();
|
||||
}
|
||||
|
||||
|
||||
|
@ -689,6 +694,8 @@ class App {
|
|||
throw new ResponseHelper.ResponseError(`Credentials with the same type and name exist already.`, undefined, 400);
|
||||
}
|
||||
|
||||
await this.externalHooks.run('credentials.new');
|
||||
|
||||
// Encrypt the data
|
||||
const credentials = new Credentials(incomingData.name, incomingData.type, incomingData.nodesAccess);
|
||||
credentials.setData(incomingData.data, encryptionKey);
|
||||
|
|
10
packages/cli/src/externalHooksTemp/test-hooks.ts
Normal file
10
packages/cli/src/externalHooksTemp/test-hooks.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
export = {
|
||||
credentials: {
|
||||
new: [
|
||||
() => {
|
||||
// Here any additional code can run or the creation blocked
|
||||
throw new Error('No additional credentials can be created.');
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
export * from './CredentialTypes';
|
||||
export * from './ExternalHooks';
|
||||
export * from './Interfaces';
|
||||
export * from './LoadNodesAndCredentials';
|
||||
export * from './NodeTypes';
|
||||
|
|
Loading…
Reference in a new issue