|  | 
|  | 1 | +// @ts-check | 
|  | 2 | + | 
|  | 3 | +import eslint from '@eslint/js'; | 
|  | 4 | +import tseslint from 'typescript-eslint'; | 
|  | 5 | +import globals from "globals"; | 
|  | 6 | + | 
|  | 7 | +export default tseslint.config( | 
|  | 8 | +  { | 
|  | 9 | +    ignores: [ | 
|  | 10 | +      "**/*", // ignore everything... | 
|  | 11 | +      "!src/**/", "!src/**/*.ts", // ... except our TypeScript source files... | 
|  | 12 | +      "!test/**/", "!test/**/*.js", // ... and our tests | 
|  | 13 | +    ], | 
|  | 14 | +  }, | 
|  | 15 | +  eslint.configs.recommended, | 
|  | 16 | +  tseslint.configs.recommended, | 
|  | 17 | +  { | 
|  | 18 | +    files: ['src/**/*.ts'], | 
|  | 19 | +    languageOptions: { | 
|  | 20 | +      parserOptions: { | 
|  | 21 | +        projectService: true, | 
|  | 22 | +        tsconfigRootDir: import.meta.dirname, | 
|  | 23 | +      }, | 
|  | 24 | +    }, | 
|  | 25 | +    extends: [tseslint.configs.recommendedTypeChecked], | 
|  | 26 | +    rules: { | 
|  | 27 | +      // Not sure if these actually serve a purpose, but they provide a way to enforce SOME of what | 
|  | 28 | +      // would be imposed by having "verbatimModuleSyntax": true in our tsconfig.json without | 
|  | 29 | +      // actually doing that. | 
|  | 30 | +      "@typescript-eslint/consistent-type-imports": 2, | 
|  | 31 | +      "@typescript-eslint/consistent-type-exports": 2, | 
|  | 32 | + | 
|  | 33 | +      // Things from the recommendedTypeChecked shared config that are disabled simply because they | 
|  | 34 | +      // caused lots of errors in our existing code when tried. Plausibly useful to turn on if | 
|  | 35 | +      // possible and somebody fancies doing the work: | 
|  | 36 | +      "@typescript-eslint/no-unsafe-argument": 0, | 
|  | 37 | +      "@typescript-eslint/no-unsafe-assignment": 0, | 
|  | 38 | +      "@typescript-eslint/no-unsafe-call": 0, | 
|  | 39 | +      "@typescript-eslint/no-unsafe-member-access": 0, | 
|  | 40 | +      "@typescript-eslint/no-unsafe-return": 0, | 
|  | 41 | +    } | 
|  | 42 | +  }, | 
|  | 43 | +  { | 
|  | 44 | +    languageOptions: { | 
|  | 45 | +      globals: { | 
|  | 46 | +        ...globals.browser, | 
|  | 47 | +      }, | 
|  | 48 | +    }, | 
|  | 49 | + | 
|  | 50 | +    rules: { | 
|  | 51 | +      // Possible Errors // | 
|  | 52 | +      //-----------------// | 
|  | 53 | +      "comma-dangle": [2, "never"], | 
|  | 54 | +      "no-console": 1, // Allow for debugging | 
|  | 55 | +      "no-debugger": 1, // Allow for debugging | 
|  | 56 | +      "no-extra-parens": [2, "functions"], | 
|  | 57 | +      "no-extra-semi": 2, | 
|  | 58 | +      "no-negated-in-lhs": 2, | 
|  | 59 | +      "no-unreachable": 1, // Optimizer and coverage will handle/highlight this and can be useful for debugging | 
|  | 60 | + | 
|  | 61 | +      // Best Practices // | 
|  | 62 | +      //----------------// | 
|  | 63 | +      curly: 2, | 
|  | 64 | +      "default-case": 1, | 
|  | 65 | +      "dot-notation": [2, { | 
|  | 66 | +        allowKeywords: false, | 
|  | 67 | +      }], | 
|  | 68 | +      "guard-for-in": 1, | 
|  | 69 | +      "no-alert": 2, | 
|  | 70 | +      "no-caller": 2, | 
|  | 71 | +      "no-div-regex": 1, | 
|  | 72 | +      "no-eval": 2, | 
|  | 73 | +      "no-extend-native": 2, | 
|  | 74 | +      "no-extra-bind": 2, | 
|  | 75 | +      "no-floating-decimal": 2, | 
|  | 76 | +      "no-implied-eval": 2, | 
|  | 77 | +      "no-iterator": 2, | 
|  | 78 | +      "no-labels": 2, | 
|  | 79 | +      "no-lone-blocks": 2, | 
|  | 80 | +      "no-multi-spaces": 2, | 
|  | 81 | +      "no-multi-str": 1, | 
|  | 82 | +      "no-native-reassign": 2, | 
|  | 83 | +      "no-new": 2, | 
|  | 84 | +      "no-new-func": 2, | 
|  | 85 | +      "no-new-wrappers": 2, | 
|  | 86 | +      "no-octal-escape": 2, | 
|  | 87 | +      "no-process-env": 2, | 
|  | 88 | +      "no-proto": 2, | 
|  | 89 | +      "no-return-assign": 2, | 
|  | 90 | +      "no-script-url": 2, | 
|  | 91 | +      "no-self-compare": 2, | 
|  | 92 | +      "no-sequences": 2, | 
|  | 93 | +      "no-throw-literal": 2, | 
|  | 94 | +      "no-unused-expressions": 2, | 
|  | 95 | +      "no-warning-comments": 1, | 
|  | 96 | +      radix: 2, | 
|  | 97 | +      "wrap-iife": 2, | 
|  | 98 | + | 
|  | 99 | +      // Variables // | 
|  | 100 | +      //-----------// | 
|  | 101 | +      "no-catch-shadow": 2, | 
|  | 102 | +      "no-label-var": 2, | 
|  | 103 | +      "no-undef-init": 2, | 
|  | 104 | + | 
|  | 105 | +      // Node.js // | 
|  | 106 | +      //---------// | 
|  | 107 | + | 
|  | 108 | +      // Stylistic // | 
|  | 109 | +      //-----------// | 
|  | 110 | +      "brace-style": [2, "1tbs", { | 
|  | 111 | +        allowSingleLine: true, | 
|  | 112 | +      }], | 
|  | 113 | +      camelcase: 2, | 
|  | 114 | +      "comma-spacing": [2, { | 
|  | 115 | +        before: false, | 
|  | 116 | +        after: true, | 
|  | 117 | +      }], | 
|  | 118 | +      "comma-style": [2, "last"], | 
|  | 119 | +      "consistent-this": [1, "self"], | 
|  | 120 | +      "eol-last": 2, | 
|  | 121 | +      "func-style": [2, "declaration"], | 
|  | 122 | +      "key-spacing": [2, { | 
|  | 123 | +        beforeColon: false, | 
|  | 124 | +        afterColon: true, | 
|  | 125 | +      }], | 
|  | 126 | +      "new-cap": 2, | 
|  | 127 | +      "new-parens": 2, | 
|  | 128 | +      "no-array-constructor": 2, | 
|  | 129 | +      "no-lonely-if": 2, | 
|  | 130 | +      "no-mixed-spaces-and-tabs": 2, | 
|  | 131 | +      "no-nested-ternary": 1, | 
|  | 132 | +      "no-new-object": 2, | 
|  | 133 | +      "no-spaced-func": 2, | 
|  | 134 | +      "no-trailing-spaces": 2, | 
|  | 135 | +      "quote-props": [2, "as-needed", { | 
|  | 136 | +        keywords: true, | 
|  | 137 | +      }], | 
|  | 138 | +      quotes: [2, "single", "avoid-escape"], | 
|  | 139 | +      semi: 2, | 
|  | 140 | +      "semi-spacing": [2, { | 
|  | 141 | +        before: false, | 
|  | 142 | +        after: true, | 
|  | 143 | +      }], | 
|  | 144 | +      "space-before-blocks": [2, "always"], | 
|  | 145 | +      "space-before-function-paren": [2, { | 
|  | 146 | +        anonymous: "never", | 
|  | 147 | +        named: "never", | 
|  | 148 | +      }], | 
|  | 149 | +      "space-in-parens": [2, "never"], | 
|  | 150 | +      "space-infix-ops": 2, | 
|  | 151 | +      "space-unary-ops": 2, | 
|  | 152 | +      "spaced-comment": [2, "always"], | 
|  | 153 | +      "wrap-regex": 1, | 
|  | 154 | +      "no-var": 2, | 
|  | 155 | + | 
|  | 156 | +      // Typescript // | 
|  | 157 | +      //------------// | 
|  | 158 | +      "@typescript-eslint/no-explicit-any": 0, // Very strict rule, incompatible with our code | 
|  | 159 | + | 
|  | 160 | +      // We use these intentionally - e.g. | 
|  | 161 | +      //     export interface DiffCssOptions extends CommonDiffOptions {} | 
|  | 162 | +      // for the options argument to diffCss which currently takes no options beyond the ones | 
|  | 163 | +      // common to all diffFoo functions. Doing this allows consistency (one options interface per | 
|  | 164 | +      // diffFoo function) and future-proofs against the API having to change in future if we add a | 
|  | 165 | +      // non-common option to one of these functions. | 
|  | 166 | +      "@typescript-eslint/no-empty-object-type": [2, {allowInterfaces: 'with-single-extends'}], | 
|  | 167 | +    }, | 
|  | 168 | +  }, | 
|  | 169 | +  { | 
|  | 170 | +    files: ['test/**/*.js'], | 
|  | 171 | +    languageOptions: { | 
|  | 172 | +      globals: { | 
|  | 173 | +        ...globals.node, | 
|  | 174 | +        ...globals.mocha, | 
|  | 175 | +      }, | 
|  | 176 | +    }, | 
|  | 177 | +    rules: { | 
|  | 178 | +      "no-unused-expressions": 0, // Needs disabling to support Chai `.to.be.undefined` etc syntax | 
|  | 179 | +      "@typescript-eslint/no-unused-expressions": 0, // (as above) | 
|  | 180 | +    }, | 
|  | 181 | +  } | 
|  | 182 | +); | 
0 commit comments