@bastidood/eslint-config 0.4.0 → 0.6.1
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 +9 -12
- package/dist/compose/index.d.mts +19 -5
- package/dist/compose/index.mjs +54 -17
- package/dist/{convert-DXU3Htlu.mjs → convert-BtTj7vbK.mjs} +34 -511
- package/dist/core-tXylD6ZH.mjs +642 -0
- package/dist/core.d.mts +3 -2
- package/dist/core.mjs +30 -4
- package/dist/node.mjs +2 -1
- package/dist/tanstack/query.d.mts +3 -0
- package/dist/tanstack/query.mjs +24 -0
- package/dist/tanstack/table.d.mts +3 -0
- package/dist/tanstack/table.mjs +64 -0
- package/dist/vitest.mjs +2 -2
- package/package.json +14 -10
- package/dist/jsdoc.d.mts +0 -3
- package/dist/jsdoc.mjs +0 -42
- package/dist/promise.d.mts +0 -3
- package/dist/promise.mjs +0 -30
- package/dist/unicorn.d.mts +0 -3
- package/dist/unicorn.mjs +0 -146
package/README.md
CHANGED
|
@@ -14,26 +14,23 @@ pnpm add --save-dev @bastidood/eslint-config eslint typescript
|
|
|
14
14
|
// eslint.config.ts
|
|
15
15
|
import { compose } from '@bastidood/eslint-config';
|
|
16
16
|
import { CORE } from '@bastidood/eslint-config/core';
|
|
17
|
-
import { PROMISE } from '@bastidood/eslint-config/promise';
|
|
18
|
-
import { UNICORN } from '@bastidood/eslint-config/unicorn';
|
|
19
17
|
import { defineConfig } from 'eslint/config';
|
|
20
18
|
|
|
21
|
-
export default defineConfig({ files: ['**/*.ts'] }, compose(CORE
|
|
19
|
+
export default defineConfig({ files: ['**/*.ts'] }, compose(CORE));
|
|
22
20
|
```
|
|
23
21
|
|
|
24
22
|
List `CORE` first.
|
|
25
23
|
|
|
26
24
|
## Entry Points
|
|
27
25
|
|
|
28
|
-
| Entry point
|
|
29
|
-
|
|
|
30
|
-
| `@bastidood/eslint-config`
|
|
31
|
-
| `@bastidood/eslint-config/core`
|
|
32
|
-
| `@bastidood/eslint-config/
|
|
33
|
-
| `@bastidood/eslint-config/
|
|
34
|
-
| `@bastidood/eslint-config/
|
|
35
|
-
| `@bastidood/eslint-config/
|
|
36
|
-
| `@bastidood/eslint-config/jsdoc` | JSDoc rules for documentation that TypeScript does not cover |
|
|
26
|
+
| Entry point | Contents |
|
|
27
|
+
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
28
|
+
| `@bastidood/eslint-config` | `compose` |
|
|
29
|
+
| `@bastidood/eslint-config/core` | ESLint core, `import`, `jsdoc`, `promise`, `@typescript-eslint`, and `unicorn` rules |
|
|
30
|
+
| `@bastidood/eslint-config/node` | Node.js rules |
|
|
31
|
+
| `@bastidood/eslint-config/vitest` | Vitest rules |
|
|
32
|
+
| `@bastidood/eslint-config/tanstack/query` | Enables the slopstopper TanStack Query rules: `prefer-query-key-context`, `no-defaulted-query-key`, `no-standalone-mutate-async`, and `no-mutate-callback-cache-update` |
|
|
33
|
+
| `@bastidood/eslint-config/tanstack/table` | Enables the slopstopper TanStack Table rules: `prefer-table-atoms`, `require-table-state-pairs`, `no-render-scoped-table-schema`, and `require-exclusive-indeterminate`; bans `stockFeatures` and reading column templates outside `FlexRender` |
|
|
37
34
|
|
|
38
35
|
## Limitations
|
|
39
36
|
|
package/dist/compose/index.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NewResolver } from "eslint-plugin-import-x";
|
|
1
2
|
import { Linter } from "eslint";
|
|
2
3
|
export interface RestrictedImportPath {
|
|
3
4
|
readonly name: string;
|
|
@@ -29,24 +30,37 @@ export interface Restrictions {
|
|
|
29
30
|
readonly properties?: RestrictedProperty[];
|
|
30
31
|
readonly syntax?: RestrictedSyntax[];
|
|
31
32
|
}
|
|
33
|
+
/** An `import-x/resolver-next` resolver. `eslint-import-resolver-typescript` widens `interfaceVersion` to `number`. */
|
|
34
|
+
export interface ImportResolver extends Omit<NewResolver, 'interfaceVersion'> {
|
|
35
|
+
readonly interfaceVersion: number;
|
|
36
|
+
}
|
|
32
37
|
export interface ScopedRestrictions {
|
|
33
38
|
readonly files: string[];
|
|
34
39
|
readonly restrictions: Restrictions;
|
|
35
40
|
}
|
|
36
41
|
/**
|
|
37
42
|
* An entry point: ESLint configuration objects plus the lists that `compose` concatenates, namely the
|
|
38
|
-
* restriction lists
|
|
39
|
-
* `configs` may nest a configuration list one level deep, such as a plugin's
|
|
43
|
+
* restriction lists, the non-standard file extensions that the TypeScript project service must resolve, and the
|
|
44
|
+
* `import-x` settings lists. `configs` may nest a configuration list one level deep, such as a plugin's
|
|
45
|
+
* `recommended` list.
|
|
40
46
|
*/
|
|
41
47
|
export interface Entry {
|
|
42
48
|
readonly configs?: (Linter.Config | Linter.Config[])[];
|
|
43
49
|
readonly extraFileExtensions?: string[];
|
|
50
|
+
/** The file extensions that the `import` rules follow, as in `import-x/extensions`. */
|
|
51
|
+
readonly importExtensions?: string[];
|
|
52
|
+
/** The folders whose modules the `import` rules treat as external, as in `import-x/external-module-folders`. */
|
|
53
|
+
readonly importExternalModuleFolders?: string[];
|
|
54
|
+
/** Maps the module name of a parser to the file extensions that it parses, as in `import-x/parsers`. */
|
|
55
|
+
readonly importParsers?: Record<string, string[]>;
|
|
56
|
+
/** The resolvers that the `import` rules try in order, as in `import-x/resolver-next`. */
|
|
57
|
+
readonly importResolvers?: ImportResolver[];
|
|
44
58
|
readonly restrictions?: Restrictions;
|
|
45
59
|
readonly scopedRestrictions?: ScopedRestrictions[];
|
|
46
60
|
}
|
|
47
61
|
/**
|
|
48
|
-
* Compose entry points into one ESLint flat configuration for `extends`. Restriction lists
|
|
49
|
-
* instead of replaced, and every scoped configuration repeats the top-level restrictions
|
|
50
|
-
* drop them.
|
|
62
|
+
* Compose entry points into one ESLint flat configuration for `extends`. Restriction lists, file extension
|
|
63
|
+
* lists, and `import-x` settings lists are concatenated instead of replaced, and every scoped configuration repeats the top-level restrictions
|
|
64
|
+
* so that it cannot drop them.
|
|
51
65
|
*/
|
|
52
66
|
export declare function compose(...entries: Entry[]): Linter.Config[];
|
package/dist/compose/index.mjs
CHANGED
|
@@ -12,22 +12,21 @@ var RestrictionLists = class RestrictionLists {
|
|
|
12
12
|
#globals = ["error"];
|
|
13
13
|
#properties = ["error"];
|
|
14
14
|
#syntax = ["error"];
|
|
15
|
-
/** Append every list of an entry point's restrictions. */
|
|
16
15
|
append({ importPaths, importPatterns, globals, properties, syntax }) {
|
|
17
|
-
appendAll(this.#imports.paths, importPaths);
|
|
18
|
-
appendAll(this.#imports.patterns, importPatterns);
|
|
19
|
-
appendAll(this.#globals, globals);
|
|
20
|
-
appendAll(this.#properties, properties);
|
|
21
|
-
appendAll(this.#syntax, syntax);
|
|
16
|
+
appendAll$1(this.#imports.paths, importPaths);
|
|
17
|
+
appendAll$1(this.#imports.patterns, importPatterns);
|
|
18
|
+
appendAll$1(this.#globals, globals);
|
|
19
|
+
appendAll$1(this.#properties, properties);
|
|
20
|
+
appendAll$1(this.#syntax, syntax);
|
|
22
21
|
}
|
|
23
22
|
/** Copy these lists so that a scoped override can extend them without changing the top-level rules. */
|
|
24
23
|
copy() {
|
|
25
24
|
const copy = new RestrictionLists();
|
|
26
|
-
appendAll(copy.#imports.paths, this.#imports.paths);
|
|
27
|
-
appendAll(copy.#imports.patterns, this.#imports.patterns);
|
|
28
|
-
appendAll(copy.#globals, this.#globals.values().drop(1));
|
|
29
|
-
appendAll(copy.#properties, this.#properties.values().drop(1));
|
|
30
|
-
appendAll(copy.#syntax, this.#syntax.values().drop(1));
|
|
25
|
+
appendAll$1(copy.#imports.paths, this.#imports.paths);
|
|
26
|
+
appendAll$1(copy.#imports.patterns, this.#imports.patterns);
|
|
27
|
+
appendAll$1(copy.#globals, this.#globals.values().drop(1));
|
|
28
|
+
appendAll$1(copy.#properties, this.#properties.values().drop(1));
|
|
29
|
+
appendAll$1(copy.#syntax, this.#syntax.values().drop(1));
|
|
31
30
|
return copy;
|
|
32
31
|
}
|
|
33
32
|
importsRule() {
|
|
@@ -44,23 +43,38 @@ var RestrictionLists = class RestrictionLists {
|
|
|
44
43
|
return this.#syntax.length === 1 ? null : this.#syntax;
|
|
45
44
|
}
|
|
46
45
|
};
|
|
47
|
-
function appendAll(target, items) {
|
|
46
|
+
function appendAll$1(target, items) {
|
|
48
47
|
if (typeof items === "undefined") return;
|
|
49
48
|
for (const item of items) target.push(item);
|
|
50
49
|
}
|
|
51
50
|
// src/compose/index.ts
|
|
52
51
|
/**
|
|
53
|
-
* Compose entry points into one ESLint flat configuration for `extends`. Restriction lists
|
|
54
|
-
* instead of replaced, and every scoped configuration repeats the top-level restrictions
|
|
55
|
-
* drop them.
|
|
52
|
+
* Compose entry points into one ESLint flat configuration for `extends`. Restriction lists, file extension
|
|
53
|
+
* lists, and `import-x` settings lists are concatenated instead of replaced, and every scoped configuration repeats the top-level restrictions
|
|
54
|
+
* so that it cannot drop them.
|
|
56
55
|
*/
|
|
57
56
|
function compose(...entries) {
|
|
58
57
|
const configs = [];
|
|
59
58
|
const extraFileExtensions = [];
|
|
59
|
+
const importExtensions = [];
|
|
60
|
+
const importExternalModuleFolders = [];
|
|
61
|
+
const importParsers = {};
|
|
62
|
+
const importResolvers = [];
|
|
63
|
+
let hasImportParsers = false;
|
|
60
64
|
const restrictions = new RestrictionLists();
|
|
61
|
-
for (const { configs: entryConfigs, extraFileExtensions: entryExtensions, restrictions: entryRestrictions } of entries) {
|
|
65
|
+
for (const { configs: entryConfigs, extraFileExtensions: entryExtensions, importExtensions: entryImportExtensions, importExternalModuleFolders: entryImportExternalModuleFolders, importParsers: entryImportParsers, importResolvers: entryImportResolvers, restrictions: entryRestrictions } of entries) {
|
|
62
66
|
appendConfigs(configs, entryConfigs);
|
|
63
|
-
|
|
67
|
+
appendAll(extraFileExtensions, entryExtensions);
|
|
68
|
+
appendAll(importExtensions, entryImportExtensions);
|
|
69
|
+
appendAll(importExternalModuleFolders, entryImportExternalModuleFolders);
|
|
70
|
+
appendAll(importResolvers, entryImportResolvers);
|
|
71
|
+
if (typeof entryImportParsers !== "undefined") for (const parser in entryImportParsers) {
|
|
72
|
+
if (!Object.hasOwn(entryImportParsers, parser)) continue;
|
|
73
|
+
const extensions = importParsers[parser] ?? [];
|
|
74
|
+
appendAll(extensions, entryImportParsers[parser]);
|
|
75
|
+
importParsers[parser] = extensions;
|
|
76
|
+
hasImportParsers = true;
|
|
77
|
+
}
|
|
64
78
|
if (typeof entryRestrictions !== "undefined") restrictions.append(entryRestrictions);
|
|
65
79
|
}
|
|
66
80
|
configs.push({
|
|
@@ -83,8 +97,31 @@ function compose(...entries) {
|
|
|
83
97
|
name: "@bastidood/eslint-config/project-service",
|
|
84
98
|
languageOptions: { parserOptions: { extraFileExtensions } }
|
|
85
99
|
});
|
|
100
|
+
const importSettings = {};
|
|
101
|
+
let hasImportSettings = hasImportParsers;
|
|
102
|
+
if (hasImportParsers) importSettings["import-x/parsers"] = importParsers;
|
|
103
|
+
if (importExtensions.length > 0) {
|
|
104
|
+
importSettings["import-x/extensions"] = importExtensions;
|
|
105
|
+
hasImportSettings = true;
|
|
106
|
+
}
|
|
107
|
+
if (importExternalModuleFolders.length > 0) {
|
|
108
|
+
importSettings["import-x/external-module-folders"] = importExternalModuleFolders;
|
|
109
|
+
hasImportSettings = true;
|
|
110
|
+
}
|
|
111
|
+
if (importResolvers.length > 0) {
|
|
112
|
+
importSettings["import-x/resolver-next"] = importResolvers;
|
|
113
|
+
hasImportSettings = true;
|
|
114
|
+
}
|
|
115
|
+
if (hasImportSettings) configs.push({
|
|
116
|
+
name: "@bastidood/eslint-config/import",
|
|
117
|
+
settings: importSettings
|
|
118
|
+
});
|
|
86
119
|
return configs;
|
|
87
120
|
}
|
|
121
|
+
function appendAll(target, items) {
|
|
122
|
+
if (typeof items === "undefined") return;
|
|
123
|
+
for (const item of items) target.push(item);
|
|
124
|
+
}
|
|
88
125
|
/** Append an entry point's configurations, flattening nested configuration lists one level. */
|
|
89
126
|
function appendConfigs(target, configs) {
|
|
90
127
|
if (typeof configs === "undefined") return;
|