UNPKG

@theguild/eslint-config

Version:

The Guild's shared ESLint config

90 lines (85 loc) 3.64 kB
const RESTRICTED_SYNTAX = [ { // ❌ readFile(…, { encoding: … }) selector: 'CallExpression[callee.name=/readFileSync|readFile|writeFileSync|writeFile/] > .arguments:last-child[type=ObjectExpression][properties.length=1] Property[key.name=encoding]', message: 'Specify encoding as last argument instead of object with encoding key', }, { // ❌ readFile(…, {}) selector: 'CallExpression[callee.name=/readFileSync|readFile|writeFileSync|writeFile/] > .arguments:last-child[type=ObjectExpression][properties.length=0]', message: 'Specify encoding as last argument', }, { // ❌ readFileSync(…).toString(…) selector: 'CallExpression[callee.name=readFileSync][parent.property.name=toString]', message: 'toString is redundant, specify encoding as last argument', }, { // ❌ ….readFile(…, { encoding: … }) selector: 'CallExpression[callee.type=MemberExpression][callee.property.name=/readFileSync|readFile|writeFileSync|writeFile/] > .arguments:last-child[type=ObjectExpression][properties.length=1] Property[key.name=encoding]', message: 'Specify encoding as last argument instead of object with encoding key', }, { // ❌ ….readFile(…, {}) selector: 'CallExpression[callee.type=MemberExpression][callee.property.name=/readFileSync|readFile|writeFileSync|writeFile/] > .arguments:last-child[type=ObjectExpression][properties.length=0]', message: 'Specify encoding as last argument', }, { // ❌ Boolean(…) selector: 'CallExpression[callee.name=Boolean][arguments.1.elements.length!=0]', message: 'Prefer `!!…` over `Boolean(…)` because TypeScript infers a narrow literal boolean `type: true` instead of `type: boolean`.', }, { // ❌ process.browser selector: 'ExpressionStatement[expression.object.name=process][expression.property.name=browser]', message: '`process.browser` is deprecated, use `!!globalThis.window`', }, // { // // ❌ let { foo: { bar } } = baz // // ✅ let { bar } = baz.foo // // ✅ let { foo: { bar } } = await baz // selector: // 'VariableDeclarator[init.type!=AwaitExpression] > ObjectPattern[properties.length=1][properties.0.value.type=ObjectPattern]', // message: 'Do not use nested destructuring.', // }, ]; const REACT_RESTRICTED_SYNTAX = [ ...RESTRICTED_SYNTAX, { // ❌ useMemo(…, []) selector: 'CallExpression[callee.name=useMemo][arguments.1.type=ArrayExpression][arguments.1.elements.length=0]', message: "`useMemo` with an empty dependency array can't provide a stable reference, use `useRef` instead.", }, ]; const RESTRICTED_GLOBALS = [ 'stop', 'close', { name: 'isNaN', message: 'Use Number.isNaN instead' }, ]; const RESTRICTED_MODULES = [ { name: 'axios', message: 'Use `fetch/node-fetch` instead.' }, { name: 'moment', message: 'Use `dayjs/date-fns` instead.' }, { name: 'classnames', message: 'Use `clsx` instead because he is faster.' }, { name: 'lodash/isString.js', message: "Use `typeof yourVar === 'string'` instead." }, { name: 'lodash/isArray.js', message: 'Use `Array.isArray` instead.' }, { name: 'lodash/flatten.js', message: 'Use `Array#flat()` instead.' }, { name: 'lodash/compact.js', message: 'Use `Array#filter(Boolean)` instead.' }, { name: 'lodash/identity.js', message: 'Use `(value) => value` instead.' }, ]; module.exports = { CODE_BLOCK: '**/*.md{,x}/*', CODE_FILE: '*.{,c,m}{j,t}s{,x}', TS_FILE: '*.{,c,m}ts{,x}', RESTRICTED_GLOBALS, RESTRICTED_MODULES, RESTRICTED_SYNTAX, REACT_RESTRICTED_SYNTAX, };