@letstri/oxc-config 0.2.0 → 0.3.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 +19 -18
- package/dist/index.d.mts +28 -15
- package/dist/index.mjs +56 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@ Opinionated, shared [oxlint](https://oxc.rs/docs/guide/usage/linter.html) and [o
|
|
|
4
4
|
|
|
5
5
|
> [!NOTE]
|
|
6
6
|
> This is an **opinionated** config — it ships a curated set of rules and
|
|
7
|
-
> formatting defaults meant to work out of the box. Override
|
|
8
|
-
> disagree with
|
|
7
|
+
> formatting defaults meant to work out of the box. [Override](#overrides)
|
|
8
|
+
> anything you disagree with.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -44,7 +44,7 @@ Set up @letstri/oxc-config (oxlint + oxfmt) in this project:
|
|
|
44
44
|
- "format:check": "oxfmt --check"
|
|
45
45
|
6. Framework plugins auto-enable from the nearest package.json. If a framework
|
|
46
46
|
dep (react/vue/next/vitest/jest/typescript) lives in a nested workspace,
|
|
47
|
-
enable it manually, e.g. `oxlintConfig({
|
|
47
|
+
enable it manually, e.g. `oxlintConfig({ plugins: ['vue'] })`.
|
|
48
48
|
7. Add the VS Code and Zed editor settings from the @letstri/oxc-config README.
|
|
49
49
|
8. Run `pnpm lint` and `pnpm format` and fix anything reported.
|
|
50
50
|
````
|
|
@@ -96,39 +96,40 @@ export default oxlintConfig({
|
|
|
96
96
|
|
|
97
97
|
### Overrides
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
config via [defu](https://github.com/unjs/defu)
|
|
99
|
+
`oxlintConfig` / `oxfmtConfig` accept **any number of config objects**, all
|
|
100
|
+
deep-merged over the base config via [defu](https://github.com/unjs/defu) (arrays
|
|
101
|
+
are concatenated, so plugins from different pieces combine instead of
|
|
102
|
+
overwriting):
|
|
101
103
|
|
|
102
104
|
```ts
|
|
103
|
-
export default oxlintConfig({
|
|
104
|
-
rules: {
|
|
105
|
-
'no-console': 'off',
|
|
106
|
-
},
|
|
107
|
-
})
|
|
105
|
+
export default oxlintConfig({ rules: { 'no-console': 'off' } }, { plugins: ['vue'] })
|
|
108
106
|
```
|
|
109
107
|
|
|
110
108
|
### Tailwind
|
|
111
109
|
|
|
112
|
-
`tailwind(
|
|
110
|
+
`tailwind({ entryPoint })` returns a config chunk for
|
|
113
111
|
[`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss).
|
|
114
|
-
|
|
112
|
+
Pass it as an argument to `oxlintConfig`:
|
|
115
113
|
|
|
116
114
|
```ts
|
|
117
115
|
import { oxlintConfig, tailwind } from '@letstri/oxc-config'
|
|
118
116
|
|
|
119
|
-
export default oxlintConfig(
|
|
120
|
-
|
|
121
|
-
})
|
|
117
|
+
export default oxlintConfig(
|
|
118
|
+
{ plugins: ['react', 'jsx-a11y'] },
|
|
119
|
+
tailwind({ entryPoint: 'app/globals.css' }),
|
|
120
|
+
)
|
|
122
121
|
```
|
|
123
122
|
|
|
124
|
-
|
|
123
|
+
Because arguments are merged (not spread), Tailwind's plugins combine with the
|
|
124
|
+
ones above rather than overwriting them. `entryPoint` (required) is your Tailwind
|
|
125
|
+
entry CSS, so the plugin can resolve class names. The plugin is an **optional
|
|
126
|
+
peer dependency** — install it yourself:
|
|
125
127
|
|
|
126
128
|
```bash
|
|
127
129
|
pnpm add -D eslint-plugin-better-tailwindcss
|
|
128
130
|
```
|
|
129
131
|
|
|
130
|
-
If the plugin is missing, `tailwind()`
|
|
131
|
-
config instead of crashing oxlint.
|
|
132
|
+
If the plugin is missing, `tailwind()` throws with an install hint.
|
|
132
133
|
|
|
133
134
|
## Editor setup
|
|
134
135
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { defineConfig } from "
|
|
2
|
-
import { defineConfig as defineConfig$1 } from "
|
|
3
|
-
//#region src/
|
|
4
|
-
type OxlintOptions = Parameters<typeof defineConfig
|
|
5
|
-
type OxfmtOptions = Parameters<typeof defineConfig>[0];
|
|
1
|
+
import { defineConfig } from "oxlint";
|
|
2
|
+
import { defineConfig as defineConfig$1 } from "oxfmt";
|
|
3
|
+
//#region src/oxlint.d.ts
|
|
4
|
+
type OxlintOptions$1 = Parameters<typeof defineConfig>[0];
|
|
6
5
|
/**
|
|
7
6
|
* Build an oxlint config.
|
|
8
7
|
*
|
|
9
8
|
* Plugins are auto-enabled by detecting their package (`typescript`, `react`,
|
|
10
9
|
* `vue`, `next`, `vitest`, `jest`) in the nearest `package.json`. To enable a
|
|
11
10
|
* plugin whose dependency lives elsewhere — e.g. a nested workspace like
|
|
12
|
-
* `apps/web/package.json` — add it through `
|
|
11
|
+
* `apps/web/package.json` — add it through `plugins`.
|
|
13
12
|
*
|
|
14
|
-
*
|
|
13
|
+
* Pass any number of config objects; they are deep-merged (arrays concatenated),
|
|
14
|
+
* so pieces like {@link tailwind} compose without clobbering each other.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
17
|
* ```ts
|
|
@@ -25,11 +25,25 @@ type OxfmtOptions = Parameters<typeof defineConfig>[0];
|
|
|
25
25
|
* ```
|
|
26
26
|
* @example
|
|
27
27
|
* ```ts
|
|
28
|
-
* //
|
|
29
|
-
* export default oxlintConfig(
|
|
28
|
+
* // compose Tailwind — its plugins merge with the ones above, not overwrite
|
|
29
|
+
* export default oxlintConfig(
|
|
30
|
+
* { plugins: ['react', 'jsx-a11y'] },
|
|
31
|
+
* tailwind({ entryPoint: 'app/globals.css' }),
|
|
32
|
+
* )
|
|
30
33
|
* ```
|
|
31
34
|
*/
|
|
32
|
-
declare function oxlintConfig(overrides
|
|
35
|
+
declare function oxlintConfig(...overrides: OxlintOptions$1[]): OxlintOptions$1;
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/oxfmt.d.ts
|
|
38
|
+
type OxfmtOptions = Parameters<typeof defineConfig$1>[0];
|
|
39
|
+
/**
|
|
40
|
+
* Build an oxfmt config. Pass any number of config objects; they are deep-merged
|
|
41
|
+
* over the base config via defu.
|
|
42
|
+
*/
|
|
43
|
+
declare function oxfmtConfig(...overrides: OxfmtOptions[]): OxfmtOptions;
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/tailwind.d.ts
|
|
46
|
+
type OxlintOptions = Parameters<typeof defineConfig>[0];
|
|
33
47
|
interface TailwindOptions {
|
|
34
48
|
/**
|
|
35
49
|
* Path to the Tailwind entry CSS. Required — the plugin needs it to resolve
|
|
@@ -45,17 +59,16 @@ interface TailwindOptions {
|
|
|
45
59
|
}
|
|
46
60
|
/**
|
|
47
61
|
* Tailwind linting via [`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss).
|
|
48
|
-
*
|
|
62
|
+
* Pass the result as an argument to `oxlintConfig`:
|
|
49
63
|
*
|
|
50
64
|
* ```ts
|
|
51
|
-
* export default oxlintConfig(
|
|
65
|
+
* export default oxlintConfig(tailwind({ entryPoint: 'app/globals.css' }))
|
|
52
66
|
* ```
|
|
53
67
|
*
|
|
54
68
|
* The plugin is an optional peer dependency — install it yourself
|
|
55
|
-
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing,
|
|
56
|
-
* is
|
|
69
|
+
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing, an error
|
|
70
|
+
* is thrown.
|
|
57
71
|
*/
|
|
58
72
|
declare function tailwind({ entryPoint, cwd }: TailwindOptions): OxlintOptions;
|
|
59
|
-
declare function oxfmtConfig(overrides?: OxfmtOptions): OxfmtOptions;
|
|
60
73
|
//#endregion
|
|
61
74
|
export { oxfmtConfig, oxlintConfig, tailwind };
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
1
|
import process from "node:process";
|
|
4
2
|
import { defu } from "defu";
|
|
5
|
-
import { defineConfig } from "
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import { defineConfig } from "oxlint";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
import { defineConfig as defineConfig$1 } from "oxfmt";
|
|
7
|
+
//#region src/utils.ts
|
|
8
|
+
function getInstalledPackages(cwd) {
|
|
9
|
+
const names = /* @__PURE__ */ new Set();
|
|
10
|
+
try {
|
|
11
|
+
const pkg = JSON.parse(readFileSync(resolve(cwd, "package.json"), "utf-8"));
|
|
12
|
+
for (const field of [
|
|
13
|
+
pkg.dependencies,
|
|
14
|
+
pkg.devDependencies,
|
|
15
|
+
pkg.peerDependencies
|
|
16
|
+
]) for (const name of Object.keys(field ?? {})) names.add(name);
|
|
17
|
+
} catch {}
|
|
18
|
+
return names;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/oxlint.ts
|
|
22
|
+
const baseOxlintConfig = defineConfig({
|
|
9
23
|
categories: {
|
|
10
24
|
correctness: "error",
|
|
11
25
|
suspicious: "warn",
|
|
@@ -474,13 +488,6 @@ const baseOxlintConfig = defineConfig$1({
|
|
|
474
488
|
}
|
|
475
489
|
]
|
|
476
490
|
});
|
|
477
|
-
const baseOxfmtConfig = defineConfig({
|
|
478
|
-
singleQuote: true,
|
|
479
|
-
semi: false,
|
|
480
|
-
arrowParens: "avoid",
|
|
481
|
-
sortImports: true,
|
|
482
|
-
quoteProps: "consistent"
|
|
483
|
-
});
|
|
484
491
|
const basePlugins = [
|
|
485
492
|
"import",
|
|
486
493
|
"unicorn",
|
|
@@ -489,11 +496,6 @@ const basePlugins = [
|
|
|
489
496
|
"promise",
|
|
490
497
|
"oxc"
|
|
491
498
|
];
|
|
492
|
-
const TAILWIND_PLUGIN = "eslint-plugin-better-tailwindcss";
|
|
493
|
-
/**
|
|
494
|
-
* Map of a dependency to the oxlint plugins it enables. A plugin is registered
|
|
495
|
-
* when any of its packages is found in the nearest `package.json`.
|
|
496
|
-
*/
|
|
497
499
|
const pluginDetectors = {
|
|
498
500
|
typescript: {
|
|
499
501
|
packages: ["typescript"],
|
|
@@ -520,18 +522,6 @@ const pluginDetectors = {
|
|
|
520
522
|
plugins: ["jest"]
|
|
521
523
|
}
|
|
522
524
|
};
|
|
523
|
-
function getInstalledPackages(cwd) {
|
|
524
|
-
const names = /* @__PURE__ */ new Set();
|
|
525
|
-
try {
|
|
526
|
-
const pkg = JSON.parse(readFileSync(resolve(cwd, "package.json"), "utf-8"));
|
|
527
|
-
for (const field of [
|
|
528
|
-
pkg.dependencies,
|
|
529
|
-
pkg.devDependencies,
|
|
530
|
-
pkg.peerDependencies
|
|
531
|
-
]) for (const name of Object.keys(field ?? {})) names.add(name);
|
|
532
|
-
} catch {}
|
|
533
|
-
return names;
|
|
534
|
-
}
|
|
535
525
|
function resolvePlugins(cwd) {
|
|
536
526
|
const installed = getInstalledPackages(cwd);
|
|
537
527
|
const plugins = [...basePlugins];
|
|
@@ -544,9 +534,10 @@ function resolvePlugins(cwd) {
|
|
|
544
534
|
* Plugins are auto-enabled by detecting their package (`typescript`, `react`,
|
|
545
535
|
* `vue`, `next`, `vitest`, `jest`) in the nearest `package.json`. To enable a
|
|
546
536
|
* plugin whose dependency lives elsewhere — e.g. a nested workspace like
|
|
547
|
-
* `apps/web/package.json` — add it through `
|
|
537
|
+
* `apps/web/package.json` — add it through `plugins`.
|
|
548
538
|
*
|
|
549
|
-
*
|
|
539
|
+
* Pass any number of config objects; they are deep-merged (arrays concatenated),
|
|
540
|
+
* so pieces like {@link tailwind} compose without clobbering each other.
|
|
550
541
|
*
|
|
551
542
|
* @example
|
|
552
543
|
* ```ts
|
|
@@ -560,31 +551,51 @@ function resolvePlugins(cwd) {
|
|
|
560
551
|
* ```
|
|
561
552
|
* @example
|
|
562
553
|
* ```ts
|
|
563
|
-
* //
|
|
564
|
-
* export default oxlintConfig(
|
|
554
|
+
* // compose Tailwind — its plugins merge with the ones above, not overwrite
|
|
555
|
+
* export default oxlintConfig(
|
|
556
|
+
* { plugins: ['react', 'jsx-a11y'] },
|
|
557
|
+
* tailwind({ entryPoint: 'app/globals.css' }),
|
|
558
|
+
* )
|
|
565
559
|
* ```
|
|
566
560
|
*/
|
|
567
|
-
function oxlintConfig(overrides
|
|
568
|
-
return defu(overrides, { plugins: resolvePlugins(process.cwd()) }, baseOxlintConfig);
|
|
561
|
+
function oxlintConfig(...overrides) {
|
|
562
|
+
return defu({}, ...overrides, { plugins: resolvePlugins(process.cwd()) }, baseOxlintConfig);
|
|
563
|
+
}
|
|
564
|
+
//#endregion
|
|
565
|
+
//#region src/oxfmt.ts
|
|
566
|
+
const baseOxfmtConfig = defineConfig$1({
|
|
567
|
+
printWidth: 100,
|
|
568
|
+
singleQuote: true,
|
|
569
|
+
semi: false,
|
|
570
|
+
arrowParens: "avoid",
|
|
571
|
+
sortImports: true,
|
|
572
|
+
quoteProps: "consistent"
|
|
573
|
+
});
|
|
574
|
+
/**
|
|
575
|
+
* Build an oxfmt config. Pass any number of config objects; they are deep-merged
|
|
576
|
+
* over the base config via defu.
|
|
577
|
+
*/
|
|
578
|
+
function oxfmtConfig(...overrides) {
|
|
579
|
+
return defu({}, ...overrides, baseOxfmtConfig);
|
|
569
580
|
}
|
|
581
|
+
//#endregion
|
|
582
|
+
//#region src/tailwind.ts
|
|
583
|
+
const TAILWIND_PLUGIN = "eslint-plugin-better-tailwindcss";
|
|
570
584
|
/**
|
|
571
585
|
* Tailwind linting via [`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss).
|
|
572
|
-
*
|
|
586
|
+
* Pass the result as an argument to `oxlintConfig`:
|
|
573
587
|
*
|
|
574
588
|
* ```ts
|
|
575
|
-
* export default oxlintConfig(
|
|
589
|
+
* export default oxlintConfig(tailwind({ entryPoint: 'app/globals.css' }))
|
|
576
590
|
* ```
|
|
577
591
|
*
|
|
578
592
|
* The plugin is an optional peer dependency — install it yourself
|
|
579
|
-
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing,
|
|
580
|
-
* is
|
|
593
|
+
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing, an error
|
|
594
|
+
* is thrown.
|
|
581
595
|
*/
|
|
582
596
|
function tailwind({ entryPoint, cwd = process.cwd() }) {
|
|
583
|
-
if (!getInstalledPackages(cwd).has(TAILWIND_PLUGIN)) {
|
|
584
|
-
|
|
585
|
-
return {};
|
|
586
|
-
}
|
|
587
|
-
return defineConfig$1({
|
|
597
|
+
if (!getInstalledPackages(cwd).has(TAILWIND_PLUGIN)) throw new Error(`[@letstri/oxc-config] Tailwind linting needs "${TAILWIND_PLUGIN}". Install it: pnpm add -D ${TAILWIND_PLUGIN}`);
|
|
598
|
+
return defineConfig({
|
|
588
599
|
jsPlugins: [TAILWIND_PLUGIN],
|
|
589
600
|
settings: { "better-tailwindcss": { entryPoint } },
|
|
590
601
|
rules: {
|
|
@@ -599,8 +610,5 @@ function tailwind({ entryPoint, cwd = process.cwd() }) {
|
|
|
599
610
|
}
|
|
600
611
|
});
|
|
601
612
|
}
|
|
602
|
-
function oxfmtConfig(overrides = {}) {
|
|
603
|
-
return defu(overrides, baseOxfmtConfig);
|
|
604
|
-
}
|
|
605
613
|
//#endregion
|
|
606
614
|
export { oxfmtConfig, oxlintConfig, tailwind };
|