generated from nhcarrigan/template
feat: migrate to eslint verison 9 (#1)
This is a pretty sizeable change. It also removes all external configuration sets. Every rule is now defined by us. Additionally, this version will conflict with other formatters, and should not be used in tandem with Prettier. Reviewed-on: https://codeberg.org/nhcarrigan/eslint-config/pulls/1 Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com> Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
This commit is contained in:
parent
dea44dbd7f
commit
f13bcd87a9
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
/node_modules/
|
||||
/prod/
|
||||
|
||||
# Ignore packed files so that npm pack can be run locally
|
||||
*.tgz
|
@ -1,8 +1,7 @@
|
||||
test.js
|
||||
/.github/
|
||||
.prettierrc.json
|
||||
.gitattributes
|
||||
renovate.json
|
||||
/src/
|
||||
|
||||
# Ignore packed files so that npm pack can be run locally
|
||||
*.tgz
|
||||
|
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"eslint.validate": ["typescript"]
|
||||
}
|
65
README.md
65
README.md
@ -16,24 +16,81 @@ npm i @nhcarrigan/eslint-config eslint
|
||||
|
||||
## Compatibility
|
||||
|
||||
This package is compatible with ESLint 8.
|
||||
This package is compatible with ESLint 9.
|
||||
|
||||
## Usage
|
||||
|
||||
To use this package, add the following to your `.eslintrc.json` file:
|
||||
To use this package, add the following to your `eslint.config.js` file:
|
||||
|
||||
```js
|
||||
import NaomisConfig from "@nhcarrigan/eslint-config";
|
||||
|
||||
export default [
|
||||
...NaomisConfig,
|
||||
// Any overrides you need, such as:
|
||||
// {
|
||||
// rules: {
|
||||
// complexity: "off",
|
||||
// "max-lines-per-function": "off",
|
||||
// "max-statements": "off",
|
||||
// "jsdoc/require-file-overview": "off"
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// files: ["test/__mocks__/Database.mock.ts"],
|
||||
// rules: {
|
||||
// "require-await": "off"
|
||||
// }
|
||||
// },
|
||||
];
|
||||
```
|
||||
|
||||
Then set up these two scripts in your `package.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "@nhcarrigan/eslint-config"
|
||||
"format": "eslint src test --max-warnings 0 --fix",
|
||||
"lint": "eslint src test --max-warnings 0",
|
||||
}
|
||||
```
|
||||
|
||||
## Warnings and Errors
|
||||
### Formatting
|
||||
|
||||
Our rulesets include the `stylistic` package, which enforces quite a bit of specific formatting. With this being the case, projects should NOT use Prettier in tandem with this config.
|
||||
|
||||
Instead, set your editor to run the ESLint formatter on save. For example, in VSCodium, you can add a `.vscode/settings.json` file to your project:
|
||||
|
||||
```json
|
||||
{
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"eslint.validate": ["typescript"]
|
||||
}
|
||||
```
|
||||
|
||||
## Stylistic Standards
|
||||
|
||||
This configuration does not extend or incorporate any external rulesets. Every rule this config sets has been added deliberately and with reason.
|
||||
|
||||
### Warnings and Errors
|
||||
|
||||
A rule is set to be a warning when it is something that is okay during development (e.g. using a `console.log`, or not having a JSDoc definition yet) but should not make it to production code.
|
||||
|
||||
A rule is set to an error when it is something that should not occur in development or production (e.g. missing semi-colons, using loose equality).
|
||||
|
||||
### No Deactivated Rules
|
||||
|
||||
Because this config is built from scratch, there is no need to explicitly deactivate any rules. Everything is "off" by default, and turned on as desired by this package.
|
||||
|
||||
The tests will not allow you to explicitly disable rules.
|
||||
|
||||
The only exception is the `disabledEslintRules` object, which explicitly turns off built-in ESLint rules to avoid conflicts with external packages like `@typescript-eslint`.
|
||||
|
||||
### Proposing Style Changes
|
||||
|
||||
All style changes should be proposed in our [chat server](https://chat.nhcarrigan.com).
|
||||
|
||||
## Feedback and Bugs
|
||||
|
||||
If you have feedback or a bug report, please feel free to open a GitHub issue!
|
||||
|
14
eslint.config.js
Normal file
14
eslint.config.js
Normal file
@ -0,0 +1,14 @@
|
||||
import naomisRules from "./prod/index.js";
|
||||
|
||||
export default [
|
||||
...naomisRules,
|
||||
{
|
||||
rules: {
|
||||
"@typescript-eslint/naming-convention": "off",
|
||||
"import/no-default-export": "off",
|
||||
"import/namespace": "off",
|
||||
"import/no-deprecated": "off",
|
||||
"@typescript-eslint/consistent-type-assertions": "off"
|
||||
},
|
||||
},
|
||||
];
|
88
index.js
88
index.js
@ -1,88 +0,0 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
es2020: true,
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:jsdoc/recommended",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"plugin:deprecation/recommended",
|
||||
],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
ecmaVersion: 11,
|
||||
sourceType: "module",
|
||||
},
|
||||
plugins: ["@typescript-eslint", "jsdoc", "import", "no-only-tests", "eslint-plugin-deprecation"],
|
||||
rules: {
|
||||
"linebreak-style": ["error", "unix"],
|
||||
quotes: ["error", "double", { allowTemplateLiterals: true }],
|
||||
semi: ["error", "always"],
|
||||
"prefer-const": "warn",
|
||||
eqeqeq: ["error", "always"],
|
||||
curly: ["error"],
|
||||
"require-atomic-updates": ["warn"],
|
||||
"no-var": ["error"],
|
||||
camelcase: ["error"],
|
||||
"comma-dangle": ["error", "never"],
|
||||
"init-declarations": ["error", "always"],
|
||||
"require-await": ["warn"],
|
||||
"no-param-reassign": ["error"],
|
||||
"jsdoc/require-jsdoc": [
|
||||
"warn",
|
||||
{
|
||||
require: {
|
||||
ArrowFunctionExpression: true,
|
||||
ClassDeclaration: true,
|
||||
ClassExpression: true,
|
||||
FunctionDeclaration: true,
|
||||
FunctionExpression: true,
|
||||
MethodDefinition: true,
|
||||
},
|
||||
publicOnly: true,
|
||||
},
|
||||
],
|
||||
"jsdoc/require-description-complete-sentence": "warn",
|
||||
"import/first": "warn",
|
||||
"import/exports-last": "warn",
|
||||
"import/newline-after-import": "warn",
|
||||
"import/order": [
|
||||
"warn",
|
||||
{
|
||||
groups: [
|
||||
"builtin",
|
||||
"external",
|
||||
"internal",
|
||||
"parent",
|
||||
"sibling",
|
||||
"index",
|
||||
"object",
|
||||
"type",
|
||||
"unknown",
|
||||
],
|
||||
"newlines-between": "always",
|
||||
alphabetize: {
|
||||
order: "asc",
|
||||
caseInsensitive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
// This is necessary due to the combination of TS and such
|
||||
"import/no-unresolved": "off",
|
||||
"import/no-self-import": "error",
|
||||
"import/no-anonymous-default-export": "warn",
|
||||
"import/no-useless-path-segments": "warn",
|
||||
"no-only-tests/no-only-tests": [
|
||||
"warn",
|
||||
{
|
||||
block: ["test", "expect", "assert", "describe", "bench"],
|
||||
focus: ["only", "skip"],
|
||||
},
|
||||
],
|
||||
"no-console": "warn",
|
||||
},
|
||||
};
|
40
package.json
40
package.json
@ -1,10 +1,15 @@
|
||||
{
|
||||
"name": "@nhcarrigan/eslint-config",
|
||||
"version": "3.3.3",
|
||||
"version": "4.0.0-rc7",
|
||||
"description": "Global config for ESLint",
|
||||
"main": "index.js",
|
||||
"main": "prod/index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "eslint test.js --max-warnings 0 -c index.js"
|
||||
"prepublish": "pnpm format && pnpm test",
|
||||
"build": "tsc",
|
||||
"format": "pnpm build && eslint src test --max-warnings 0 --fix",
|
||||
"lint": "pnpm build && eslint src test --max-warnings 0",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -24,20 +29,33 @@
|
||||
},
|
||||
"homepage": "https://codeberg.org/naomi-lgbt/eslint-config",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "5.62.0",
|
||||
"@typescript-eslint/parser": "5.62.0",
|
||||
"@eslint/compat": "1.1.1",
|
||||
"@eslint/eslintrc": "3.1.0",
|
||||
"@eslint/js": "9.7.0",
|
||||
"@stylistic/eslint-plugin": "2.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "rc-v8",
|
||||
"@typescript-eslint/parser": "rc-v8",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-deprecation": "2.0.0",
|
||||
"eslint-plugin-deprecation": "3.0.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-jsdoc": "41.1.2",
|
||||
"eslint-plugin-jsdoc": "48.8.3",
|
||||
"eslint-plugin-no-only-tests": "3.1.0",
|
||||
"eslint-plugin-prettier": "5.1.3"
|
||||
"eslint-plugin-prettier": "5.2.1",
|
||||
"eslint-plugin-sort-keys-fix": "1.1.2",
|
||||
"eslint-plugin-unicorn": "55.0.0",
|
||||
"globals": "15.8.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=8"
|
||||
"eslint": ">=9",
|
||||
"typescript": ">=5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nhcarrigan/prettier-config": "1.0.1",
|
||||
"prettier": "^3.0.2"
|
||||
"@nhcarrigan/prettier-config": "3.2.0",
|
||||
"@nhcarrigan/typescript-config": "4.0.0",
|
||||
"@types/eslint": "9.6.0",
|
||||
"@types/node": "20.14.12",
|
||||
"prettier": "^3.3.3",
|
||||
"typescript": "5.5.4",
|
||||
"vitest": "2.0.4"
|
||||
}
|
||||
}
|
||||
|
2430
pnpm-lock.yaml
generated
2430
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
114
src/index.ts
Normal file
114
src/index.ts
Normal file
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { fixupPluginRules } from "@eslint/compat";
|
||||
import stylistic from "@stylistic/eslint-plugin";
|
||||
import tslint from "@typescript-eslint/eslint-plugin";
|
||||
import parser from "@typescript-eslint/parser";
|
||||
import deprecation from "eslint-plugin-deprecation";
|
||||
import importPlugin from "eslint-plugin-import";
|
||||
import jsdoc from "eslint-plugin-jsdoc";
|
||||
import noOnlyTests from "eslint-plugin-no-only-tests";
|
||||
import sortKeysFix from "eslint-plugin-sort-keys-fix";
|
||||
import unicorn from "eslint-plugin-unicorn";
|
||||
import globals from "globals";
|
||||
import { deprecationRules } from "./rules/deprecation.js";
|
||||
import { disabledEslintRules, eslintRules } from "./rules/eslint.js";
|
||||
import { importRules } from "./rules/import.js";
|
||||
import { jsdocRules } from "./rules/jsdoc.js";
|
||||
import { noOnlyTestsRules } from "./rules/noOnlyTests.js";
|
||||
import { sortKeysFixRules } from "./rules/sortKeysFix.js";
|
||||
import { stylisticRules } from "./rules/stylistic.js";
|
||||
import { typescriptEslintRules, typescriptEslintRulesWithTypes }
|
||||
from "./rules/typescriptEslint.js";
|
||||
import { unicornRules } from "./rules/unicorn.js";
|
||||
import type { ESLint, Linter } from "eslint";
|
||||
|
||||
const config: Array<Linter.Config> = [
|
||||
{
|
||||
files: [ "src/**/*.ts" ],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
},
|
||||
parser: parser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 11,
|
||||
project: true,
|
||||
sourceType: "module",
|
||||
tsconfigRootDir: process.cwd(),
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
// @ts-expect-error It's a config. It's just not the narrow config. SMH.
|
||||
"@typescript-eslint": tslint,
|
||||
// @ts-expect-error They haven't typedef this yet because it technically doesn't support eslint9
|
||||
"deprecation": fixupPluginRules(deprecation),
|
||||
"import": fixupPluginRules(importPlugin as ESLint.Plugin),
|
||||
"jsdoc": jsdoc,
|
||||
"no-only-tests": noOnlyTests as ESLint.Plugin,
|
||||
"sort-keys-fix": sortKeysFix as ESLint.Plugin,
|
||||
// @ts-expect-error They haven't typedef this yet because it technically doesn't support eslint9
|
||||
"stylistic": fixupPluginRules(stylistic),
|
||||
"unicorn": unicorn,
|
||||
},
|
||||
rules: {
|
||||
...eslintRules,
|
||||
...disabledEslintRules,
|
||||
...typescriptEslintRules,
|
||||
...typescriptEslintRulesWithTypes,
|
||||
...noOnlyTestsRules,
|
||||
...importRules,
|
||||
...jsdocRules,
|
||||
...deprecationRules,
|
||||
...stylisticRules,
|
||||
...unicornRules,
|
||||
...sortKeysFixRules,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [ "test/**/*.spec.ts" ],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
},
|
||||
parser: parser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 11,
|
||||
sourceType: "module",
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
// @ts-expect-error It's a config. It's just not the narrow config. SMH.
|
||||
"@typescript-eslint": tslint,
|
||||
"import": fixupPluginRules(importPlugin as ESLint.Plugin),
|
||||
"jsdoc": jsdoc,
|
||||
"no-only-tests": noOnlyTests as ESLint.Plugin,
|
||||
"sort-keys-fix": sortKeysFix as ESLint.Plugin,
|
||||
// @ts-expect-error They haven't typedef this yet because it technically doesn't support eslint9
|
||||
"stylistic": fixupPluginRules(stylistic),
|
||||
"unicorn": unicorn,
|
||||
},
|
||||
rules: {
|
||||
...eslintRules,
|
||||
...disabledEslintRules,
|
||||
...typescriptEslintRules,
|
||||
...noOnlyTestsRules,
|
||||
...importRules,
|
||||
...jsdocRules,
|
||||
...stylisticRules,
|
||||
...unicornRules,
|
||||
...sortKeysFixRules,
|
||||
// Overrides
|
||||
"complexity": "off",
|
||||
"import/no-extraneous-dependencies": "error",
|
||||
"max-lines-per-function": "off",
|
||||
"max-nested-callbacks": "off",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default config;
|
11
src/rules/deprecation.ts
Normal file
11
src/rules/deprecation.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
export const deprecationRules: Linter.RulesRecord = {
|
||||
"deprecation/deprecation": "error",
|
||||
};
|
202
src/rules/eslint.ts
Normal file
202
src/rules/eslint.ts
Normal file
@ -0,0 +1,202 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
const maxComplexity = 10;
|
||||
const maxClasses = 1;
|
||||
const maxDepth = 5;
|
||||
const maxCallbacks = 2;
|
||||
const maxStatements = 20;
|
||||
|
||||
/**
|
||||
* Rules explicitly disabled to be overridden
|
||||
* by external packages.
|
||||
*/
|
||||
const disabledEslintRules: Linter.RulesRecord = {
|
||||
"class-methods-use-this": "off",
|
||||
"default-param-last": "off",
|
||||
"dot-notation": "off",
|
||||
"init-declarations": "off",
|
||||
"max-params": "off",
|
||||
"no-array-constructor": "off",
|
||||
"no-empty-function": "off",
|
||||
"no-implied-eval": "off",
|
||||
"no-loop-func": "off",
|
||||
"no-loss-of-precision": "off",
|
||||
"no-return-await": "off",
|
||||
"no-shadow": "off",
|
||||
"no-throw-literal": "off",
|
||||
"no-unused-expressions": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-use-before-define": "off",
|
||||
"no-useless-constructor": "off",
|
||||
"prefer-destructuring": "off",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"require-await": "off",
|
||||
};
|
||||
|
||||
/**
|
||||
* Rules for the base eslint.
|
||||
*/
|
||||
const eslintRules: Linter.RulesRecord = {
|
||||
"accessor-pairs": "error",
|
||||
"array-callback-return": [ "error", { allowImplicit: true } ],
|
||||
"arrow-body-style": [ "warn", "always" ],
|
||||
"block-scoped-var": "error",
|
||||
"capitalized-comments": "warn",
|
||||
"complexity": [ "error", maxComplexity ],
|
||||
"consistent-return": "error",
|
||||
"curly": "error",
|
||||
"default-case": "error",
|
||||
"default-case-last": "warn",
|
||||
"eqeqeq": "error",
|
||||
"for-direction": "error",
|
||||
"func-name-matching": "error",
|
||||
"func-names": [ "warn", "always" ],
|
||||
"func-style":
|
||||
[ "warn", "declaration", { allowArrowFunctions: true } ],
|
||||
"getter-return": [ "error", { allowImplicit: false } ],
|
||||
"grouped-accessor-pairs": "warn",
|
||||
"logical-assignment-operators": [ "error", "never" ],
|
||||
"max-classes-per-file": [ "error", maxClasses ],
|
||||
"max-depth": [ "warn", maxDepth ],
|
||||
"max-lines":
|
||||
[ "warn", { max: 300, skipBlankLines: true, skipComments: true } ],
|
||||
"max-lines-per-function": [
|
||||
"warn",
|
||||
{ IIFEs: true, max: 50, skipBlankLines: true, skipComments: false },
|
||||
],
|
||||
"max-nested-callbacks": [ "warn", maxCallbacks ],
|
||||
"max-statements": [ "warn", maxStatements ],
|
||||
"new-cap": "warn",
|
||||
"no-alert": "warn",
|
||||
"no-async-promise-executor": "error",
|
||||
"no-await-in-loop": "warn",
|
||||
"no-bitwise": "error",
|
||||
"no-caller": "error",
|
||||
"no-case-declarations": "warn",
|
||||
"no-class-assign": "error",
|
||||
"no-compare-neg-zero": "error",
|
||||
"no-cond-assign": "error",
|
||||
"no-console": "warn",
|
||||
// Technically covered by ts
|
||||
"no-const-assign": "error",
|
||||
"no-constant-binary-expression": "error",
|
||||
"no-constant-condition": "error",
|
||||
"no-constructor-return": "error",
|
||||
"no-control-regex": "error",
|
||||
"no-debugger": "warn",
|
||||
"no-delete-var": "error",
|
||||
"no-div-regex": "warn",
|
||||
"no-dupe-args": "error",
|
||||
"no-dupe-class-members": "error",
|
||||
"no-dupe-else-if": "error",
|
||||
"no-dupe-keys": "error",
|
||||
"no-duplicate-case": "error",
|
||||
"no-duplicate-imports": "warn",
|
||||
"no-else-return": "warn",
|
||||
"no-empty": "warn",
|
||||
"no-empty-character-class": "warn",
|
||||
"no-empty-pattern": "warn",
|
||||
"no-empty-static-block": "warn",
|
||||
"no-eq-null": "error",
|
||||
"no-eval": "error",
|
||||
"no-ex-assign": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "warn",
|
||||
"no-extra-boolean-cast": "warn",
|
||||
"no-extra-label": "warn",
|
||||
"no-fallthrough": "error",
|
||||
"no-func-assign": "error",
|
||||
"no-global-assign": "error",
|
||||
"no-implicit-coercion": "warn",
|
||||
"no-implicit-globals": "error",
|
||||
"no-import-assign": "error",
|
||||
"no-inner-declarations": "warn",
|
||||
"no-invalid-regexp": "warn",
|
||||
"no-invalid-this": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"no-iterator": "error",
|
||||
"no-label-var": "error",
|
||||
"no-labels": "warn",
|
||||
"no-lone-blocks": "warn",
|
||||
"no-lonely-if": "warn",
|
||||
"no-misleading-character-class": "warn",
|
||||
"no-multi-assign": "warn",
|
||||
"no-multi-str": "warn",
|
||||
"no-negated-condition": "warn",
|
||||
"no-nested-ternary": "warn",
|
||||
"no-new": "warn",
|
||||
"no-new-native-nonconstructor": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-nonoctal-decimal-escape": "warn",
|
||||
"no-obj-calls": "warn",
|
||||
"no-object-constructor": "error",
|
||||
"no-octal": "warn",
|
||||
"no-octal-escape": "warn",
|
||||
"no-param-reassign": "error",
|
||||
"no-plusplus": "warn",
|
||||
"no-promise-executor-return": "warn",
|
||||
"no-proto": "warn",
|
||||
"no-prototype-builtins": "error",
|
||||
"no-regex-spaces": "warn",
|
||||
"no-return-assign": "error",
|
||||
"no-script-url": "warn",
|
||||
"no-self-assign": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-sequences": "warn",
|
||||
"no-setter-return": "error",
|
||||
"no-sparse-arrays": "error",
|
||||
"no-template-curly-in-string": "warn",
|
||||
"no-this-before-super": "error",
|
||||
"no-undef": "error",
|
||||
"no-undef-init": "warn",
|
||||
"no-underscore-dangle": "warn",
|
||||
"no-unexpected-multiline": "warn",
|
||||
"no-unmodified-loop-condition": "warn",
|
||||
"no-unneeded-ternary": "warn",
|
||||
"no-unreachable": "warn",
|
||||
"no-unreachable-loop": "warn",
|
||||
"no-unsafe-finally": "error",
|
||||
"no-unsafe-negation": "error",
|
||||
"no-unsafe-optional-chaining": "error",
|
||||
"no-unused-private-class-members": "warn",
|
||||
"no-useless-assignment": "warn",
|
||||
"no-useless-backreference": "warn",
|
||||
"no-useless-call": "warn",
|
||||
"no-useless-catch": "warn",
|
||||
"no-useless-computed-key": "warn",
|
||||
"no-useless-concat": "warn",
|
||||
"no-useless-escape": "warn",
|
||||
"no-useless-rename": "warn",
|
||||
"no-useless-return": "warn",
|
||||
"no-var": "error",
|
||||
"no-warning-comments": "warn",
|
||||
"no-with": "error",
|
||||
"object-shorthand": [ "warn", "consistent-as-needed" ],
|
||||
"operator-assignment": [ "warn", "never" ],
|
||||
"prefer-arrow-callback": "warn",
|
||||
"prefer-const": "error",
|
||||
"prefer-named-capture-group": "warn",
|
||||
"prefer-object-has-own": "warn",
|
||||
"prefer-object-spread": "warn",
|
||||
"prefer-regex-literals": "warn",
|
||||
"prefer-rest-params": "warn",
|
||||
"prefer-spread": "warn",
|
||||
"prefer-template": "warn",
|
||||
"radix": "error",
|
||||
"require-atomic-updates": "error",
|
||||
"require-yield": "warn",
|
||||
"sort-keys": "warn",
|
||||
"sort-vars": "warn",
|
||||
"symbol-description": "warn",
|
||||
"use-isnan": "warn",
|
||||
"valid-typeof": "error",
|
||||
"yoda": [ "warn", "never" ],
|
||||
};
|
||||
|
||||
export { disabledEslintRules, eslintRules };
|
62
src/rules/import.ts
Normal file
62
src/rules/import.ts
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
export const importRules: Linter.RulesRecord = {
|
||||
"import/default": "error",
|
||||
"import/export": "error",
|
||||
"import/exports-last": "warn",
|
||||
"import/extensions": [ "warn", "ignorePackages" ],
|
||||
"import/first": "warn",
|
||||
"import/group-exports": "warn",
|
||||
"import/newline-after-import": [ "warn", { count: 1 } ],
|
||||
"import/no-absolute-path": [ "error" ],
|
||||
"import/no-amd": "error",
|
||||
"import/no-anonymous-default-export": [ "warn" ],
|
||||
"import/no-commonjs": [ "error" ],
|
||||
"import/no-cycle": [ "error" ],
|
||||
"import/no-default-export": "warn",
|
||||
"import/no-duplicates": [ "error" ],
|
||||
"import/no-dynamic-require": "error",
|
||||
"import/no-empty-named-blocks": "error",
|
||||
"import/no-extraneous-dependencies": [
|
||||
"error",
|
||||
{ devDependencies: [ "**/*.test.js", "**/*.spec.js" ] },
|
||||
],
|
||||
"import/no-import-module-exports": [ "error" ],
|
||||
"import/no-mutable-exports": "error",
|
||||
"import/no-named-as-default": "warn",
|
||||
"import/no-named-as-default-member": "warn",
|
||||
"import/no-namespace": [ "warn" ],
|
||||
"import/no-relative-packages": "warn",
|
||||
"import/no-self-import": "error",
|
||||
"import/no-unassigned-import": [ "error" ],
|
||||
"import/no-unused-modules": [ "warn" ],
|
||||
"import/no-useless-path-segments": [ "warn" ],
|
||||
"import/no-webpack-loader-syntax": "error",
|
||||
"import/order": [
|
||||
"warn",
|
||||
{
|
||||
"alphabetize": {
|
||||
caseInsensitive: true,
|
||||
order: "asc",
|
||||
},
|
||||
"groups": [
|
||||
"builtin",
|
||||
"external",
|
||||
"internal",
|
||||
"parent",
|
||||
"sibling",
|
||||
"index",
|
||||
"object",
|
||||
"type",
|
||||
"unknown",
|
||||
],
|
||||
"newlines-between": "never",
|
||||
},
|
||||
],
|
||||
};
|
102
src/rules/jsdoc.ts
Normal file
102
src/rules/jsdoc.ts
Normal file
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
export const jsdocRules: Linter.RulesRecord = {
|
||||
"jsdoc/check-access": "warn",
|
||||
"jsdoc/check-alignment": "warn",
|
||||
"jsdoc/check-indentation": "warn",
|
||||
"jsdoc/check-param-names": "warn",
|
||||
"jsdoc/check-property-names": "warn",
|
||||
"jsdoc/check-syntax": "warn",
|
||||
"jsdoc/check-tag-names": "warn",
|
||||
"jsdoc/check-template-names": "warn",
|
||||
"jsdoc/check-values": [
|
||||
"warn",
|
||||
{
|
||||
allowedLicenses: [ "Naomi's Public License" ],
|
||||
},
|
||||
],
|
||||
"jsdoc/convert-to-jsdoc-comments": [
|
||||
"warn",
|
||||
{
|
||||
enableFixer: true,
|
||||
enforceJsdocLineStyle: "multi",
|
||||
lineOrBlockStyle: "both",
|
||||
},
|
||||
],
|
||||
"jsdoc/empty-tags": "warn",
|
||||
"jsdoc/implements-on-classes": "warn",
|
||||
"jsdoc/imports-as-dependencies": "warn",
|
||||
"jsdoc/informative-docs": "warn",
|
||||
"jsdoc/match-description": "warn",
|
||||
"jsdoc/multiline-blocks":
|
||||
[ "warn", { noSingleLineBlocks: true } ],
|
||||
"jsdoc/no-bad-blocks": "warn",
|
||||
"jsdoc/no-blank-block-descriptions": "warn",
|
||||
"jsdoc/no-blank-blocks": "warn",
|
||||
"jsdoc/no-defaults": "warn",
|
||||
"jsdoc/no-types": "warn",
|
||||
"jsdoc/require-asterisk-prefix": "warn",
|
||||
"jsdoc/require-description": "warn",
|
||||
"jsdoc/require-description-complete-sentence": "warn",
|
||||
"jsdoc/require-file-overview": [
|
||||
"warn",
|
||||
{
|
||||
tags: {
|
||||
author: {
|
||||
mustExist: true,
|
||||
preventDuplicates: true,
|
||||
},
|
||||
copyright: {
|
||||
mustExist: true,
|
||||
preventDuplicates: true,
|
||||
},
|
||||
license: {
|
||||
mustExist: true,
|
||||
preventDuplicates: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
"jsdoc/require-hyphen-before-param-description": "warn",
|
||||
"jsdoc/require-jsdoc": [
|
||||
"warn",
|
||||
{
|
||||
publicOnly: true,
|
||||
require: {
|
||||
ArrowFunctionExpression: true,
|
||||
ClassDeclaration: true,
|
||||
ClassExpression: true,
|
||||
FunctionDeclaration: true,
|
||||
FunctionExpression: true,
|
||||
MethodDefinition: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
"jsdoc/require-param": "warn",
|
||||
"jsdoc/require-param-description": "warn",
|
||||
"jsdoc/require-param-name": "warn",
|
||||
"jsdoc/require-property": "warn",
|
||||
"jsdoc/require-property-description": "warn",
|
||||
"jsdoc/require-property-name": "warn",
|
||||
"jsdoc/require-returns": "warn",
|
||||
"jsdoc/require-returns-check": "warn",
|
||||
"jsdoc/require-returns-description": "warn",
|
||||
"jsdoc/require-template": "warn",
|
||||
"jsdoc/require-throws": "warn",
|
||||
"jsdoc/require-yields": "warn",
|
||||
"jsdoc/require-yields-check": "warn",
|
||||
"jsdoc/sort-tags": [
|
||||
"warn",
|
||||
{
|
||||
linesBetween: 0,
|
||||
},
|
||||
],
|
||||
"jsdoc/tag-lines": [ "warn", "never" ],
|
||||
"jsdoc/valid-types": "warn",
|
||||
};
|
17
src/rules/noOnlyTests.ts
Normal file
17
src/rules/noOnlyTests.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
export const noOnlyTestsRules: Linter.RulesRecord = {
|
||||
"no-only-tests/no-only-tests": [
|
||||
"warn",
|
||||
{
|
||||
block: [ "test", "expect", "assert", "describe", "bench" ],
|
||||
focus: [ "only", "skip" ],
|
||||
},
|
||||
],
|
||||
};
|
11
src/rules/sortKeysFix.ts
Normal file
11
src/rules/sortKeysFix.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
export const sortKeysFixRules: Linter.RulesRecord = {
|
||||
"sort-keys-fix/sort-keys-fix": "warn",
|
||||
};
|
105
src/rules/stylistic.ts
Normal file
105
src/rules/stylistic.ts
Normal file
@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
const spacesPerIndent = 2;
|
||||
|
||||
export const stylisticRules: Linter.RulesRecord = {
|
||||
"stylistic/array-bracket-newline": [ "warn", "consistent" ],
|
||||
"stylistic/array-bracket-spacing": [ "warn", "always" ],
|
||||
"stylistic/array-element-newline": [ "warn", "consistent" ],
|
||||
"stylistic/arrow-parens": [ "warn", "always" ],
|
||||
"stylistic/arrow-spacing":
|
||||
[ "warn", { after: true, before: true } ],
|
||||
"stylistic/block-spacing": [ "warn", "always" ],
|
||||
"stylistic/brace-style": [ "warn", "1tbs" ],
|
||||
"stylistic/comma-dangle": [ "warn", "always-multiline" ],
|
||||
"stylistic/comma-spacing": [ "warn" ],
|
||||
"stylistic/comma-style": [ "warn", "last" ],
|
||||
"stylistic/computed-property-spacing": [ "warn", "never" ],
|
||||
"stylistic/dot-location": [ "warn", "object" ],
|
||||
"stylistic/eol-last": [ "warn", "always" ],
|
||||
"stylistic/function-call-argument-newline": [ "warn", "consistent" ],
|
||||
"stylistic/function-call-spacing": [ "warn", "never" ],
|
||||
"stylistic/function-paren-newline": [ "warn", "consistent" ],
|
||||
"stylistic/generator-star-spacing": [ "warn", "after" ],
|
||||
"stylistic/indent": [ "warn", spacesPerIndent ],
|
||||
"stylistic/key-spacing": [
|
||||
"warn",
|
||||
{ afterColon: true,
|
||||
align: "value",
|
||||
beforeColon: false,
|
||||
mode: "strict" },
|
||||
],
|
||||
"stylistic/keyword-spacing":
|
||||
[ "warn", { after: true, before: true } ],
|
||||
"stylistic/line-comment-position": [ "warn", "above" ],
|
||||
"stylistic/linebreak-style": [ "warn", "unix" ],
|
||||
"stylistic/lines-around-comment": [
|
||||
"warn",
|
||||
{ afterBlockComment: false, beforeBlockComment: true },
|
||||
],
|
||||
"stylistic/max-len": [
|
||||
"warn",
|
||||
{ code: 80,
|
||||
ignoreComments: true,
|
||||
ignoreTemplateLiterals: true,
|
||||
tabWidth: 2 },
|
||||
],
|
||||
"stylistic/max-statements-per-line": [ "warn", { max: 1 } ],
|
||||
"stylistic/member-delimiter-style": "warn",
|
||||
"stylistic/multiline-comment-style": [ "warn", "starred-block" ],
|
||||
"stylistic/multiline-ternary": [ "warn", "always" ],
|
||||
"stylistic/new-parens": [ "warn", "always" ],
|
||||
"stylistic/newline-per-chained-call":
|
||||
[ "warn", { ignoreChainWithDepth: 2 } ],
|
||||
"stylistic/no-confusing-arrow": [
|
||||
"warn",
|
||||
{ allowParens: false, onlyOneSimpleParam: false },
|
||||
],
|
||||
"stylistic/no-extra-parens": [ "warn", "all" ],
|
||||
"stylistic/no-extra-semi": "warn",
|
||||
"stylistic/no-floating-decimal": "warn",
|
||||
"stylistic/no-mixed-operators":
|
||||
[ "warn", { allowSamePrecedence: false } ],
|
||||
"stylistic/no-mixed-spaces-and-tabs": [ "warn" ],
|
||||
"stylistic/no-multi-spaces":
|
||||
[ "warn", { exceptions: { Property: true, TSTypeAnnotation: true } } ],
|
||||
"stylistic/no-multiple-empty-lines": [ "warn", { max: 1 } ],
|
||||
"stylistic/no-tabs": "warn",
|
||||
"stylistic/no-trailing-spaces": "warn",
|
||||
"stylistic/no-whitespace-before-property": "warn",
|
||||
"stylistic/object-curly-newline":
|
||||
[ "warn", { consistent: true } ],
|
||||
"stylistic/object-curly-spacing": [ "warn", "always" ],
|
||||
"stylistic/one-var-declaration-per-line": [ "warn", "always" ],
|
||||
"stylistic/operator-linebreak": [ "warn", "before" ],
|
||||
"stylistic/padded-blocks": [ "warn", "never" ],
|
||||
"stylistic/quote-props": [ "warn", "consistent-as-needed" ],
|
||||
"stylistic/quotes":
|
||||
[ "warn", "double", { allowTemplateLiterals: true } ],
|
||||
"stylistic/rest-spread-spacing": [ "warn", "never" ],
|
||||
"stylistic/semi": [ "warn", "always" ],
|
||||
"stylistic/semi-spacing":
|
||||
[ "warn", { after: true, before: false } ],
|
||||
"stylistic/semi-style": [ "warn", "last" ],
|
||||
"stylistic/space-before-blocks": [ "warn", "always" ],
|
||||
"stylistic/space-before-function-paren": [ "warn", "never" ],
|
||||
"stylistic/space-in-parens": [ "warn", "never" ],
|
||||
"stylistic/space-infix-ops": [ "warn" ],
|
||||
"stylistic/spaced-comment": [ "warn", "always" ],
|
||||
"stylistic/switch-colon-spacing":
|
||||
[ "warn", { after: true, before: false } ],
|
||||
"stylistic/template-curly-spacing": [ "warn", "never" ],
|
||||
"stylistic/template-tag-spacing": [ "warn", "never" ],
|
||||
"stylistic/type-annotation-spacing":
|
||||
[ "warn", { after: true, before: false } ],
|
||||
"stylistic/type-generic-spacing": "warn",
|
||||
"stylistic/type-named-tuple-spacing": "warn",
|
||||
"stylistic/wrap-iife": [ "warn", "inside" ],
|
||||
"stylistic/yield-star-spacing": [ "warn", "after" ],
|
||||
};
|
231
src/rules/typescriptEslint.ts
Normal file
231
src/rules/typescriptEslint.ts
Normal file
@ -0,0 +1,231 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
/**
|
||||
* Rules that require type definitions.
|
||||
* These CANNOT run on the test directory as our typescript
|
||||
* configuration excludes tests from compliation.
|
||||
*/
|
||||
const typescriptEslintRulesWithTypes: Linter.RulesRecord = {
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
"@typescript-eslint/consistent-type-exports": [
|
||||
"warn",
|
||||
{ fixMixedExportsWithInlineTypeSpecifier: true },
|
||||
],
|
||||
"@typescript-eslint/dot-notation": [ "error" ],
|
||||
"@typescript-eslint/no-array-delete": "error",
|
||||
"@typescript-eslint/no-base-to-string": [ "error" ],
|
||||
"@typescript-eslint/no-confusing-void-expression": [ "error" ],
|
||||
"@typescript-eslint/no-duplicate-type-constituents": [ "error" ],
|
||||
"@typescript-eslint/no-floating-promises": [ "error" ],
|
||||
"@typescript-eslint/no-implied-eval": [ "error" ],
|
||||
"@typescript-eslint/no-meaningless-void-operator": [ "warn" ],
|
||||
"@typescript-eslint/no-misused-promises":
|
||||
[ "error" ],
|
||||
"@typescript-eslint/no-mixed-enums": "error",
|
||||
"@typescript-eslint/no-redundant-type-constituents": "warn",
|
||||
"@typescript-eslint/no-unnecessary-boolean-literal-compare": [ "warn" ],
|
||||
"@typescript-eslint/no-unnecessary-condition": [ "warn" ],
|
||||
"@typescript-eslint/no-unnecessary-qualifier": "warn",
|
||||
"@typescript-eslint/no-unnecessary-template-expression": "warn",
|
||||
"@typescript-eslint/no-unnecessary-type-arguments": "warn",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": [ "warn" ],
|
||||
"@typescript-eslint/no-unnecessary-type-parameters": "warn",
|
||||
"@typescript-eslint/no-unsafe-argument": "error",
|
||||
"@typescript-eslint/no-unsafe-assignment": "error",
|
||||
"@typescript-eslint/no-unsafe-call": "error",
|
||||
"@typescript-eslint/no-unsafe-declaration-merging": "error",
|
||||
"@typescript-eslint/no-unsafe-enum-comparison": "error",
|
||||
"@typescript-eslint/no-unsafe-function-type": "error",
|
||||
"@typescript-eslint/no-unsafe-member-access": "error",
|
||||
"@typescript-eslint/no-unsafe-return": "error",
|
||||
"@typescript-eslint/no-unsafe-unary-minus": "error",
|
||||
"@typescript-eslint/only-throw-error": [ "error" ],
|
||||
"@typescript-eslint/prefer-destructuring": [ "warn" ],
|
||||
"@typescript-eslint/prefer-find": "error",
|
||||
"@typescript-eslint/prefer-includes": "warn",
|
||||
"@typescript-eslint/prefer-nullish-coalescing": "error",
|
||||
"@typescript-eslint/prefer-optional-chain": [ "warn" ],
|
||||
"@typescript-eslint/prefer-promise-reject-errors": [ "error" ],
|
||||
"@typescript-eslint/prefer-readonly": "warn",
|
||||
"@typescript-eslint/prefer-reduce-type-parameter": "warn",
|
||||
"@typescript-eslint/prefer-regexp-exec": "error",
|
||||
"@typescript-eslint/prefer-return-this-type": "warn",
|
||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||
"@typescript-eslint/promise-function-async":
|
||||
[ "error", { allowAny: false } ],
|
||||
"@typescript-eslint/require-array-sort-compare": [
|
||||
"error",
|
||||
{ ignoreStringArrays: false },
|
||||
],
|
||||
"@typescript-eslint/require-await": "error",
|
||||
"@typescript-eslint/restrict-plus-operands": [
|
||||
"error",
|
||||
{
|
||||
allowAny: false,
|
||||
allowBoolean: false,
|
||||
allowNullish: false,
|
||||
allowNumberAndString: false,
|
||||
allowRegExp: false,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/restrict-template-expressions": [
|
||||
"error",
|
||||
{
|
||||
allowAny: false,
|
||||
allowBoolean: false,
|
||||
allowNever: false,
|
||||
allowNullish: false,
|
||||
allowNumber: false,
|
||||
allowRegExp: false,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/return-await": [ "error", "always" ],
|
||||
"@typescript-eslint/strict-boolean-expressions": [
|
||||
"error",
|
||||
{
|
||||
allowNullableObject: true,
|
||||
allowNumber: false,
|
||||
allowString: false,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/switch-exhaustiveness-check": [
|
||||
"error",
|
||||
{ requireDefaultForNonUnion: true },
|
||||
],
|
||||
"@typescript-eslint/unbound-method": "error",
|
||||
"@typescript-eslint/use-unknown-in-catch-callback-variable": "error",
|
||||
};
|
||||
|
||||
/**
|
||||
* Rules that do not require type definitions.
|
||||
* These can run on both the src and test directories.
|
||||
*/
|
||||
const typescriptEslintRules: Linter.RulesRecord = {
|
||||
"@typescript-eslint/adjacent-overload-signatures": "warn",
|
||||
"@typescript-eslint/array-type":
|
||||
[ "warn", { default: "generic" } ],
|
||||
"@typescript-eslint/ban-ts-comment": [
|
||||
"error",
|
||||
{ "ts-expect-error": "allow-with-description" },
|
||||
],
|
||||
"@typescript-eslint/class-literal-property-style": [ "error", "getters" ],
|
||||
"@typescript-eslint/class-methods-use-this": [ "error" ],
|
||||
"@typescript-eslint/consistent-generic-constructors": [
|
||||
"error",
|
||||
"constructor",
|
||||
],
|
||||
"@typescript-eslint/consistent-indexed-object-style": [ "warn", "record" ],
|
||||
"@typescript-eslint/consistent-type-assertions": [
|
||||
"warn",
|
||||
{ assertionStyle: "never" },
|
||||
],
|
||||
"@typescript-eslint/consistent-type-definitions": [ "warn", "interface" ],
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"warn",
|
||||
{ fixStyle: "inline-type-imports", prefer: "type-imports" },
|
||||
],
|
||||
"@typescript-eslint/default-param-last": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": [ "warn" ],
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"warn",
|
||||
{ accessibility: "explicit" },
|
||||
],
|
||||
"@typescript-eslint/explicit-module-boundary-types": [ "warn" ],
|
||||
"@typescript-eslint/init-declarations": [ "error", "always" ],
|
||||
// Anything more than 3 and we should be using a params object
|
||||
"@typescript-eslint/max-params":
|
||||
[ "error", { max: 3 } ],
|
||||
"@typescript-eslint/member-ordering": [ "warn" ],
|
||||
"@typescript-eslint/method-signature-style": [ "warn", "property" ],
|
||||
"@typescript-eslint/naming-convention": [
|
||||
"warn",
|
||||
{
|
||||
format: [ "camelCase" ],
|
||||
leadingUnderscore: "allow",
|
||||
selector: "default",
|
||||
trailingUnderscore: "forbid",
|
||||
},
|
||||
{
|
||||
format: [ "PascalCase" ],
|
||||
leadingUnderscore: "forbid",
|
||||
selector: "typeLike",
|
||||
trailingUnderscore: "forbid",
|
||||
},
|
||||
{
|
||||
format: [ "PascalCase" ],
|
||||
leadingUnderscore: "forbid",
|
||||
selector: "class",
|
||||
trailingUnderscore: "forbid",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-array-constructor": [ "error" ],
|
||||
"@typescript-eslint/no-confusing-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-duplicate-enum-values": "error",
|
||||
"@typescript-eslint/no-dynamic-delete": "error",
|
||||
"@typescript-eslint/no-empty-function": [ "error" ],
|
||||
"@typescript-eslint/no-empty-interface": [ "warn" ],
|
||||
"@typescript-eslint/no-empty-object-type": [ "warn" ],
|
||||
"@typescript-eslint/no-explicit-any":
|
||||
[ "error", { fixToUnknown: true } ],
|
||||
"@typescript-eslint/no-extraneous-class": [ "error" ],
|
||||
"@typescript-eslint/no-for-in-array": "error",
|
||||
"@typescript-eslint/no-import-type-side-effects": "error",
|
||||
"@typescript-eslint/no-inferrable-types": [ "warn" ],
|
||||
"@typescript-eslint/no-invalid-void-type":
|
||||
[ "error" ],
|
||||
"@typescript-eslint/no-loop-func": "error",
|
||||
"@typescript-eslint/no-loss-of-precision": "error",
|
||||
"@typescript-eslint/no-misused-new": "error",
|
||||
"@typescript-eslint/no-namespace": "error",
|
||||
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
|
||||
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
||||
"@typescript-eslint/no-non-null-assertion": "error",
|
||||
"@typescript-eslint/no-require-imports":
|
||||
[ "error" ],
|
||||
"@typescript-eslint/no-shadow":
|
||||
[ "error" ],
|
||||
"@typescript-eslint/no-this-alias": [ "warn" ],
|
||||
"@typescript-eslint/no-unnecessary-parameter-property-assignment": "warn",
|
||||
"@typescript-eslint/no-unnecessary-type-constraint": "warn",
|
||||
"@typescript-eslint/no-unused-expressions": [ "warn" ],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
args: "all",
|
||||
argsIgnorePattern: "^_",
|
||||
caughtErrors: "all",
|
||||
vars: "all",
|
||||
varsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-use-before-define": [ "error" ],
|
||||
"@typescript-eslint/no-useless-constructor": "warn",
|
||||
"@typescript-eslint/no-useless-empty-export": "warn",
|
||||
"@typescript-eslint/no-var-requires": [ "error" ],
|
||||
"@typescript-eslint/no-wrapper-object-types": "warn",
|
||||
"@typescript-eslint/parameter-properties": [
|
||||
"warn",
|
||||
{ prefer: "parameter-property" },
|
||||
],
|
||||
"@typescript-eslint/prefer-as-const": "warn",
|
||||
"@typescript-eslint/prefer-enum-initializers": "error",
|
||||
"@typescript-eslint/prefer-for-of": "warn",
|
||||
"@typescript-eslint/prefer-function-type": "warn",
|
||||
"@typescript-eslint/prefer-literal-enum-member": [ "error" ],
|
||||
"@typescript-eslint/triple-slash-reference": [
|
||||
"warn",
|
||||
{ lib: "never", path: "never", types: "prefer-import" },
|
||||
],
|
||||
"@typescript-eslint/unified-signatures": [ "warn" ],
|
||||
};
|
||||
|
||||
export {
|
||||
typescriptEslintRules,
|
||||
typescriptEslintRulesWithTypes,
|
||||
};
|
85
src/rules/unicorn.ts
Normal file
85
src/rules/unicorn.ts
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { Linter } from "eslint";
|
||||
|
||||
export const unicornRules: Linter.RulesRecord = {
|
||||
"unicorn/better-regex": "warn",
|
||||
"unicorn/catch-error-name":
|
||||
[ "warn", { name: "error" } ],
|
||||
"unicorn/consistent-destructuring": "warn",
|
||||
"unicorn/consistent-empty-array-spread": "error",
|
||||
"unicorn/consistent-function-scoping": "error",
|
||||
"unicorn/error-message": "error",
|
||||
"unicorn/escape-case": "warn",
|
||||
"unicorn/filename-case":
|
||||
[ "warn", { case: "camelCase" } ],
|
||||
"unicorn/no-array-callback-reference": "error",
|
||||
"unicorn/no-array-for-each": "warn",
|
||||
"unicorn/no-array-method-this-argument": "error",
|
||||
"unicorn/no-array-push-push": "warn",
|
||||
"unicorn/no-array-reduce": "warn",
|
||||
"unicorn/no-await-expression-member": "warn",
|
||||
"unicorn/no-await-in-promise-methods": "error",
|
||||
"unicorn/no-empty-file": "error",
|
||||
"unicorn/no-for-loop": "warn",
|
||||
"unicorn/no-hex-escape": "error",
|
||||
"unicorn/no-instanceof-array": "error",
|
||||
"unicorn/no-invalid-fetch-options": "warn",
|
||||
"unicorn/no-keyword-prefix": "warn",
|
||||
"unicorn/no-length-as-slice-end": "warn",
|
||||
"unicorn/no-lonely-if": "warn",
|
||||
"unicorn/no-negation-in-equality-check": "error",
|
||||
"unicorn/no-new-buffer": "error",
|
||||
"unicorn/no-object-as-default-parameter": "warn",
|
||||
"unicorn/no-single-promise-in-promise-methods": "warn",
|
||||
"unicorn/no-static-only-class": "warn",
|
||||
"unicorn/no-thenable": "warn",
|
||||
"unicorn/no-this-assignment": "warn",
|
||||
"unicorn/no-typeof-undefined": "error",
|
||||
"unicorn/no-unnecessary-await": "warn",
|
||||
"unicorn/no-unreadable-array-destructuring": "warn",
|
||||
"unicorn/no-unreadable-iife": "warn",
|
||||
"unicorn/no-useless-promise-resolve-reject": "warn",
|
||||
"unicorn/no-useless-spread": "warn",
|
||||
"unicorn/no-useless-switch-case": "warn",
|
||||
"unicorn/no-zero-fractions": "warn",
|
||||
"unicorn/number-literal-case": "warn",
|
||||
"unicorn/numeric-separators-style": "warn",
|
||||
"unicorn/prefer-array-flat": "warn",
|
||||
"unicorn/prefer-array-flat-map": "warn",
|
||||
"unicorn/prefer-array-index-of": "warn",
|
||||
"unicorn/prefer-array-some": "warn",
|
||||
"unicorn/prefer-at": "warn",
|
||||
"unicorn/prefer-code-point": "error",
|
||||
"unicorn/prefer-date-now": "warn",
|
||||
"unicorn/prefer-default-parameters": "warn",
|
||||
"unicorn/prefer-includes": "warn",
|
||||
"unicorn/prefer-math-trunc": "warn",
|
||||
"unicorn/prefer-modern-math-apis": "warn",
|
||||
"unicorn/prefer-module": "error",
|
||||
"unicorn/prefer-native-coercion-functions": "error",
|
||||
"unicorn/prefer-negative-index": "warn",
|
||||
"unicorn/prefer-node-protocol": "warn",
|
||||
"unicorn/prefer-number-properties": "error",
|
||||
"unicorn/prefer-object-from-entries": "warn",
|
||||
"unicorn/prefer-optional-catch-binding": "warn",
|
||||
"unicorn/prefer-prototype-methods": "warn",
|
||||
"unicorn/prefer-regexp-test": "warn",
|
||||
"unicorn/prefer-set-has": "warn",
|
||||
"unicorn/prefer-set-size": "warn",
|
||||
"unicorn/prefer-spread": "warn",
|
||||
"unicorn/prefer-string-replace-all": "warn",
|
||||
"unicorn/prefer-string-slice": "warn",
|
||||
"unicorn/prefer-string-starts-ends-with": "warn",
|
||||
"unicorn/prefer-string-trim-start-end": "warn",
|
||||
"unicorn/prefer-structured-clone": "warn",
|
||||
"unicorn/prefer-top-level-await": "warn",
|
||||
"unicorn/prefer-type-error": "warn",
|
||||
"unicorn/prevent-abbreviations": "warn",
|
||||
"unicorn/require-array-join-separator": "error",
|
||||
"unicorn/require-number-to-fixed-digits-argument": "error",
|
||||
};
|
9
src/types.d.ts
vendored
Normal file
9
src/types.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
declare module "eslint-plugin-no-only-tests";
|
||||
declare module "eslint-plugin-import";
|
||||
declare module "eslint-plugin-sort-keys-fix";
|
46
test/eslint.spec.ts
Normal file
46
test/eslint.spec.ts
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { suite, assert, test } from "vitest";
|
||||
import { disabledEslintRules, eslintRules } from "../src/rules/eslint.ts";
|
||||
|
||||
suite("ESLint Configs", () => {
|
||||
test("should not enable disabled rules", () => {
|
||||
const disabled = Object.keys(disabledEslintRules);
|
||||
const enabled = Object.keys(eslintRules);
|
||||
for (const key of disabled) {
|
||||
assert.notInclude(
|
||||
enabled,
|
||||
key,
|
||||
`Disabled rule ${key} has been re-enabled!`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("all disabled rules should be off", () => {
|
||||
const rules = Object.entries(disabledEslintRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.strictEqual(
|
||||
rule.at(0),
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.strictEqual(
|
||||
rule,
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
177
test/off.spec.ts
Normal file
177
test/off.spec.ts
Normal file
@ -0,0 +1,177 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { suite, assert, test } from "vitest";
|
||||
import { eslintRules } from "../src/rules/eslint.ts";
|
||||
import { importRules } from "../src/rules/import.js";
|
||||
import { jsdocRules } from "../src/rules/jsdoc.js";
|
||||
import { noOnlyTestsRules } from "../src/rules/noOnlyTests.js";
|
||||
import { stylisticRules } from "../src/rules/stylistic.ts";
|
||||
import { typescriptEslintRules } from "../src/rules/typescriptEslint.js";
|
||||
import { unicornRules } from "../src/rules/unicorn.js";
|
||||
|
||||
suite("No rules should be turned off in", () => {
|
||||
test("eslint rules", () => {
|
||||
const rules = Object.entries(eslintRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.notStrictEqual(
|
||||
rule.at(0),
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.notStrictEqual(
|
||||
rule,
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
|
||||
test("import rules", () => {
|
||||
const rules = Object.entries(importRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.notStrictEqual(
|
||||
rule.at(0),
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.notStrictEqual(
|
||||
rule,
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
|
||||
test("jsdoc rules", () => {
|
||||
const rules = Object.entries(jsdocRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.notStrictEqual(
|
||||
rule.at(0),
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.notStrictEqual(
|
||||
rule,
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
|
||||
test("no-only-tests rules", () => {
|
||||
const rules = Object.entries(noOnlyTestsRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.notStrictEqual(
|
||||
rule.at(0),
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.notStrictEqual(
|
||||
rule,
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
|
||||
test("stylistic rules", () => {
|
||||
const rules = Object.entries(stylisticRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.notStrictEqual(
|
||||
rule.at(0),
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.notStrictEqual(
|
||||
rule,
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
|
||||
test("typescript-eslint rules", () => {
|
||||
const rules = Object.entries(typescriptEslintRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.notStrictEqual(
|
||||
rule.at(0),
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.notStrictEqual(
|
||||
rule,
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
|
||||
test("unicorn rules", () => {
|
||||
const rules = Object.entries(unicornRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.notStrictEqual(
|
||||
rule.at(0),
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.notStrictEqual(
|
||||
rule,
|
||||
"off",
|
||||
`${name} appears to be turned off - this project does not use any external configs, so all rules should be off by default.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
});
|
33
test/stylistic.spec.ts
Normal file
33
test/stylistic.spec.ts
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { suite, assert, test } from "vitest";
|
||||
import { stylisticRules } from "../src/rules/stylistic.ts";
|
||||
|
||||
suite("Stylistic Configs", () => {
|
||||
test("should never be an error", () => {
|
||||
const rules = Object.entries(stylisticRules);
|
||||
for (const [ name, rule ] of rules) {
|
||||
if (Array.isArray(rule)) {
|
||||
assert.include(
|
||||
[ "off", "warn" ],
|
||||
rule.at(0),
|
||||
`${name} appears to be set to an error!`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (typeof rule === "string") {
|
||||
assert.include(
|
||||
[ "off", "warn" ],
|
||||
rule,
|
||||
`${name} appears to be set to an error!`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
assert.fail(`Could not determine rule type for ${name}!`);
|
||||
}
|
||||
});
|
||||
});
|
23
tsconfig.json
Normal file
23
tsconfig.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "Node16",
|
||||
"moduleResolution": "Node16",
|
||||
"allowUnreachableCode": false,
|
||||
"allowUnusedLabels": false,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"rootDir": "src",
|
||||
"outDir": "prod"
|
||||
},
|
||||
"exclude": ["./test", "vitest.config.ts"]
|
||||
}
|
3
vitest.config.ts
Normal file
3
vitest.config.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({});
|
Loading…
x
Reference in New Issue
Block a user