mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
refactor: lint for inefficient deep clones (#4378)
* 👕 Create rule `no-json-parse-json-stringify` * 🧪 Add tests * 👕 Enable new rule * 👕 FIx unrelated lint issue
This commit is contained in:
parent
a02e92d664
commit
6a1838d8c1
|
@ -323,6 +323,9 @@ const config = (module.exports = {
|
|||
// TODO: set to `error` and fix offenses
|
||||
'n8n-local-rules/no-uncaught-json-parse': 'warn',
|
||||
|
||||
// TODO: set to `error` and fix offenses
|
||||
'n8n-local-rules/no-json-parse-json-stringify': 'warn',
|
||||
|
||||
// ******************************************************************
|
||||
// overrides to base ruleset
|
||||
// ******************************************************************
|
||||
|
|
|
@ -46,7 +46,7 @@ module.exports = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isDeepCloneOperation(node)) {
|
||||
if (isJsonStringifyCall(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,47 @@ module.exports = {
|
|||
};
|
||||
},
|
||||
},
|
||||
|
||||
'no-json-parse-json-stringify': {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'Calls to `JSON.parse(JSON.stringify(arg))` must be replaced with `deepCopy(arg)` from `n8n-workflow`.',
|
||||
recommended: 'error',
|
||||
},
|
||||
messages: {
|
||||
noJsonParseJsonStringify: 'Replace with `deepCopy({{ argText }})`',
|
||||
},
|
||||
fixable: 'code',
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
if (isJsonParseCall(node) && isJsonStringifyCall(node)) {
|
||||
const [callExpression] = node.arguments;
|
||||
|
||||
const { arguments: args } = callExpression;
|
||||
|
||||
if (!Array.isArray(args) || args.length !== 1) return;
|
||||
|
||||
const [arg] = args;
|
||||
|
||||
if (!arg) return;
|
||||
|
||||
const argText = context.getSourceCode().getText(arg);
|
||||
|
||||
context.report({
|
||||
messageId: 'noJsonParseJsonStringify',
|
||||
node,
|
||||
data: { argText },
|
||||
fix: (fixer) => fixer.replaceText(node, `deepCopy(${argText})`),
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const isJsonParseCall = (node) =>
|
||||
|
@ -72,7 +113,7 @@ const isJsonParseCall = (node) =>
|
|||
node.callee.property.type === 'Identifier' &&
|
||||
node.callee.property.name === 'parse';
|
||||
|
||||
const isDeepCloneOperation = (node) => {
|
||||
const isJsonStringifyCall = (node) => {
|
||||
const parseArg = node.arguments?.[0];
|
||||
return (
|
||||
parseArg !== undefined &&
|
||||
|
|
|
@ -21,3 +21,33 @@ ruleTester.run('no-uncaught-json-parse', rules['no-uncaught-json-parse'], {
|
|||
},
|
||||
],
|
||||
});
|
||||
|
||||
ruleTester.run('no-json-parse-json-stringify', rules['no-json-parse-json-stringify'], {
|
||||
valid: [
|
||||
{
|
||||
code: 'deepCopy(foo)',
|
||||
},
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: 'JSON.parse(JSON.stringify(foo))',
|
||||
errors: [{ messageId: 'noJsonParseJsonStringify' }],
|
||||
output: 'deepCopy(foo)',
|
||||
},
|
||||
{
|
||||
code: 'JSON.parse(JSON.stringify(foo.bar))',
|
||||
errors: [{ messageId: 'noJsonParseJsonStringify' }],
|
||||
output: 'deepCopy(foo.bar)',
|
||||
},
|
||||
{
|
||||
code: 'JSON.parse(JSON.stringify(foo.bar.baz))',
|
||||
errors: [{ messageId: 'noJsonParseJsonStringify' }],
|
||||
output: 'deepCopy(foo.bar.baz)',
|
||||
},
|
||||
{
|
||||
code: 'JSON.parse(JSON.stringify(foo.bar[baz]))',
|
||||
errors: [{ messageId: 'noJsonParseJsonStringify' }],
|
||||
output: 'deepCopy(foo.bar[baz])',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -62,6 +62,7 @@ export class ScheduleTrigger implements INodeType {
|
|||
name: 'field',
|
||||
type: 'options',
|
||||
default: 'days',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-options-type-unsorted-items
|
||||
options: [
|
||||
{
|
||||
name: 'Seconds',
|
||||
|
|
Loading…
Reference in a new issue