mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
⚡ Add first basic code for external hooks
This commit is contained in:
parent
582ff76799
commit
a380a9a394
|
@ -12,6 +12,7 @@ import {
|
||||||
ActiveWorkflowRunner,
|
ActiveWorkflowRunner,
|
||||||
CredentialTypes,
|
CredentialTypes,
|
||||||
Db,
|
Db,
|
||||||
|
ExternalHooks,
|
||||||
GenericHelpers,
|
GenericHelpers,
|
||||||
LoadNodesAndCredentials,
|
LoadNodesAndCredentials,
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
|
@ -108,6 +109,12 @@ export class Start extends Command {
|
||||||
const loadNodesAndCredentials = LoadNodesAndCredentials();
|
const loadNodesAndCredentials = LoadNodesAndCredentials();
|
||||||
await loadNodesAndCredentials.init();
|
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
|
// Add the found types to an instance other parts of the application can use
|
||||||
const nodeTypes = NodeTypes();
|
const nodeTypes = NodeTypes();
|
||||||
await nodeTypes.init(loadNodesAndCredentials.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: {
|
nodes: {
|
||||||
exclude: {
|
exclude: {
|
||||||
doc: 'Nodes not to load',
|
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>;
|
workflowExecution?: PCancelable<IRun>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IExternalHooks {
|
||||||
|
init(): Promise<void>;
|
||||||
|
run(hookName: string): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IN8nConfig {
|
export interface IN8nConfig {
|
||||||
database: IN8nConfigDatabase;
|
database: IN8nConfigDatabase;
|
||||||
endpoints: IN8nConfigEndpoints;
|
endpoints: IN8nConfigEndpoints;
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
ActiveWorkflowRunner,
|
ActiveWorkflowRunner,
|
||||||
CredentialTypes,
|
CredentialTypes,
|
||||||
Db,
|
Db,
|
||||||
|
ExternalHooks,
|
||||||
IActivationError,
|
IActivationError,
|
||||||
ICustomRequest,
|
ICustomRequest,
|
||||||
ICredentialsDb,
|
ICredentialsDb,
|
||||||
|
@ -33,6 +34,7 @@ import {
|
||||||
IExecutionsListResponse,
|
IExecutionsListResponse,
|
||||||
IExecutionsStopData,
|
IExecutionsStopData,
|
||||||
IExecutionsSummary,
|
IExecutionsSummary,
|
||||||
|
IExternalHooks,
|
||||||
IN8nUISettings,
|
IN8nUISettings,
|
||||||
IPackageVersions,
|
IPackageVersions,
|
||||||
IWorkflowBase,
|
IWorkflowBase,
|
||||||
|
@ -93,6 +95,7 @@ class App {
|
||||||
testWebhooks: TestWebhooks.TestWebhooks;
|
testWebhooks: TestWebhooks.TestWebhooks;
|
||||||
endpointWebhook: string;
|
endpointWebhook: string;
|
||||||
endpointWebhookTest: string;
|
endpointWebhookTest: string;
|
||||||
|
externalHooks: IExternalHooks;
|
||||||
saveDataErrorExecution: string;
|
saveDataErrorExecution: string;
|
||||||
saveDataSuccessExecution: string;
|
saveDataSuccessExecution: string;
|
||||||
saveManualExecutions: boolean;
|
saveManualExecutions: boolean;
|
||||||
|
@ -124,6 +127,8 @@ class App {
|
||||||
this.protocol = config.get('protocol');
|
this.protocol = config.get('protocol');
|
||||||
this.sslKey = config.get('ssl_key');
|
this.sslKey = config.get('ssl_key');
|
||||||
this.sslCert = config.get('ssl_cert');
|
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);
|
throw new ResponseHelper.ResponseError(`Credentials with the same type and name exist already.`, undefined, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.externalHooks.run('credentials.new');
|
||||||
|
|
||||||
// Encrypt the data
|
// Encrypt the data
|
||||||
const credentials = new Credentials(incomingData.name, incomingData.type, incomingData.nodesAccess);
|
const credentials = new Credentials(incomingData.name, incomingData.type, incomingData.nodesAccess);
|
||||||
credentials.setData(incomingData.data, encryptionKey);
|
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 './CredentialTypes';
|
||||||
|
export * from './ExternalHooks';
|
||||||
export * from './Interfaces';
|
export * from './Interfaces';
|
||||||
export * from './LoadNodesAndCredentials';
|
export * from './LoadNodesAndCredentials';
|
||||||
export * from './NodeTypes';
|
export * from './NodeTypes';
|
||||||
|
|
Loading…
Reference in a new issue