2024-06-28 02:11:56 +03:00
|
|
|
// @ts-check
|
|
|
|
import eslint from "@eslint/js";
|
2024-08-14 00:16:53 +03:00
|
|
|
import * as regexpPlugin from "eslint-plugin-regexp";
|
2024-06-28 02:11:56 +03:00
|
|
|
import fs from "fs";
|
|
|
|
import globals from "globals";
|
|
|
|
import { createRequire } from "module";
|
|
|
|
import path from "path";
|
|
|
|
import tseslint from "typescript-eslint";
|
|
|
|
import url from "url";
|
|
|
|
|
|
|
|
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
|
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
|
|
|
|
const require = createRequire(import.meta.url);
|
|
|
|
|
|
|
|
const rulesDir = path.join(__dirname, "scripts", "eslint", "rules");
|
|
|
|
const ext = ".cjs";
|
|
|
|
const ruleFiles = fs.readdirSync(rulesDir).filter(p => p.endsWith(ext));
|
|
|
|
|
|
|
|
export default tseslint.config(
|
|
|
|
{
|
|
|
|
files: ["**/*.{ts,tsx,cts,mts,js,cjs,mjs}"],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ignores: [
|
|
|
|
"**/node_modules/**",
|
|
|
|
"built/**",
|
|
|
|
"tests/**",
|
|
|
|
"lib/**",
|
|
|
|
"src/lib/*.generated.d.ts",
|
|
|
|
"scripts/**/*.js",
|
|
|
|
"scripts/**/*.d.*",
|
|
|
|
"internal/**",
|
|
|
|
"coverage/**",
|
|
|
|
],
|
|
|
|
},
|
|
|
|
eslint.configs.recommended,
|
|
|
|
...tseslint.configs.recommended,
|
|
|
|
...tseslint.configs.stylistic,
|
2024-08-14 00:16:53 +03:00
|
|
|
regexpPlugin.configs["flat/recommended"],
|
2024-06-28 02:11:56 +03:00
|
|
|
{
|
|
|
|
plugins: {
|
|
|
|
local: {
|
|
|
|
rules: Object.fromEntries(ruleFiles.map(p => {
|
|
|
|
return [p.slice(0, -ext.length), require(path.join(rulesDir, p))];
|
|
|
|
})),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
languageOptions: {
|
|
|
|
parserOptions: {
|
|
|
|
warnOnUnsupportedTypeScriptVersion: false,
|
|
|
|
},
|
|
|
|
globals: globals.node,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
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-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"],
|
|
|
|
|
|
|
|
"no-restricted-syntax": [
|
|
|
|
"error",
|
|
|
|
{
|
|
|
|
selector: "Literal[raw=null]",
|
|
|
|
message: "Avoid using null; use undefined instead.",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
selector: "TSNullKeyword",
|
|
|
|
message: "Avoid using null; use undefined instead.",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
|
|
|
|
// 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 } },
|
|
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
|
|
{ selector: "property", format: null },
|
|
|
|
],
|
|
|
|
|
|
|
|
"@typescript-eslint/unified-signatures": "error",
|
|
|
|
"no-unused-expressions": "off",
|
|
|
|
"@typescript-eslint/no-unused-expressions": ["error", { allowTernary: true }],
|
|
|
|
|
|
|
|
// 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",
|
2024-09-16 04:10:52 +03:00
|
|
|
"@typescript-eslint/consistent-generic-constructors": "off",
|
2024-06-28 02:11:56 +03:00
|
|
|
"@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",
|
2024-08-13 03:13:24 +03:00
|
|
|
"@typescript-eslint/no-empty-object-type": "off", // {} is a totally useful and valid type.
|
|
|
|
"@typescript-eslint/no-require-imports": "off",
|
2024-06-28 02:11:56 +03:00
|
|
|
"@typescript-eslint/no-unused-vars": [
|
|
|
|
"warn",
|
|
|
|
{
|
|
|
|
// Ignore: (solely underscores | starting with exactly one underscore)
|
|
|
|
argsIgnorePattern: "^(_+$|_[^_])",
|
|
|
|
varsIgnorePattern: "^(_+$|_[^_])",
|
2024-08-13 03:13:24 +03:00
|
|
|
// Not setting an ignore pattern for caught errors; those can always be safely removed.
|
2024-06-28 02:11:56 +03:00
|
|
|
},
|
|
|
|
],
|
|
|
|
"@typescript-eslint/no-inferrable-types": "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",
|
|
|
|
"local/js-extensions": "error",
|
2024-08-14 19:28:57 +03:00
|
|
|
"local/no-array-mutating-method-expressions": "error",
|
2024-06-28 02:11:56 +03:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
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" },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
files: ["src/**"],
|
|
|
|
languageOptions: {
|
|
|
|
parserOptions: {
|
|
|
|
tsconfigRootDir: __dirname,
|
|
|
|
project: "./src/tsconfig-eslint.json",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-07-10 01:15:35 +03:00
|
|
|
{
|
|
|
|
files: ["scripts/**"],
|
|
|
|
languageOptions: {
|
|
|
|
parserOptions: {
|
|
|
|
tsconfigRootDir: __dirname,
|
|
|
|
project: "./scripts/tsconfig.json",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-06-28 02:11:56 +03:00
|
|
|
{
|
|
|
|
files: ["src/**"],
|
|
|
|
rules: {
|
|
|
|
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
|
|
|
"no-restricted-globals": [
|
|
|
|
"error",
|
|
|
|
{ name: "setTimeout" },
|
|
|
|
{ name: "clearTimeout" },
|
|
|
|
{ name: "setInterval" },
|
|
|
|
{ name: "clearInterval" },
|
|
|
|
{ name: "setImmediate" },
|
|
|
|
{ name: "clearImmediate" },
|
|
|
|
{ name: "performance" },
|
|
|
|
],
|
2024-08-08 19:38:10 +03:00
|
|
|
"local/no-direct-import": "error",
|
2024-06-28 02:11:56 +03:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
files: ["src/harness/**", "src/testRunner/**"],
|
|
|
|
rules: {
|
|
|
|
"no-restricted-globals": "off",
|
2024-08-14 00:16:53 +03:00
|
|
|
"regexp/no-super-linear-backtracking": "off",
|
2024-08-08 19:38:10 +03:00
|
|
|
"local/no-direct-import": "off",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
files: ["src/**/_namespaces/**"],
|
|
|
|
rules: {
|
|
|
|
"local/no-direct-import": "off",
|
2024-06-28 02:11:56 +03:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
files: ["src/lib/*.d.ts"],
|
|
|
|
...tseslint.configs.disableTypeChecked,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
files: ["src/lib/*.d.ts"],
|
|
|
|
languageOptions: {
|
|
|
|
globals: {},
|
|
|
|
},
|
|
|
|
rules: {
|
|
|
|
"@typescript-eslint/interface-name-prefix": "off",
|
|
|
|
"@typescript-eslint/prefer-function-type": "off",
|
|
|
|
"@typescript-eslint/unified-signatures": "off",
|
2024-08-13 03:13:24 +03:00
|
|
|
"@typescript-eslint/no-unsafe-function-type": "off",
|
|
|
|
"@typescript-eslint/no-wrapper-object-types": "off",
|
2024-06-28 02:11:56 +03:00
|
|
|
"@typescript-eslint/no-unused-vars": "off",
|
|
|
|
|
|
|
|
// scripts/eslint/rules
|
|
|
|
"local/no-keywords": "off",
|
|
|
|
|
|
|
|
// eslint
|
|
|
|
"no-var": "off",
|
|
|
|
"no-restricted-globals": "off",
|
|
|
|
"no-shadow-restricted-names": "off",
|
|
|
|
"no-restricted-syntax": "off",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
files: ["src/lib/es2019.array.d.ts"],
|
|
|
|
rules: {
|
|
|
|
"@typescript-eslint/array-type": "off",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
);
|