@theholocron/eslint-config 8.2.4 → 8.4.2
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 +4 -0
- package/dist/bundles/library.d.ts +45 -2
- package/dist/bundles/library.js +41 -3
- package/dist/bundles/next-app.js +1 -1
- package/dist/bundles/react-app.js +1 -1
- package/dist/configs/base.js +36 -1
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -82,6 +82,10 @@ export default [...nodeApp()];
|
|
|
82
82
|
// Publishable library (base + typescript + vitest)
|
|
83
83
|
import { library } from "@theholocron/eslint-config/bundles/library";
|
|
84
84
|
export default [...library()];
|
|
85
|
+
|
|
86
|
+
// With browser-targeted packages (turns off a Node-builtins rule that
|
|
87
|
+
// false-positives on navigator/sessionStorage/KeyboardEvent/…):
|
|
88
|
+
export default [...library({ browserPackages: ["packages/browser-utils/src"] })];
|
|
85
89
|
```
|
|
86
90
|
|
|
87
91
|
Add project-specific configs after the bundle — they are merged in order:
|
|
@@ -1,4 +1,47 @@
|
|
|
1
|
+
import { Linter } from "eslint";
|
|
1
2
|
//#region bundles/library.d.ts
|
|
2
|
-
|
|
3
|
+
interface LibraryOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Package (or path) globs whose code runs in the browser, not Node —
|
|
6
|
+
* `n/no-unsupported-features/node-builtins` false-positives on browser
|
|
7
|
+
* APIs (`navigator`, `sessionStorage`, `KeyboardEvent`, …) it doesn't
|
|
8
|
+
* recognize. Each entry gets a `<glob>/**` files match with the rule
|
|
9
|
+
* turned off. Rare — most repos need nothing here (`theholocron/utils`
|
|
10
|
+
* is the one org repo that does, for its browser-targeted packages).
|
|
11
|
+
*/
|
|
12
|
+
browserPackages?: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Every 5-of-6 org repos' `eslint.config.ts` already reduces to `...library()`
|
|
16
|
+
* with no further composition once `base()`'s gitignore/docs-src absorption
|
|
17
|
+
* (#460) is in place — the sixth (`holocron` itself) only differs by also
|
|
18
|
+
* spreading `vitest()` at its root, which is safe to bake in unconditionally
|
|
19
|
+
* here: {@link vitest}'s config is glob-scoped to test/setup files, so it's a
|
|
20
|
+
* no-op anywhere it doesn't match, same reasoning as `docsSrcConfig`. Once
|
|
21
|
+
* every repo drops its now-redundant local composition (#680, the migration
|
|
22
|
+
* pass), `library()` alone — resolved via `eslint --config`, zero committed
|
|
23
|
+
* file — covers every repo but the `browserPackages` outlier, which keeps a
|
|
24
|
+
* tiny `export default library({ browserPackages: [...] })` (config-resolution
|
|
25
|
+
* workstream, #676 in theholocron/holocron).
|
|
26
|
+
*/
|
|
27
|
+
declare function library(options?: LibraryOptions): Linter.Config[];
|
|
28
|
+
/**
|
|
29
|
+
* Ready-to-use config for packages that need no customisation — matches
|
|
30
|
+
* `@theholocron/vitest-config`'s and `@theholocron/tsdown-config`'s existing
|
|
31
|
+
* `export default <preset>()` pattern. `eslint --config <path>` loads a
|
|
32
|
+
* file's *default* export as the flat config directly; a named-export-only
|
|
33
|
+
* file throws `ConfigError: Unexpected key "library" found` (ESLint treats
|
|
34
|
+
* the whole module namespace as the config when there's no default) —
|
|
35
|
+
* required for the resolver (config-resolution workstream, #676 in
|
|
36
|
+
* theholocron/holocron) to point `--config` straight at this file with zero
|
|
37
|
+
* committed local content.
|
|
38
|
+
*
|
|
39
|
+
* The explicit `Linter.Config[]` binding (rather than `export default
|
|
40
|
+
* library();` directly) works around TS2742 — declaration-emit can't
|
|
41
|
+
* portably name library()'s inferred return type without a reference to
|
|
42
|
+
* @eslint/core's internal types; an explicitly-typed intermediate avoids
|
|
43
|
+
* needing to re-infer it.
|
|
44
|
+
*/
|
|
45
|
+
declare const resolvedLibrary: Linter.Config[];
|
|
3
46
|
//#endregion
|
|
4
|
-
export { library };
|
|
47
|
+
export { LibraryOptions, resolvedLibrary as default, library };
|
package/dist/bundles/library.js
CHANGED
|
@@ -2,21 +2,59 @@ import { base } from "../configs/base.js";
|
|
|
2
2
|
import { packageJson } from "../configs/package-json.js";
|
|
3
3
|
import { typescript } from "../configs/typescript.js";
|
|
4
4
|
import { node } from "../configs/node.js";
|
|
5
|
+
import { vitest as vitestConfig } from "../configs/vitest.js";
|
|
5
6
|
//#region bundles/library.ts
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Every 5-of-6 org repos' `eslint.config.ts` already reduces to `...library()`
|
|
9
|
+
* with no further composition once `base()`'s gitignore/docs-src absorption
|
|
10
|
+
* (#460) is in place — the sixth (`holocron` itself) only differs by also
|
|
11
|
+
* spreading `vitest()` at its root, which is safe to bake in unconditionally
|
|
12
|
+
* here: {@link vitest}'s config is glob-scoped to test/setup files, so it's a
|
|
13
|
+
* no-op anywhere it doesn't match, same reasoning as `docsSrcConfig`. Once
|
|
14
|
+
* every repo drops its now-redundant local composition (#680, the migration
|
|
15
|
+
* pass), `library()` alone — resolved via `eslint --config`, zero committed
|
|
16
|
+
* file — covers every repo but the `browserPackages` outlier, which keeps a
|
|
17
|
+
* tiny `export default library({ browserPackages: [...] })` (config-resolution
|
|
18
|
+
* workstream, #676 in theholocron/holocron).
|
|
19
|
+
*/
|
|
20
|
+
function library(options = {}) {
|
|
7
21
|
return [
|
|
8
22
|
...base(),
|
|
9
23
|
...node(),
|
|
10
24
|
...typescript(),
|
|
11
25
|
...packageJson(),
|
|
26
|
+
...vitestConfig(),
|
|
12
27
|
{
|
|
13
28
|
name: "@theholocron/library",
|
|
14
29
|
rules: {
|
|
15
30
|
"n/hashbang": "off",
|
|
16
31
|
"n/no-unpublished-import": "off"
|
|
17
32
|
}
|
|
18
|
-
}
|
|
33
|
+
},
|
|
34
|
+
...options.browserPackages?.length ? [{
|
|
35
|
+
name: "@theholocron/library/browser-packages",
|
|
36
|
+
files: options.browserPackages.map((pkg) => `${pkg}/**`),
|
|
37
|
+
rules: { "n/no-unsupported-features/node-builtins": "off" }
|
|
38
|
+
}] : []
|
|
19
39
|
];
|
|
20
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Ready-to-use config for packages that need no customisation — matches
|
|
43
|
+
* `@theholocron/vitest-config`'s and `@theholocron/tsdown-config`'s existing
|
|
44
|
+
* `export default <preset>()` pattern. `eslint --config <path>` loads a
|
|
45
|
+
* file's *default* export as the flat config directly; a named-export-only
|
|
46
|
+
* file throws `ConfigError: Unexpected key "library" found` (ESLint treats
|
|
47
|
+
* the whole module namespace as the config when there's no default) —
|
|
48
|
+
* required for the resolver (config-resolution workstream, #676 in
|
|
49
|
+
* theholocron/holocron) to point `--config` straight at this file with zero
|
|
50
|
+
* committed local content.
|
|
51
|
+
*
|
|
52
|
+
* The explicit `Linter.Config[]` binding (rather than `export default
|
|
53
|
+
* library();` directly) works around TS2742 — declaration-emit can't
|
|
54
|
+
* portably name library()'s inferred return type without a reference to
|
|
55
|
+
* @eslint/core's internal types; an explicitly-typed intermediate avoids
|
|
56
|
+
* needing to re-infer it.
|
|
57
|
+
*/
|
|
58
|
+
const resolvedLibrary = library();
|
|
21
59
|
//#endregion
|
|
22
|
-
export { library };
|
|
60
|
+
export { resolvedLibrary as default, library };
|
package/dist/bundles/next-app.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { base } from "../configs/base.js";
|
|
2
2
|
import { packageJson } from "../configs/package-json.js";
|
|
3
3
|
import { typescript } from "../configs/typescript.js";
|
|
4
|
+
import { vitest as vitestConfig } from "../configs/vitest.js";
|
|
4
5
|
import { cypress as cypressConfig } from "../configs/cypress.js";
|
|
5
6
|
import { next as nextConfig } from "../configs/next.js";
|
|
6
7
|
import { react as reactConfig } from "../configs/react.js";
|
|
7
8
|
import { storybook as storybookConfig } from "../configs/storybook.js";
|
|
8
|
-
import { vitest as vitestConfig } from "../configs/vitest.js";
|
|
9
9
|
//#region bundles/next-app.ts
|
|
10
10
|
function nextApp() {
|
|
11
11
|
return [
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { base } from "../configs/base.js";
|
|
2
2
|
import { packageJson } from "../configs/package-json.js";
|
|
3
3
|
import { typescript } from "../configs/typescript.js";
|
|
4
|
+
import { vitest as vitestConfig } from "../configs/vitest.js";
|
|
4
5
|
import { react as reactConfig } from "../configs/react.js";
|
|
5
6
|
import { storybook as storybookConfig } from "../configs/storybook.js";
|
|
6
|
-
import { vitest as vitestConfig } from "../configs/vitest.js";
|
|
7
7
|
//#region bundles/react-app.ts
|
|
8
8
|
function reactApp() {
|
|
9
9
|
return [
|
package/dist/configs/base.js
CHANGED
|
@@ -1,9 +1,43 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { includeIgnoreFile } from "@eslint/compat";
|
|
1
4
|
import js from "@eslint/js";
|
|
2
5
|
import globals from "globals";
|
|
3
6
|
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
|
4
7
|
//#region configs/base.ts
|
|
8
|
+
/**
|
|
9
|
+
* Ignore whatever the consuming repo's own .gitignore already ignores
|
|
10
|
+
* (dist/, coverage/, node_modules/, …) instead of every repo hand-maintaining
|
|
11
|
+
* its own `ignores:` array in eslint.config.ts. Resolved against
|
|
12
|
+
* process.cwd() — the repo root ESLint is actually invoked from, whether
|
|
13
|
+
* that's a committed eslint.config.ts re-exporting this bundle or a future
|
|
14
|
+
* `eslint --config <shared path>` invocation with no local file at all
|
|
15
|
+
* (config-resolution workstream, #676 in theholocron/holocron). A repo
|
|
16
|
+
* without a .gitignore (unusual, but not invalid) just gets no extra
|
|
17
|
+
* ignores from this — never throws.
|
|
18
|
+
*/
|
|
19
|
+
function gitignoreConfig() {
|
|
20
|
+
const gitignorePath = join(process.cwd(), ".gitignore");
|
|
21
|
+
if (!existsSync(gitignorePath)) return void 0;
|
|
22
|
+
return includeIgnoreFile(gitignorePath, "@theholocron/gitignore");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* docs/src imports resolve against the repo ROOT package.json (docs sites
|
|
26
|
+
* in this org are never their own workspace package — see clients/themes/
|
|
27
|
+
* utils/observability), so n/no-extraneous-import flags every import in
|
|
28
|
+
* that directory as a false positive. Scoped to a glob that simply matches
|
|
29
|
+
* nothing in a repo without a docs/src — safe to always include rather
|
|
30
|
+
* than opt into per repo.
|
|
31
|
+
*/
|
|
32
|
+
const docsSrcConfig = {
|
|
33
|
+
name: "@theholocron/docs-src",
|
|
34
|
+
files: ["docs/src/**"],
|
|
35
|
+
rules: { "n/no-extraneous-import": "off" }
|
|
36
|
+
};
|
|
5
37
|
function base() {
|
|
38
|
+
const gitignore = gitignoreConfig();
|
|
6
39
|
return [
|
|
40
|
+
...gitignore ? [gitignore] : [],
|
|
7
41
|
{
|
|
8
42
|
name: "@theholocron/base",
|
|
9
43
|
languageOptions: { globals: {
|
|
@@ -19,7 +53,8 @@ function base() {
|
|
|
19
53
|
"simple-import-sort/imports": "error",
|
|
20
54
|
"simple-import-sort/exports": "error"
|
|
21
55
|
}
|
|
22
|
-
}
|
|
56
|
+
},
|
|
57
|
+
docsSrcConfig
|
|
23
58
|
];
|
|
24
59
|
}
|
|
25
60
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/eslint-config",
|
|
3
|
-
"version": "8.2
|
|
3
|
+
"version": "8.4.2",
|
|
4
4
|
"description": "A ESLint configuration for writing well-formed Javascript within the Galaxy.",
|
|
5
5
|
"homepage": "https://github.com/theholocron/configs/tree/main/packages/eslint-config#readme",
|
|
6
6
|
"bugs": "https://github.com/theholocron/configs/issues",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@eslint/js": "^10.0.0",
|
|
30
|
+
"@theholocron/cli": "5.0.0-alpha.3",
|
|
30
31
|
"@vitest/coverage-v8": "^4.1.10",
|
|
31
32
|
"eslint-plugin-simple-import-sort": "^14.0.0",
|
|
32
33
|
"globals": "^17.11.0",
|
|
@@ -34,8 +35,8 @@
|
|
|
34
35
|
"typescript": "^5.9.3",
|
|
35
36
|
"typescript-eslint": "^8.67.0",
|
|
36
37
|
"vitest": "^4.1.10",
|
|
37
|
-
"@theholocron/tsconfig": "8.2
|
|
38
|
-
"@theholocron/vitest-config": "8.2
|
|
38
|
+
"@theholocron/tsconfig": "8.4.2",
|
|
39
|
+
"@theholocron/vitest-config": "8.4.2"
|
|
39
40
|
},
|
|
40
41
|
"exports": {
|
|
41
42
|
".": {
|
|
@@ -164,9 +165,10 @@
|
|
|
164
165
|
"releases": "https://github.com/theholocron/configs/releases",
|
|
165
166
|
"wiki": "https://github.com/theholocron/configs/wiki",
|
|
166
167
|
"scripts": {
|
|
167
|
-
"build": "tsdown",
|
|
168
|
-
"
|
|
169
|
-
"test": "vitest
|
|
170
|
-
"
|
|
168
|
+
"delivery.build": "tsdown",
|
|
169
|
+
"sourceQuality.staticAnalysis": "holocron run sourceQuality.staticAnalysis --",
|
|
170
|
+
"test:watch": "vitest",
|
|
171
|
+
"verification.typeSafety": "holocron run verification.typeSafety --",
|
|
172
|
+
"verification.unitTests": "holocron run verification.unitTests --"
|
|
171
173
|
}
|
|
172
174
|
}
|