eslint-config-decent
Version:
A decent ESLint configuration
607 lines (605 loc) • 24.7 kB
JavaScript
const VITEST_FILE_GLOBS = ["**/__tests__/**/*.ts", "**/__tests__/**/*.tsx", "**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"];
const TEST_FILE_GLOBS = [...VITEST_FILE_GLOBS, "**/*.tests.ts", "**/*.tests.tsx"];
const eslintBaseRules = {
"eslint/array-callback-return": ["error", { allowImplicit: true }],
"eslint/block-scoped-var": "error",
"eslint/default-case": ["error", { commentPattern: "^no default$" }],
"eslint/default-case-last": "error",
"eslint/eqeqeq": ["error", "smart"],
"eslint/func-names": "error",
"eslint/func-style": ["error", "declaration", { allowArrowFunctions: false }],
"eslint/grouped-accessor-pairs": "error",
"eslint/guard-for-in": "error",
"eslint/id-length": ["error", { exceptions: ["_", "$", "e", "i", "j", "k", "q", "t", "x", "y"] }],
"eslint/max-classes-per-file": ["error", 1],
"eslint/operator-assignment": ["error", "always"],
"eslint/no-await-in-loop": "error",
"eslint/no-bitwise": "error",
"eslint/no-caller": "error",
"eslint/no-cond-assign": ["error", "always"],
"eslint/no-console": "error",
"eslint/no-constructor-return": "error",
"eslint/no-else-return": ["error", { allowElseIf: false }],
"eslint/no-empty-static-block": "error",
"eslint/no-eval": "error",
"eslint/no-extend-native": "error",
"eslint/no-extra-bind": "error",
"eslint/no-extra-label": "error",
"eslint/no-inner-declarations": "error",
"eslint/no-iterator": "error",
"eslint/no-label-var": "error",
"eslint/no-labels": ["error", { allowLoop: false, allowSwitch: false }],
"eslint/no-lone-blocks": "error",
"eslint/no-lonely-if": "error",
"eslint/no-multi-assign": "error",
"eslint/no-multi-str": "error",
"eslint/no-negated-condition": "error",
"eslint/no-nested-ternary": "error",
"eslint/no-new-wrappers": "error",
"eslint/no-promise-executor-return": "error",
"eslint/no-proto": "error",
"eslint/no-restricted-globals": [
"error",
{
name: "isFinite",
message: "Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite"
},
{
name: "isNaN",
message: "Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan"
}
],
"eslint/no-return-assign": ["error", "always"],
"eslint/no-self-compare": "error",
"eslint/no-sequences": "error",
"eslint/no-script-url": "error",
"eslint/no-template-curly-in-string": "error",
"eslint/no-unneeded-ternary": ["error", { defaultAssignment: false }],
"eslint/no-unused-expressions": ["error", { allowShortCircuit: false, allowTernary: false, allowTaggedTemplates: false }],
"eslint/no-useless-computed-key": "error",
"eslint/no-useless-concat": "error",
"eslint/no-useless-rename": "error",
"eslint/no-useless-return": "error",
"eslint/prefer-const": ["error", { destructuring: "any", ignoreReadBeforeAssign: true }],
"eslint/prefer-exponentiation-operator": "off",
"eslint/prefer-numeric-literals": "error",
"eslint/prefer-object-spread": "error",
"eslint/prefer-template": "error",
"eslint/sort-imports": ["error", { ignoreCase: true, ignoreDeclarationSort: true, allowSeparatedGroups: true }],
"eslint/symbol-description": "error",
"eslint/unicode-bom": ["error", "never"],
"eslint/vars-on-top": "error",
"eslint/yoda": "error",
// Node rules (remapped from base eslint)
"node/global-require": "error",
"node/no-new-require": "error",
"node/no-path-concat": "error"
};
const eslintCjsEsmRules = {
"eslint/curly": ["error", "multi-line"],
"eslint/getter-return": ["error", { allowImplicit: true }],
"eslint/no-array-constructor": "error",
"eslint/no-empty-function": ["error", { allow: ["arrowFunctions", "functions", "methods"] }],
"eslint/no-new-func": "error",
"eslint/no-shadow": "error",
"eslint/no-unexpected-multiline": "error",
"eslint/no-use-before-define": ["error", { functions: true, classes: true, variables: true }],
"eslint/no-useless-constructor": "error",
"eslint/no-var": "error",
"eslint/prefer-promise-reject-errors": ["error", { allowEmptyReject: true }]
};
const eslintCompatRules = {
"eslint-compat/object-shorthand": ["error", "always", { ignoreConstructors: false, avoidQuotes: true, avoidExplicitReturnArrows: true }],
"eslint-compat/one-var": ["error", "never"],
"eslint-compat/no-octal-escape": "error",
"eslint-compat/no-restricted-exports": ["error", { restrictedNamedExports: ["default", "then"] }],
"eslint-compat/no-restricted-properties": [
"error",
{ object: "arguments", property: "callee", message: "arguments.callee is deprecated" },
{ property: "__defineGetter__", message: "Please use Object.defineProperty instead." },
{ property: "__defineSetter__", message: "Please use Object.defineProperty instead." }
],
"eslint-compat/no-restricted-syntax": ["error", "DebuggerStatement", "LabeledStatement", "WithStatement"],
"eslint-compat/no-undef-init": "error",
"eslint-compat/no-unreachable-loop": ["error", { ignore: [] }],
"eslint-compat/prefer-regex-literals": ["error", { disallowRedundantWrapping: true }]
};
const typescriptRules = {
// Disable base ESLint rules that TS extends
"eslint/no-loss-of-precision": "off",
"eslint/no-unused-expressions": "off",
"typescript/array-type": ["error", { default: "array" }],
"typescript/await-thenable": "error",
"typescript/ban-ts-comment": ["error", { minimumDescriptionLength: 10, "ts-expect-error": { descriptionFormat: "^ - [^ ].*$" } }],
"typescript/ban-tslint-comment": "error",
"typescript/class-literal-property-style": "error",
"typescript/consistent-generic-constructors": "error",
"typescript/consistent-indexed-object-style": "error",
"typescript/consistent-type-assertions": "error",
"typescript/consistent-type-definitions": "error",
"typescript/consistent-type-imports": ["error", { prefer: "type-imports", fixStyle: "inline-type-imports" }],
"typescript/default-param-last": "error",
"typescript/dot-notation": "error",
"typescript/explicit-function-return-type": "off",
"typescript/no-array-delete": "error",
"typescript/no-base-to-string": "error",
"typescript/no-confusing-non-null-assertion": "error",
"typescript/no-confusing-void-expression": "error",
"typescript/no-deprecated": "off",
"typescript/no-dupe-class-members": "error",
"typescript/no-duplicate-enum-values": "error",
"typescript/no-duplicate-type-constituents": "error",
"typescript/no-dynamic-delete": "error",
"typescript/no-empty-interface": "error",
"typescript/no-empty-object-type": "error",
"typescript/no-explicit-any": "error",
"typescript/no-extra-non-null-assertion": "error",
"typescript/no-extraneous-class": "error",
"typescript/no-floating-promises": "error",
"typescript/no-for-in-array": "error",
"typescript/no-implied-eval": "error",
"typescript/no-inferrable-types": "error",
"typescript/no-invalid-void-type": "error",
"typescript/no-loop-func": "error",
"typescript/no-meaningless-void-operator": "error",
"typescript/no-misused-new": "error",
"typescript/no-misused-promises": "error",
"typescript/no-mixed-enums": "error",
"typescript/no-namespace": "error",
"typescript/no-non-null-asserted-nullish-coalescing": "error",
"typescript/no-non-null-asserted-optional-chain": "error",
"typescript/no-non-null-assertion": "error",
"typescript/no-redeclare": "error",
"typescript/no-redundant-type-constituents": "error",
"typescript/no-require-imports": "error",
"typescript/no-shadow": "error",
"typescript/no-this-alias": "error",
"typescript/no-unnecessary-boolean-literal-compare": "error",
"typescript/no-unnecessary-condition": "error",
"typescript/no-unnecessary-template-expression": "error",
"typescript/no-unnecessary-type-arguments": "error",
"typescript/no-unnecessary-type-assertion": "error",
"typescript/no-unnecessary-type-constraint": "error",
"typescript/no-unnecessary-type-parameters": "error",
"typescript/no-unsafe-argument": "error",
"typescript/no-unsafe-assignment": "error",
"typescript/no-unsafe-call": "error",
"typescript/no-unsafe-declaration-merging": "error",
"typescript/no-unsafe-enum-comparison": "error",
"typescript/no-unsafe-function-type": "error",
"typescript/no-unsafe-member-access": "error",
"typescript/no-unsafe-return": "error",
"typescript/no-unsafe-unary-minus": "error",
"typescript/no-useless-empty-export": "error",
"typescript/no-wrapper-object-types": "error",
"typescript/non-nullable-type-assertion-style": "error",
"typescript/only-throw-error": "error",
"typescript/parameter-properties": ["error", { allow: ["readonly"] }],
"typescript/prefer-as-const": "error",
"typescript/prefer-find": "error",
"typescript/prefer-for-of": "error",
"typescript/prefer-function-type": "error",
"typescript/prefer-includes": "error",
"typescript/prefer-literal-enum-member": "error",
"typescript/prefer-namespace-keyword": "error",
"typescript/prefer-nullish-coalescing": "error",
"typescript/prefer-optional-chain": "error",
"typescript/prefer-promise-reject-errors": "error",
"typescript/prefer-reduce-type-parameter": "error",
"typescript/prefer-regexp-exec": "error",
"typescript/prefer-return-this-type": "error",
"typescript/prefer-string-starts-ends-with": "error",
"typescript/prefer-ts-expect-error": "error",
"typescript/require-await": "error",
"typescript/restrict-plus-operands": "error",
"typescript/restrict-template-expressions": ["error", { allowNumber: true }],
"typescript/return-await": "error",
"typescript/switch-exhaustiveness-check": "error",
"typescript/triple-slash-reference": "error",
"typescript/unbound-method": "error",
"typescript/unified-signatures": "error",
"typescript/use-unknown-in-catch-callback-variable": "off"
};
const typescriptCompatRules = {
"typescript-compat/explicit-member-accessibility": "error",
"typescript-compat/member-ordering": [
"error",
{
default: [
"signature",
"private-field",
"public-field",
"protected-field",
"public-constructor",
"protected-constructor",
"private-constructor",
"public-method",
"protected-method",
"private-method"
]
}
]
};
const importRules = {
"import/consistent-type-specifier-style": ["error", "prefer-inline"],
"import/first": "error",
"import/no-duplicates": "error"
};
const unicornRules = {
"unicorn/no-array-method-this-argument": "error",
"unicorn/prefer-array-find": "error",
"unicorn/prefer-node-protocol": "error",
"unicorn/prefer-object-from-entries": "error",
"unicorn/prefer-set-has": "error"
};
const unicornCompatRules = {
"unicorn-compat/better-regex": "error",
"unicorn-compat/custom-error-definition": "error",
"unicorn-compat/no-for-loop": "error"
};
const promiseRules = {
"promise/always-return": "error",
"promise/catch-or-return": ["error", { allowThen: true }],
"promise/param-names": "error"
};
const jsdocRules = {
// Explicitly configured
"jsdoc/check-tag-names": "error",
"jsdoc/require-param": ["error", { enableFixer: false, ignoreWhenAllParamsMissing: true, unnamedRootBase: ["args"] }],
"jsdoc/require-param-description": "off",
"jsdoc/require-param-name": "error",
"jsdoc/require-param-type": "error",
"jsdoc/require-returns-description": "off",
"jsdoc/require-returns-type": "off",
// From flat/recommended inheritance
"jsdoc/check-access": "error",
"jsdoc/check-property-names": "error",
"jsdoc/empty-tags": "error",
"jsdoc/implements-on-classes": "error",
"jsdoc/no-defaults": "error",
"jsdoc/require-property": "error",
"jsdoc/require-property-description": "error",
"jsdoc/require-property-name": "error",
"jsdoc/require-property-type": "error",
"jsdoc/require-returns": "error",
"jsdoc/require-yields": "error"
};
const jsdocCompatRules = {
"jsdoc-compat/check-alignment": "error",
"jsdoc-compat/check-indentation": "error",
"jsdoc-compat/check-types": "error",
"jsdoc-compat/require-hyphen-before-param-description": "error",
"jsdoc-compat/require-returns-check": "error",
"jsdoc-compat/require-yields-check": "error",
"jsdoc-compat/tag-lines": "error",
"jsdoc-compat/valid-types": "error"
};
const stylisticCompatRules = {
"stylistic-compat/padding-line-between-statements": [
"error",
{
blankLine: "always",
prev: ["directive", "block", "block-like", "multiline-block-like", "cjs-export", "cjs-import", "class", "export", "import", "if"],
next: "*"
},
{
blankLine: "never",
prev: "directive",
next: "directive"
},
{
blankLine: "any",
prev: "*",
next: ["if", "for", "cjs-import", "import"]
},
{
blankLine: "any",
prev: ["export", "import"],
next: ["export", "import"]
},
{
blankLine: "always",
prev: "*",
next: ["try", "function", "switch"]
},
{
blankLine: "always",
prev: "if",
next: "if"
},
{
blankLine: "never",
prev: ["return", "throw"],
next: "*"
}
]
};
const securityRules = {
"security/detect-buffer-noassert": "error",
"security/detect-child-process": "error",
"security/detect-disable-mustache-escape": "error",
"security/detect-eval-with-expression": "error",
"security/detect-new-buffer": "error",
"security/detect-no-csrf-before-method-override": "error",
"security/detect-non-literal-fs-filename": "error",
"security/detect-non-literal-regexp": "error",
"security/detect-non-literal-require": "error",
"security/detect-object-injection": "off",
"security/detect-possible-timing-attacks": "error",
"security/detect-pseudoRandomBytes": "error",
"security/detect-unsafe-regex": "error"
};
const reactRules = {
// From react.configs.recommended
"react/jsx-key": "error",
"react/jsx-no-comment-textnodes": "error",
"react/jsx-no-duplicate-props": "error",
"react/no-children-prop": "error",
"react/no-find-dom-node": "error",
"react/no-render-return-value": "error",
"react/no-string-refs": "error",
"react/no-unescaped-entities": "error",
"react/no-unknown-property": "error",
// Explicitly configured rules with native oxlint equivalents
"react/display-name": ["error", { ignoreTranspilerName: false }],
"react/iframe-missing-sandbox": "warn",
"react/jsx-fragments": "error",
"react/jsx-no-script-url": "error",
"react/jsx-no-target-blank": "error",
"react/jsx-no-undef": "error",
"react/jsx-no-useless-fragment": "error",
"react/jsx-pascal-case": ["error", { allowAllCaps: true, ignore: [] }],
"react/no-danger-with-children": "error",
"react/no-did-mount-set-state": "error",
"react/no-direct-mutation-state": "error",
"react/no-namespace": "error",
"react/no-redundant-should-component-update": "error",
"react/no-this-in-sfc": "error",
"react/no-unsafe": "error",
"react/no-will-update-set-state": "error",
"react/require-render-return": "error",
"react/self-closing-comp": "error",
"react/style-prop-object": "error",
// React hooks (prefix changes from react-hooks/ to react/ in oxlint)
"react/rules-of-hooks": "error",
"react/exhaustive-deps": "error"
};
const reactCompatRules = {
"react-compat/default-props-match-prop-types": "error",
"react-compat/forbid-foreign-prop-types": ["error", { allowInPropTypes: true }],
"react-compat/jsx-no-leaked-render": ["error", { validStrategies: ["ternary"] }],
"react-compat/no-access-state-in-setstate": "error",
"react-compat/no-arrow-function-lifecycle": "error",
"react-compat/no-deprecated": "error",
"react-compat/no-did-update-set-state": "error",
"react-compat/no-invalid-html-attribute": "error",
"react-compat/no-typos": "error",
"react-compat/no-unstable-nested-components": "error",
"react-compat/no-unused-class-component-methods": "error",
"react-compat/no-unused-prop-types": "error",
"react-compat/no-unused-state": "error",
"react-compat/prefer-stateless-function": "error"
// Formatting rules excluded: jsx-closing-bracket-location, jsx-props-no-multi-spaces
};
const jsxA11yRules = {
"jsx-a11y/alt-text": "error",
"jsx-a11y/anchor-has-content": "error",
"jsx-a11y/anchor-is-valid": "error",
"jsx-a11y/aria-activedescendant-has-tabindex": "error",
"jsx-a11y/aria-props": "error",
"jsx-a11y/aria-proptypes": "error",
"jsx-a11y/aria-role": ["error", { ignoreNonDOM: true }],
"jsx-a11y/aria-unsupported-elements": "error",
"jsx-a11y/autocomplete-valid": "error",
"jsx-a11y/click-events-have-key-events": "error",
"jsx-a11y/heading-has-content": "error",
"jsx-a11y/html-has-lang": "error",
"jsx-a11y/iframe-has-title": "error",
"jsx-a11y/img-redundant-alt": "error",
"jsx-a11y/label-has-associated-control": "error",
"jsx-a11y/lang": "error",
"jsx-a11y/media-has-caption": "error",
"jsx-a11y/mouse-events-have-key-events": "error",
"jsx-a11y/no-access-key": "error",
"jsx-a11y/no-aria-hidden-on-focusable": "error",
"jsx-a11y/no-autofocus": "error",
"jsx-a11y/no-distracting-elements": "error",
"jsx-a11y/no-noninteractive-tabindex": "error",
"jsx-a11y/no-redundant-roles": "error",
"jsx-a11y/no-static-element-interactions": "error",
"jsx-a11y/role-has-required-aria-props": "error",
"jsx-a11y/role-supports-aria-props": "error",
"jsx-a11y/scope": "error",
"jsx-a11y/tabindex-no-positive": "error"
};
const nextjsRules = {
"nextjs/google-font-display": "error",
"nextjs/google-font-preconnect": "error",
"nextjs/inline-script-id": "error",
"nextjs/next-script-for-ga": "error",
"nextjs/no-assign-module-variable": "error",
"nextjs/no-async-client-component": "error",
"nextjs/no-before-interactive-script-outside-document": "error",
"nextjs/no-css-tags": "error",
"nextjs/no-document-import-in-page": "error",
"nextjs/no-duplicate-head": "error",
"nextjs/no-head-element": "error",
"nextjs/no-head-import-in-document": "error",
"nextjs/no-html-link-for-pages": "error",
"nextjs/no-img-element": "error",
"nextjs/no-page-custom-font": "error",
"nextjs/no-script-component-in-head": "error",
"nextjs/no-styled-jsx-in-document": "error",
"nextjs/no-sync-scripts": "error",
"nextjs/no-title-in-document-head": "error",
"nextjs/no-typos": "error",
"nextjs/no-unwanted-polyfillio": "error"
};
const vitestRules = {
// From vitest.configs.recommended
"vitest/expect-expect": "error",
"vitest/no-identical-title": "error",
"vitest/no-commented-out-tests": "error",
"vitest/valid-title": "error",
"vitest/valid-expect": "error",
"vitest/valid-describe-callback": "error",
"vitest/no-import-node-test": "error",
// Explicitly configured
"vitest/consistent-test-it": ["error", { fn: "it", withinDescribe: "it" }],
"vitest/no-conditional-tests": "error",
"vitest/no-disabled-tests": "error",
"vitest/no-duplicate-hooks": "error",
"vitest/no-focused-tests": "error",
"vitest/no-standalone-expect": "error",
"vitest/no-test-prefixes": "error",
"vitest/prefer-comparison-matcher": "error",
"vitest/prefer-equality-matcher": "error",
"vitest/prefer-hooks-in-order": "error",
"vitest/prefer-hooks-on-top": "error",
"vitest/prefer-lowercase-title": ["error", { ignore: ["describe"] }],
"vitest/prefer-mock-promise-shorthand": "error",
"vitest/prefer-spy-on": "error",
"vitest/prefer-strict-equal": "error",
"vitest/require-to-throw-message": "error",
"vitest/require-top-level-describe": "error"
};
const vitestCompatRules = {
"vitest-compat/padding-around-after-all-blocks": "error",
"vitest-compat/padding-around-after-each-blocks": "error",
"vitest-compat/padding-around-describe-blocks": "error",
"vitest-compat/prefer-snapshot-hint": "error",
"vitest-compat/prefer-vi-mocked": "error"
};
const testingLibraryRules = {
"testing-library/await-async-events": ["error", { eventModule: "userEvent" }],
"testing-library/await-async-queries": "error",
"testing-library/await-async-utils": "error",
"testing-library/no-await-sync-events": ["error", { eventModules: ["fire-event"] }],
"testing-library/no-await-sync-queries": "error",
"testing-library/no-container": "error",
"testing-library/no-debugging-utils": "error",
"testing-library/no-dom-import": ["error", "react"],
"testing-library/no-global-regexp-flag-in-query": "error",
"testing-library/no-manual-cleanup": "error",
"testing-library/no-node-access": "error",
"testing-library/no-promise-in-fire-event": "error",
"testing-library/no-render-in-lifecycle": "error",
"testing-library/no-unnecessary-act": "error",
"testing-library/no-wait-for-multiple-assertions": "error",
"testing-library/no-wait-for-side-effects": "error",
"testing-library/no-wait-for-snapshot": "error",
"testing-library/prefer-explicit-assert": "warn",
"testing-library/prefer-find-by": "error",
"testing-library/prefer-implicit-assert": "error",
"testing-library/prefer-presence-queries": "error",
"testing-library/prefer-query-by-disappearance": "error",
"testing-library/prefer-query-matchers": "off",
"testing-library/prefer-screen-queries": "error",
"testing-library/render-result-naming-convention": "error"
};
function oxlintConfig(options) {
const enableReact = options?.enableReact ?? true;
const enableVitest = options?.enableVitest ?? true;
const enableNextJs = options?.enableNextJs ?? false;
const enableTestingLibrary = options?.enableTestingLibrary ?? true;
const plugins = [
"eslint",
"typescript",
"unicorn",
"oxc",
"import",
"promise",
"jsdoc",
"node",
...enableReact ? ["react", "jsx-a11y"] : [],
...enableNextJs ? ["nextjs"] : [],
...enableVitest ? ["vitest"] : []
];
const jsPlugins = [
// Standalone JS plugins (no native equivalents)
"eslint-plugin-security",
// -compat JS plugins for gap rules in partially-supported native plugins
{ name: "eslint-compat", specifier: "oxlint-plugin-eslint" },
{ name: "unicorn-compat", specifier: "eslint-plugin-unicorn" },
{ name: "jsdoc-compat", specifier: "eslint-plugin-jsdoc" },
{ name: "typescript-compat", specifier: "@typescript-eslint/eslint-plugin" },
{ name: "stylistic-compat", specifier: "@stylistic/eslint-plugin" },
...enableReact ? [{ name: "react-compat", specifier: "eslint-plugin-react" }] : [],
...enableVitest ? [{ name: "vitest-compat", specifier: "@vitest/eslint-plugin" }] : [],
...enableTestingLibrary ? ["eslint-plugin-testing-library"] : []
];
const settings = {
...enableReact ? { react: { version: options?.reactVersion ?? "19" } } : {},
...enableNextJs && options?.nextJsRootDir ? { next: { rootDir: options.nextJsRootDir } } : {}
};
const rules = {
...eslintBaseRules,
...eslintCjsEsmRules,
...eslintCompatRules,
...typescriptRules,
...importRules,
...unicornRules,
...unicornCompatRules,
...promiseRules,
...jsdocRules,
...jsdocCompatRules,
...stylisticCompatRules,
...securityRules,
...enableReact ? { ...reactRules, ...reactCompatRules, ...jsxA11yRules } : {},
...enableNextJs ? nextjsRules : {}
};
const overrides = [
{
files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
rules: typescriptCompatRules
},
...enableReact ? [
{
files: ["**/*.tsx"],
rules: { "typescript/explicit-function-return-type": "off" }
},
{
files: ["**/components/**/*.tsx"],
rules: {
"import/no-default-export": "error",
"unicorn/filename-case": ["error", { case: "pascalCase" }]
}
}
] : [],
...enableVitest ? [
{
files: VITEST_FILE_GLOBS,
rules: { ...vitestRules, ...vitestCompatRules }
}
] : [],
...enableTestingLibrary ? [
{
files: TEST_FILE_GLOBS,
jsPlugins: ["eslint-plugin-testing-library"],
rules: testingLibraryRules
}
] : [],
...enableVitest || enableTestingLibrary ? [
{
files: TEST_FILE_GLOBS,
rules: {
"typescript/explicit-function-return-type": "off",
"typescript/no-confusing-void-expression": "off",
"typescript/no-non-null-assertion": "off",
"typescript/no-unsafe-member-access": "off"
}
}
] : []
];
return {
plugins,
jsPlugins,
rules,
options: { typeAware: true },
...Object.keys(settings).length > 0 ? { settings } : {},
...overrides.length > 0 ? { overrides } : {},
ignorePatterns: ["**/dist/**", "**/node_modules/**"],
env: { node: true, es6: true }
};
}
export { oxlintConfig };