mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 05:17:28 -08:00
feat(eslint-config): add custom eslint rule 'no-uncaught-json-parse' (#4087)
feat(eslint-config): add custom eslint rule 'no-uncaugh-json-parse' Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
parent
7aa40bf95d
commit
31391a5b19
2629
package-lock.json
generated
2629
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -40,6 +40,12 @@ module.exports = {
|
|||
* https://github.com/paleite/eslint-plugin-diff#plugindiffdiff-recommended
|
||||
*/
|
||||
'eslint-plugin-diff',
|
||||
|
||||
/*
|
||||
* Plugin to allow specifying local ESLint rules.
|
||||
* https://github.com/ivov/eslint-plugin-n8n-local-rules
|
||||
*/
|
||||
'eslint-plugin-n8n-local-rules',
|
||||
],
|
||||
|
||||
extends: [
|
||||
|
@ -324,6 +330,13 @@ module.exports = {
|
|||
*/
|
||||
'import/order': 'error',
|
||||
|
||||
// ----------------------------------
|
||||
// eslint-plugin-n8n-local-rules
|
||||
// ----------------------------------
|
||||
|
||||
// TODO: set to `error` and fix offenses
|
||||
'n8n-local-rules/no-uncaught-json-parse': 'warn',
|
||||
|
||||
// ******************************************************************
|
||||
// overrides to base ruleset
|
||||
// ******************************************************************
|
||||
|
|
86
packages/@n8n_io/eslint-config/local-rules.js
Normal file
86
packages/@n8n_io/eslint-config/local-rules.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* This file contains any locally defined ESLint rules. They are picked up by
|
||||
* eslint-plugin-n8n-local-rules and exposed as 'n8n-local-rules/<rule-name>'.
|
||||
*/
|
||||
module.exports = {
|
||||
/**
|
||||
* A rule to detect calls to JSON.parse() that are not wrapped inside try/catch blocks.
|
||||
*
|
||||
* Valid:
|
||||
* ```js
|
||||
* try { JSON.parse(foo) } catch(err) { baz() }
|
||||
* ```
|
||||
*
|
||||
* Invalid:
|
||||
* ```js
|
||||
* JSON.parse(foo)
|
||||
* ```
|
||||
*
|
||||
* The pattern where an object is cloned with JSON.parse(JSON.stringify()) is allowed
|
||||
* (abundant in the n8n codebase):
|
||||
*
|
||||
* Valid:
|
||||
* ```js
|
||||
* JSON.parse(JSON.stringify(foo))
|
||||
* ```
|
||||
*/
|
||||
'no-uncaught-json-parse': {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Calls to JSON.parse() must be surrounded with a try/catch block.',
|
||||
recommended: 'error',
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
noUncaughtJsonParse: 'Surround the JSON.parse() call with a try/catch block.',
|
||||
},
|
||||
},
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
if (!isJsonParseCall(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDeepCloneOperation(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.getAncestors().find((node) => node.type === 'TryStatement') !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Found a JSON.parse() call not wrapped into a try/catch, so report it
|
||||
context.report({
|
||||
messageId: 'noUncaughtJsonParse',
|
||||
node,
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const isJsonParseCall = (node) =>
|
||||
node.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.type === 'Identifier' &&
|
||||
node.callee.object.name === 'JSON' &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
node.callee.property.name === 'parse';
|
||||
|
||||
const isDeepCloneOperation = (node) => {
|
||||
const parseArg = node.arguments?.[0];
|
||||
return (
|
||||
parseArg !== undefined &&
|
||||
parseArg.type === 'CallExpression' &&
|
||||
parseArg.callee.type === 'MemberExpression' &&
|
||||
parseArg.callee.object.type === 'Identifier' &&
|
||||
parseArg.callee.object.name === 'JSON' &&
|
||||
parseArg.callee.property.type === 'Identifier' &&
|
||||
parseArg.callee.property.name === 'stringify'
|
||||
);
|
||||
};
|
23
packages/@n8n_io/eslint-config/local-rules.test.js
Normal file
23
packages/@n8n_io/eslint-config/local-rules.test.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
const rules = require('./local-rules'),
|
||||
RuleTester = require('eslint').RuleTester;
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run('no-uncaught-json-parse', rules['no-uncaught-json-parse'], {
|
||||
valid: [
|
||||
{
|
||||
code: 'try { JSON.parse(foo) } catch (e) {}',
|
||||
},
|
||||
{
|
||||
code: 'JSON.parse(JSON.stringify(foo))',
|
||||
},
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: 'JSON.parse(foo)',
|
||||
errors: [{ messageId: 'noUncaughtJsonParse' }],
|
||||
},
|
||||
],
|
||||
});
|
|
@ -11,7 +11,12 @@
|
|||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-diff": "^2.0.1",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-n8n-local-rules": "^1.0.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-vue": "^9.4.0"
|
||||
"eslint-plugin-vue": "^9.4.0",
|
||||
"jest": "^28.1.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue