From 4166a830671e35faf03bb0519a99372be36249d3 Mon Sep 17 00:00:00 2001 From: Elias Meire Date: Thu, 8 Feb 2024 15:32:04 +0100 Subject: [PATCH] refactor: Add lint rule for unsafe property access with lodash get/set (no-changelog) (#8587) --- .../OutputParserStructured.node.ts | 4 ++-- packages/@n8n_io/eslint-config/base.js | 5 +++++ packages/@n8n_io/eslint-config/package.json | 1 + packages/core/src/NodeExecuteFunctions.ts | 2 +- packages/core/src/WorkflowExecute.ts | 11 +++++++---- .../src/components/CollectionParameter.vue | 4 ++-- .../src/components/FixedCollectionParameter.vue | 2 +- .../editor-ui/src/components/WorkflowLMChat.vue | 6 +++--- .../nodes-base/nodes/Aws/ELB/GenericFunctions.ts | 9 +++------ .../nodes/Aws/Rekognition/GenericFunctions.ts | 14 +++++++------- .../nodes-base/nodes/Aws/S3/V1/GenericFunctions.ts | 14 +++++++------- .../nodes-base/nodes/Aws/S3/V2/GenericFunctions.ts | 14 +++++++------- .../nodes-base/nodes/Aws/SES/GenericFunctions.ts | 13 +++++++------ .../nodes/Aws/Transcribe/GenericFunctions.ts | 13 +++++++------ .../nodes/CompareDatasets/GenericFunctions.ts | 2 +- packages/nodes-base/nodes/Crypto/Crypto.node.ts | 2 +- .../nodes/CustomerIo/GenericFunctions.ts | 4 +--- .../nodes/DateTime/V1/DateTimeV1.node.ts | 4 ++-- .../nodes-base/nodes/Linear/GenericFunctions.ts | 6 +++--- packages/nodes-base/nodes/S3/GenericFunctions.ts | 14 +++++++------- .../nodes-base/nodes/WhatsApp/MessageFunctions.ts | 4 ++-- pnpm-lock.yaml | 13 +++++++++++++ 22 files changed, 90 insertions(+), 71 deletions(-) diff --git a/packages/@n8n/nodes-langchain/nodes/output_parser/OutputParserStructured/OutputParserStructured.node.ts b/packages/@n8n/nodes-langchain/nodes/output_parser/OutputParserStructured/OutputParserStructured.node.ts index 568590db197dd1..6ee592ef399057 100644 --- a/packages/@n8n/nodes-langchain/nodes/output_parser/OutputParserStructured/OutputParserStructured.node.ts +++ b/packages/@n8n/nodes-langchain/nodes/output_parser/OutputParserStructured/OutputParserStructured.node.ts @@ -28,8 +28,8 @@ class N8nStructuredOutputParser extends StructuredOutput const parsed = (await super.parse(text)) as object; return ( - get(parsed, `${STRUCTURED_OUTPUT_KEY}.${STRUCTURED_OUTPUT_OBJECT_KEY}`) ?? - get(parsed, `${STRUCTURED_OUTPUT_KEY}.${STRUCTURED_OUTPUT_ARRAY_KEY}`) ?? + get(parsed, [STRUCTURED_OUTPUT_KEY, STRUCTURED_OUTPUT_OBJECT_KEY]) ?? + get(parsed, [STRUCTURED_OUTPUT_KEY, STRUCTURED_OUTPUT_ARRAY_KEY]) ?? get(parsed, STRUCTURED_OUTPUT_KEY) ?? parsed ); diff --git a/packages/@n8n_io/eslint-config/base.js b/packages/@n8n_io/eslint-config/base.js index 4cb51b0cbb2f0e..ce8cab90078cfd 100644 --- a/packages/@n8n_io/eslint-config/base.js +++ b/packages/@n8n_io/eslint-config/base.js @@ -39,6 +39,9 @@ const config = (module.exports = { /** https://github.com/sindresorhus/eslint-plugin-unicorn */ 'eslint-plugin-unicorn', + + /** https://github.com/wix-incubator/eslint-plugin-lodash */ + 'eslint-plugin-lodash', ], extends: [ @@ -458,6 +461,8 @@ const config = (module.exports = { /** https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-promise-resolve-reject.md */ 'unicorn/no-useless-promise-resolve-reject': 'error', + + 'lodash/path-style': ['error', 'as-needed'], }, overrides: [ diff --git a/packages/@n8n_io/eslint-config/package.json b/packages/@n8n_io/eslint-config/package.json index 333c198156f9cf..0e93a3fbd551b7 100644 --- a/packages/@n8n_io/eslint-config/package.json +++ b/packages/@n8n_io/eslint-config/package.json @@ -13,6 +13,7 @@ "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.0", + "eslint-plugin-lodash": "^7.4.0", "eslint-plugin-n8n-local-rules": "^1.0.0", "eslint-plugin-prettier": "^5.0.1", "eslint-plugin-unicorn": "^49.0.0", diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index 9ae33f6b963e3e..99fe4bf28006d4 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -2548,7 +2548,7 @@ const addExecutionDataFunctions = async ( runExecutionData.executionData!.metadata = {}; } - let sourceTaskData = get(runExecutionData, `executionData.metadata[${sourceNodeName}]`); + let sourceTaskData = get(runExecutionData, ['executionData', 'metadata', sourceNodeName]); if (!sourceTaskData) { runExecutionData.executionData!.metadata[sourceNodeName] = []; diff --git a/packages/core/src/WorkflowExecute.ts b/packages/core/src/WorkflowExecute.ts index 542704e6fef915..96002b91abcdfc 100644 --- a/packages/core/src/WorkflowExecute.ts +++ b/packages/core/src/WorkflowExecute.ts @@ -337,10 +337,13 @@ export class WorkflowExecute { ): boolean { // for (const inputConnection of workflow.connectionsByDestinationNode[nodeToAdd].main[0]) { for (const inputConnection of inputConnections) { - const nodeIncomingData = get( - runData, - `[${inputConnection.node}][${runIndex}].data.main[${inputConnection.index}]`, - ); + const nodeIncomingData = get(runData, [ + inputConnection.node, + runIndex, + 'data', + 'main', + inputConnection.index, + ]); if (nodeIncomingData !== undefined && (nodeIncomingData as object[]).length !== 0) { return false; } diff --git a/packages/editor-ui/src/components/CollectionParameter.vue b/packages/editor-ui/src/components/CollectionParameter.vue index 9d15f042d5f213..16b5ac6b8243fe 100644 --- a/packages/editor-ui/src/components/CollectionParameter.vue +++ b/packages/editor-ui/src/components/CollectionParameter.vue @@ -176,11 +176,11 @@ function optionSelected(optionName: string) { // The "fixedCollection" entries are different as they save values // in an object and then underneath there is an array. So initialize // them differently. - const retrievedObjectValue = get(props.nodeValues, `${props.path}.${optionName}`, {}); + const retrievedObjectValue = get(props.nodeValues, [props.path, optionName], {}); newValue = retrievedObjectValue; } else { // Everything else saves them directly as an array. - const retrievedArrayValue = get(props.nodeValues, `${props.path}.${optionName}`, []) as Array< + const retrievedArrayValue = get(props.nodeValues, [props.path, optionName], []) as Array< typeof option.default >; if (Array.isArray(retrievedArrayValue)) { diff --git a/packages/editor-ui/src/components/FixedCollectionParameter.vue b/packages/editor-ui/src/components/FixedCollectionParameter.vue index a5d4f7b14ebb9e..303035a329b55b 100644 --- a/packages/editor-ui/src/components/FixedCollectionParameter.vue +++ b/packages/editor-ui/src/components/FixedCollectionParameter.vue @@ -297,7 +297,7 @@ export default defineComponent({ // Multiple values are allowed so append option to array newParameterValue[optionParameter.name] = get( this.nodeValues, - `${this.path}.${optionParameter.name}`, + [this.path, optionParameter.name], [], ); if (Array.isArray(optionParameter.default)) { diff --git a/packages/editor-ui/src/components/WorkflowLMChat.vue b/packages/editor-ui/src/components/WorkflowLMChat.vue index 65e30e7836617f..f60c83277bbabf 100644 --- a/packages/editor-ui/src/components/WorkflowLMChat.vue +++ b/packages/editor-ui/src/components/WorkflowLMChat.vue @@ -480,15 +480,15 @@ export default defineComponent({ const nodeResponseDataArray = get( this.workflowsStore.getWorkflowExecution?.data?.resultData.runData, - `[${lastNodeExecuted}]`, + lastNodeExecuted, ) as ITaskData[]; const nodeResponseData = nodeResponseDataArray[nodeResponseDataArray.length - 1]; let responseMessage: string; - if (get(nodeResponseData, ['error'])) { - responseMessage = '[ERROR: ' + get(nodeResponseData, ['error', 'message']) + ']'; + if (get(nodeResponseData, 'error')) { + responseMessage = '[ERROR: ' + get(nodeResponseData, 'error.message') + ']'; } else { const responseData = get(nodeResponseData, 'data.main[0][0].json'); responseMessage = this.extractResponseMessage(responseData); diff --git a/packages/nodes-base/nodes/Aws/ELB/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/ELB/GenericFunctions.ts index ad6271c8f639a8..b7c48a06d1353c 100644 --- a/packages/nodes-base/nodes/Aws/ELB/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Aws/ELB/GenericFunctions.ts @@ -142,11 +142,8 @@ export async function awsApiRequestSOAPAllItems( region, ); - if (get(responseData, `${propertyNameArray[0]}.${propertyNameArray[1]}.NextMarker`)) { - query.Marker = get( - responseData, - `${propertyNameArray[0]}.${propertyNameArray[1]}.NextMarker`, - ); + if (get(responseData, [propertyNameArray[0], propertyNameArray[1], 'NextMarker'])) { + query.Marker = get(responseData, [propertyNameArray[0], propertyNameArray[1], 'NextMarker']); } if (get(responseData, propertyName)) { if (Array.isArray(get(responseData, propertyName))) { @@ -156,7 +153,7 @@ export async function awsApiRequestSOAPAllItems( } } } while ( - get(responseData, `${propertyNameArray[0]}.${propertyNameArray[1]}.NextMarker`) !== undefined + get(responseData, [propertyNameArray[0], propertyNameArray[1], 'NextMarker']) !== undefined ); return returnData; diff --git a/packages/nodes-base/nodes/Aws/Rekognition/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/Rekognition/GenericFunctions.ts index e6192426452288..4b8ce458262e28 100644 --- a/packages/nodes-base/nodes/Aws/Rekognition/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Aws/Rekognition/GenericFunctions.ts @@ -139,11 +139,11 @@ export async function awsApiRequestSOAPAllItems( ); //https://forums.aws.amazon.com/thread.jspa?threadID=55746 - if (get(responseData, `${propertyName.split('.')[0]}.NextContinuationToken`)) { - query['continuation-token'] = get( - responseData, - `${propertyName.split('.')[0]}.NextContinuationToken`, - ); + if (get(responseData, [propertyName.split('.')[0], 'NextContinuationToken'])) { + query['continuation-token'] = get(responseData, [ + propertyName.split('.')[0], + 'NextContinuationToken', + ]); } if (get(responseData, propertyName)) { if (Array.isArray(get(responseData, propertyName))) { @@ -157,8 +157,8 @@ export async function awsApiRequestSOAPAllItems( return returnData; } } while ( - get(responseData, `${propertyName.split('.')[0]}.IsTruncated`) !== undefined && - get(responseData, `${propertyName.split('.')[0]}.IsTruncated`) !== 'false' + get(responseData, [propertyName.split('.')[0], 'IsTruncated']) !== undefined && + get(responseData, [propertyName.split('.')[0], 'IsTruncated']) !== 'false' ); return returnData; diff --git a/packages/nodes-base/nodes/Aws/S3/V1/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/S3/V1/GenericFunctions.ts index 26a99a6d7054ba..181fd6f60d92c8 100644 --- a/packages/nodes-base/nodes/Aws/S3/V1/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Aws/S3/V1/GenericFunctions.ts @@ -137,11 +137,11 @@ export async function awsApiRequestSOAPAllItems( ); //https://forums.aws.amazon.com/thread.jspa?threadID=55746 - if (get(responseData, `${propertyName.split('.')[0]}.NextContinuationToken`)) { - query['continuation-token'] = get( - responseData, - `${propertyName.split('.')[0]}.NextContinuationToken`, - ); + if (get(responseData, [propertyName.split('.')[0], 'NextContinuationToken'])) { + query['continuation-token'] = get(responseData, [ + propertyName.split('.')[0], + 'NextContinuationToken', + ]); } if (get(responseData, propertyName)) { if (Array.isArray(get(responseData, propertyName))) { @@ -155,8 +155,8 @@ export async function awsApiRequestSOAPAllItems( return returnData; } } while ( - get(responseData, `${propertyName.split('.')[0]}.IsTruncated`) !== undefined && - get(responseData, `${propertyName.split('.')[0]}.IsTruncated`) !== 'false' + get(responseData, [propertyName.split('.')[0], 'IsTruncated']) !== undefined && + get(responseData, [propertyName.split('.')[0], 'IsTruncated']) !== 'false' ); return returnData; diff --git a/packages/nodes-base/nodes/Aws/S3/V2/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/S3/V2/GenericFunctions.ts index 8e5e3ba668b9d0..908c1b7b58ed16 100644 --- a/packages/nodes-base/nodes/Aws/S3/V2/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Aws/S3/V2/GenericFunctions.ts @@ -107,11 +107,11 @@ export async function awsApiRequestRESTAllItems( region, ); //https://forums.aws.amazon.com/thread.jspa?threadID=55746 - if (get(responseData, `${propertyName.split('.')[0]}.NextContinuationToken`)) { - query['continuation-token'] = get( - responseData, - `${propertyName.split('.')[0]}.NextContinuationToken`, - ); + if (get(responseData, [propertyName.split('.')[0], 'NextContinuationToken'])) { + query['continuation-token'] = get(responseData, [ + propertyName.split('.')[0], + 'NextContinuationToken', + ]); } if (get(responseData, propertyName)) { if (Array.isArray(get(responseData, propertyName))) { @@ -125,8 +125,8 @@ export async function awsApiRequestRESTAllItems( return returnData; } } while ( - get(responseData, `${propertyName.split('.')[0]}.IsTruncated`) !== undefined && - get(responseData, `${propertyName.split('.')[0]}.IsTruncated`) !== 'false' + get(responseData, [propertyName.split('.')[0], 'IsTruncated']) !== undefined && + get(responseData, [propertyName.split('.')[0], 'IsTruncated']) !== 'false' ); return returnData; } diff --git a/packages/nodes-base/nodes/Aws/SES/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/SES/GenericFunctions.ts index f725d35bee15c9..382661f708be76 100644 --- a/packages/nodes-base/nodes/Aws/SES/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Aws/SES/GenericFunctions.ts @@ -102,11 +102,12 @@ export async function awsApiRequestSOAPAllItems( do { responseData = await awsApiRequestSOAP.call(this, service, method, path, body, query); - if (get(responseData, `${propertyNameArray[0]}.${propertyNameArray[1]}.NextToken`)) { - query.NextToken = get( - responseData, - `${propertyNameArray[0]}.${propertyNameArray[1]}.NextToken`, - ); + if (get(responseData, [propertyNameArray[0], propertyNameArray[1], 'NextToken'])) { + query.NextToken = get(responseData, [ + propertyNameArray[0], + propertyNameArray[1], + 'NextToken', + ]); } if (get(responseData, propertyName)) { if (Array.isArray(get(responseData, propertyName))) { @@ -116,7 +117,7 @@ export async function awsApiRequestSOAPAllItems( } } } while ( - get(responseData, `${propertyNameArray[0]}.${propertyNameArray[1]}.NextToken`) !== undefined + get(responseData, [propertyNameArray[0], propertyNameArray[1], 'NextToken']) !== undefined ); return returnData; diff --git a/packages/nodes-base/nodes/Aws/Transcribe/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/Transcribe/GenericFunctions.ts index 08615252906e85..c94b833ec7ddda 100644 --- a/packages/nodes-base/nodes/Aws/Transcribe/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Aws/Transcribe/GenericFunctions.ts @@ -109,11 +109,12 @@ export async function awsApiRequestRESTAllItems( do { responseData = await awsApiRequestREST.call(this, service, method, path, body, query); - if (get(responseData, `${propertyNameArray[0]}.${propertyNameArray[1]}.NextToken`)) { - query.NextToken = get( - responseData, - `${propertyNameArray[0]}.${propertyNameArray[1]}.NextToken`, - ); + if (get(responseData, [propertyNameArray[0], propertyNameArray[1], 'NextToken'])) { + query.NextToken = get(responseData, [ + propertyNameArray[0], + propertyNameArray[1], + 'NextToken', + ]); } if (get(responseData, propertyName)) { if (Array.isArray(get(responseData, propertyName))) { @@ -123,7 +124,7 @@ export async function awsApiRequestRESTAllItems( } } } while ( - get(responseData, `${propertyNameArray[0]}.${propertyNameArray[1]}.NextToken`) !== undefined + get(responseData, [propertyNameArray[0], propertyNameArray[1], 'NextToken']) !== undefined ); return returnData; diff --git a/packages/nodes-base/nodes/CompareDatasets/GenericFunctions.ts b/packages/nodes-base/nodes/CompareDatasets/GenericFunctions.ts index 14318acabca503..f8d707e3ce0c0b 100644 --- a/packages/nodes-base/nodes/CompareDatasets/GenericFunctions.ts +++ b/packages/nodes-base/nodes/CompareDatasets/GenericFunctions.ts @@ -171,7 +171,7 @@ function combineItems( entry.json[field] = match.json[field]; } else { const value = get(match.json, field) || null; - set(entry, `json.${field}`, value); + set(entry, ['json', field], value); } }); diff --git a/packages/nodes-base/nodes/Crypto/Crypto.node.ts b/packages/nodes-base/nodes/Crypto/Crypto.node.ts index 5ce4ba5dcde6f5..fc6416349c5a90 100644 --- a/packages/nodes-base/nodes/Crypto/Crypto.node.ts +++ b/packages/nodes-base/nodes/Crypto/Crypto.node.ts @@ -527,7 +527,7 @@ export class Crypto implements INodeType { newItem.binary = item.binary; } - set(newItem, `json.${dataPropertyName}`, newValue); + set(newItem, ['json', dataPropertyName], newValue); returnData.push(newItem); } catch (error) { diff --git a/packages/nodes-base/nodes/CustomerIo/GenericFunctions.ts b/packages/nodes-base/nodes/CustomerIo/GenericFunctions.ts index 5efc6729e1f9cb..0ff12804bd8845 100644 --- a/packages/nodes-base/nodes/CustomerIo/GenericFunctions.ts +++ b/packages/nodes-base/nodes/CustomerIo/GenericFunctions.ts @@ -48,9 +48,7 @@ export async function customerIoApiRequest( export function eventExists(currentEvents: string[], webhookEvents: IDataObject) { for (const currentEvent of currentEvents) { - if ( - get(webhookEvents, `${currentEvent.split('.')[0]}.${currentEvent.split('.')[1]}`) !== true - ) { + if (get(webhookEvents, [currentEvent.split('.')[0], currentEvent.split('.')[1]]) !== true) { return false; } } diff --git a/packages/nodes-base/nodes/DateTime/V1/DateTimeV1.node.ts b/packages/nodes-base/nodes/DateTime/V1/DateTimeV1.node.ts index 44ab99045e186e..2d5f24880b86f2 100644 --- a/packages/nodes-base/nodes/DateTime/V1/DateTimeV1.node.ts +++ b/packages/nodes-base/nodes/DateTime/V1/DateTimeV1.node.ts @@ -521,7 +521,7 @@ export class DateTimeV1 implements INodeType { newItem.binary = item.binary; } - set(newItem, `json.${dataPropertyName}`, newDate); + set(newItem, ['json', dataPropertyName], newDate); returnData.push(newItem); } @@ -565,7 +565,7 @@ export class DateTimeV1 implements INodeType { newItem.binary = item.binary; } - set(newItem, `json.${dataPropertyName}`, newDate.toISOString()); + set(newItem, ['json', dataPropertyName], newDate.toISOString()); returnData.push(newItem); } diff --git a/packages/nodes-base/nodes/Linear/GenericFunctions.ts b/packages/nodes-base/nodes/Linear/GenericFunctions.ts index 3a21e9d641728d..3ba7c9deba5069 100644 --- a/packages/nodes-base/nodes/Linear/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Linear/GenericFunctions.ts @@ -64,9 +64,9 @@ export async function linearApiRequestAllItems( do { responseData = await linearApiRequest.call(this, body); - returnData.push.apply(returnData, get(responseData, `${propertyName}.nodes`) as IDataObject[]); - body.variables.after = get(responseData, `${propertyName}.pageInfo.endCursor`); - } while (get(responseData, `${propertyName}.pageInfo.hasNextPage`)); + returnData.push.apply(returnData, get(responseData, [propertyName, 'nodes']) as IDataObject[]); + body.variables.after = get(responseData, [propertyName, 'pageInfo', 'endCursor']); + } while (get(responseData, [propertyName, 'pageInfo', 'hasNextPage'])); return returnData; } diff --git a/packages/nodes-base/nodes/S3/GenericFunctions.ts b/packages/nodes-base/nodes/S3/GenericFunctions.ts index ee57c29191d4f5..e79ef743486844 100644 --- a/packages/nodes-base/nodes/S3/GenericFunctions.ts +++ b/packages/nodes-base/nodes/S3/GenericFunctions.ts @@ -190,11 +190,11 @@ export async function s3ApiRequestSOAPAllItems( ); //https://forums.aws.amazon.com/thread.jspa?threadID=55746 - if (get(responseData, `${propertyName.split('.')[0]}.NextContinuationToken`)) { - query['continuation-token'] = get( - responseData, - `${propertyName.split('.')[0]}.NextContinuationToken`, - ); + if (get(responseData, [propertyName.split('.')[0], 'NextContinuationToken'])) { + query['continuation-token'] = get(responseData, [ + propertyName.split('.')[0], + 'NextContinuationToken', + ]); } if (get(responseData, propertyName)) { if (Array.isArray(get(responseData, propertyName))) { @@ -208,8 +208,8 @@ export async function s3ApiRequestSOAPAllItems( return returnData; } } while ( - get(responseData, `${propertyName.split('.')[0]}.IsTruncated`) !== undefined && - get(responseData, `${propertyName.split('.')[0]}.IsTruncated`) !== 'false' + get(responseData, [propertyName.split('.')[0], 'IsTruncated']) !== undefined && + get(responseData, [propertyName.split('.')[0], 'IsTruncated']) !== 'false' ); return returnData; diff --git a/packages/nodes-base/nodes/WhatsApp/MessageFunctions.ts b/packages/nodes-base/nodes/WhatsApp/MessageFunctions.ts index d602f971a797e4..77f6f081c91112 100644 --- a/packages/nodes-base/nodes/WhatsApp/MessageFunctions.ts +++ b/packages/nodes-base/nodes/WhatsApp/MessageFunctions.ts @@ -76,9 +76,9 @@ export async function mediaUploadFromItem( if (!requestOptions.body) { requestOptions.body = {}; } - set(requestOptions.body as IDataObject, `${operation}.id`, result.id); + set(requestOptions.body as IDataObject, [operation, 'id'], result.id); if (operation === 'document') { - set(requestOptions.body as IDataObject, `${operation}.filename`, uploadData.fileName); + set(requestOptions.body as IDataObject, [operation, 'filename'], uploadData.fileName); } return requestOptions; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98f5f0d9290c04..3275f986acf0cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -340,6 +340,9 @@ importers: eslint-plugin-import: specifier: ^2.29.0 version: 2.29.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + eslint-plugin-lodash: + specifier: ^7.4.0 + version: 7.4.0(eslint@8.54.0) eslint-plugin-n8n-local-rules: specifier: ^1.0.0 version: 1.0.0 @@ -15028,6 +15031,16 @@ packages: - supports-color dev: true + /eslint-plugin-lodash@7.4.0(eslint@8.54.0): + resolution: {integrity: sha512-Tl83UwVXqe1OVeBRKUeWcfg6/pCW1GTRObbdnbEJgYwjxp5Q92MEWQaH9+dmzbRt6kvYU1Mp893E79nJiCSM8A==} + engines: {node: '>=10'} + peerDependencies: + eslint: '>=2' + dependencies: + eslint: 8.54.0 + lodash: 4.17.21 + dev: true + /eslint-plugin-n8n-local-rules@1.0.0: resolution: {integrity: sha512-qe6sVFDP1Vj5eXlqZxYZpIjwYvhuqXlI0P8OfPyhiPOhMkFtr0TpFphD8/6WCzkm7LJCvG1eJEzURCtMIsFTAg==} dev: true