{ "root": true, "parser": "@typescript-eslint/parser", "parserOptions": { "warnOnUnsupportedTypeScriptVersion": false, "sourceType": "module" }, "env": { "browser": false, "node": true, "es6": true }, "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/stylistic" ], "plugins": [ "@typescript-eslint", "no-null", "eslint-plugin-local", "simple-import-sort" ], "ignorePatterns": [ "**/node_modules/**", "/built/**", "/tests/**", "/lib/**", "/src/lib/*.generated.d.ts", "/scripts/**/*.js", "/scripts/**/*.d.*", "/internal/**", "/coverage/**" ], "rules": { // eslint "dot-notation": "error", "eqeqeq": "error", "no-caller": "error", "no-constant-condition": ["error", { "checkLoops": false }], "no-eval": "error", "no-extra-bind": "error", "no-new-func": "error", "no-new-wrappers": "error", "no-return-await": "error", "no-restricted-globals": [ "error", { "name": "setTimeout" }, { "name": "clearTimeout" }, { "name": "setInterval" }, { "name": "clearInterval" }, { "name": "setImmediate" }, { "name": "clearImmediate" } ], "no-template-curly-in-string": "error", "no-throw-literal": "error", "no-undef-init": "error", "no-var": "error", "object-shorthand": "error", "prefer-const": "error", "prefer-object-spread": "error", "unicode-bom": ["error", "never"], // Enabled in eslint:recommended, but not applicable here "no-extra-boolean-cast": "off", "no-case-declarations": "off", "no-cond-assign": "off", "no-control-regex": "off", "no-inner-declarations": "off", // @typescript-eslint/eslint-plugin "@typescript-eslint/naming-convention": [ "error", { "selector": "typeLike", "format": ["PascalCase"], "filter": { "regex": "^(__String|[A-Za-z]+_[A-Za-z]+)$", "match": false } }, { "selector": "interface", "format": ["PascalCase"], "custom": { "regex": "^I[A-Z]", "match": false }, "filter": { "regex": "^I(Arguments|TextWriter|O([A-Z][a-z]+[A-Za-z]*)?)$", "match": false } }, { "selector": "variable", "format": ["camelCase", "PascalCase", "UPPER_CASE"], "leadingUnderscore": "allow", "filter": { "regex": "^(_{1,2}filename|_{1,2}dirname|_+|[A-Za-z]+_[A-Za-z]+)$", "match": false } }, { "selector": "function", "format": ["camelCase", "PascalCase"], "leadingUnderscore": "allow", "filter": { "regex": "^[A-Za-z]+_[A-Za-z]+$", "match": false } }, { "selector": "parameter", "format": ["camelCase"], "leadingUnderscore": "allow", "filter": { "regex": "^(_+|[A-Za-z]+_[A-Z][a-z]+)$", "match": false } }, { "selector": "method", "format": ["camelCase", "PascalCase"], "leadingUnderscore": "allow", "filter": { "regex": "^([0-9]+|[A-Za-z]+_[A-Za-z]+)$", "match": false } }, { "selector": "memberLike", "format": ["camelCase"], "leadingUnderscore": "allow", "filter": { "regex": "^([0-9]+|[A-Za-z]+_[A-Za-z]+)$", "match": false } }, { "selector": "enumMember", "format": ["camelCase", "PascalCase"], "leadingUnderscore": "allow", "filter": { "regex": "^[A-Za-z]+_[A-Za-z]+$", "match": false } }, { "selector": "property", "format": null } ], // Rules enabled in typescript-eslint configs that are not applicable here "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/class-literal-property-style": "off", "@typescript-eslint/consistent-indexed-object-style": "off", "@typescript-eslint/no-duplicate-enum-values": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-non-null-asserted-optional-chain": "off", "@typescript-eslint/no-var-requires": "off", "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/ban-types": [ "error", { "extendDefaults": true, "types": { // This is theoretically good, but ts-eslint appears to mistake our declaration of Symbol for the global Symbol type. // See: https://github.com/typescript-eslint/typescript-eslint/issues/7306 "Symbol": false, "{}": false // {} is a totally useful and valid type. } } ], // Todo: For each of these, investigate whether we want to enable them ✨ "@typescript-eslint/no-unused-vars": "off", // Pending https://github.com/typescript-eslint/typescript-eslint/issues/4820 "@typescript-eslint/prefer-optional-chain": "off", // scripts/eslint/rules "local/only-arrow-functions": [ "error", { "allowNamedFunctions": true, "allowDeclarations": true } ], "local/argument-trivia": "error", "local/no-in-operator": "error", "local/debug-assert": "error", "local/no-keywords": "error", "local/jsdoc-format": "error", // eslint-plugin-no-null "no-null/no-null": "error", // eslint-plugin-simple-import-sort "simple-import-sort/imports": "error", "simple-import-sort/exports": "error" }, "overrides": [ // By default, the ESLint CLI only looks at .js files. But, it will also look at // any files which are referenced in an override config. Most users of typescript-eslint // get this behavior by default by extending a recommended typescript-eslint config, which // just so happens to override some core ESLint rules. We don't extend from any config, so // explicitly reference TS files here so the CLI picks them up. // // ESLint in VS Code will lint any opened file (so long as it's not eslintignore'd), so // that will work regardless of the below. // // The same applies to mjs files; ESLint appears to not scan those either. { "files": ["*.ts", "*.mts", "*.cts", "*.mjs", "*.cjs"] }, { "files": ["*.mjs", "*.mts"], "rules": { // These globals don't exist outside of CJS files. "no-restricted-globals": [ "error", { "name": "__filename" }, { "name": "__dirname" }, { "name": "require" }, { "name": "module" }, { "name": "exports" } ] } }, { // These files contain imports in a specific order that are generally unsafe to modify. "files": ["**/_namespaces/**"], "rules": { "simple-import-sort/imports": "off", "simple-import-sort/exports": "off" } } ] }