eslint-config-decent
Version:
A decent ESLint configuration
948 lines (930 loc) • 26.8 kB
JavaScript
import eslint from '@eslint/js';
import { defineConfig } from 'eslint/config';
import prettier from 'eslint-plugin-prettier/recommended';
import globals from 'globals';
import tsEslint from 'typescript-eslint';
import { existsSync, lstatSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { fixupPluginRules } from '@eslint/compat';
import importPlugin from 'eslint-plugin-import-x';
import jsdoc from 'eslint-plugin-jsdoc';
import nextJs from '@next/eslint-plugin-next';
import promise from 'eslint-plugin-promise';
import a11y from 'eslint-plugin-jsx-a11y';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import security from 'eslint-plugin-security';
import stylistic from '@stylistic/eslint-plugin';
import testingLibrary from 'eslint-plugin-testing-library';
import unicorn from 'eslint-plugin-unicorn';
import vitest from '@vitest/eslint-plugin';
const base$c = {
rules: {
"array-callback-return": ["error", { allowImplicit: true }],
"block-scoped-var": "error",
"callback-return": "off",
"class-methods-use-this": "off",
"default-case": ["error", { commentPattern: "^no default$" }],
"default-case-last": "error",
eqeqeq: ["error", "smart"],
"func-names": "error",
"func-style": [
"error",
"declaration",
{
allowArrowFunctions: false
}
],
"global-require": "error",
"grouped-accessor-pairs": "error",
"guard-for-in": "error",
"id-length": [
"error",
{
exceptions: ["_", "$", "e", "i", "j", "k", "q", "t", "x", "y"]
}
],
"lines-around-directive": [
"error",
{
before: "always",
after: "always"
}
],
"handle-callback-err": ["error", "^.*err"],
"max-classes-per-file": ["error", 1],
"object-shorthand": [
"error",
"always",
{
ignoreConstructors: false,
avoidQuotes: true,
avoidExplicitReturnArrows: true
}
],
"one-var": ["error", "never"],
"operator-assignment": ["error", "always"],
"no-await-in-loop": "error",
"no-bitwise": "error",
"no-buffer-constructor": "error",
"no-caller": "error",
"no-cond-assign": ["error", "always"],
"no-console": "error",
"no-constructor-return": "error",
"no-else-return": ["error", { allowElseIf: false }],
"no-empty-static-block": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-label": "error",
"no-inner-declarations": "error",
"no-iterator": "error",
"no-label-var": "error",
"no-labels": ["error", { allowLoop: false, allowSwitch: false }],
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-multi-assign": ["error"],
"no-multi-str": "error",
"no-negated-condition": "error",
"no-nested-ternary": "error",
"no-new-object": "error",
"no-new-require": "error",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-path-concat": "error",
"no-promise-executor-return": "error",
"no-proto": "error",
"no-restricted-exports": [
"error",
{
restrictedNamedExports: [
"default",
// use `export default` to provide a default export
"then"
// this will cause tons of confusion when your module is dynamically `import()`ed, and will break in most node ESM versions
]
}
],
"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"
}
],
"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."
}
],
"no-restricted-syntax": ["error", "DebuggerStatement", "LabeledStatement", "WithStatement"],
"no-return-assign": ["error", "always"],
"no-self-compare": "error",
"no-sequences": "error",
"no-script-url": "error",
"no-template-curly-in-string": "error",
"no-undef-init": "error",
"no-unneeded-ternary": ["error", { defaultAssignment: false }],
"no-unreachable-loop": [
"error",
{
ignore: []
// WhileStatement, DoWhileStatement, ForStatement, ForInStatement, ForOfStatement
}
],
"no-unused-expressions": [
"error",
{
allowShortCircuit: false,
allowTernary: false,
allowTaggedTemplates: false
}
],
"no-useless-computed-key": "error",
"no-useless-concat": "error",
"no-useless-rename": "error",
"no-useless-return": "error",
"prefer-const": [
"error",
{
destructuring: "any",
ignoreReadBeforeAssign: true
}
],
"prefer-exponentiation-operator": "off",
"prefer-numeric-literals": "error",
"prefer-object-spread": "error",
"prefer-regex-literals": [
"error",
{
disallowRedundantWrapping: true
}
],
"prefer-template": "error",
"sort-imports": [
"error",
{
ignoreCase: true,
ignoreDeclarationSort: true,
allowSeparatedGroups: true
}
],
"symbol-description": "error",
"unicode-bom": ["error", "never"],
"vars-on-top": "error",
yoda: "error"
}
};
const cjsAndEsm = {
rules: {
curly: ["error", "multi-line"],
"dot-notation": ["error", { allowKeywords: true }],
"getter-return": ["error", { allowImplicit: true }],
"no-array-constructor": "error",
"no-empty-function": [
"error",
{
allow: ["arrowFunctions", "functions", "methods"]
}
],
"no-new-func": "error",
"no-new-symbol": "error",
"no-return-await": "error",
"no-shadow": "error",
"no-undef": "error",
"no-unexpected-multiline": "error",
"no-use-before-define": ["error", { functions: true, classes: true, variables: true }],
"no-useless-constructor": "error",
"no-var": "error",
"prefer-arrow-callback": [
"error",
{
allowNamedFunctions: false,
allowUnboundThis: true
}
],
"prefer-promise-reject-errors": ["error", { allowEmptyReject: true }]
}
};
const cjs = {
rules: {
strict: ["error", "global"]
}
};
const configs$c = {
base: base$c,
cjsAndEsm,
cjs
};
const requireExtensionRule = {
meta: {
type: "suggestion",
docs: {
description: "Ensure import and export statements include a file extension",
url: "https://github.com/jgeurts/eslint-config-decent/tree/main/src/rules/requireExtensionRule.ts"
},
fixable: "code",
schema: [],
messages: {
requireExtension: "Relative imports and exports must include a file extension."
}
},
create(context) {
function checkSource(source) {
if (source?.type !== "Literal" || typeof source.value !== "string") {
return;
}
const importPath = source.value;
if (!importPath || !importPath.startsWith(".") || importPath.endsWith(".js")) {
return;
}
const resolvedPath = resolve(dirname(context.filename), importPath);
if (!existsSync(resolvedPath)) {
context.report({
node: source,
messageId: "requireExtension",
fix(fixer) {
const fixedPath = `${importPath}.js`;
return fixer.replaceText(source, `'${fixedPath}'`);
}
});
}
}
return {
ImportDeclaration(node) {
if (node.type === "ImportDeclaration") {
checkSource(node.source);
}
},
ExportNamedDeclaration(node) {
if (node.type === "ExportNamedDeclaration" && node.source) {
checkSource(node.source);
}
},
ExportAllDeclaration(node) {
if (node.type === "ExportAllDeclaration") {
checkSource(node.source);
}
}
};
}
};
const requireIndexRule = {
meta: {
type: "suggestion",
docs: {
description: "Ensure directory import and export statements use index.js",
url: "https://github.com/jgeurts/eslint-config-decent/tree/main/src/rules/requireIndexRule.ts"
},
fixable: "code",
schema: [],
messages: {
requireIndex: "Directory imports and exports must use index.js."
}
},
create(context) {
function checkSource(source) {
if (source?.type !== "Literal" || typeof source.value !== "string") {
return;
}
const importPath = source.value;
const resolvedPath = resolve(dirname(context.filename), importPath);
const isDirectory = existsSync(resolvedPath) && lstatSync(resolvedPath).isDirectory();
if (isDirectory) {
context.report({
node: source,
messageId: "requireIndex",
fix(fixer) {
const fixedPath = importPath.replace(/\/?$/, "/index.js");
return fixer.replaceText(source, `'${fixedPath}'`);
}
});
}
}
return {
ImportDeclaration(node) {
if (node.type === "ImportDeclaration") {
checkSource(node.source);
}
},
ExportNamedDeclaration(node) {
if (node.type === "ExportNamedDeclaration" && node.source) {
checkSource(node.source);
}
},
ExportAllDeclaration(node) {
if (node.type === "ExportAllDeclaration") {
checkSource(node.source);
}
}
};
}
};
const decentExtensionPlugin = {
meta: {
name: "decent-extension",
version: "1.0.0"
},
rules: {
"require-extension": requireExtensionRule,
"require-index": requireIndexRule
}
};
const base$b = {
plugins: {
"decent-extension": decentExtensionPlugin
},
rules: {
"decent-extension/require-extension": "error",
"decent-extension/require-index": "error"
}
};
const configs$b = {
base: base$b
};
const base$a = {
plugins: {
import: fixupPluginRules(importPlugin)
},
rules: {
"import/consistent-type-specifier-style": ["error", "prefer-inline"],
"import/first": "error",
"import/newline-after-import": "error",
"import/no-duplicates": "error",
"import/order": [
"error",
{
"newlines-between": "always",
alphabetize: { order: "asc", caseInsensitive: true },
pathGroupsExcludedImportTypes: ["builtin"],
groups: ["builtin", "external", "internal", "parent", "sibling", "index"]
}
]
}
};
const configs$a = {
base: base$a
};
const base$9 = {
settings: {
jsdoc: {
preferredTypes: {
Array: "Array<object>",
"Array.": "Array<object>",
"Array<>": "[]",
"Array.<>": "[]",
"Promise.<>": "Promise<>"
}
}
},
plugins: {
jsdoc
},
rules: {
...jsdoc.configs["flat/recommended"].rules,
"jsdoc/check-alignment": "error",
"jsdoc/check-indentation": "error",
"jsdoc/check-param-names": "off",
"jsdoc/check-tag-names": "error",
"jsdoc/check-types": "error",
"jsdoc/require-description": "off",
"jsdoc/require-description-complete-sentence": "off",
"jsdoc/require-example": "off",
"jsdoc/require-hyphen-before-param-description": "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-jsdoc": "off",
"jsdoc/require-returns-type": "off",
"jsdoc/valid-types": "error"
}
};
const configs$9 = {
base: base$9
};
const recommendedRules = {};
for (const ruleName of Object.keys({ ...nextJs.configs.recommended.rules })) {
recommendedRules[ruleName] = "error";
}
const base$8 = {
plugins: {
"@next/next": fixupPluginRules(nextJs)
},
rules: {
...recommendedRules
}
};
const configs$8 = {
base: base$8
};
const base$7 = {
plugins: {
promise
},
rules: {
"promise/always-return": "error",
"promise/always-catch": "off",
"promise/catch-or-return": [
"error",
{
allowThen: true
}
],
"promise/no-native": "off",
"promise/param-names": "error"
}
};
const configs$7 = {
base: base$7
};
const base$6 = {
settings: {
react: {
version: "detect",
runtime: "automatic"
}
},
languageOptions: {
...react.configs["jsx-runtime"].languageOptions
},
plugins: {
"jsx-a11y": a11y,
react: fixupPluginRules(react),
"react-hooks": reactHooks
},
rules: {
...a11y.configs.recommended.rules,
"jsx-a11y/aria-proptypes": "error",
"jsx-a11y/aria-role": ["error", { ignoreNonDOM: true }],
"jsx-a11y/aria-unsupported-elements": "error",
"jsx-a11y/role-has-required-aria-props": "error",
...react.configs.recommended.rules,
...react.configs["jsx-runtime"].rules,
"react/default-props-match-prop-types": "error",
"react/display-name": ["error", { ignoreTranspilerName: false }],
"react/forbid-foreign-prop-types": ["error", { allowInPropTypes: true }],
"react/iframe-missing-sandbox": "warn",
"react/jsx-closing-bracket-location": "error",
"react/jsx-fragments": "error",
"react/jsx-no-leaked-render": ["error", { validStrategies: ["ternary"] }],
"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/jsx-props-no-multi-spaces": "error",
"react/no-access-state-in-setstate": "error",
"react/no-arrow-function-lifecycle": "error",
"react/no-danger-with-children": "error",
"react/no-deprecated": "error",
"react/no-did-mount-set-state": "error",
"react/no-did-update-set-state": "error",
"react/no-direct-mutation-state": "error",
"react/no-invalid-html-attribute": "error",
"react/no-namespace": "error",
"react/no-redundant-should-component-update": "error",
"react/no-this-in-sfc": "error",
"react/no-typos": "error",
"react/no-unsafe": "error",
"react/no-unstable-nested-components": "error",
"react/no-unused-class-component-methods": "error",
"react/no-unused-prop-types": "error",
"react/no-unused-state": "error",
"react/no-will-update-set-state": "error",
"react/prefer-stateless-function": "error",
"react/require-render-return": "error",
"react/self-closing-comp": "error",
"react/style-prop-object": "error",
...reactHooks.configs.flat["recommended-latest"].rules,
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "error"
}
};
const configs$6 = {
base: base$6
};
const base$5 = {
plugins: {
security
},
rules: {
"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 configs$5 = {
base: base$5
};
const baseStylistic = stylistic.configs.customize({
braceStyle: "1tbs",
jsx: true
});
const base$4 = {
...baseStylistic,
rules: {
...stylistic.configs["disable-legacy"].rules,
...baseStylistic.rules,
"@stylistic/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 configs$4 = {
base: base$4
};
const base$3 = {
plugins: {
"testing-library": fixupPluginRules(testingLibrary)
},
rules: {
...testingLibrary.configs["flat/react"].rules,
"testing-library/no-debugging-utils": "error",
"testing-library/prefer-explicit-assert": "warn",
"testing-library/prefer-implicit-assert": "error",
"testing-library/prefer-query-matchers": "off"
}
};
const configs$3 = {
base: base$3
};
const base$2 = {
rules: {
"no-loss-of-precision": "off",
"no-loop-func": "off",
"no-return-await": "off",
"no-unused-expressions": "off",
"no-use-before-defined": "off",
"@typescript-eslint/array-type": [
"error",
{
default: "array"
}
],
"@typescript-eslint/consistent-type-imports": ["error", { prefer: "type-imports", fixStyle: "inline-type-imports" }],
"@typescript-eslint/ban-ts-comment": [
"error",
{
minimumDescriptionLength: 10,
"ts-expect-error": {
descriptionFormat: "^ - [^ ].*$"
}
}
],
"@typescript-eslint/default-param-last": "error",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-member-accessibility": "error",
"@typescript-eslint/naming-convention": [
"error",
{
selector: "enumMember",
format: ["camelCase", "PascalCase", "UPPER_CASE"],
trailingUnderscore: "forbid"
}
],
"@typescript-eslint/no-dupe-class-members": "error",
"@typescript-eslint/no-loop-func": "error",
"@typescript-eslint/no-redeclare": "error",
"@typescript-eslint/member-ordering": [
"error",
{
default: [
"signature",
"private-field",
"public-field",
"protected-field",
"public-constructor",
"protected-constructor",
"private-constructor",
"public-method",
"protected-method",
"private-method"
]
}
],
"@typescript-eslint/only-throw-error": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-extra-semi": "error",
"@typescript-eslint/no-shadow": "error",
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
"@typescript-eslint/parameter-properties": [
"error",
{
allow: ["readonly"]
}
],
"@typescript-eslint/restrict-template-expressions": ["error", { allowNumber: true }],
"@typescript-eslint/return-await": "error",
"@typescript-eslint/sort-type-constituents": "error",
"@typescript-eslint/use-unknown-in-catch-callback-variable": "off"
}
};
const configs$2 = {
base: base$2
};
const base$1 = {
plugins: {
unicorn
},
rules: {
"unicorn/better-regex": "error",
"unicorn/custom-error-definition": "error",
"unicorn/no-array-method-this-argument": "error",
"unicorn/no-for-loop": "error",
"unicorn/prefer-array-find": "error",
"unicorn/prefer-node-protocol": "error",
"unicorn/prefer-object-from-entries": "error",
"unicorn/prefer-set-has": "error"
}
};
const configs$1 = {
base: base$1
};
const base = {
plugins: {
vitest
},
rules: {
...vitest.configs.recommended.rules,
"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/padding-around-after-all-blocks": "error",
"vitest/padding-around-after-each-blocks": "error",
"vitest/padding-around-describe-blocks": "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-snapshot-hint": "error",
"vitest/prefer-spy-on": "error",
"vitest/prefer-strict-equal": "error",
"vitest/prefer-vi-mocked": "error",
"vitest/require-to-throw-message": "error",
"vitest/require-top-level-describe": "error"
}
};
const configs = {
base
};
function tsEslintConfig(options) {
return decentConfig(options);
}
function decentConfig(options) {
const enableRequireExtensionRule = options?.enableRequireExtensionRule ?? true;
const enableVitest = options?.enableVitest ?? true;
const enableReact = options?.enableReact ?? true;
const enableNextJs = options?.enableNextJs ?? false;
const enableTestingLibrary = options?.enableTestingLibrary ?? true;
const languageOptions = {
globals: {
...globals.node
},
parserOptions: {
projectService: {
defaultProject: "tsconfig.json"
},
tsconfigRootDir: options?.tsconfigRootDir ?? import.meta.dirname,
...options?.parserOptions
}
};
return [
{
ignores: ["**/dist/**", "**/node_modules/**"]
},
eslint.configs.recommended,
{
languageOptions: {
...tsEslint.configs.base.languageOptions
}
},
{
files: ["**/*.ts", "**/*.tsx"],
extends: [...tsEslint.configs.strictTypeChecked, ...tsEslint.configs.stylisticTypeChecked]
},
{
languageOptions,
settings: {
...configs$9.base.settings
}
},
{
name: "eslint-config-decent/base",
files: ["**/*.ts", "**/*.js", "**/*.cjs", "**/*.mjs", "**/*.tsx"],
plugins: {
...configs$b.base.plugins,
...configs$a.base.plugins,
...configs$9.base.plugins,
...configs$7.base.plugins,
...configs$5.base.plugins,
...configs$1.base.plugins
},
rules: {
...configs$c.base.rules,
...enableRequireExtensionRule ? configs$b.base.rules : {},
...configs$a.base.rules,
...configs$9.base.rules,
...configs$7.base.rules,
...configs$5.base.rules,
...configs$1.base.rules
}
},
{
name: "eslint-config-decent/ts",
files: ["**/*.ts", "**/*.tsx"],
...configs$2.base
},
...enableReact ? [
{
name: "eslint-config-decent/tsx",
files: ["**/*.tsx"],
...configs$6.base
},
{
name: "eslint-config-decent/tsx-components",
files: ["**/components/**/*.tsx"],
rules: {
"import/no-default-export": "error",
"unicorn/filename-case": [
"error",
{
case: "pascalCase"
}
]
}
},
{
name: "eslint-config-decent/tsx-disable-ts-rules",
files: ["**/*.tsx"],
rules: {
"@typescript-eslint/explicit-function-return-type": "off"
}
}
] : [],
...enableNextJs ? [
{
name: "eslint-config-decent/nextjs",
files: ["**/*.tsx"],
settings: {
next: {
rootDir: options?.nextJsRootDir
}
},
...configs$8.base
}
] : [],
{
name: "eslint-config-decent/cjs-and-esm",
files: ["**/*.js", "**/*.cjs", "**/*.mjs"],
languageOptions: {
sourceType: "script"
},
...configs$c.cjsAndEsm
},
{
name: "eslint-config-decent/cjs",
files: ["**/*.js", "**/*.cjs"],
languageOptions: {
sourceType: "script"
},
...configs$c.cjs
},
...enableVitest ? [
{
name: "eslint-config-decent/vitest-tests",
files: ["**/__tests__/**/*.ts?(x)", "**/*.{spec,test}.ts?(x)"],
...configs.base
}
] : [],
...enableTestingLibrary ? [
{
name: "eslint-config-decent/testing-library",
files: ["**/__tests__/**/*.ts?(x)", "**/*.{spec,test,tests}.ts?(x)"],
...configs$3.base
}
] : [],
...enableVitest || enableTestingLibrary ? [
{
name: "eslint-config-decent/tests-disable-ts-rules",
files: ["**/__tests__/**/*.ts?(x)", "**/*.{spec,test,tests}.ts?(x)"],
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-confusing-void-expression": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-unsafe-member-access": "off"
}
}
] : [],
{
...configs$4.base,
name: "eslint-config-decent/stylistic",
files: ["**/*.ts", "**/*.js", "**/*.cjs", "**/*.mjs", "**/*.tsx"]
},
{
name: "eslint-config-decent/cjs-and-esm-disable-ts-rules",
files: ["**/*.js", "**/*.cjs", "**/*.mjs"],
extends: [tsEslint.configs.disableTypeChecked]
},
{
...prettier,
rules: {
...prettier.rules,
curly: ["error", "all"],
"prettier/prettier": "error",
"arrow-body-style": "off",
"prefer-arrow-callback": "off"
}
}
];
}
function config(options) {
return defineConfig(...decentConfig(options));
}
export { config, configs$c as eslintConfigs, configs$b as extensionConfigs, configs$a as importConfigs, configs$9 as jsdocConfigs, configs$8 as nextJsConfigs, configs$7 as promiseConfigs, configs$6 as reactConfigs, configs$5 as securityConfigs, configs$3 as testingLibraryConfigs, tsEslintConfig, configs$2 as typescriptEslintConfigs, configs$1 as unicornConfigs, configs as vitestConfigs };