UNPKG

@atomicsmash/coding-standards

Version:

A collection of coding standards configurations.

200 lines (199 loc) 6.43 kB
const OFF = 0; const WARN = 1; const ERROR = 2; import { defineConfig } from "@eslint/config-helpers"; import js from "@eslint/js"; import esLintComments from "@eslint-community/eslint-plugin-eslint-comments/configs"; import importPlugin from "eslint-plugin-import"; import { default as playwrightPlugin } from "eslint-plugin-playwright"; import reactPlugin from "eslint-plugin-react"; import reactHooksPlugin from "eslint-plugin-react-hooks"; import globals from "globals"; import tseslint from "typescript-eslint"; const baseConfig = defineConfig({ name: "@atomicsmash/coding-standards/base-config", files: ["**/*.js", "**/*.cjs", "**/*.mjs"], extends: [ js.configs.recommended, esLintComments.recommended, importPlugin.flatConfigs.recommended, ], languageOptions: { ecmaVersion: 2022, sourceType: "module", globals: { ...globals.browser, ...globals.node, }, }, rules: { "no-case-declarations": [OFF], "import/order": [ ERROR, { alphabetize: { order: "asc", }, groups: [ "type", "builtin", "external", "internal", "parent", ["sibling", "index"], ], "newlines-between": "ignore", pathGroups: [], pathGroupsExcludedImportTypes: [], }, ], "prefer-const": [ERROR], "no-var": [ERROR], "import/no-duplicates": WARN, "@eslint-community/eslint-comments/no-unused-disable": [ERROR], "@eslint-community/eslint-comments/require-description": [ ERROR, { ignore: ["eslint-enable"] }, ], }, settings: { "import/resolver": { typescript: true, // This is needed even for js files because of errors with resolving subpaths. node: true, }, }, }); const typescriptConfig = defineConfig([ { name: "@atomicsmash/coding-standards/typescript-config", files: ["**/*.ts", "**/*.cts", "**/*.mts"], extends: [ baseConfig, tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked, importPlugin.flatConfigs.typescript, ], plugins: { "@typescript-eslint": tseslint.plugin, }, languageOptions: { parser: tseslint.parser, parserOptions: { projectService: true, }, }, rules: { "@typescript-eslint/naming-convention": [ ERROR, { selector: "variableLike", format: ["camelCase", "PascalCase", "UPPER_CASE"], leadingUnderscore: "allow", }, { selector: "function", format: ["camelCase", "PascalCase"] }, { selector: "typeLike", format: ["PascalCase"] }, { selector: "variable", types: ["boolean"], format: ["PascalCase"], prefix: ["is", "should", "has", "can", "did", "will", "are"], leadingUnderscore: "allow", }, ], "@typescript-eslint/consistent-type-definitions": [ERROR, "type"], "@typescript-eslint/non-nullable-type-assertion-style": OFF, "@typescript-eslint/no-unused-vars": [ ERROR, { args: "all", argsIgnorePattern: "^_", caughtErrors: "all", caughtErrorsIgnorePattern: "^_", destructuredArrayIgnorePattern: "^_", varsIgnorePattern: "^_", ignoreRestSiblings: true, }, ], }, settings: { "import/resolver": { typescript: true, node: true, }, }, }, ]); if (reactPlugin.configs.flat.recommended === undefined || reactPlugin.configs.flat["jsx-runtime"] === undefined) { // Throw is needed to fix types correctly // This should never happen so if it does, it's an error worthy of breaking all eslint configs. throw new Error("Failed to get config from eslint-plugin-react."); } const sharedReactRulesAndSettings = { extends: [ reactPlugin.configs.flat.recommended, reactPlugin.configs.flat["jsx-runtime"], reactHooksPlugin.configs.flat.recommended, ], settings: { react: { version: "detect", }, }, rules: { "react-hooks/exhaustive-deps": [ WARN, { additionalHooks: "(useSelect|useSuspenseSelect)", }, ], }, }; const reactConfig = defineConfig([ { name: "@atomicsmash/coding-standards/react-config", files: ["**/*.jsx"], extends: [baseConfig, ...sharedReactRulesAndSettings.extends], settings: { ...sharedReactRulesAndSettings.settings, }, rules: { ...sharedReactRulesAndSettings.rules, }, }, ]); const reactTypescriptConfig = defineConfig([ { name: "@atomicsmash/coding-standards/react-typescript-config", files: ["**/*.tsx"], extends: [typescriptConfig, ...sharedReactRulesAndSettings.extends], settings: { ...sharedReactRulesAndSettings.settings, }, rules: { ...sharedReactRulesAndSettings.rules, }, }, ]); export const playwrightConfig = defineConfig([ { name: "@atomicsmash/coding-standards/playwright-config", extends: [playwrightPlugin.configs["flat/recommended"]], rules: { "playwright/expect-expect": [ ERROR, { assertFunctionNames: [ "playAudit", // This is the lighthouse playwright test, which contains threshold assertions. ], }, ], }, }, ]); export const recommendedConfig = defineConfig([ baseConfig, typescriptConfig, reactConfig, reactTypescriptConfig, ]);