n8n-workflow
Advanced tools
Comparing version 1.44.0 to 1.45.0
@@ -294,3 +294,3 @@ "use strict"; | ||
name: 'isEmpty', | ||
description: 'Returns <code>true</code> if the array has no elements', | ||
description: 'Returns <code>true</code> if the array has no elements or is <code>null</code>', | ||
examples: [ | ||
@@ -297,0 +297,0 @@ { example: '[].isEmpty()', evaluated: 'true' }, |
@@ -210,2 +210,8 @@ "use strict"; | ||
} | ||
function isEmpty() { | ||
return false; | ||
} | ||
function isNotEmpty() { | ||
return true; | ||
} | ||
endOfMonth.doc = { | ||
@@ -453,3 +459,3 @@ name: 'endOfMonth', | ||
{ | ||
example: "dt = '2023-03-30T18:49:07.234.toDateTime()\ndt.diffToNow(['months', 'days'])", | ||
example: "dt = '2023-03-30T18:49:07.234'.toDateTime()\ndt.diffToNow(['months', 'days'])", | ||
evaluated: '{ months: 12, days: 5.9 }', | ||
@@ -470,2 +476,22 @@ }, | ||
}; | ||
isEmpty.doc = { | ||
name: 'isEmpty', | ||
description: 'Returns <code>false</code> for all DateTimes. Returns <code>true</code> for <code>null</code>.', | ||
examples: [ | ||
{ example: "dt = '2023-03-30T18:49:07.234'.toDateTime()\ndt.isEmpty()", evaluated: 'false' }, | ||
{ example: 'dt = null\ndt.isEmpty()', evaluated: 'true' }, | ||
], | ||
returnType: 'boolean', | ||
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/arrays/#array-isEmpty', | ||
}; | ||
isNotEmpty.doc = { | ||
name: 'isNotEmpty', | ||
description: 'Returns <code>true</code> for all DateTimes. Returns <code>false</code> for <code>null</code>.', | ||
examples: [ | ||
{ example: "dt = '2023-03-30T18:49:07.234'.toDateTime()\ndt.isNotEmpty()", evaluated: 'true' }, | ||
{ example: 'dt = null\ndt.isNotEmpty()', evaluated: 'false' }, | ||
], | ||
returnType: 'boolean', | ||
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/arrays/#array-isNotEmpty', | ||
}; | ||
exports.dateExtensions = { | ||
@@ -490,4 +516,6 @@ typeName: 'Date', | ||
toBoolean, | ||
isEmpty, | ||
isNotEmpty, | ||
}, | ||
}; | ||
//# sourceMappingURL=DateExtensions.js.map |
@@ -99,3 +99,3 @@ "use strict"; | ||
name: 'isEmpty', | ||
description: 'Returns <code>true</code> if the Object has no keys (fields) set', | ||
description: 'Returns <code>true</code> if the Object has no keys (fields) set or is <code>null</code>', | ||
examples: [ | ||
@@ -102,0 +102,0 @@ { example: "({'name': 'Nathan'}).isEmpty()", evaluated: 'false' }, |
@@ -493,3 +493,3 @@ "use strict"; | ||
name: 'isEmpty', | ||
description: 'Returns <code>true</code> if the string has no characters.', | ||
description: 'Returns <code>true</code> if the string has no characters or is <code>null</code>', | ||
section: 'validation', | ||
@@ -496,0 +496,0 @@ returnType: 'boolean', |
@@ -17,2 +17,3 @@ import type { DateTime } from 'luxon'; | ||
} | ||
export declare const messageEventBusDestinationTypeNames: MessageEventBusDestinationTypeNames[]; | ||
export interface IAbstractEventMessage { | ||
@@ -19,0 +20,0 @@ __type: EventMessageTypeNames; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.defaultMessageEventBusDestinationSentryOptions = exports.defaultMessageEventBusDestinationWebhookOptions = exports.defaultMessageEventBusDestinationSyslogOptions = exports.defaultMessageEventBusDestinationOptions = exports.MessageEventBusDestinationTypeNames = exports.EventMessageTypeNames = void 0; | ||
exports.defaultMessageEventBusDestinationSentryOptions = exports.defaultMessageEventBusDestinationWebhookOptions = exports.defaultMessageEventBusDestinationSyslogOptions = exports.defaultMessageEventBusDestinationOptions = exports.messageEventBusDestinationTypeNames = exports.MessageEventBusDestinationTypeNames = exports.EventMessageTypeNames = void 0; | ||
var EventMessageTypeNames; | ||
@@ -20,2 +20,8 @@ (function (EventMessageTypeNames) { | ||
})(MessageEventBusDestinationTypeNames || (exports.MessageEventBusDestinationTypeNames = MessageEventBusDestinationTypeNames = {})); | ||
exports.messageEventBusDestinationTypeNames = [ | ||
"$$AbstractMessageEventBusDestination", | ||
"$$MessageEventBusDestinationWebhook", | ||
"$$MessageEventBusDestinationSentry", | ||
"$$MessageEventBusDestinationSyslog", | ||
]; | ||
exports.defaultMessageEventBusDestinationOptions = { | ||
@@ -22,0 +28,0 @@ __type: "$$AbstractMessageEventBusDestination", |
import type { FieldType, IContextObject, INode, INodeCredentialDescription, INodeIssues, INodeParameterResourceLocator, INodeParameters, INodeProperties, INodePropertyCollection, INodePropertyMode, INodeType, IParameterDependencies, IRunExecutionData, IVersionedNodeType, IWebhookData, IWorkflowExecuteAdditionalData, NodeParameterValue, ResourceMapperValue, ConnectionTypes, INodeTypeDescription, INodeOutputConfiguration, INodeInputConfiguration, GenericValue, NodeHint, INodeExecutionData } from './Interfaces'; | ||
import type { Workflow } from './Workflow'; | ||
export declare const cronNodeOptions: INodePropertyCollection[]; | ||
export declare function applyDeclarativeNodeOptionParameters(nodeType: INodeType): void; | ||
export declare function applySpecialNodeParameters(nodeType: INodeType): void; | ||
@@ -5,0 +6,0 @@ export declare function displayParameter(nodeValues: INodeParameters, parameter: INodeProperties | INodeCredentialDescription, node: Pick<INode, 'typeVersion'> | null, nodeValuesRoot?: INodeParameters): boolean; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isSingleExecution = exports.getCredentialsForNode = exports.getVersionedNodeTypeAll = exports.getVersionedNodeType = exports.mergeNodeProperties = exports.mergeIssues = exports.getParameterIssues = exports.getParameterValueByPath = exports.addToIssuesIfMissing = exports.validateParameter = exports.validateResourceMapperParameter = exports.validateResourceLocatorParameter = exports.nodeIssuesToString = exports.getNodeParametersIssues = exports.getNodeOutputs = exports.getNodeHints = exports.getNodeInputs = exports.getConnectionTypes = exports.getNodeWebhookUrl = exports.getNodeWebhookPath = exports.getNodeWebhooks = exports.getNodeParameters = exports.getParameterResolveOrder = exports.getContext = exports.displayParameterPath = exports.displayParameter = exports.applySpecialNodeParameters = exports.cronNodeOptions = void 0; | ||
exports.isSingleExecution = exports.getCredentialsForNode = exports.getVersionedNodeTypeAll = exports.getVersionedNodeType = exports.mergeNodeProperties = exports.mergeIssues = exports.getParameterIssues = exports.getParameterValueByPath = exports.addToIssuesIfMissing = exports.validateParameter = exports.validateResourceMapperParameter = exports.validateResourceLocatorParameter = exports.nodeIssuesToString = exports.getNodeParametersIssues = exports.getNodeOutputs = exports.getNodeHints = exports.getNodeInputs = exports.getConnectionTypes = exports.getNodeWebhookUrl = exports.getNodeWebhookPath = exports.getNodeWebhooks = exports.getNodeParameters = exports.getParameterResolveOrder = exports.getContext = exports.displayParameterPath = exports.displayParameter = exports.applySpecialNodeParameters = exports.applyDeclarativeNodeOptionParameters = exports.cronNodeOptions = void 0; | ||
const get_1 = __importDefault(require("lodash/get")); | ||
@@ -226,2 +226,116 @@ const isEqual_1 = __importDefault(require("lodash/isEqual")); | ||
]; | ||
const declarativeNodeOptionParameters = { | ||
displayName: 'Request Options', | ||
name: 'requestOptions', | ||
type: 'collection', | ||
isNodeSetting: true, | ||
placeholder: 'Add Option', | ||
default: {}, | ||
options: [ | ||
{ | ||
displayName: 'Batching', | ||
name: 'batching', | ||
placeholder: 'Add Batching', | ||
type: 'fixedCollection', | ||
typeOptions: { | ||
multipleValues: false, | ||
}, | ||
default: { | ||
batch: {}, | ||
}, | ||
options: [ | ||
{ | ||
displayName: 'Batching', | ||
name: 'batch', | ||
values: [ | ||
{ | ||
displayName: 'Items per Batch', | ||
name: 'batchSize', | ||
type: 'number', | ||
typeOptions: { | ||
minValue: -1, | ||
}, | ||
default: 50, | ||
description: 'Input will be split in batches to throttle requests. -1 for disabled. 0 will be treated as 1.', | ||
}, | ||
{ | ||
displayName: 'Batch Interval (ms)', | ||
name: 'batchInterval', | ||
type: 'number', | ||
typeOptions: { | ||
minValue: 0, | ||
}, | ||
default: 1000, | ||
description: 'Time (in milliseconds) between each batch of requests. 0 for disabled.', | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
{ | ||
displayName: 'Ignore SSL Issues', | ||
name: 'allowUnauthorizedCerts', | ||
type: 'boolean', | ||
noDataExpression: true, | ||
default: false, | ||
description: 'Whether to accept the response even if SSL certificate validation is not possible', | ||
}, | ||
{ | ||
displayName: 'Proxy', | ||
name: 'proxy', | ||
type: 'string', | ||
default: '', | ||
placeholder: 'e.g. http://myproxy:3128', | ||
description: 'HTTP proxy to use. If authentication is required it can be defined as follow: http://username:password@myproxy:3128', | ||
}, | ||
{ | ||
displayName: 'Timeout', | ||
name: 'timeout', | ||
type: 'number', | ||
typeOptions: { | ||
minValue: 1, | ||
}, | ||
default: 10000, | ||
description: 'Time in ms to wait for the server to send response headers (and start the response body) before aborting the request', | ||
}, | ||
], | ||
}; | ||
function applyDeclarativeNodeOptionParameters(nodeType) { | ||
var _a, _b; | ||
if (nodeType.execute || nodeType.trigger || nodeType.webhook || nodeType.description.polling) { | ||
return; | ||
} | ||
const parameters = nodeType.description.properties; | ||
if (!parameters) { | ||
return; | ||
} | ||
const existingRequestOptionsIndex = parameters.findIndex((parameter) => parameter.name === 'requestOptions'); | ||
if (existingRequestOptionsIndex !== -1) { | ||
parameters[existingRequestOptionsIndex] = { | ||
...declarativeNodeOptionParameters, | ||
options: [ | ||
...(declarativeNodeOptionParameters.options || []), | ||
...(((_a = parameters[existingRequestOptionsIndex]) === null || _a === void 0 ? void 0 : _a.options) || []), | ||
], | ||
}; | ||
if ((_b = parameters[existingRequestOptionsIndex]) === null || _b === void 0 ? void 0 : _b.options) { | ||
parameters[existingRequestOptionsIndex].options.sort((a, b) => { | ||
if ('displayName' in a && 'displayName' in b) { | ||
if (a.displayName < b.displayName) { | ||
return -1; | ||
} | ||
if (a.displayName > b.displayName) { | ||
return 1; | ||
} | ||
} | ||
return 0; | ||
}); | ||
} | ||
} | ||
else { | ||
parameters.push(declarativeNodeOptionParameters); | ||
} | ||
return; | ||
} | ||
exports.applyDeclarativeNodeOptionParameters = applyDeclarativeNodeOptionParameters; | ||
function applySpecialNodeParameters(nodeType) { | ||
@@ -242,2 +356,3 @@ const { properties, polling, supportsCORS } = nodeType.description; | ||
} | ||
applyDeclarativeNodeOptionParameters(nodeType); | ||
} | ||
@@ -244,0 +359,0 @@ exports.applySpecialNodeParameters = applySpecialNodeParameters; |
@@ -173,2 +173,6 @@ "use strict"; | ||
switch (condition.operator.operation) { | ||
case 'empty': | ||
return !exists; | ||
case 'notEmpty': | ||
return exists; | ||
case 'equals': | ||
@@ -191,2 +195,8 @@ return left === right; | ||
const right = rightValue; | ||
if (condition.operator.operation === 'empty') { | ||
return !exists; | ||
} | ||
else if (condition.operator.operation === 'notEmpty') { | ||
return exists; | ||
} | ||
if (!left || !right) { | ||
@@ -214,2 +224,6 @@ return false; | ||
switch (condition.operator.operation) { | ||
case 'empty': | ||
return !exists; | ||
case 'notEmpty': | ||
return exists; | ||
case 'true': | ||
@@ -216,0 +230,0 @@ return left; |
@@ -33,5 +33,7 @@ "use strict"; | ||
const set_1 = __importDefault(require("lodash/set")); | ||
const node_url_1 = __importDefault(require("node:url")); | ||
const NodeHelpers = __importStar(require("./NodeHelpers")); | ||
const node_operation_error_1 = require("./errors/node-operation.error"); | ||
const node_api_error_1 = require("./errors/node-api.error"); | ||
const utils_1 = require("./utils"); | ||
class RoutingNode { | ||
@@ -47,6 +49,5 @@ constructor(workflow, node, connectionInputData, runExecutionData, additionalData, mode) { | ||
async runNode(inputData, runIndex, nodeType, executeData, nodeExecuteFunctions, credentialsDecrypted, abortSignal) { | ||
var _a, _b; | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
const items = inputData.main[0]; | ||
const returnData = []; | ||
let responseData; | ||
let credentialType; | ||
@@ -76,7 +77,16 @@ if ((_a = nodeType.description.credentials) === null || _a === void 0 ? void 0 : _a.length) { | ||
} | ||
for (let i = 0; i < items.length; i++) { | ||
let thisArgs; | ||
try { | ||
thisArgs = nodeExecuteFunctions.getExecuteSingleFunctions(this.workflow, this.runExecutionData, runIndex, this.connectionInputData, inputData, this.node, i, this.additionalData, executeData, this.mode, abortSignal); | ||
const requestData = { | ||
const { batching } = executeFunctions.getNodeParameter('requestOptions', 0, {}); | ||
const batchSize = ((_c = batching === null || batching === void 0 ? void 0 : batching.batch) === null || _c === void 0 ? void 0 : _c.batchSize) > 0 ? (_d = batching === null || batching === void 0 ? void 0 : batching.batch) === null || _d === void 0 ? void 0 : _d.batchSize : 1; | ||
const batchInterval = batching === null || batching === void 0 ? void 0 : batching.batch.batchInterval; | ||
const requestPromises = []; | ||
const itemContext = []; | ||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { | ||
if (itemIndex > 0 && batchSize >= 0 && batchInterval > 0) { | ||
if (itemIndex % batchSize === 0) { | ||
await (0, utils_1.sleep)(batchInterval); | ||
} | ||
} | ||
itemContext.push({ | ||
thisArgs: nodeExecuteFunctions.getExecuteSingleFunctions(this.workflow, this.runExecutionData, runIndex, this.connectionInputData, inputData, this.node, itemIndex, this.additionalData, executeData, this.mode, abortSignal), | ||
requestData: { | ||
options: { | ||
@@ -90,27 +100,72 @@ qs: {}, | ||
requestOperations: {}, | ||
}, | ||
}); | ||
const { proxy, timeout, allowUnauthorizedCerts } = itemContext[itemIndex].thisArgs.getNodeParameter('requestOptions', 0, {}); | ||
if (nodeType.description.requestOperations) { | ||
itemContext[itemIndex].requestData.requestOperations = { | ||
...nodeType.description.requestOperations, | ||
}; | ||
if (nodeType.description.requestOperations) { | ||
requestData.requestOperations = { ...nodeType.description.requestOperations }; | ||
} | ||
if (nodeType.description.requestDefaults) { | ||
for (const key of Object.keys(nodeType.description.requestDefaults)) { | ||
let value = nodeType.description.requestDefaults[key]; | ||
value = this.getParameterValue(value, itemIndex, runIndex, executeData, { $credentials: credentials, $version: this.node.typeVersion }, false); | ||
itemContext[itemIndex].requestData.options[key] = value; | ||
} | ||
if (nodeType.description.requestDefaults) { | ||
for (const key of Object.keys(nodeType.description.requestDefaults)) { | ||
let value = nodeType.description.requestDefaults[key]; | ||
value = this.getParameterValue(value, i, runIndex, executeData, { $credentials: credentials, $version: this.node.typeVersion }, false); | ||
requestData.options[key] = value; | ||
} | ||
for (const property of nodeType.description.properties) { | ||
let value = (0, get_1.default)(this.node.parameters, property.name, []); | ||
value = this.getParameterValue(value, itemIndex, runIndex, executeData, { $credentials: credentials, $version: this.node.typeVersion }, false); | ||
const tempOptions = this.getRequestOptionsFromParameters(itemContext[itemIndex].thisArgs, property, itemIndex, runIndex, '', { $credentials: credentials, $value: value, $version: this.node.typeVersion }); | ||
this.mergeOptions(itemContext[itemIndex].requestData, tempOptions); | ||
} | ||
if (proxy) { | ||
const proxyParsed = node_url_1.default.parse(proxy); | ||
const proxyProperties = ['host', 'port']; | ||
for (const property of proxyProperties) { | ||
if (!(property in proxyParsed) || | ||
proxyParsed[property] === null) { | ||
throw new node_operation_error_1.NodeOperationError(this.node, 'The proxy is not value', { | ||
runIndex, | ||
itemIndex, | ||
description: `The proxy URL does not contain a valid value for "${property}"`, | ||
}); | ||
} | ||
} | ||
for (const property of nodeType.description.properties) { | ||
let value = (0, get_1.default)(this.node.parameters, property.name, []); | ||
value = this.getParameterValue(value, i, runIndex, executeData, { $credentials: credentials, $version: this.node.typeVersion }, false); | ||
const tempOptions = this.getRequestOptionsFromParameters(thisArgs, property, i, runIndex, '', { $credentials: credentials, $value: value, $version: this.node.typeVersion }); | ||
this.mergeOptions(requestData, tempOptions); | ||
itemContext[itemIndex].requestData.options.proxy = { | ||
host: proxyParsed.hostname, | ||
port: parseInt(proxyParsed.port), | ||
protocol: ((_e = proxyParsed.protocol) === null || _e === void 0 ? void 0 : _e.replace(/:$/, '')) || undefined, | ||
}; | ||
if (proxyParsed.auth) { | ||
const [username, password] = proxyParsed.auth.split(':'); | ||
itemContext[itemIndex].requestData.options.proxy.auth = { | ||
username, | ||
password, | ||
}; | ||
} | ||
responseData = await this.makeRoutingRequest(requestData, thisArgs, i, runIndex, credentialType, requestData.requestOperations, credentialsDecrypted); | ||
if (requestData.maxResults) { | ||
responseData.splice(requestData.maxResults); | ||
} | ||
if (allowUnauthorizedCerts) { | ||
itemContext[itemIndex].requestData.options.skipSslCertificateValidation = | ||
allowUnauthorizedCerts; | ||
} | ||
if (timeout) { | ||
itemContext[itemIndex].requestData.options.timeout = timeout; | ||
} | ||
else { | ||
itemContext[itemIndex].requestData.options.timeout = 300000; | ||
} | ||
requestPromises.push(this.makeRoutingRequest(itemContext[itemIndex].requestData, itemContext[itemIndex].thisArgs, itemIndex, runIndex, credentialType, itemContext[itemIndex].requestData.requestOperations, credentialsDecrypted)); | ||
} | ||
const promisesResponses = await Promise.allSettled(requestPromises); | ||
let responseData; | ||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { | ||
responseData = promisesResponses.shift(); | ||
if (responseData.status !== 'fulfilled') { | ||
if (responseData.reason.statusCode === 429) { | ||
responseData.reason.message = | ||
"Try spacing your requests out using the batching settings under 'Options'"; | ||
} | ||
returnData.push(...responseData); | ||
} | ||
catch (error) { | ||
if (thisArgs !== undefined && thisArgs.continueOnFail()) { | ||
const error = responseData.reason; | ||
if ((_f = itemContext[itemIndex].thisArgs) === null || _f === void 0 ? void 0 : _f.continueOnFail()) { | ||
returnData.push({ json: {}, error: error }); | ||
@@ -120,3 +175,3 @@ continue; | ||
if (error instanceof node_api_error_1.NodeApiError) { | ||
(0, set_1.default)(error, 'context.itemIndex', i); | ||
(0, set_1.default)(error, 'context.itemIndex', itemIndex); | ||
(0, set_1.default)(error, 'context.runIndex', runIndex); | ||
@@ -127,5 +182,12 @@ throw error; | ||
runIndex, | ||
itemIndex: i, | ||
itemIndex, | ||
message: error === null || error === void 0 ? void 0 : error.message, | ||
description: error === null || error === void 0 ? void 0 : error.description, | ||
httpCode: error.isAxiosError && error.response ? String((_g = error.response) === null || _g === void 0 ? void 0 : _g.status) : 'none', | ||
}); | ||
} | ||
if (itemContext[itemIndex].requestData.maxResults) { | ||
responseData.value.splice(itemContext[itemIndex].requestData.maxResults); | ||
} | ||
returnData.push(...responseData.value); | ||
} | ||
@@ -132,0 +194,0 @@ return [returnData]; |
{ | ||
"name": "n8n-workflow", | ||
"version": "1.44.0", | ||
"version": "1.45.0", | ||
"description": "Workflow base code of n8n", | ||
@@ -5,0 +5,0 @@ "license": "SEE LICENSE IN LICENSE.md", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1012593
13499