diff --git a/.eslintignore b/.eslintignore index 69fd511..a83cadb 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1 @@ -invalid.js +invalid.* diff --git a/.eslintrc.js b/.eslintrc.js index a681b28..04af489 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,5 @@ module.exports = { - extends: ['./packages/eslint-config-norton'], + extends: ['./packages/eslint-config-norton', './packages/eslint-config-norton/typescript'], rules: { 'import/no-extraneous-dependencies': ['error', { @@ -12,4 +12,8 @@ module.exports = { }, ], }, + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./packages/eslint-config-norton/tsconfig.json'], + }, }; diff --git a/package-lock.json b/package-lock.json index 5671f17..16c5e69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,19 +13,19 @@ } }, "@babel/core": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz", - "integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.5.tgz", + "integrity": "sha512-fsEANVOcZHzrsV6dMVWqpSeXClq3lNbYrfFGme6DE25FQWe7pyeYpXyx9guqUnpy466JLzZ8z4uwSr2iv60V5Q==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.4", + "@babel/generator": "^7.11.5", "@babel/helper-module-transforms": "^7.11.0", "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.4", + "@babel/parser": "^7.11.5", "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/traverse": "^7.11.5", + "@babel/types": "^7.11.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -33,7 +33,7 @@ "lodash": "^4.17.19", "resolve": "^1.3.2", "semver": "^5.4.1", - "source-map": "^0.5.0" + "source-map": "^0.6.1" }, "dependencies": { "json5": { @@ -50,32 +50,18 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, "@babel/generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", - "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.5.tgz", + "integrity": "sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g==", "dev": true, "requires": { - "@babel/types": "^7.11.0", + "@babel/types": "^7.11.5", "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "source-map": "^0.6.1" } }, "@babel/helper-function-name": { @@ -252,9 +238,9 @@ } }, "@babel/parser": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", - "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", + "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", "dev": true }, "@babel/runtime": { @@ -288,17 +274,17 @@ } }, "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", + "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", + "@babel/generator": "^7.11.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/parser": "^7.11.5", + "@babel/types": "^7.11.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" @@ -313,9 +299,9 @@ } }, "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -496,6 +482,38 @@ "arrify": "^1.0.1" } }, + "@eslint/eslintrc": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", + "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } + } + }, "@evocateur/libnpmaccess": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz", @@ -2739,9 +2757,9 @@ } }, "@types/json-schema": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", - "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, "@types/json5": { @@ -2763,9 +2781,9 @@ "dev": true }, "@types/node": { - "version": "14.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.1.tgz", - "integrity": "sha512-HnYlg/BRF8uC1FyKRFZwRaCPTPYKa+6I8QiUZFLredaGOou481cgFS4wKRFyKvQtX8xudqkSdBczJHIYSQYKrQ==", + "version": "14.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.2.tgz", + "integrity": "sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A==", "dev": true }, "@types/normalize-package-data": { @@ -2780,6 +2798,22 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "@types/react": { + "version": "16.9.49", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.49.tgz", + "integrity": "sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, "@types/unist": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", @@ -3669,9 +3703,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001119", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001119.tgz", - "integrity": "sha512-Hpwa4obv7EGP+TjkCh/wVvbtNJewxmtg4yVJBLFnxo35vbPapBr138bUWENkb5j5L9JZJ9RXLn4OrXRG/cecPQ==", + "version": "1.0.30001122", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001122.tgz", + "integrity": "sha512-pxjw28CThdrqfz06nJkpAc5SXM404TXB/h5f4UJX+rrXJKE/1bu/KAILc2AY+O6cQIFtRjV9qOR2vaEp9LDGUA==", "dev": true }, "caseless": { @@ -3802,9 +3836,9 @@ "dev": true }, "cli-boxes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", - "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true }, "cli-cursor": { @@ -4815,6 +4849,12 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "csstype": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz", + "integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==", + "dev": true + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -5191,9 +5231,9 @@ } }, "electron-to-chromium": { - "version": "1.3.554", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.554.tgz", - "integrity": "sha512-Vtz2dVH5nMtKK4brahmgScwFS8PBnpA4VObYXtlsqN8ZpT9IFelv0Rpflc1+NIILjGVaj6vEiXQbhrs3Pl8O7g==", + "version": "1.3.557", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.557.tgz", + "integrity": "sha512-M2p3nWulBqSEIisykYUVYnaSuRikHvxv8Wf209/Vg/sjrOew12hBQv2JvNGy+i+eDeJU9uQ3dbUbCCQ/CkudEg==", "dev": true }, "emittery": { @@ -5338,12 +5378,13 @@ "dev": true }, "eslint": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz", - "integrity": "sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.8.1.tgz", + "integrity": "sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.1.3", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -5353,7 +5394,7 @@ "eslint-scope": "^5.1.0", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^1.3.0", - "espree": "^7.2.0", + "espree": "^7.3.0", "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", @@ -5656,6 +5697,85 @@ "error-ex": "^1.2.0" } }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -5788,12 +5908,6 @@ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true - }, "espree": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", @@ -5837,12 +5951,20 @@ } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "estraverse": { @@ -6155,6 +6277,12 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, "fastq": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", @@ -7620,6 +7748,201 @@ "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", "dev": true }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + } + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "irregular-plurals": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.2.0.tgz", + "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", + "dev": true + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -8258,12 +8581,6 @@ } } }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8573,9 +8890,9 @@ } }, "mem": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.0.tgz", - "integrity": "sha512-RlbnLQgRHk5lwqTtpEkBTQ2ll/CG/iB+J4Hy2Wh97PjgZgXgWJWrFF+XXujh3UUVLvR4OOTgZzcWMMwnehlEUg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.1.tgz", + "integrity": "sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==", "dev": true, "requires": { "map-age-cleaner": "^0.1.3", @@ -8591,9 +8908,9 @@ } }, "meow": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.0.tgz", - "integrity": "sha512-kq5F0KVteskZ3JdfyQFivJEj2RaA8NFsS4+r9DaMKLcUHpk5OcHS3Q0XkCXONB1mZRPsu/Y/qImKri0nwSEZog==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", + "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -9965,6 +10282,12 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, + "prettier": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.1.tgz", + "integrity": "sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==", + "dev": true + }, "pretty-ms": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.0.tgz", @@ -10127,6 +10450,17 @@ "strip-json-comments": "~2.0.1" } }, + "react": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", + "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -11220,19 +11554,21 @@ "dev": true }, "stylelint": { - "version": "13.6.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.6.1.tgz", - "integrity": "sha512-XyvKyNE7eyrqkuZ85Citd/Uv3ljGiuYHC6UiztTR6sWS9rza8j3UeQv/eGcQS9NZz/imiC4GKdk1EVL3wst5vw==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.7.0.tgz", + "integrity": "sha512-1wStd4zVetnlHO98VjcHQbjSDmvcA39smkZQMct2cf+hom40H0xlQNdzzbswoG/jGBh61/Ue9m7Lu99PY51O6A==", "dev": true, "requires": { - "@stylelint/postcss-css-in-js": "^0.37.1", + "@stylelint/postcss-css-in-js": "^0.37.2", "@stylelint/postcss-markdown": "^0.36.1", - "autoprefixer": "^9.8.0", + "autoprefixer": "^9.8.6", "balanced-match": "^1.0.0", "chalk": "^4.1.0", - "cosmiconfig": "^6.0.0", + "cosmiconfig": "^7.0.0", "debug": "^4.1.1", "execall": "^2.0.0", + "fast-glob": "^3.2.4", + "fastest-levenshtein": "^1.0.12", "file-entry-cache": "^5.0.1", "get-stdin": "^8.0.0", "global-modules": "^2.0.0", @@ -11243,18 +11579,16 @@ "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "known-css-properties": "^0.19.0", - "leven": "^3.1.0", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "log-symbols": "^4.0.0", "mathml-tag-names": "^2.1.3", - "meow": "^7.0.1", + "meow": "^7.1.1", "micromatch": "^4.0.2", "normalize-selector": "^0.2.0", "postcss": "^7.0.32", "postcss-html": "^0.36.0", "postcss-less": "^3.1.4", "postcss-media-query-parser": "^0.2.3", - "postcss-reporter": "^6.0.1", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^4.0.2", "postcss-sass": "^0.4.4", @@ -11270,11 +11604,24 @@ "style-search": "^0.1.0", "sugarss": "^2.0.0", "svg-tags": "^1.0.0", - "table": "^5.4.6", + "table": "^6.0.1", "v8-compile-cache": "^2.1.1", "write-file-atomic": "^3.0.3" }, "dependencies": { + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, "get-stdin": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", @@ -11286,6 +11633,29 @@ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "table": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.1.tgz", + "integrity": "sha512-fmr6168splcy/3XIvhSm5w6hYYOqyr3plAsd7OqoerzyoMnIpoxYuwrpdO2Cm22dh6KCnvirvigPrFZp+tdWFA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + } } } }, @@ -11797,9 +12167,9 @@ "dev": true }, "uglify-js": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.2.tgz", - "integrity": "sha512-GXCYNwqoo0MbLARghYjxVBxDCnU0tLqN7IPLdHHbibCb1NI5zBkU2EPcy/GaVxc0BtTjqyGXJCINe6JMR2Dpow==", + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.3.tgz", + "integrity": "sha512-Lh00i69Uf6G74mvYpHCI9KVVXLcHW/xu79YTvH7Mkc9zyKUeSPz0owW0dguj0Scavns3ZOh3wY63J0Zb97Za2g==", "dev": true, "optional": true }, @@ -12047,9 +12417,9 @@ } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "dev": true, "requires": { "punycode": "^2.1.0" diff --git a/package.json b/package.json index 5bbddba..bda90a7 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,6 @@ "ava": { "files": [ "**/test/*.js" - ], - "require": [ - "esm" ] }, "devDependencies": { @@ -23,6 +20,7 @@ "@commitlint/config-conventional": "^9.1.1", "@commitlint/lint": "^9.1.1", "@commitlint/load": "^9.1.1", + "@types/react": "^16.9.48", "@typescript-eslint/eslint-plugin": "^3.10.1", "@typescript-eslint/parser": "^3.10.1", "ava": "^3.10.1", @@ -34,11 +32,12 @@ "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-react": "^7.20.3", "eslint-plugin-react-hooks": "^4.0.0", - "esm": "^3.2.25", "lerna": "^3.22.1", + "react": "^16.13.1", "stylelint": "^13.6.1", "stylelint-config-sass-guidelines": "^7.0.0", "stylelint-config-standard": "^20.0.0", - "typescript": "^4.0.2" + "typescript": "^4.0.2", + "prettier": "2.x" } } diff --git a/packages/commitlint-config-norton/test/index.js b/packages/commitlint-config-norton/test/index.js index 766ad11..b702be9 100644 --- a/packages/commitlint-config-norton/test/index.js +++ b/packages/commitlint-config-norton/test/index.js @@ -1,7 +1,7 @@ -import test from 'ava'; -import load from '@commitlint/load'; -import commitlint from '@commitlint/lint'; -import config from '..'; +const test = require('ava'); +const { default: load } = require('@commitlint/load'); +const { default: commitlint } = require('@commitlint/lint'); +const config = require('..'); let lint; diff --git a/packages/eslint-config-norton/README.md b/packages/eslint-config-norton/README.md index d8e8009..ece9edd 100644 --- a/packages/eslint-config-norton/README.md +++ b/packages/eslint-config-norton/README.md @@ -56,21 +56,7 @@ module.exports = { } ``` -## TYPESCRIPT PROJECTS - -> **No other setup is necessary for Typescript support.** - -### How this works. - -The eslint-config-norton package is setup to automatically work with projects that use Typescript as well as projects that do not use Typescript. The package contains an "overrides" parameter which provides support for .ts and .tsx files if those files are present in the project. When Typescript files are detected the override supplies the necessary configuration to enable Typescript linting. - -### **For more information please see...** - -Typescript Lint Setup - https://www.notion.so/Typescript-Lint-Setup-06cef0036d0b4887b4e07b57def202e4 -Typescript Style Guide - https://www.notion.so/TypeScript-Style-Guide-a73cca890fb342b0a1f99a7ba1ce55d8 -ESLint Plugin TypeScript - https://www.npmjs.com/package/@typescript-eslint/eslint-plugin - -## FOR NON REACT PROJECTS +## For Non React Projects If you don't want React linting you can simply extend the base.js entry point in our config, `eslint-config-norton/base`. @@ -87,6 +73,54 @@ module.exports = { } ``` +## For Typescript projects + +This package also provides configuration for Typescript liniting. In order to use our Typescript linting you need to extend an additional entrypoint based on your needs. Under the hood this configuration disables some base ESLint rules which do not interface well with Typescript files and Prettier options and subsequently provides Typescript linting. + +It uses [`@typescript-eslint`](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin) for most of its Typescript rules. + +Note: These configurations are still meant to be used alongside [`prettier-config-norton`](https://github.com/wwnorton/style/tree/master/packages/prettier-config-norton) to facilitate most of the formatting. + +### How this works. + +The entrypoints below provide Typescript overrides. + +- **eslint-config-norton/typescript**: this includes an extendable override file providing linting for Typescript along with React. +- **eslint-config-norton/typescript-base**: this includes an extendable override file providing linting for *only* Typescript. + +> The TypeScript ruleset relies on Type definitions and being aware of the location of your TSConfig. Make sure your `'./tsconfig.json'` is in your root directory. + +### Examples + +Incorporating Typescript and React Linting: + +```js +module.exports = { + extemds: [ + 'norton', + 'eslint-config-norton/typescript' + ] +} +``` + +Incorporating just Typescript Linting: + +```js +module.exports = { + extemds: [ + 'eslint-config-norton/base', + 'eslint-config-norton/typescript-base' + ] +} +``` + +### **For more information please see...** + +Typescript Lint Setup - https://www.notion.so/Typescript-Lint-Setup-06cef0036d0b4887b4e07b57def202e4 +Typescript Style Guide - https://www.notion.so/TypeScript-Style-Guide-a73cca890fb342b0a1f99a7ba1ce55d8 +ESLint Plugin TypeScript - https://www.npmjs.com/package/@typescript-eslint/eslint-plugin + + ## Rules This configuration extends [airbnb's base style guide](https://github.com/airbnb/javascript) ([eslint-config-airbnb](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb)). It overrides the following rules: diff --git a/packages/eslint-config-norton/base.js b/packages/eslint-config-norton/base.js index 838119a..c561bc5 100644 --- a/packages/eslint-config-norton/base.js +++ b/packages/eslint-config-norton/base.js @@ -1,24 +1,11 @@ -/** - * ? This is the base configuration for projects without React. - */ -const typescript = require('./overrides/typescript'); - module.exports = { /** * add eslint-config-prettier to handle formatting conflicts with prettier * @see https://github.com/prettier/eslint-config-prettier */ extends: [ - 'eslint-config-airbnb-base', + 'eslint-config-airbnb/base', + 'eslint-config-prettier', './rules/style', - 'eslint-config-prettier' ].map(require.resolve), - rules: {}, - /** - * Add overrides for React and TypesScript environments. - * Note that additional eslint tooling will be required for these to work. - */ - overrides: [ - typescript, - ], }; diff --git a/packages/eslint-config-norton/index.js b/packages/eslint-config-norton/index.js index 49cb6bd..bab81f8 100644 --- a/packages/eslint-config-norton/index.js +++ b/packages/eslint-config-norton/index.js @@ -1,26 +1,15 @@ -const typescript = require('./overrides/typescript'); - +/** + * Use Airbnb as base and add Prettier to handle formatting conflicts. + * @see https://github.com/airbnb/javascript/ + * @see https://github.com/prettier/eslint-config-prettier + */ module.exports = { - /** - * use airbnb's well-reasoned style guide as base - * @see https://github.com/airbnb/javascript/ - */ - /** - * add eslint-config-prettier to handle formatting conflicts with prettier - * @see https://github.com/prettier/eslint-config-prettier - */ extends: [ 'eslint-config-airbnb', - './rules/style', - './rules/react', + 'eslint-config-airbnb/hooks', 'eslint-config-prettier', 'eslint-config-prettier/react', + './rules/style', + './rules/react', ].map(require.resolve), - /** - * Add overrides for React and TypesScript environments. - * Note that additional eslint tooling will be required for these to work. - */ - overrides: [ - typescript, - ], }; diff --git a/packages/eslint-config-norton/overrides/typescript.js b/packages/eslint-config-norton/overrides/typescript.js deleted file mode 100644 index 75f0c0a..0000000 --- a/packages/eslint-config-norton/overrides/typescript.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Overrides for usage with TypeScript. - */ -module.exports = { - files: ['*.ts', '*.tsx'], - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - 'plugin:import/typescript', - 'prettier/@typescript-eslint' - ], - plugins: [ - "@typescript-eslint" - ], - rules: { - indent: 'off', - 'no-tabs': 'off', - '@typescript-eslint/indent': ['error', 'tab'], - '@typescript-eslint/no-empty-interface': 'off', - 'no-extra-semi': 'off', - '@typescript-eslint/no-extra-semi': 'error' - }, - parserOptions: { - project: "./tsconfig.json" - } -}; - -/*prettier/@typescript-eslint rules - -"@typescript-eslint/quotes": 0, - -"@typescript-eslint/brace-style": "off", -"@typescript-eslint/comma-spacing": "off", -"@typescript-eslint/func-call-spacing": "off", -"@typescript-eslint/indent": "off", -"@typescript-eslint/keyword-spacing": "off", -"@typescript-eslint/member-delimiter-style": "off", -"@typescript-eslint/no-extra-parens": "off", -"@typescript-eslint/no-extra-semi": "off", -"@typescript-eslint/semi": "off", -"@typescript-eslint/space-before-function-paren": "off", -"@typescript-eslint/type-annotation-spacing": "off",*/ diff --git a/packages/eslint-config-norton/package.json b/packages/eslint-config-norton/package.json index 9c471a5..26b5750 100644 --- a/packages/eslint-config-norton/package.json +++ b/packages/eslint-config-norton/package.json @@ -24,7 +24,8 @@ "files": [ "base.js", "index.js", - "overrides", + "typescript.js", + "typescript-base.js", "rules" ], "dependencies": { @@ -38,7 +39,11 @@ "eslint-plugin-import": "^2.22.0", "eslint-plugin-jsx-a11y": "^6.3.0", "eslint-plugin-react": "^7.20.0", - "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0", - "typescript": ">=3.3.1 <4.1.0" + "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } } diff --git a/packages/eslint-config-norton/rules/react.js b/packages/eslint-config-norton/rules/react.js index d8ae3d3..b4ffc29 100644 --- a/packages/eslint-config-norton/rules/react.js +++ b/packages/eslint-config-norton/rules/react.js @@ -9,27 +9,9 @@ * Note that all of these can be added via `eslint-config-airbnb`. */ module.exports = { - // files: ['*.jsx', '*.tsx'], - env: { browser: true }, - plugins: ['react-hooks'], rules: { + /** Enable tabs in JSX. */ 'react/jsx-indent': ['error', 'tab'], 'react/jsx-indent-props': ['error', 'tab'], - 'react/jsx-filename-extension': [ - 'error', - { - extensions: ['.jsx', '.tsx'], - }, - ], - 'react/jsx-props-no-spreading': ['off'], - 'react/static-property-placement': [ - 'error', - 'property assignment', - { - defaultProps: 'static public field', - }, - ], - 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn', }, }; diff --git a/packages/eslint-config-norton/rules/style.js b/packages/eslint-config-norton/rules/style.js index e7f6bc3..e1f0bc6 100644 --- a/packages/eslint-config-norton/rules/style.js +++ b/packages/eslint-config-norton/rules/style.js @@ -5,6 +5,12 @@ module.exports = { * @see https://gitlab.com/wwnorton/style/guide/issues/1 */ indent: ['error', 'tab'], - 'no-tabs': 0, + 'no-tabs': 'off', + + /** Prettier overrides for semicolons. */ + 'no-extra-semi': 'error', + semi: ['error', 'always'], + 'semi-spacing': ['error', { before: false, after: true }], + 'semi-style': ['error', 'last'], }, }; diff --git a/packages/eslint-config-norton/rules/typescript-base.js b/packages/eslint-config-norton/rules/typescript-base.js new file mode 100644 index 0000000..c8274e6 --- /dev/null +++ b/packages/eslint-config-norton/rules/typescript-base.js @@ -0,0 +1,25 @@ +module.exports = { + rules: { + /** Enable tabs with @typescript-eslint/indent instead of eslint/indent. */ + indent: 'off', + '@typescript-eslint/indent': ['error', 'tab'], + + /** Prettier overrides for semicolons using the @typescript-eslint version of the rules. */ + 'no-extra-semi': 'off', + '@typescript-eslint/no-extra-semi': 'error', + semi: 'off', + '@typescript-eslint/semi': 'error', + + /** Add ts to airbnb's list. */ + 'import/extensions': [ + 'error', + 'ignorePackages', + { + js: 'never', + mjs: 'never', + jsx: 'never', + ts: 'never', + }, + ], + }, +}; diff --git a/packages/eslint-config-norton/rules/typescript-react.js b/packages/eslint-config-norton/rules/typescript-react.js new file mode 100644 index 0000000..6977634 --- /dev/null +++ b/packages/eslint-config-norton/rules/typescript-react.js @@ -0,0 +1,32 @@ +module.exports = { + rules: { + /** Add .tsx to react/jsx-filename-extension. */ + 'react/jsx-filename-extension': [ + 'error', + { + extensions: ['.jsx', '.tsx'], + }, + ], + /** + * TypeScript supports public class fields so prefer public fields for static properties. + * https://github.com/airbnb/javascript/blob/a24dc34a4a2748c99006a48e997aa0a06b1d4d94/packages/eslint-config-airbnb/rules/react.js#L487-L490 + * + */ + 'react/static-property-placement': [ + 'error', + 'static public field', + ], + /** Add tsx to the base config. */ + 'import/extensions': [ + 'error', + 'ignorePackages', + { + js: 'never', + jsx: 'never', + mjs: 'never', + ts: 'never', + tsx: 'never', + }, + ], + }, +}; diff --git a/packages/eslint-config-norton/test/fixtures/invalid.js b/packages/eslint-config-norton/test/fixtures/invalid.js index 8f09881..885fbf3 100644 --- a/packages/eslint-config-norton/test/fixtures/invalid.js +++ b/packages/eslint-config-norton/test/fixtures/invalid.js @@ -1,3 +1,6 @@ const foo = [ 'bar', -]; +] +;export const bar = foo[0] + +export default foo;; diff --git a/packages/eslint-config-norton/test/fixtures/invalid.jsx b/packages/eslint-config-norton/test/fixtures/invalid.jsx new file mode 100644 index 0000000..a2c0b0a --- /dev/null +++ b/packages/eslint-config-norton/test/fixtures/invalid.jsx @@ -0,0 +1,31 @@ +import React from 'react'; + +export default class Foo extends React.Component { + constructor(props) { + super(props); + this.state = { + isOpen: true, + } + } + + render() { + const { isOpen } = this.state + ;if (!isOpen) return null;; + const { className } = this.props; + return ( +
+ foo +
+ ); + } +} + +Foo.propTypes = { + className: String, +}; + +Foo.defaultProps = { + className: 'foo', +}; diff --git a/packages/eslint-config-norton/test/fixtures/invalid.ts b/packages/eslint-config-norton/test/fixtures/invalid.ts new file mode 100644 index 0000000..885fbf3 --- /dev/null +++ b/packages/eslint-config-norton/test/fixtures/invalid.ts @@ -0,0 +1,6 @@ +const foo = [ + 'bar', +] +;export const bar = foo[0] + +export default foo;; diff --git a/packages/eslint-config-norton/test/fixtures/invalid.tsx b/packages/eslint-config-norton/test/fixtures/invalid.tsx new file mode 100644 index 0000000..dd6fe4d --- /dev/null +++ b/packages/eslint-config-norton/test/fixtures/invalid.tsx @@ -0,0 +1,30 @@ +import React from 'react'; + +type FooProps = React.HTMLAttributes; +interface FooState { isOpen: boolean; } + +export default class Foo extends React.Component { + constructor(props: FooProps) { + super(props); + this.state = { + isOpen: true, + } + } + + render(): JSX.Element { + const { isOpen } = this.state + ;if (!isOpen) return null;; + const { className } = this.props; + return ( +
+ foo +
+ ); + } +} + +Foo.defaultProps = { + className: 'foo', +}; diff --git a/packages/eslint-config-norton/test/fixtures/valid.js b/packages/eslint-config-norton/test/fixtures/valid.js index df79250..7884d10 100755 --- a/packages/eslint-config-norton/test/fixtures/valid.js +++ b/packages/eslint-config-norton/test/fixtures/valid.js @@ -1,5 +1,6 @@ -export default class Foo { - static add(x, y) { return x + y; } +const foo = [ + 'bar', +]; +export const bar = foo[0]; - static sub(x, y) { return x - y; } -} +export default foo; diff --git a/packages/eslint-config-norton/test/fixtures/valid.jsx b/packages/eslint-config-norton/test/fixtures/valid.jsx new file mode 100644 index 0000000..6beb966 --- /dev/null +++ b/packages/eslint-config-norton/test/fixtures/valid.jsx @@ -0,0 +1,31 @@ +import React from 'react'; + +export default class Foo extends React.Component { + constructor(props) { + super(props); + this.state = { + isOpen: true, + }; + } + + render() { + const { isOpen } = this.state; + if (!isOpen) return null; + const { className } = this.props; + return ( +
+ foo +
+ ); + } +} + +Foo.propTypes = { + className: String, +}; + +Foo.defaultProps = { + className: 'foo', +}; diff --git a/packages/eslint-config-norton/test/fixtures/valid.ts b/packages/eslint-config-norton/test/fixtures/valid.ts new file mode 100644 index 0000000..7884d10 --- /dev/null +++ b/packages/eslint-config-norton/test/fixtures/valid.ts @@ -0,0 +1,6 @@ +const foo = [ + 'bar', +]; +export const bar = foo[0]; + +export default foo; diff --git a/packages/eslint-config-norton/test/fixtures/valid.tsx b/packages/eslint-config-norton/test/fixtures/valid.tsx new file mode 100644 index 0000000..865cbb6 --- /dev/null +++ b/packages/eslint-config-norton/test/fixtures/valid.tsx @@ -0,0 +1,30 @@ +import React from 'react'; + +type FooProps = React.HTMLAttributes; +interface FooState { isOpen: boolean; } + +export default class Foo extends React.Component { + static defaultProps = { + className: 'foo', + }; + + constructor(props: FooProps) { + super(props); + this.state = { + isOpen: true, + }; + } + + render(): JSX.Element { + const { isOpen } = this.state; + if (!isOpen) return null; + const { className } = this.props; + return ( +
+ foo +
+ ); + } +} diff --git a/packages/eslint-config-norton/test/index.js b/packages/eslint-config-norton/test/index.js index 207e5d0..b808d5a 100644 --- a/packages/eslint-config-norton/test/index.js +++ b/packages/eslint-config-norton/test/index.js @@ -1,17 +1,53 @@ -import test from 'ava'; -import path from 'path'; -import { ESLint } from 'eslint'; +const test = require('ava'); +const path = require('path'); +const prettier = require('prettier'); +const { ESLint } = require('eslint'); +const fs = require('fs'); -const valid = path.join(__dirname, 'fixtures/valid.js'); -const invalid = path.join(__dirname, 'fixtures/invalid.js'); +const prettierOptions = { + arrowParens: "always", // match AirBnb 8.4 + singleQuote: true, + useTabs: true, +}; + +const valid = { + js: path.join(__dirname, 'fixtures/valid.js'), + ts: path.join(__dirname, 'fixtures/valid.ts'), + jsx: path.join(__dirname, 'fixtures/valid.jsx'), + tsx: path.join(__dirname, 'fixtures/valid.tsx'), +}; +const invalid = { + js: path.join(__dirname, 'fixtures/invalid.js'), + ts: path.join(__dirname, 'fixtures/invalid.ts'), + jsx: path.join(__dirname, 'fixtures/invalid.jsx'), + tsx: path.join(__dirname, 'fixtures/invalid.tsx'), +}; + +const validText = { + js: prettier.format(fs.readFileSync(valid.js,'utf8'), prettierOptions), + ts: prettier.format(fs.readFileSync(valid.ts,'utf8'), prettierOptions), + jsx: prettier.format(fs.readFileSync(valid.jsx,'utf8'), prettierOptions), + tsx: prettier.format(fs.readFileSync(valid.tsx,'utf8'), prettierOptions), +}; + +const invalidText = { + js: prettier.format(fs.readFileSync(invalid.js,'utf8'), prettierOptions), + ts: prettier.format(fs.readFileSync(invalid.ts,'utf8'), prettierOptions), + jsx: prettier.format(fs.readFileSync(invalid.jsx,'utf8'), prettierOptions), + tsx: prettier.format(fs.readFileSync(invalid.tsx,'utf8'), prettierOptions), +}; const eslint = new ESLint({ useEslintrc: true, ignore: false, }); +let postPrettierResult = []; + let result; +const getPrettierReport = (file) => postPrettierResult.find(({ filePath }) => filePath === file); + const getReport = (file) => result.find(({ filePath }) => filePath === file); const flagged = (messages, rule, severity = 2) => messages.some( @@ -19,21 +55,260 @@ const flagged = (messages, rule, severity = 2) => messages.some( ); test.before(async () => { - result = await eslint.lintFiles([valid, invalid]); + const validTextKeys = [...Object.keys(validText)]; + const invalidTextKeys = [...Object.keys(invalidText)]; + + await Promise.all(validTextKeys.map(async (key) => { + const lintedCode = await eslint.lintText(validText[key], {filePath: `packages/eslint-config-norton/test/fixtures/valid.${key}`}); + postPrettierResult = postPrettierResult.concat(lintedCode); + })); + + await Promise.all(invalidTextKeys.map(async (key) => { + const lintedCode = await eslint.lintText(invalidText[key], {filePath: `packages/eslint-config-norton/test/fixtures/invalid.${key}`}); + postPrettierResult = postPrettierResult.concat(lintedCode); + })); + + result = await eslint.lintFiles([ + ...Object.values(valid), + ...Object.values(invalid), + ]); +}); + + +// JavaScript + +test('js: valid file did not error or warn', (t) => { + const { errorCount, warningCount } = getReport(valid.js); + t.is(errorCount, 0); + t.is(warningCount, 0); +}); + +test('js: valid file did not error or warn postPrettier', (t) => { + const { errorCount, warningCount } = getPrettierReport(valid.js); + t.is(errorCount, 0); + t.is(warningCount, 0); +}); + +test('js: using spaces instead of tabs triggers an error', (t) => { + const { messages } = getReport(invalid.js); + t.true(flagged(messages, 'indent')); +}); + +test('js: using spaces instead of tabs does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.js); + t.false(flagged(messages, 'indent')); +}); + +test('js: using unnecessary semicolons triggers an error', (t) => { + const { messages } = getReport(invalid.js); + t.true(flagged(messages, 'no-extra-semi')); +}); + +test('js: using unnecessary semicolons does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.js); + t.false(flagged(messages, 'no-extra-semi')); }); -test('valid file did not error', async (t) => { - const { errorCount } = getReport(valid); +test('js: missing whitespace after semicolon triggers an error', (t) => { + const { messages } = getReport(invalid.js); + t.true(flagged(messages, 'semi-spacing')); +}); + +test('js: missing whitespace after semicolon does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.js); + t.false(flagged(messages, 'semi-spacing')); +}); + +test('js: setting a semicolon at the beginning of the line triggers an error', (t) => { + const { messages } = getReport(invalid.js); + t.true(flagged(messages, 'semi-style')); +}); + +test('js: setting a semicolon at the beginning of the line does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.js); + t.false(flagged(messages, 'semi-style')); +}); + +test('js: omitting a semicolon triggers an error', (t) => { + const { messages } = getReport(invalid.js); + t.true(flagged(messages, 'semi')); +}); + +test('js: omitting a semicolon does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.js); + t.false(flagged(messages, 'semi')); +}); + + +// TypeScript + +test('ts: valid file did not error or warn', (t) => { + const { errorCount, warningCount } = getReport(valid.ts); t.is(errorCount, 0); + t.is(warningCount, 0); }); -test('valid file flags no warnings', async (t) => { - const { warningCount } = getReport(valid); +test('ts: valid file did not error or warn post Prettier', (t) => { + const { errorCount, warningCount } = getPrettierReport(valid.ts); + t.is(errorCount, 0); t.is(warningCount, 0); }); -// This is turned off due to the inclusion of eslint-config-prettier -// test('using spaces instead of tabs triggers an error', (t) => { -// const { messages } = getReport(invalid); -// t.true(flagged(messages, 'indent')); -// }); +test('ts: expected JavaScript rules are triggered', (t) => { + const { messages } = getReport(invalid.ts); + t.true(flagged(messages, 'semi-spacing')); + t.true(flagged(messages, 'semi-style')); +}); + +test('ts: expected no Javascript semi errors post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.ts); + t.false(flagged(messages, 'semi-spacing')); + t.false(flagged(messages, 'semi-style')); +}); + +test('ts: using spaces instead of tabs triggers an error', (t) => { + const { messages } = getReport(invalid.ts); + t.false(flagged(messages, 'indent')); + t.true(flagged(messages, '@typescript-eslint/indent')); +}); + +test('ts: using spaces instead of tabs does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.ts); + t.false(flagged(messages, 'indent')); + t.false(flagged(messages, '@typescript-eslint/indent')); +}); + +test('ts: omitting a semicolon triggers an error', (t) => { + const { messages } = getReport(invalid.ts); + t.false(flagged(messages, 'semi')); + t.true(flagged(messages, '@typescript-eslint/semi')); +}); + +test('ts: omitting a semicolon triggers an error does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.ts); + t.false(flagged(messages, 'semi')); + t.false(flagged(messages, '@typescript-eslint/semi')); +}); + +test('ts: using unnecessary semicolons triggers an error', (t) => { + const { messages } = getReport(invalid.ts); + t.false(flagged(messages, 'no-extra-semi')); + t.true(flagged(messages, '@typescript-eslint/no-extra-semi')); +}); + +test('ts: using unnecessary semicolons does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.ts); + t.false(flagged(messages, 'no-extra-semi')); + t.false(flagged(messages, '@typescript-eslint/no-extra-semi')); +}); + + +// React + +test('jsx: valid file did not error or warn', (t) => { + const { errorCount, warningCount } = getReport(valid.jsx); + t.is(errorCount, 0); + t.is(warningCount, 0); +}); + +test('jsx: valid file did not error or warn post Prettier', (t) => { + const { errorCount, warningCount } = getPrettierReport(valid.jsx); + t.is(errorCount, 0); + t.is(warningCount, 0); +}); + +test('jsx: expected JavaScript rules are triggered', (t) => { + const { messages } = getReport(invalid.jsx); + t.true(flagged(messages, 'indent')); + t.true(flagged(messages, 'no-extra-semi')); + t.true(flagged(messages, 'semi-spacing')); + t.true(flagged(messages, 'semi-style')); + t.true(flagged(messages, 'semi')); +}); + +test('jsx: expected JavaScript rules are not triggered post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.jsx); + t.false(flagged(messages, 'indent')); + t.false(flagged(messages, 'no-extra-semi')); + t.false(flagged(messages, 'semi-spacing')); + t.false(flagged(messages, 'semi-style')); + t.false(flagged(messages, 'semi')); +}); + +test('jsx: using spaces instead of tabs for JSX triggers an error', (t) => { + const { messages } = getReport(invalid.jsx); + t.true(flagged(messages, 'react/jsx-indent')); +}); + +test('jsx: using spaces instead of tabs for JSX does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.jsx); + t.false(flagged(messages, 'react/jsx-indent')); +}); + +test('jsx: using spaces instead of tabs for JSX props triggers an error', (t) => { + const { messages } = getReport(invalid.jsx); + t.true(flagged(messages, 'react/jsx-indent-props')); +}); + +test('jsx: using spaces instead of tabs for JSX props does not trigger an error post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.jsx); + t.false(flagged(messages, 'react/jsx-indent-props')); +}); + + +// React + TypeScript + +test('tsx: valid file did not error or warn', (t) => { + const { errorCount, warningCount } = getReport(valid.tsx); + t.is(errorCount, 0); + t.is(warningCount, 0); +}); + +test('tsx: valid file did not error or warn post Prettier', (t) => { + const { errorCount, warningCount } = getPrettierReport(valid.tsx); + t.is(errorCount, 0); + t.is(warningCount, 0); +}); + +test('tsx: expected JavaScript rules are triggered', (t) => { + const { messages } = getReport(invalid.tsx); + t.true(flagged(messages, 'semi-spacing')); + t.true(flagged(messages, 'semi-style')); +}); + +test('tsx: expected JavaScript rules are not triggered post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.tsx); + t.false(flagged(messages, 'semi-spacing')); + t.false(flagged(messages, 'semi-style')); +}); + +test('tsx: expected TypeScript rules are triggered', (t) => { + const { messages } = getReport(invalid.tsx); + t.true(flagged(messages, '@typescript-eslint/semi')); + t.true(flagged(messages, '@typescript-eslint/no-extra-semi')); + t.true(flagged(messages, '@typescript-eslint/indent')); +}); + +test('tsx: expected TypeScript rules are not triggered post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.tsx); + t.false(flagged(messages, '@typescript-eslint/semi')); + t.false(flagged(messages, '@typescript-eslint/no-extra-semi')); + t.false(flagged(messages, '@typescript-eslint/indent')); +}); + +test('tsx: expected React rules are triggered', (t) => { + const { messages } = getReport(invalid.tsx); + t.true(flagged(messages, 'react/jsx-indent-props')); + t.true(flagged(messages, 'react/jsx-indent')); +}); + +test('tsx: expected React rules are not triggered post Prettier', (t) => { + const { messages } = getPrettierReport(invalid.tsx); + t.false(flagged(messages, 'react/jsx-indent-props')); + t.false(flagged(messages, 'react/jsx-indent')); +}); + +test('tsx: using property assignment for React static properties triggers an error', (t) => { + const { messages } = getReport(invalid.tsx); + t.true(flagged(messages, 'react/static-property-placement')); +}); diff --git a/packages/eslint-config-norton/tsconfig.json b/packages/eslint-config-norton/tsconfig.json new file mode 100644 index 0000000..f8b3611 --- /dev/null +++ b/packages/eslint-config-norton/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "ESNext", + "jsx": "react", + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + }, +} diff --git a/packages/eslint-config-norton/typescript-base.js b/packages/eslint-config-norton/typescript-base.js new file mode 100644 index 0000000..e7469d2 --- /dev/null +++ b/packages/eslint-config-norton/typescript-base.js @@ -0,0 +1,38 @@ +/** + * Overrides for usage with TypeScript. + */ +module.exports = { + overrides: [ + { + files: ['*.ts?(x)'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + extends: [ + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:import/typescript', + 'prettier/@typescript-eslint', + './rules/typescript-base' + ], + parserOptions: { + project: './tsconfig.json', + }, + settings: { + 'import/extensions': [ + '.js', + '.jsx', + '.mjs', + '.ts', + ], + 'import/resolver': { + node: { + extensions: ['.js', '.json', '.ts'], + }, + webpack: { + extensions: ['.js', '.json', '.ts'], + }, + }, + }, + } + ] +}; diff --git a/packages/eslint-config-norton/typescript.js b/packages/eslint-config-norton/typescript.js new file mode 100644 index 0000000..adeeffa --- /dev/null +++ b/packages/eslint-config-norton/typescript.js @@ -0,0 +1,31 @@ +/** + * Overrides for usage with TypeScript + React. + */ +module.exports = { + overrides: [ + { + files: ['*.ts?(x)'], + extends: [ + './typescript-base', + './rules/typescript-react', + ].map(require.resolve), + settings: { + 'import/extensions': [ + '.js', + '.jsx', + '.mjs', + '.ts', + '.tsx', + ], + 'import/resolver': { + node: { + extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'], + }, + webpack: { + extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'], + }, + }, + }, + }, + ], +}; diff --git a/packages/stylelint-config-norton/test/index.js b/packages/stylelint-config-norton/test/index.js index 281464a..be82a81 100644 --- a/packages/stylelint-config-norton/test/index.js +++ b/packages/stylelint-config-norton/test/index.js @@ -1,10 +1,10 @@ -import fs from 'fs'; -import test from 'ava'; -import path from 'path'; -import { lint } from 'stylelint'; -import { promisify } from 'util'; -import sassConfig from '../src/sass'; -import cssConfig from '../src/css'; +const fs = require('fs'); +const test = require('ava'); +const path = require('path'); +const { lint } = require('stylelint'); +const { promisify } = require('util'); +const sassConfig = require('../src/sass'); +const cssConfig = require('../src/css'); const readFile = promisify(fs.readFile);