@forthtilliath/eslint-config 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/base.d.ts +27 -1
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +46 -24
- package/dist/nextjs.d.ts.map +1 -1
- package/dist/nextjs.js +4 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +32 -25
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -115,6 +115,7 @@ export default createBaseConfig({ strict: false, turbo: false });
|
|
|
115
115
|
| `prettier` | `true` | Append `eslint-config-prettier` at the end. |
|
|
116
116
|
| `strict` | `true` | Use `strictTypeChecked`/`stylisticTypeChecked` instead of plain `recommended`. |
|
|
117
117
|
| `turbo` | `true` | Enable `eslint-plugin-turbo`'s `no-undeclared-env-vars` rule. |
|
|
118
|
+
| `snakeCase` | `false` | Also accept `snake_case` variable names in `@typescript-eslint/naming-convention` (e.g. rows destructured straight from a Supabase/SQL database). |
|
|
118
119
|
| `a11y` | `true`\* | _(react/nextjs/storybook/react-native)_ Enable `eslint-plugin-jsx-a11y`'s recommended rules. \*Defaults to `false` in `createReactNativeConfig` (jsx-a11y targets DOM semantics, which RN doesn't have). |
|
|
119
120
|
| `i18n` | `false` | _(react/nextjs/storybook/react-native)_ Enable `eslint-plugin-i18next`'s `no-literal-string` rule. |
|
|
120
121
|
| `testingLibrary` | `false` | _(react/nextjs/storybook/react-native)_ Enable `eslint-plugin-testing-library` + `eslint-plugin-jest-dom` on test files. |
|
package/dist/base.d.ts
CHANGED
|
@@ -11,14 +11,33 @@
|
|
|
11
11
|
* @property {boolean} [turbo=true] - Enable eslint-plugin-turbo's
|
|
12
12
|
* `no-undeclared-env-vars` rule. Only relevant inside a Turborepo; set to
|
|
13
13
|
* `false` for a standalone project.
|
|
14
|
+
* @property {boolean} [snakeCase=false] - Also accept `snake_case` variable
|
|
15
|
+
* names in `@typescript-eslint/naming-convention` — for code that
|
|
16
|
+
* destructures rows straight from a SQL database (e.g. Supabase), whose
|
|
17
|
+
* columns are snake_case.
|
|
14
18
|
*/
|
|
19
|
+
/**
|
|
20
|
+
* Builds the `@typescript-eslint/naming-convention` rule entry. Exported so
|
|
21
|
+
* variants that loosen it (react.js accepts PascalCase components) stay in
|
|
22
|
+
* sync with the `snakeCase` option instead of redeclaring the whole list.
|
|
23
|
+
*
|
|
24
|
+
* @param {object} [options]
|
|
25
|
+
* @param {boolean} [options.snakeCase=false] - See {@link BaseConfigOptions}.
|
|
26
|
+
* @param {boolean} [options.react=false] - Accept PascalCase for `const`
|
|
27
|
+
* variables and functions (React components).
|
|
28
|
+
* @returns {import("eslint").Linter.RuleEntry}
|
|
29
|
+
*/
|
|
30
|
+
export function createNamingConventionRule({ snakeCase, react, }?: {
|
|
31
|
+
snakeCase?: boolean | undefined;
|
|
32
|
+
react?: boolean | undefined;
|
|
33
|
+
}): import("eslint").Linter.RuleEntry;
|
|
15
34
|
/**
|
|
16
35
|
* Builds a shared ESLint configuration for the repository.
|
|
17
36
|
*
|
|
18
37
|
* @param {BaseConfigOptions} [options]
|
|
19
38
|
* @returns {import("eslint").Linter.Config[]}
|
|
20
39
|
*/
|
|
21
|
-
export function createBaseConfig({ prettier, strict, turbo, }?: BaseConfigOptions): import("eslint").Linter.Config[];
|
|
40
|
+
export function createBaseConfig({ prettier, strict, turbo, snakeCase, }?: BaseConfigOptions): import("eslint").Linter.Config[];
|
|
22
41
|
/**
|
|
23
42
|
* Node.js builtins without the `node:` prefix, as the first
|
|
24
43
|
* `simple-import-sort/imports` group. Exported so other variants (e.g.
|
|
@@ -55,5 +74,12 @@ export type BaseConfigOptions = {
|
|
|
55
74
|
* `false` for a standalone project.
|
|
56
75
|
*/
|
|
57
76
|
turbo?: boolean | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* - Also accept `snake_case` variable
|
|
79
|
+
* names in `@typescript-eslint/naming-convention` — for code that
|
|
80
|
+
* destructures rows straight from a SQL database (e.g. Supabase), whose
|
|
81
|
+
* columns are snake_case.
|
|
82
|
+
*/
|
|
83
|
+
snakeCase?: boolean | undefined;
|
|
58
84
|
};
|
|
59
85
|
//# sourceMappingURL=base.d.ts.map
|
package/dist/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.js"],"names":[],"mappings":"AAuBA
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.js"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;;;;GAUG;AACH,mEALG;IAA0B,SAAS;IACT,KAAK;CAE/B,GAAU,OAAO,QAAQ,EAAE,MAAM,CAAC,SAAS,CA+B7C;AAED;;;;;GAKG;AACH,2EAHW,iBAAiB,GACf,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAiH5C;AAjMD;;;;;;GAMG;AACH,wCAFU,MAAM,EAAE,CAQhB;AAsLF;;;;;KAKK;AACL,yBAFU,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAEG"}
|
package/dist/base.js
CHANGED
|
@@ -32,14 +32,56 @@ export const NODE_BUILTIN_IMPORT_GROUP = [
|
|
|
32
32
|
* @property {boolean} [turbo=true] - Enable eslint-plugin-turbo's
|
|
33
33
|
* `no-undeclared-env-vars` rule. Only relevant inside a Turborepo; set to
|
|
34
34
|
* `false` for a standalone project.
|
|
35
|
+
* @property {boolean} [snakeCase=false] - Also accept `snake_case` variable
|
|
36
|
+
* names in `@typescript-eslint/naming-convention` — for code that
|
|
37
|
+
* destructures rows straight from a SQL database (e.g. Supabase), whose
|
|
38
|
+
* columns are snake_case.
|
|
35
39
|
*/
|
|
40
|
+
/**
|
|
41
|
+
* Builds the `@typescript-eslint/naming-convention` rule entry. Exported so
|
|
42
|
+
* variants that loosen it (react.js accepts PascalCase components) stay in
|
|
43
|
+
* sync with the `snakeCase` option instead of redeclaring the whole list.
|
|
44
|
+
*
|
|
45
|
+
* @param {object} [options]
|
|
46
|
+
* @param {boolean} [options.snakeCase=false] - See {@link BaseConfigOptions}.
|
|
47
|
+
* @param {boolean} [options.react=false] - Accept PascalCase for `const`
|
|
48
|
+
* variables and functions (React components).
|
|
49
|
+
* @returns {import("eslint").Linter.RuleEntry}
|
|
50
|
+
*/
|
|
51
|
+
export function createNamingConventionRule({ snakeCase = false, react = false, } = {}) {
|
|
52
|
+
const snake = snakeCase ? ["snake_case"] : [];
|
|
53
|
+
const pascal = react ? ["PascalCase"] : [];
|
|
54
|
+
return [
|
|
55
|
+
"error",
|
|
56
|
+
// https://typescript-eslint.io/rules/naming-convention
|
|
57
|
+
{
|
|
58
|
+
selector: "variable",
|
|
59
|
+
format: ["camelCase", ...snake],
|
|
60
|
+
leadingUnderscore: "allow",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
selector: "variable",
|
|
64
|
+
modifiers: ["const"],
|
|
65
|
+
format: ["camelCase", "UPPER_CASE", ...pascal, ...snake],
|
|
66
|
+
leadingUnderscore: "allow",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
selector: "function",
|
|
70
|
+
format: ["camelCase", ...pascal],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
selector: "typeLike",
|
|
74
|
+
format: ["PascalCase"],
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
}
|
|
36
78
|
/**
|
|
37
79
|
* Builds a shared ESLint configuration for the repository.
|
|
38
80
|
*
|
|
39
81
|
* @param {BaseConfigOptions} [options]
|
|
40
82
|
* @returns {import("eslint").Linter.Config[]}
|
|
41
83
|
*/
|
|
42
|
-
export function createBaseConfig({ prettier = true, strict = true, turbo = true, } = {}) {
|
|
84
|
+
export function createBaseConfig({ prettier = true, strict = true, turbo = true, snakeCase = false, } = {}) {
|
|
43
85
|
return defineConfig([
|
|
44
86
|
eslint.configs.recommended,
|
|
45
87
|
strict ? tseslint.configs.strictTypeChecked : tseslint.configs.recommended,
|
|
@@ -138,29 +180,9 @@ export function createBaseConfig({ prettier = true, strict = true, turbo = true,
|
|
|
138
180
|
"error",
|
|
139
181
|
{ allowNumber: true },
|
|
140
182
|
],
|
|
141
|
-
"@typescript-eslint/naming-convention":
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
{
|
|
145
|
-
selector: "variable",
|
|
146
|
-
format: ["camelCase"],
|
|
147
|
-
leadingUnderscore: "allow",
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
selector: "variable",
|
|
151
|
-
modifiers: ["const"],
|
|
152
|
-
format: ["camelCase", "UPPER_CASE"],
|
|
153
|
-
leadingUnderscore: "allow",
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
selector: "function",
|
|
157
|
-
format: ["camelCase"],
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
selector: "typeLike",
|
|
161
|
-
format: ["PascalCase"],
|
|
162
|
-
},
|
|
163
|
-
],
|
|
183
|
+
"@typescript-eslint/naming-convention": createNamingConventionRule({
|
|
184
|
+
snakeCase,
|
|
185
|
+
}),
|
|
164
186
|
},
|
|
165
187
|
},
|
|
166
188
|
prettier ? eslintConfigPrettier : [],
|
package/dist/nextjs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../src/nextjs.js"],"names":[],"mappings":"AAKA;;;;;;;KAOK;AACL,6CAHW,OAAO,WAAW,EAAE,iBAAiB,GAAG,OAAO,YAAY,EAAE,kBAAkB,GAC7E,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../src/nextjs.js"],"names":[],"mappings":"AAKA;;;;;;;KAOK;AACL,6CAHW,OAAO,WAAW,EAAE,iBAAiB,GAAG,OAAO,YAAY,EAAE,kBAAkB,GAC7E,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAsD5C;AAED;;;;;KAKK;AACL,2BAFU,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAEO"}
|
package/dist/nextjs.js
CHANGED
|
@@ -12,7 +12,10 @@ import { createReactConfig } from "./react.js";
|
|
|
12
12
|
export function createNextJsConfig(options) {
|
|
13
13
|
return defineConfig([
|
|
14
14
|
{
|
|
15
|
-
ignores
|
|
15
|
+
// Same default ignores as eslint-config-next: build output
|
|
16
|
+
// (`.next/`, and `out/`/`build/` for static exports) and the generated
|
|
17
|
+
// `next-env.d.ts`.
|
|
18
|
+
ignores: [".next/**", "out/**", "build/**", "next-env.d.ts"],
|
|
16
19
|
},
|
|
17
20
|
...createReactConfig(options),
|
|
18
21
|
{
|
package/dist/react.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* @param {import("./base.js").BaseConfigOptions & ReactConfigOptions} [options]
|
|
22
22
|
* @returns {import("eslint").Linter.Config[]}
|
|
23
23
|
*/
|
|
24
|
-
export function createReactConfig({ a11y, i18n, testingLibrary, ...options }?: import("./base.js").BaseConfigOptions & ReactConfigOptions): import("eslint").Linter.Config[];
|
|
24
|
+
export function createReactConfig({ a11y, i18n, testingLibrary, snakeCase, ...options }?: import("./base.js").BaseConfigOptions & ReactConfigOptions): import("eslint").Linter.Config[];
|
|
25
25
|
/**
|
|
26
26
|
* A custom ESLint configuration for libraries that use React, with the
|
|
27
27
|
* default options. Use `createReactConfig(options)` instead to customize it.
|
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.js"],"names":[],"mappings":"AAuCA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;GAKG;AACH,0FAHW,OAAO,WAAW,EAAE,iBAAiB,GAAG,kBAAkB,GACxD,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAwF5C;AAED;;;;8CAI8C;AAC9C,0BADU,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CACK"}
|
package/dist/react.js
CHANGED
|
@@ -8,7 +8,7 @@ import pluginReactHooks from "eslint-plugin-react-hooks";
|
|
|
8
8
|
import pluginReactRefresh from "eslint-plugin-react-refresh";
|
|
9
9
|
import pluginTestingLibrary from "eslint-plugin-testing-library";
|
|
10
10
|
import globals from "globals";
|
|
11
|
-
import { createBaseConfig } from "./base.js";
|
|
11
|
+
import { createBaseConfig, createNamingConventionRule } from "./base.js";
|
|
12
12
|
/**
|
|
13
13
|
* Any file matching this is a test file, whatever runner or naming
|
|
14
14
|
* convention is used to suffix it (`.test.`, `.spec.`, `.dom.test.`...) —
|
|
@@ -16,6 +16,23 @@ import { createBaseConfig } from "./base.js";
|
|
|
16
16
|
* @type {string[]}
|
|
17
17
|
*/
|
|
18
18
|
const TEST_FILE_GLOBS = ["**/*.{test,spec}.{ts,tsx,js,jsx}"];
|
|
19
|
+
/**
|
|
20
|
+
* eslint-plugin-react-hooks rules that @eslint-react also implements, under
|
|
21
|
+
* the same name. Only the @eslint-react version is kept (see the rules block
|
|
22
|
+
* below); `src/nextjs.test.js` fails if a new overlap appears.
|
|
23
|
+
* @type {string[]}
|
|
24
|
+
*/
|
|
25
|
+
const RULES_COVERED_BY_ESLINT_REACT = [
|
|
26
|
+
"rules-of-hooks",
|
|
27
|
+
"exhaustive-deps",
|
|
28
|
+
"static-components",
|
|
29
|
+
"use-memo",
|
|
30
|
+
"set-state-in-effect",
|
|
31
|
+
"error-boundaries",
|
|
32
|
+
"purity",
|
|
33
|
+
"set-state-in-render",
|
|
34
|
+
"unsupported-syntax",
|
|
35
|
+
];
|
|
19
36
|
/**
|
|
20
37
|
* @typedef {object} ReactConfigOptions
|
|
21
38
|
* @property {boolean} [a11y=true] - Enable eslint-plugin-jsx-a11y's
|
|
@@ -39,9 +56,9 @@ const TEST_FILE_GLOBS = ["**/*.{test,spec}.{ts,tsx,js,jsx}"];
|
|
|
39
56
|
* @param {import("./base.js").BaseConfigOptions & ReactConfigOptions} [options]
|
|
40
57
|
* @returns {import("eslint").Linter.Config[]}
|
|
41
58
|
*/
|
|
42
|
-
export function createReactConfig({ a11y = true, i18n = false, testingLibrary = false, ...options } = {}) {
|
|
59
|
+
export function createReactConfig({ a11y = true, i18n = false, testingLibrary = false, snakeCase = false, ...options } = {}) {
|
|
43
60
|
return defineConfig([
|
|
44
|
-
...createBaseConfig(options),
|
|
61
|
+
...createBaseConfig({ snakeCase, ...options }),
|
|
45
62
|
a11y ? pluginJsxA11y.flatConfigs.recommended : [],
|
|
46
63
|
i18n
|
|
47
64
|
? {
|
|
@@ -79,6 +96,14 @@ export function createReactConfig({ a11y = true, i18n = false, testingLibrary =
|
|
|
79
96
|
settings: { react: { version: "19" } },
|
|
80
97
|
rules: {
|
|
81
98
|
...pluginReactHooks.configs.recommended.rules,
|
|
99
|
+
// Already covered by @eslint-react's recommended-type-checked preset
|
|
100
|
+
// (sometimes more thoroughly: its `purity` flags `new Date()`, the
|
|
101
|
+
// react-hooks one doesn't). Left on, every problem is reported twice
|
|
102
|
+
// and every disable comment has to name both plugins.
|
|
103
|
+
...Object.fromEntries(RULES_COVERED_BY_ESLINT_REACT.map((rule) => [
|
|
104
|
+
`react-hooks/${rule}`,
|
|
105
|
+
"off",
|
|
106
|
+
])),
|
|
82
107
|
// React scope no longer necessary with new JSX transform.
|
|
83
108
|
"react/react-in-jsx-scope": "off",
|
|
84
109
|
},
|
|
@@ -102,28 +127,10 @@ export function createReactConfig({ a11y = true, i18n = false, testingLibrary =
|
|
|
102
127
|
rules: {
|
|
103
128
|
"@typescript-eslint/no-unsafe-call": "warn",
|
|
104
129
|
"@typescript-eslint/restrict-template-expressions": "warn",
|
|
105
|
-
"@typescript-eslint/naming-convention":
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
format: ["camelCase"],
|
|
110
|
-
leadingUnderscore: "allow",
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
selector: "variable",
|
|
114
|
-
modifiers: ["const"],
|
|
115
|
-
format: ["camelCase", "UPPER_CASE", "PascalCase"],
|
|
116
|
-
leadingUnderscore: "allow",
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
selector: "function",
|
|
120
|
-
format: ["camelCase", "PascalCase"],
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
selector: "typeLike",
|
|
124
|
-
format: ["PascalCase"],
|
|
125
|
-
},
|
|
126
|
-
],
|
|
130
|
+
"@typescript-eslint/naming-convention": createNamingConventionRule({
|
|
131
|
+
snakeCase,
|
|
132
|
+
react: true,
|
|
133
|
+
}),
|
|
127
134
|
},
|
|
128
135
|
},
|
|
129
136
|
]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forthtilliath/eslint-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"rxjs": "^7.8.0",
|
|
51
51
|
"typescript": "^5.9.3",
|
|
52
52
|
"vitest": "^4.1.10",
|
|
53
|
-
"@forthtilliath/typescript-config": "0.
|
|
53
|
+
"@forthtilliath/typescript-config": "0.1.1"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"dev": "tsc --watch -p tsconfig.build.json",
|