| // @ts-check |
| |
| import eslint from '@eslint/js'; |
| import tseslint from 'typescript-eslint'; |
| import globals from "globals"; |
| |
| export default tseslint.config( |
| { |
| ignores: [ |
| "**/*", // ignore everything... |
| "!src/**/", "!src/**/*.ts", // ... except our TypeScript source files... |
| "!test/**/", "!test/**/*.js", // ... and our tests |
| ], |
| }, |
| eslint.configs.recommended, |
| tseslint.configs.recommended, |
| { |
| files: ['src/**/*.ts'], |
| languageOptions: { |
| parserOptions: { |
| projectService: true, |
| tsconfigRootDir: import.meta.dirname, |
| }, |
| }, |
| extends: [tseslint.configs.recommendedTypeChecked], |
| rules: { |
| // Not sure if these actually serve a purpose, but they provide a way to enforce SOME of what |
| // would be imposed by having "verbatimModuleSyntax": true in our tsconfig.json without |
| // actually doing that. |
| "@typescript-eslint/consistent-type-imports": 2, |
| "@typescript-eslint/consistent-type-exports": 2, |
| |
| // Things from the recommendedTypeChecked shared config that are disabled simply because they |
| // caused lots of errors in our existing code when tried. Plausibly useful to turn on if |
| // possible and somebody fancies doing the work: |
| "@typescript-eslint/no-unsafe-argument": 0, |
| "@typescript-eslint/no-unsafe-assignment": 0, |
| "@typescript-eslint/no-unsafe-call": 0, |
| "@typescript-eslint/no-unsafe-member-access": 0, |
| "@typescript-eslint/no-unsafe-return": 0, |
| } |
| }, |
| { |
| languageOptions: { |
| globals: { |
| ...globals.browser, |
| }, |
| }, |
| |
| rules: { |
| // Possible Errors // |
| //-----------------// |
| "comma-dangle": [2, "never"], |
| "no-console": 1, // Allow for debugging |
| "no-debugger": 1, // Allow for debugging |
| "no-extra-parens": [2, "functions"], |
| "no-extra-semi": 2, |
| "no-negated-in-lhs": 2, |
| "no-unreachable": 1, // Optimizer and coverage will handle/highlight this and can be useful for debugging |
| |
| // Best Practices // |
| //----------------// |
| curly: 2, |
| "default-case": 1, |
| "dot-notation": [2, { |
| allowKeywords: false, |
| }], |
| "guard-for-in": 1, |
| "no-alert": 2, |
| "no-caller": 2, |
| "no-div-regex": 1, |
| "no-eval": 2, |
| "no-extend-native": 2, |
| "no-extra-bind": 2, |
| "no-floating-decimal": 2, |
| "no-implied-eval": 2, |
| "no-iterator": 2, |
| "no-labels": 2, |
| "no-lone-blocks": 2, |
| "no-multi-spaces": 2, |
| "no-multi-str": 1, |
| "no-native-reassign": 2, |
| "no-new": 2, |
| "no-new-func": 2, |
| "no-new-wrappers": 2, |
| "no-octal-escape": 2, |
| "no-process-env": 2, |
| "no-proto": 2, |
| "no-return-assign": 2, |
| "no-script-url": 2, |
| "no-self-compare": 2, |
| "no-sequences": 2, |
| "no-throw-literal": 2, |
| "no-unused-expressions": 2, |
| "no-warning-comments": 1, |
| radix: 2, |
| "wrap-iife": 2, |
| |
| // Variables // |
| //-----------// |
| "no-catch-shadow": 2, |
| "no-label-var": 2, |
| "no-undef-init": 2, |
| |
| // Node.js // |
| //---------// |
| |
| // Stylistic // |
| //-----------// |
| "brace-style": [2, "1tbs", { |
| allowSingleLine: true, |
| }], |
| camelcase: 2, |
| "comma-spacing": [2, { |
| before: false, |
| after: true, |
| }], |
| "comma-style": [2, "last"], |
| "consistent-this": [1, "self"], |
| "eol-last": 2, |
| "func-style": [2, "declaration"], |
| "key-spacing": [2, { |
| beforeColon: false, |
| afterColon: true, |
| }], |
| "new-cap": 2, |
| "new-parens": 2, |
| "no-array-constructor": 2, |
| "no-lonely-if": 2, |
| "no-mixed-spaces-and-tabs": 2, |
| "no-nested-ternary": 1, |
| "no-new-object": 2, |
| "no-spaced-func": 2, |
| "no-trailing-spaces": 2, |
| "quote-props": [2, "as-needed", { |
| keywords: true, |
| }], |
| quotes: [2, "single", "avoid-escape"], |
| semi: 2, |
| "semi-spacing": [2, { |
| before: false, |
| after: true, |
| }], |
| "space-before-blocks": [2, "always"], |
| "space-before-function-paren": [2, { |
| anonymous: "never", |
| named: "never", |
| }], |
| "space-in-parens": [2, "never"], |
| "space-infix-ops": 2, |
| "space-unary-ops": 2, |
| "spaced-comment": [2, "always"], |
| "wrap-regex": 1, |
| "no-var": 2, |
| |
| // Typescript // |
| //------------// |
| "@typescript-eslint/no-explicit-any": 0, // Very strict rule, incompatible with our code |
| |
| // We use these intentionally - e.g. |
| // export interface DiffCssOptions extends CommonDiffOptions {} |
| // for the options argument to diffCss which currently takes no options beyond the ones |
| // common to all diffFoo functions. Doing this allows consistency (one options interface per |
| // diffFoo function) and future-proofs against the API having to change in future if we add a |
| // non-common option to one of these functions. |
| "@typescript-eslint/no-empty-object-type": [2, {allowInterfaces: 'with-single-extends'}], |
| }, |
| }, |
| { |
| files: ['test/**/*.js'], |
| languageOptions: { |
| globals: { |
| ...globals.node, |
| ...globals.mocha, |
| }, |
| }, |
| rules: { |
| "no-unused-expressions": 0, // Needs disabling to support Chai `.to.be.undefined` etc syntax |
| "@typescript-eslint/no-unused-expressions": 0, // (as above) |
| }, |
| } |
| ); |