mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
refactor: Add lint rule for unsafe property access with lodash get/set (no-changelog) (#8587)
This commit is contained in:
parent
8e392cfc1d
commit
de6d466e5e
|
@ -28,8 +28,8 @@ class N8nStructuredOutputParser<T extends z.ZodTypeAny> 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
|
||||
);
|
||||
|
|
|
@ -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: [
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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] = [];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue