n8n/packages/core/src/NodeExecuteFunctions.ts

1091 lines
39 KiB
TypeScript
Raw Normal View History

2019-06-23 03:35:23 -07:00
import {
2020-10-22 06:46:03 -07:00
BINARY_ENCODING,
2019-06-23 03:35:23 -07:00
IHookFunctions,
ILoadOptionsFunctions,
IResponseError,
2019-06-23 03:35:23 -07:00
IWorkflowSettings,
} from './';
import {
IAllExecuteFunctions,
2019-06-23 03:35:23 -07:00
IBinaryData,
IContextObject,
ICredentialDataDecryptedObject,
ICredentialsExpressionResolveValues,
2019-06-23 03:35:23 -07:00
IDataObject,
IExecuteFunctions,
IExecuteSingleFunctions,
IExecuteWorkflowInfo,
2019-06-23 03:35:23 -07:00
INode,
INodeExecutionData,
INodeParameters,
INodeType,
2020-10-22 06:46:03 -07:00
IOAuth2Options,
IPollFunctions,
2019-06-23 03:35:23 -07:00
IRunExecutionData,
ITaskDataConnections,
ITriggerFunctions,
IWebhookData,
2019-06-23 03:35:23 -07:00
IWebhookDescription,
IWebhookFunctions,
IWorkflowDataProxyData,
2019-06-23 03:35:23 -07:00
IWorkflowExecuteAdditionalData,
IWorkflowMetadata,
2019-06-23 03:35:23 -07:00
NodeHelpers,
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
NodeOperationError,
2019-06-23 03:35:23 -07:00
NodeParameterValue,
Workflow,
WorkflowActivateMode,
WorkflowDataProxy,
2019-06-23 03:35:23 -07:00
WorkflowExecuteMode,
} from 'n8n-workflow';
import * as clientOAuth1 from 'oauth-1.0a';
import { Token } from 'oauth-1.0a';
import * as clientOAuth2 from 'client-oauth2';
2020-02-08 21:25:46 -08:00
import { get } from 'lodash';
import * as express from 'express';
2019-06-23 03:35:23 -07:00
import * as path from 'path';
2020-10-22 06:46:03 -07:00
import { OptionsWithUri, OptionsWithUrl } from 'request';
2019-06-23 03:35:23 -07:00
import * as requestPromise from 'request-promise-native';
import { createHmac } from 'crypto';
import { fromBuffer } from 'file-type';
import { lookup } from 'mime-types';
:sparkles: Added logging to n8n (#1381) * Added logging to n8n This commit adds logging to n8n using the Winston library. For now, this commit only allows logging to console (default behavior) or file (need to pass in config via environment variables). Other logging methods can be further implemented using hooks. These were skipped for now as it would require adding more dependencies. Logging level is notice by default, meaning no additional messages would be displayed at the moment. Logging level can be set to info or debug as well to enrich the generated logs. The ILogger interface was added to the workflow project as it would make it available for all other projects but the implementation was done on the cli project. * Lint fixes and logging level naming. Also fixed the way we use the logger as it was not working previously * Improvements to logging framework Using appropriate single quotes Improving the way the logger is declared * Improved naming for Log Types * Removed logger global variable, replacing it by a proxy * Add logging to CLI commands * Remove unused GenericHelpers * Changed back some messages to console instead of logger and added npm shortcuts for worker and webhook * Fix typos * Adding basic file rotation to logs as suggested by @mutdmour * Fixed linting issues * Correcting comment to correctly reflect space usage * Added settings for log files rotation * Correcting config type from String to Number * Changed default file settings to number To reflect previous changes to the type * Changed the way log messages are added to be called statically. Also minor naming improvements * Applying latest corrections sent by @ivov * :zap: Some logging improvements * Saving logs to a folder inside n8n home instead of root * Fixed broken tests and linting * Changed some log messages to improve formatting * Adding quotes to names on log messages * Added execution and session IDs to logs. Also removed unnecessary line breaks * :zap: Added file caller to log messages (#1657) This is done using callsites library which already existed in the project as another library's dependency. So in fact it does not add any new dependency. * Adding logs to help debug Salesforce node * :zap: Add function name to logs and add more logs * :zap: Improve some error messages * :zap: Improve some more log messages * :zap: Rename logging env variables to match others Co-authored-by: dali <servfrdali@yahoo.fr> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-05-01 20:43:01 -07:00
import {
LoggerProxy as Logger,
} from 'n8n-workflow';
2019-06-23 03:35:23 -07:00
const requestPromiseWithDefaults = requestPromise.defaults({
timeout: 300000, // 5 minutes
});
2019-06-23 03:35:23 -07:00
/**
* Takes a buffer and converts it into the format n8n uses. It encodes the binary data as
* base64 and adds metadata.
*
* @export
* @param {Buffer} binaryData
* @param {string} [filePath]
* @param {string} [mimeType]
* @returns {Promise<IBinaryData>}
*/
export async function prepareBinaryData(binaryData: Buffer, filePath?: string, mimeType?: string): Promise<IBinaryData> {
if (!mimeType) {
// If no mime type is given figure it out
if (filePath) {
// Use file path to guess mime type
const mimeTypeLookup = lookup(filePath);
if (mimeTypeLookup) {
mimeType = mimeTypeLookup;
}
}
2019-06-23 03:35:23 -07:00
if (!mimeType) {
// Use buffer to guess mime type
const fileTypeData = await fromBuffer(binaryData);
if (fileTypeData) {
mimeType = fileTypeData.mime;
2019-06-23 03:35:23 -07:00
}
}
if (!mimeType) {
// Fall back to text
mimeType = 'text/plain';
}
2019-06-23 03:35:23 -07:00
}
const returnData: IBinaryData = {
mimeType,
// TODO: Should program it in a way that it does not have to converted to base64
// It should only convert to and from base64 when saved in database because
// of for example an error or when there is a wait node.
2020-10-22 06:46:03 -07:00
data: binaryData.toString(BINARY_ENCODING),
2019-06-23 03:35:23 -07:00
};
if (filePath) {
if (filePath.includes('?')) {
// Remove maybe present query parameters
filePath = filePath.split('?').shift();
}
const filePathParts = path.parse(filePath as string);
if (filePathParts.dir !== '') {
returnData.directory = filePathParts.dir;
}
2019-06-23 03:35:23 -07:00
returnData.fileName = filePathParts.base;
// Remove the dot
const fileExtension = filePathParts.ext.slice(1);
if (fileExtension) {
returnData.fileExtension = fileExtension;
}
}
return returnData;
}
/**
* Makes a request using OAuth data for authentication
*
* @export
* @param {IAllExecuteFunctions} this
* @param {string} credentialsType
* @param {(OptionsWithUri | requestPromise.RequestPromiseOptions)} requestOptions
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
*
* @returns
*/
export function requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, node: INode, additionalData: IWorkflowExecuteAdditionalData, oAuth2Options?: IOAuth2Options) {
const credentials = this.getCredentials(credentialsType) as ICredentialDataDecryptedObject;
if (credentials === undefined) {
throw new Error('No credentials got returned!');
}
if (credentials.oauthTokenData === undefined) {
throw new Error('OAuth credentials not connected!');
}
2020-02-08 21:25:46 -08:00
const oAuthClient = new clientOAuth2({
clientId: credentials.clientId as string,
clientSecret: credentials.clientSecret as string,
accessTokenUri: credentials.accessTokenUrl as string,
});
const oauthTokenData = credentials.oauthTokenData as clientOAuth2.Data;
const token = oAuthClient.createToken(get(oauthTokenData, oAuth2Options?.property as string) || oauthTokenData.accessToken, oauthTokenData.refreshToken, oAuth2Options?.tokenType || oauthTokenData.tokenType, oauthTokenData);
// Signs the request by adding authorization headers or query parameters depending
// on the token-type used.
const newRequestOptions = token.sign(requestOptions as clientOAuth2.RequestObject);
// If keep bearer is false remove the it from the authorization header
if (oAuth2Options?.keepBearer === false) {
//@ts-ignore
newRequestOptions?.headers?.Authorization = newRequestOptions?.headers?.Authorization.split(' ')[1];
}
return this.helpers.request!(newRequestOptions)
.catch(async (error: IResponseError) => {
:sparkles: GoToWebinar node (#1422) * Create scaffolding for node * Add SVG logo * Create scaffolding for generic functions * Add index for descriptions * Simplify retrieval of details * Introduce minor fixes in generic functions * Add attendee description * Fix attendee description operation * Add coorganizer description * Add panelist description * Add registrant description * Add session description * Add webinar description * Register node and credentials * Add scaffolding for credentials * Minor creds fixes * Fix SVG icon size and position * Fix capitalization in description * Fix credentials connection * Add attendee fields * Populate webinar description * Remove organizer key from params * Add timezones array constant * Implement webinar:create * Implement webinar:delete * Convert times to fixed collection * Add missing segments to endpoints * Fix webinar:update operation * Implement all-items request * Add params for session:getAll * Add params for webinar:getAll * Implement session:getAll and webinar:getAll * Implement session:get and session:getDetails * Implement coorganizer:create * Implement coorganizer:delete * Implement coorganizer:getAll * Implement coorganizer:delete * Refactor time range for getAll operations * Implement coorganizer:reinvite * Implement panelist:create and panelist:getAll * Implement panelist:delete and panelist:reinvite * Remove array body helper types * Implement registrant:create and registrant:getAll * Implement registrant:delete * Prettify error handling * Add returnAll toggle and limit for all operations * Preload webinars * Preload webinar key in more fields * Refactor getAll as handler * Add descriptions for session * Add descriptions for attendee * Add descriptions for co-organizer * Add descriptions for panelist * Add descriptions for registrant * Add descriptions for webinar * Add 403 check for refresh token * Fix defaults for webinar loader * Add descriptions for webinar types * :zap: Improvements * Remove unneeded return type annotation * Add handler for continue on fail * Remove 403 check in error handler The Go To Webinar API returns 403 for a range of various errors, so this check ended up overriding more specific error messages not related to 403 Forbidden errors. * Remove logging * :zap: Small improvement * :zap: Minor improvements * :zap: Improvements * :zap: Minor improvements Co-authored-by: ricardo <ricardoespinoza105@gmail.com> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-02-21 23:49:00 -08:00
const statusCodeReturned = oAuth2Options?.tokenExpiredStatusCode === undefined ? 401 : oAuth2Options?.tokenExpiredStatusCode;
if (error.statusCode === statusCodeReturned) {
// Token is probably not valid anymore. So try refresh it.
const tokenRefreshOptions: IDataObject = {};
if (oAuth2Options?.includeCredentialsOnRefreshOnBody) {
const body: IDataObject = {
client_id: credentials.clientId as string,
client_secret: credentials.clientSecret as string,
};
tokenRefreshOptions.body = body;
// Override authorization property so the credentails are not included in it
tokenRefreshOptions.headers = {
Authorization: '',
};
}
:sparkles: Added logging to n8n (#1381) * Added logging to n8n This commit adds logging to n8n using the Winston library. For now, this commit only allows logging to console (default behavior) or file (need to pass in config via environment variables). Other logging methods can be further implemented using hooks. These were skipped for now as it would require adding more dependencies. Logging level is notice by default, meaning no additional messages would be displayed at the moment. Logging level can be set to info or debug as well to enrich the generated logs. The ILogger interface was added to the workflow project as it would make it available for all other projects but the implementation was done on the cli project. * Lint fixes and logging level naming. Also fixed the way we use the logger as it was not working previously * Improvements to logging framework Using appropriate single quotes Improving the way the logger is declared * Improved naming for Log Types * Removed logger global variable, replacing it by a proxy * Add logging to CLI commands * Remove unused GenericHelpers * Changed back some messages to console instead of logger and added npm shortcuts for worker and webhook * Fix typos * Adding basic file rotation to logs as suggested by @mutdmour * Fixed linting issues * Correcting comment to correctly reflect space usage * Added settings for log files rotation * Correcting config type from String to Number * Changed default file settings to number To reflect previous changes to the type * Changed the way log messages are added to be called statically. Also minor naming improvements * Applying latest corrections sent by @ivov * :zap: Some logging improvements * Saving logs to a folder inside n8n home instead of root * Fixed broken tests and linting * Changed some log messages to improve formatting * Adding quotes to names on log messages * Added execution and session IDs to logs. Also removed unnecessary line breaks * :zap: Added file caller to log messages (#1657) This is done using callsites library which already existed in the project as another library's dependency. So in fact it does not add any new dependency. * Adding logs to help debug Salesforce node * :zap: Add function name to logs and add more logs * :zap: Improve some error messages * :zap: Improve some more log messages * :zap: Rename logging env variables to match others Co-authored-by: dali <servfrdali@yahoo.fr> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-05-01 20:43:01 -07:00
Logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" expired. Should revalidate.`);
const newToken = await token.refresh(tokenRefreshOptions);
:sparkles: Added logging to n8n (#1381) * Added logging to n8n This commit adds logging to n8n using the Winston library. For now, this commit only allows logging to console (default behavior) or file (need to pass in config via environment variables). Other logging methods can be further implemented using hooks. These were skipped for now as it would require adding more dependencies. Logging level is notice by default, meaning no additional messages would be displayed at the moment. Logging level can be set to info or debug as well to enrich the generated logs. The ILogger interface was added to the workflow project as it would make it available for all other projects but the implementation was done on the cli project. * Lint fixes and logging level naming. Also fixed the way we use the logger as it was not working previously * Improvements to logging framework Using appropriate single quotes Improving the way the logger is declared * Improved naming for Log Types * Removed logger global variable, replacing it by a proxy * Add logging to CLI commands * Remove unused GenericHelpers * Changed back some messages to console instead of logger and added npm shortcuts for worker and webhook * Fix typos * Adding basic file rotation to logs as suggested by @mutdmour * Fixed linting issues * Correcting comment to correctly reflect space usage * Added settings for log files rotation * Correcting config type from String to Number * Changed default file settings to number To reflect previous changes to the type * Changed the way log messages are added to be called statically. Also minor naming improvements * Applying latest corrections sent by @ivov * :zap: Some logging improvements * Saving logs to a folder inside n8n home instead of root * Fixed broken tests and linting * Changed some log messages to improve formatting * Adding quotes to names on log messages * Added execution and session IDs to logs. Also removed unnecessary line breaks * :zap: Added file caller to log messages (#1657) This is done using callsites library which already existed in the project as another library's dependency. So in fact it does not add any new dependency. * Adding logs to help debug Salesforce node * :zap: Add function name to logs and add more logs * :zap: Improve some error messages * :zap: Improve some more log messages * :zap: Rename logging env variables to match others Co-authored-by: dali <servfrdali@yahoo.fr> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-05-01 20:43:01 -07:00
Logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`);
2020-02-08 21:25:46 -08:00
credentials.oauthTokenData = newToken.data;
// Find the name of the credentials
if (!node.credentials || !node.credentials[credentialsType]) {
throw new Error(`The node "${node.name}" does not have credentials of type "${credentialsType}"!`);
}
const name = node.credentials[credentialsType];
// Save the refreshed token
2020-02-08 21:25:46 -08:00
await additionalData.credentialsHelper.updateCredentials(name, credentialsType, credentials);
:sparkles: Added logging to n8n (#1381) * Added logging to n8n This commit adds logging to n8n using the Winston library. For now, this commit only allows logging to console (default behavior) or file (need to pass in config via environment variables). Other logging methods can be further implemented using hooks. These were skipped for now as it would require adding more dependencies. Logging level is notice by default, meaning no additional messages would be displayed at the moment. Logging level can be set to info or debug as well to enrich the generated logs. The ILogger interface was added to the workflow project as it would make it available for all other projects but the implementation was done on the cli project. * Lint fixes and logging level naming. Also fixed the way we use the logger as it was not working previously * Improvements to logging framework Using appropriate single quotes Improving the way the logger is declared * Improved naming for Log Types * Removed logger global variable, replacing it by a proxy * Add logging to CLI commands * Remove unused GenericHelpers * Changed back some messages to console instead of logger and added npm shortcuts for worker and webhook * Fix typos * Adding basic file rotation to logs as suggested by @mutdmour * Fixed linting issues * Correcting comment to correctly reflect space usage * Added settings for log files rotation * Correcting config type from String to Number * Changed default file settings to number To reflect previous changes to the type * Changed the way log messages are added to be called statically. Also minor naming improvements * Applying latest corrections sent by @ivov * :zap: Some logging improvements * Saving logs to a folder inside n8n home instead of root * Fixed broken tests and linting * Changed some log messages to improve formatting * Adding quotes to names on log messages * Added execution and session IDs to logs. Also removed unnecessary line breaks * :zap: Added file caller to log messages (#1657) This is done using callsites library which already existed in the project as another library's dependency. So in fact it does not add any new dependency. * Adding logs to help debug Salesforce node * :zap: Add function name to logs and add more logs * :zap: Improve some error messages * :zap: Improve some more log messages * :zap: Rename logging env variables to match others Co-authored-by: dali <servfrdali@yahoo.fr> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-05-01 20:43:01 -07:00
Logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been saved to database successfully.`);
// Make the request again with the new token
const newRequestOptions = newToken.sign(requestOptions as clientOAuth2.RequestObject);
return this.helpers.request!(newRequestOptions);
}
// Unknown error so simply throw it
throw error;
});
}
/* Makes a request using OAuth1 data for authentication
*
* @export
* @param {IAllExecuteFunctions} this
* @param {string} credentialsType
* @param {(OptionsWithUrl | requestPromise.RequestPromiseOptions)} requestOptionså
* @returns
*/
export function requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | OptionsWithUri | requestPromise.RequestPromiseOptions) {
const credentials = this.getCredentials(credentialsType) as ICredentialDataDecryptedObject;
if (credentials === undefined) {
throw new Error('No credentials got returned!');
}
if (credentials.oauthTokenData === undefined) {
throw new Error('OAuth credentials not connected!');
}
const oauth = new clientOAuth1({
consumer: {
key: credentials.consumerKey as string,
secret: credentials.consumerSecret as string,
},
signature_method: credentials.signatureMethod as string,
hash_function(base, key) {
const algorithm = (credentials.signatureMethod === 'HMAC-SHA1') ? 'sha1' : 'sha256';
return createHmac(algorithm, key)
.update(base)
.digest('base64');
},
});
const oauthTokenData = credentials.oauthTokenData as IDataObject;
const token: Token = {
key: oauthTokenData.oauth_token as string,
secret: oauthTokenData.oauth_token_secret as string,
};
//@ts-ignore
requestOptions.data = { ...requestOptions.qs, ...requestOptions.form };
// Fixes issue that OAuth1 library only works with "url" property and not with "uri"
// @ts-ignore
if (requestOptions.uri && !requestOptions.url) {
// @ts-ignore
requestOptions.url = requestOptions.uri;
// @ts-ignore
delete requestOptions.uri;
}
//@ts-ignore
requestOptions.headers = oauth.toHeader(oauth.authorize(requestOptions, token));
return this.helpers.request!(requestOptions)
.catch(async (error: IResponseError) => {
// Unknown error so simply throw it
throw error;
});
}
2019-06-23 03:35:23 -07:00
/**
* Takes generic input data and brings it into the json format n8n uses.
*
* @export
* @param {(IDataObject | IDataObject[])} jsonData
* @returns {INodeExecutionData[]}
*/
export function returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[] {
const returnData: INodeExecutionData[] = [];
if (!Array.isArray(jsonData)) {
jsonData = [jsonData];
}
jsonData.forEach((data) => {
returnData.push({ json: data });
});
return returnData;
}
/**
* Returns the requested decrypted credentials if the node has access to them.
*
* @export
* @param {Workflow} workflow Workflow which requests the data
* @param {INode} node Node which request the data
* @param {string} type The credential type to return
* @param {IWorkflowExecuteAdditionalData} additionalData
* @returns {(ICredentialDataDecryptedObject | undefined)}
*/
2021-01-29 03:16:46 -08:00
export function getCredentials(workflow: Workflow, node: INode, type: string, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, runExecutionData?: IRunExecutionData | null, runIndex?: number, connectionInputData?: INodeExecutionData[], itemIndex?: number): ICredentialDataDecryptedObject | undefined {
2019-06-23 03:35:23 -07:00
// Get the NodeType as it has the information if the credentials are required
const nodeType = workflow.nodeTypes.getByName(node.type);
if (nodeType === undefined) {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(node, `Node type "${node.type}" is not known so can not get credentials!`);
2019-06-23 03:35:23 -07:00
}
if (nodeType.description.credentials === undefined) {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(node, `Node type "${node.type}" does not have any credentials defined!`);
2019-06-23 03:35:23 -07:00
}
const nodeCredentialDescription = nodeType.description.credentials.find((credentialTypeDescription) => credentialTypeDescription.name === type);
if (nodeCredentialDescription === undefined) {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(node, `Node type "${node.type}" does not have any credentials of type "${type}" defined!`);
2019-06-23 03:35:23 -07:00
}
if (NodeHelpers.displayParameter(additionalData.currentNodeParameters || node.parameters, nodeCredentialDescription, node.parameters) === false) {
2019-06-23 03:35:23 -07:00
// Credentials should not be displayed so return undefined even if they would be defined
return undefined;
}
// Check if node has any credentials defined
if (!node.credentials || !node.credentials[type]) {
// If none are defined check if the credentials are required or not
if (nodeCredentialDescription.required === true) {
// Credentials are required so error
if (!node.credentials) {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(node,'Node does not have any credentials set!');
2019-06-23 03:35:23 -07:00
}
if (!node.credentials[type]) {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(node,`Node does not have any credentials set for "${type}"!`);
2019-06-23 03:35:23 -07:00
}
} else {
// Credentials are not required so resolve with undefined
return undefined;
}
}
let expressionResolveValues: ICredentialsExpressionResolveValues | undefined;
if (connectionInputData && runExecutionData && runIndex !== undefined) {
expressionResolveValues = {
connectionInputData,
itemIndex: itemIndex || 0,
node,
runExecutionData,
runIndex,
workflow,
} as ICredentialsExpressionResolveValues;
}
2019-06-23 03:35:23 -07:00
const name = node.credentials[type];
2021-01-29 03:16:46 -08:00
const decryptedDataObject = additionalData.credentialsHelper.getDecrypted(name, type, mode, false, expressionResolveValues);
2019-06-23 03:35:23 -07:00
return decryptedDataObject;
}
/**
* Returns a copy of the node
*
* @export
* @param {INode} node
* @returns {INode}
*/
export function getNode(node: INode): INode {
return JSON.parse(JSON.stringify(node));
}
2019-06-23 03:35:23 -07:00
/**
* Returns the requested resolved (all expressions replaced) node parameters.
*
* @export
* @param {Workflow} workflow
* @param {(IRunExecutionData | null)} runExecutionData
* @param {number} runIndex
* @param {INodeExecutionData[]} connectionInputData
* @param {INode} node
* @param {string} parameterName
* @param {number} itemIndex
* @param {*} [fallbackValue]
* @returns {(NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object)}
*/
2021-01-29 00:31:40 -08:00
export function getNodeParameter(workflow: Workflow, runExecutionData: IRunExecutionData | null, runIndex: number, connectionInputData: INodeExecutionData[], node: INode, parameterName: string, itemIndex: number, mode: WorkflowExecuteMode, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object { //tslint:disable-line:no-any
2019-06-23 03:35:23 -07:00
const nodeType = workflow.nodeTypes.getByName(node.type);
if (nodeType === undefined) {
throw new Error(`Node type "${node.type}" is not known so can not return paramter value!`);
}
const value = get(node.parameters, parameterName, fallbackValue);
if (value === undefined) {
throw new Error(`Could not get parameter "${parameterName}"!`);
}
let returnData;
try {
2021-01-29 00:31:40 -08:00
returnData = workflow.expression.getParameterValue(value, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode);
} catch (e) {
e.message += ` [Error in parameter: "${parameterName}"]`;
throw e;
}
2019-06-23 03:35:23 -07:00
return returnData;
}
2020-03-17 05:18:04 -07:00
/**
* Returns if execution should be continued even if there was an error.
*
* @export
* @param {INode} node
* @returns {boolean}
*/
export function continueOnFail(node: INode): boolean {
return get(node, 'continueOnFail', false);
}
/**
* Returns the webhook URL of the webhook with the given name
*
* @export
* @param {string} name
* @param {Workflow} workflow
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
* @param {boolean} [isTest]
* @returns {(string | undefined)}
*/
2021-01-29 00:31:40 -08:00
export function getNodeWebhookUrl(name: string, workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, isTest?: boolean): string | undefined {
let baseUrl = additionalData.webhookBaseUrl;
if (isTest === true) {
baseUrl = additionalData.webhookTestBaseUrl;
}
const webhookDescription = getWebhookDescription(name, workflow, node);
if (webhookDescription === undefined) {
return undefined;
}
2021-01-29 00:31:40 -08:00
const path = workflow.expression.getSimpleParameterValue(node, webhookDescription['path'], mode);
if (path === undefined) {
return undefined;
}
2021-01-29 00:31:40 -08:00
const isFullPath: boolean = workflow.expression.getSimpleParameterValue(node, webhookDescription['isFullPath'], mode, false) as boolean;
return NodeHelpers.getNodeWebhookUrl(baseUrl, workflow.id!, node, path.toString(), isFullPath);
}
2019-06-23 03:35:23 -07:00
/**
* Returns the timezone for the workflow
*
* @export
* @param {Workflow} workflow
* @param {IWorkflowExecuteAdditionalData} additionalData
* @returns {string}
*/
export function getTimezone(workflow: Workflow, additionalData: IWorkflowExecuteAdditionalData):string {
if (workflow.settings !== undefined && workflow.settings.timezone !== undefined) {
return (workflow.settings as IWorkflowSettings).timezone as string;
}
return additionalData.timezone;
}
/**
* Returns the full webhook description of the webhook with the given name
*
* @export
* @param {string} name
* @param {Workflow} workflow
* @param {INode} node
* @returns {(IWebhookDescription | undefined)}
*/
export function getWebhookDescription(name: string, workflow: Workflow, node: INode): IWebhookDescription | undefined {
const nodeType = workflow.nodeTypes.getByName(node.type) as INodeType;
if (nodeType.description.webhooks === undefined) {
// Node does not have any webhooks so return
return undefined;
}
for (const webhookDescription of nodeType.description.webhooks) {
if (webhookDescription.name === name) {
return webhookDescription;
}
}
return undefined;
}
/**
* Returns the workflow metadata
*
* @export
* @param {Workflow} workflow
* @returns {IWorkflowMetadata}
*/
export function getWorkflowMetadata(workflow: Workflow): IWorkflowMetadata {
return {
id: workflow.id,
name: workflow.name,
active: workflow.active,
};
}
/**
* Returns the execute functions the poll nodes have access to.
*
* @export
* @param {Workflow} workflow
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
* @param {WorkflowExecuteMode} mode
* @returns {ITriggerFunctions}
*/
// TODO: Check if I can get rid of: additionalData, and so then maybe also at ActiveWorkflowRunner.add
export function getExecutePollFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, activation: WorkflowActivateMode): IPollFunctions {
return ((workflow: Workflow, node: INode) => {
return {
__emit: (data: INodeExecutionData[][]): void => {
throw new Error('Overwrite NodeExecuteFunctions.getExecutePullFunctions.__emit function!');
},
getCredentials(type: string): ICredentialDataDecryptedObject | undefined {
2021-01-29 03:16:46 -08:00
return getCredentials(workflow, node, type, additionalData, mode);
},
getMode: (): WorkflowExecuteMode => {
return mode;
},
getActivationMode: (): WorkflowActivateMode => {
return activation;
},
getNode: () => {
return getNode(node);
},
getNodeParameter: (parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any
const runExecutionData: IRunExecutionData | null = null;
const itemIndex = 0;
const runIndex = 0;
const connectionInputData: INodeExecutionData[] = [];
2021-01-29 00:31:40 -08:00
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, fallbackValue);
},
getRestApiUrl: (): string => {
return additionalData.restApiUrl;
},
getTimezone: (): string => {
return getTimezone(workflow, additionalData);
},
getWorkflow: () => {
return getWorkflowMetadata(workflow);
},
getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node);
},
helpers: {
prepareBinaryData,
request: requestPromiseWithDefaults,
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any
return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
},
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
return requestOAuth1.call(this, credentialsType, requestOptions);
},
returnJsonArray,
},
};
})(workflow, node);
}
2019-06-23 03:35:23 -07:00
/**
* Returns the execute functions the trigger nodes have access to.
*
* @export
* @param {Workflow} workflow
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
* @param {WorkflowExecuteMode} mode
* @returns {ITriggerFunctions}
*/
// TODO: Check if I can get rid of: additionalData, and so then maybe also at ActiveWorkflowRunner.add
export function getExecuteTriggerFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, activation: WorkflowActivateMode): ITriggerFunctions {
2019-06-23 03:35:23 -07:00
return ((workflow: Workflow, node: INode) => {
return {
emit: (data: INodeExecutionData[][]): void => {
throw new Error('Overwrite NodeExecuteFunctions.getExecuteTriggerFunctions.emit function!');
2019-06-23 03:35:23 -07:00
},
getCredentials(type: string): ICredentialDataDecryptedObject | undefined {
2021-01-29 03:16:46 -08:00
return getCredentials(workflow, node, type, additionalData, mode);
2019-06-23 03:35:23 -07:00
},
getNode: () => {
return getNode(node);
},
2019-06-23 03:35:23 -07:00
getMode: (): WorkflowExecuteMode => {
return mode;
},
getActivationMode: (): WorkflowActivateMode => {
return activation;
},
2019-06-23 03:35:23 -07:00
getNodeParameter: (parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any
const runExecutionData: IRunExecutionData | null = null;
const itemIndex = 0;
const runIndex = 0;
const connectionInputData: INodeExecutionData[] = [];
2021-01-29 00:31:40 -08:00
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, fallbackValue);
2019-06-23 03:35:23 -07:00
},
2019-12-19 14:07:55 -08:00
getRestApiUrl: (): string => {
return additionalData.restApiUrl;
},
2019-06-23 03:35:23 -07:00
getTimezone: (): string => {
return getTimezone(workflow, additionalData);
},
getWorkflow: () => {
return getWorkflowMetadata(workflow);
},
2019-06-23 03:35:23 -07:00
getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node);
},
helpers: {
prepareBinaryData,
request: requestPromiseWithDefaults,
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any
return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
},
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
return requestOAuth1.call(this, credentialsType, requestOptions);
},
2019-06-23 03:35:23 -07:00
returnJsonArray,
},
};
}) (workflow, node);
}
/**
* Returns the execute functions regular nodes have access to.
*
* @export
* @param {Workflow} workflow
* @param {IRunExecutionData} runExecutionData
* @param {number} runIndex
* @param {INodeExecutionData[]} connectionInputData
* @param {ITaskDataConnections} inputData
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
* @param {WorkflowExecuteMode} mode
* @returns {IExecuteFunctions}
*/
export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunExecutionData, runIndex: number, connectionInputData: INodeExecutionData[], inputData: ITaskDataConnections, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): IExecuteFunctions {
return ((workflow, runExecutionData, connectionInputData, inputData, node) => {
return {
2020-03-17 05:18:04 -07:00
continueOnFail: () => {
return continueOnFail(node);
},
evaluateExpression: (expression: string, itemIndex: number) => {
2021-01-29 00:31:40 -08:00
return workflow.expression.resolveSimpleParameterValue('=' + expression, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode);
},
async executeWorkflow(workflowInfo: IExecuteWorkflowInfo, inputData?: INodeExecutionData[]): Promise<any> { // tslint:disable-line:no-any
return additionalData.executeWorkflow(workflowInfo, additionalData, inputData);
2019-12-19 14:07:55 -08:00
},
2019-06-23 03:35:23 -07:00
getContext(type: string): IContextObject {
return NodeHelpers.getContext(runExecutionData, type, node);
},
getCredentials(type: string, itemIndex?: number): ICredentialDataDecryptedObject | undefined {
2021-01-29 03:16:46 -08:00
return getCredentials(workflow, node, type, additionalData, mode, runExecutionData, runIndex, connectionInputData, itemIndex);
2019-06-23 03:35:23 -07:00
},
getInputData: (inputIndex = 0, inputName = 'main') => {
if (!inputData.hasOwnProperty(inputName)) {
// Return empty array because else it would throw error when nothing is connected to input
return [];
}
// TODO: Check if nodeType has input with that index defined
if (inputData[inputName].length < inputIndex) {
throw new Error(`Could not get input index "${inputIndex}" of input "${inputName}"!`);
}
if (inputData[inputName][inputIndex] === null) {
// return [];
throw new Error(`Value "${inputIndex}" of input "${inputName}" did not get set!`);
}
// TODO: Maybe do clone of data only here so it only clones the data that is really needed
return inputData[inputName][inputIndex] as INodeExecutionData[];
},
getNodeParameter: (parameterName: string, itemIndex: number, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any
2021-01-29 00:31:40 -08:00
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, fallbackValue);
2019-06-23 03:35:23 -07:00
},
getMode: (): WorkflowExecuteMode => {
return mode;
},
getNode: () => {
return getNode(node);
},
2019-12-19 14:07:55 -08:00
getRestApiUrl: (): string => {
return additionalData.restApiUrl;
},
2019-06-23 03:35:23 -07:00
getTimezone: (): string => {
return getTimezone(workflow, additionalData);
},
getWorkflow: () => {
return getWorkflowMetadata(workflow);
},
getWorkflowDataProxy: (itemIndex: number): IWorkflowDataProxyData => {
2021-01-29 00:31:40 -08:00
const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode);
return dataProxy.getDataProxy();
},
2019-06-23 03:35:23 -07:00
getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node);
},
prepareOutputData: NodeHelpers.prepareOutputData,
helpers: {
prepareBinaryData,
request: requestPromiseWithDefaults,
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any
return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
},
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
return requestOAuth1.call(this, credentialsType, requestOptions);
},
2019-06-23 03:35:23 -07:00
returnJsonArray,
},
};
})(workflow, runExecutionData, connectionInputData, inputData, node);
}
/**
* Returns the execute functions regular nodes have access to when single-function is defined.
*
* @export
* @param {Workflow} workflow
* @param {IRunExecutionData} runExecutionData
* @param {number} runIndex
* @param {INodeExecutionData[]} connectionInputData
* @param {ITaskDataConnections} inputData
* @param {INode} node
* @param {number} itemIndex
* @param {IWorkflowExecuteAdditionalData} additionalData
* @param {WorkflowExecuteMode} mode
* @returns {IExecuteSingleFunctions}
*/
export function getExecuteSingleFunctions(workflow: Workflow, runExecutionData: IRunExecutionData, runIndex: number, connectionInputData: INodeExecutionData[], inputData: ITaskDataConnections, node: INode, itemIndex: number, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): IExecuteSingleFunctions {
return ((workflow, runExecutionData, connectionInputData, inputData, node, itemIndex) => {
return {
2020-03-17 05:18:04 -07:00
continueOnFail: () => {
return continueOnFail(node);
},
evaluateExpression: (expression: string, evaluateItemIndex: number | undefined) => {
evaluateItemIndex = evaluateItemIndex === undefined ? itemIndex : evaluateItemIndex;
2021-01-29 00:31:40 -08:00
return workflow.expression.resolveSimpleParameterValue('=' + expression, runExecutionData, runIndex, evaluateItemIndex, node.name, connectionInputData, mode);
},
2019-06-23 03:35:23 -07:00
getContext(type: string): IContextObject {
return NodeHelpers.getContext(runExecutionData, type, node);
},
getCredentials(type: string): ICredentialDataDecryptedObject | undefined {
2021-01-29 03:16:46 -08:00
return getCredentials(workflow, node, type, additionalData, mode, runExecutionData, runIndex, connectionInputData, itemIndex);
2019-06-23 03:35:23 -07:00
},
getInputData: (inputIndex = 0, inputName = 'main') => {
if (!inputData.hasOwnProperty(inputName)) {
// Return empty array because else it would throw error when nothing is connected to input
return {json: {}};
}
// TODO: Check if nodeType has input with that index defined
if (inputData[inputName].length < inputIndex) {
throw new Error(`Could not get input index "${inputIndex}" of input "${inputName}"!`);
}
const allItems = inputData[inputName][inputIndex];
if (allItems === null) {
// return [];
throw new Error(`Value "${inputIndex}" of input "${inputName}" did not get set!`);
}
if (allItems[itemIndex] === null) {
// return [];
throw new Error(`Value "${inputIndex}" of input "${inputName}" with itemIndex "${itemIndex}" did not get set!`);
}
return allItems[itemIndex] as INodeExecutionData;
},
getMode: (): WorkflowExecuteMode => {
return mode;
},
getNode: () => {
return getNode(node);
},
2019-12-19 14:07:55 -08:00
getRestApiUrl: (): string => {
return additionalData.restApiUrl;
},
2019-06-23 03:35:23 -07:00
getTimezone: (): string => {
return getTimezone(workflow, additionalData);
},
getNodeParameter: (parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any
2021-01-29 00:31:40 -08:00
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, fallbackValue);
2019-06-23 03:35:23 -07:00
},
getWorkflow: () => {
return getWorkflowMetadata(workflow);
},
getWorkflowDataProxy: (): IWorkflowDataProxyData => {
2021-01-29 00:31:40 -08:00
const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode);
return dataProxy.getDataProxy();
},
2019-06-23 03:35:23 -07:00
getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node);
},
helpers: {
prepareBinaryData,
request: requestPromiseWithDefaults,
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any
return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
},
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
return requestOAuth1.call(this, credentialsType, requestOptions);
},
2019-06-23 03:35:23 -07:00
},
};
})(workflow, runExecutionData, connectionInputData, inputData, node, itemIndex);
}
/**
* Returns the execute functions regular nodes have access to in load-options-function.
*
* @export
* @param {Workflow} workflow
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
* @returns {ILoadOptionsFunctions}
*/
export function getLoadOptionsFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData): ILoadOptionsFunctions {
return ((workflow: Workflow, node: INode) => {
const that = {
getCredentials(type: string): ICredentialDataDecryptedObject | undefined {
2021-01-29 03:16:46 -08:00
return getCredentials(workflow, node, type, additionalData, 'internal');
2019-06-23 03:35:23 -07:00
},
2019-10-20 12:42:34 -07:00
getCurrentNodeParameter: (parameterName: string): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object | undefined => {
const nodeParameters = additionalData.currentNodeParameters;
2019-10-20 12:42:34 -07:00
if (nodeParameters && nodeParameters[parameterName]) {
return nodeParameters[parameterName];
}
2019-10-20 12:42:34 -07:00
return undefined;
},
getCurrentNodeParameters: (): INodeParameters | undefined => {
return additionalData.currentNodeParameters;
},
getNode: () => {
return getNode(node);
},
2019-06-23 03:35:23 -07:00
getNodeParameter: (parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any
const runExecutionData: IRunExecutionData | null = null;
const itemIndex = 0;
const runIndex = 0;
const connectionInputData: INodeExecutionData[] = [];
2021-01-29 00:31:40 -08:00
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, 'internal' as WorkflowExecuteMode, fallbackValue);
2019-06-23 03:35:23 -07:00
},
getTimezone: (): string => {
return getTimezone(workflow, additionalData);
},
2019-12-19 14:07:55 -08:00
getRestApiUrl: (): string => {
return additionalData.restApiUrl;
},
2019-06-23 03:35:23 -07:00
helpers: {
request: requestPromiseWithDefaults,
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any
return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
},
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
return requestOAuth1.call(this, credentialsType, requestOptions);
},
2019-06-23 03:35:23 -07:00
},
};
return that;
})(workflow, node);
}
/**
* Returns the execute functions regular nodes have access to in hook-function.
*
* @export
* @param {Workflow} workflow
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
* @param {WorkflowExecuteMode} mode
* @returns {IHookFunctions}
*/
export function getExecuteHookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, activation: WorkflowActivateMode, isTest?: boolean, webhookData?: IWebhookData): IHookFunctions {
2019-06-23 03:35:23 -07:00
return ((workflow: Workflow, node: INode) => {
const that = {
getCredentials(type: string): ICredentialDataDecryptedObject | undefined {
2021-01-29 03:16:46 -08:00
return getCredentials(workflow, node, type, additionalData, mode);
2019-06-23 03:35:23 -07:00
},
getMode: (): WorkflowExecuteMode => {
return mode;
},
getActivationMode: (): WorkflowActivateMode => {
return activation;
},
getNode: () => {
return getNode(node);
},
2019-06-23 03:35:23 -07:00
getNodeParameter: (parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any
const runExecutionData: IRunExecutionData | null = null;
const itemIndex = 0;
const runIndex = 0;
const connectionInputData: INodeExecutionData[] = [];
2021-01-29 00:31:40 -08:00
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, fallbackValue);
2019-06-23 03:35:23 -07:00
},
getNodeWebhookUrl: (name: string): string | undefined => {
2021-01-29 00:31:40 -08:00
return getNodeWebhookUrl(name, workflow, node, additionalData, mode, isTest);
2019-06-23 03:35:23 -07:00
},
getTimezone: (): string => {
return getTimezone(workflow, additionalData);
},
getWebhookName(): string {
if (webhookData === undefined) {
throw new Error('Is only supported in webhook functions!');
2019-06-23 03:35:23 -07:00
}
return webhookData.webhookDescription.name;
},
getWebhookDescription(name: string): IWebhookDescription | undefined {
return getWebhookDescription(name, workflow, node);
2019-06-23 03:35:23 -07:00
},
getWorkflow: () => {
return getWorkflowMetadata(workflow);
},
2019-06-23 03:35:23 -07:00
getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node);
},
helpers: {
request: requestPromiseWithDefaults,
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any
return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
},
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
return requestOAuth1.call(this, credentialsType, requestOptions);
},
2019-06-23 03:35:23 -07:00
},
};
return that;
})(workflow, node);
}
/**
* Returns the execute functions regular nodes have access to when webhook-function is defined.
*
* @export
* @param {Workflow} workflow
* @param {IRunExecutionData} runExecutionData
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
* @param {WorkflowExecuteMode} mode
* @returns {IWebhookFunctions}
*/
export function getExecuteWebhookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, webhookData: IWebhookData): IWebhookFunctions {
2019-06-23 03:35:23 -07:00
return ((workflow: Workflow, node: INode) => {
return {
getBodyData(): IDataObject {
if (additionalData.httpRequest === undefined) {
throw new Error('Request is missing!');
}
return additionalData.httpRequest.body;
},
getCredentials(type: string): ICredentialDataDecryptedObject | undefined {
2021-01-29 03:16:46 -08:00
return getCredentials(workflow, node, type, additionalData, mode);
2019-06-23 03:35:23 -07:00
},
getHeaderData(): object {
if (additionalData.httpRequest === undefined) {
throw new Error('Request is missing!');
}
return additionalData.httpRequest.headers;
},
getMode: (): WorkflowExecuteMode => {
return mode;
},
getNode: () => {
return getNode(node);
},
2019-06-23 03:35:23 -07:00
getNodeParameter: (parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any
const runExecutionData: IRunExecutionData | null = null;
const itemIndex = 0;
const runIndex = 0;
const connectionInputData: INodeExecutionData[] = [];
2021-01-29 00:31:40 -08:00
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, mode, fallbackValue);
2019-06-23 03:35:23 -07:00
},
:sparkles: Add support for webhook route parameters (#1343) * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :zap: Fix issue that tab-title did not get reset on new workflow * Revert ":zap: Fix issue that tab-title did not get reset on new workflow" This reverts commit 699d0a8946e08339558c72b2714601329fbf5f2c. * :wrench: reset params before extraction * :elephant: removing unique constraint for webhookId * :construction: handle multiple webhooks per id * :wrench: enable webhook-test for multiple WH with same id * :elephant: add migration for postgres * :zap: add mysql migration * :art: fix lint issue Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-01-23 11:00:32 -08:00
getParamsData(): object {
if (additionalData.httpRequest === undefined) {
throw new Error('Request is missing!');
}
return additionalData.httpRequest.params;
},
2019-06-23 03:35:23 -07:00
getQueryData(): object {
if (additionalData.httpRequest === undefined) {
throw new Error('Request is missing!');
}
return additionalData.httpRequest.query;
},
getRequestObject(): express.Request {
if (additionalData.httpRequest === undefined) {
throw new Error('Request is missing!');
}
return additionalData.httpRequest;
},
getResponseObject(): express.Response {
if (additionalData.httpResponse === undefined) {
throw new Error('Response is missing!');
}
return additionalData.httpResponse;
},
getNodeWebhookUrl: (name: string): string | undefined => {
2021-01-29 00:31:40 -08:00
return getNodeWebhookUrl(name, workflow, node, additionalData, mode);
},
2019-06-23 03:35:23 -07:00
getTimezone: (): string => {
return getTimezone(workflow, additionalData);
},
getWorkflow: () => {
return getWorkflowMetadata(workflow);
},
2019-06-23 03:35:23 -07:00
getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node);
},
getWebhookName(): string {
return webhookData.webhookDescription.name;
},
2019-06-23 03:35:23 -07:00
prepareOutputData: NodeHelpers.prepareOutputData,
helpers: {
prepareBinaryData,
request: requestPromiseWithDefaults,
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any
return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
},
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
return requestOAuth1.call(this, credentialsType, requestOptions);
},
2019-06-23 03:35:23 -07:00
returnJsonArray,
},
};
})(workflow, node);
}