@letstri/oxc-config 0.1.0 → 0.2.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 +38 -32
- package/dist/index.d.mts +47 -47
- package/dist/index.mjs +55 -37
- package/package.json +13 -16
package/README.md
CHANGED
|
@@ -71,59 +71,65 @@ export default oxfmtConfig()
|
|
|
71
71
|
|
|
72
72
|
### Plugins
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
Plugins are enabled automatically by detecting dependencies in the nearest
|
|
75
|
+
`package.json`:
|
|
76
|
+
|
|
77
|
+
| Dependency | Plugins enabled |
|
|
78
|
+
| ------------ | ------------------- |
|
|
79
|
+
| `typescript` | `typescript` |
|
|
80
|
+
| `react` | `react`, `jsx-a11y` |
|
|
81
|
+
| `vue` | `vue` |
|
|
82
|
+
| `next` | `nextjs` |
|
|
83
|
+
| `vitest` | `vitest` |
|
|
84
|
+
| `jest` | `jest` |
|
|
85
|
+
|
|
86
|
+
Detection only reads the **nearest** `package.json`. If a dependency isn't found
|
|
87
|
+
there — e.g. it lives in a nested workspace like `apps/web/package.json`, or is
|
|
88
|
+
hoisted somewhere the scan doesn't see — its plugin won't be enabled. Add it
|
|
89
|
+
manually via `plugins`:
|
|
78
90
|
|
|
79
91
|
```ts
|
|
80
92
|
export default oxlintConfig({
|
|
81
|
-
|
|
82
|
-
jest: false, // force off
|
|
93
|
+
plugins: ['vue'],
|
|
83
94
|
})
|
|
84
95
|
```
|
|
85
96
|
|
|
86
|
-
###
|
|
87
|
-
|
|
88
|
-
`tailwind: true` enables [`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss)
|
|
89
|
-
(auto-detected from a `tailwindcss` dependency). The plugin is an **optional peer
|
|
90
|
-
dependency** — install it yourself:
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
pnpm add -D eslint-plugin-better-tailwindcss
|
|
94
|
-
```
|
|
97
|
+
### Overrides
|
|
95
98
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
entry CSS so it can resolve class names:
|
|
99
|
+
Anything you pass to `oxlintConfig` / `oxfmtConfig` is deep-merged over the base
|
|
100
|
+
config via [defu](https://github.com/unjs/defu):
|
|
99
101
|
|
|
100
102
|
```ts
|
|
101
103
|
export default oxlintConfig({
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
settings: {
|
|
105
|
-
'better-tailwindcss': {
|
|
106
|
-
entryPoint: 'src/styles/globals.css',
|
|
107
|
-
},
|
|
108
|
-
},
|
|
104
|
+
rules: {
|
|
105
|
+
'no-console': 'off',
|
|
109
106
|
},
|
|
110
107
|
})
|
|
111
108
|
```
|
|
112
109
|
|
|
113
|
-
###
|
|
110
|
+
### Tailwind
|
|
114
111
|
|
|
115
|
-
`
|
|
112
|
+
`tailwind(options?)` returns a config chunk for
|
|
113
|
+
[`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss).
|
|
114
|
+
Spread it into `oxlintConfig`:
|
|
116
115
|
|
|
117
116
|
```ts
|
|
117
|
+
import { oxlintConfig, tailwind } from '@letstri/oxc-config'
|
|
118
|
+
|
|
118
119
|
export default oxlintConfig({
|
|
119
|
-
|
|
120
|
-
rules: {
|
|
121
|
-
'no-console': 'off',
|
|
122
|
-
},
|
|
123
|
-
},
|
|
120
|
+
...tailwind({ entryPoint: 'app/globals.css' }),
|
|
124
121
|
})
|
|
125
122
|
```
|
|
126
123
|
|
|
124
|
+
`entryPoint` is your Tailwind entry CSS, so the plugin can resolve class names. The plugin is an **optional peer dependency** — install it yourself:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pnpm add -D eslint-plugin-better-tailwindcss
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
If the plugin is missing, `tailwind()` logs a reminder and returns an empty
|
|
131
|
+
config instead of crashing oxlint.
|
|
132
|
+
|
|
127
133
|
## Editor setup
|
|
128
134
|
|
|
129
135
|
Both editors use the official [oxc](https://oxc.rs) tooling — `oxlint` for
|
package/dist/index.d.mts
CHANGED
|
@@ -3,59 +3,59 @@ import { defineConfig as defineConfig$1 } from "oxlint";
|
|
|
3
3
|
//#region src/index.d.ts
|
|
4
4
|
type OxlintOptions = Parameters<typeof defineConfig$1>[0];
|
|
5
5
|
type OxfmtOptions = Parameters<typeof defineConfig>[0];
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
interface
|
|
6
|
+
/**
|
|
7
|
+
* Build an oxlint config.
|
|
8
|
+
*
|
|
9
|
+
* Plugins are auto-enabled by detecting their package (`typescript`, `react`,
|
|
10
|
+
* `vue`, `next`, `vitest`, `jest`) in the nearest `package.json`. To enable a
|
|
11
|
+
* plugin whose dependency lives elsewhere — e.g. a nested workspace like
|
|
12
|
+
* `apps/web/package.json` — add it through `overrides.plugins`.
|
|
13
|
+
*
|
|
14
|
+
* `overrides` is deep-merged over the base config via defu.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* // auto-detect from the current package.json
|
|
19
|
+
* export default oxlintConfig()
|
|
20
|
+
* ```
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* // enable a plugin by hand, tweak a rule
|
|
24
|
+
* export default oxlintConfig({ plugins: ['vue'], rules: { 'no-console': 'off' } })
|
|
25
|
+
* ```
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* // add Tailwind linting
|
|
29
|
+
* export default oxlintConfig({ ...tailwind('app/globals.css') })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare function oxlintConfig(overrides?: OxlintOptions): OxlintOptions;
|
|
33
|
+
interface TailwindOptions {
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* The plugin is an optional peer dependency — install it yourself
|
|
39
|
-
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing, a warning
|
|
40
|
-
* is logged and Tailwind linting is skipped. Point the plugin at your entry
|
|
41
|
-
* CSS via `override.settings`.
|
|
42
|
-
*/
|
|
43
|
-
tailwind?: boolean;
|
|
44
|
-
/**
|
|
45
|
-
* Deep-merged over the base config via defu.
|
|
35
|
+
* Path to the Tailwind entry CSS. Required — the plugin needs it to resolve
|
|
36
|
+
* class names.
|
|
46
37
|
*/
|
|
47
|
-
|
|
38
|
+
entryPoint: string;
|
|
48
39
|
/**
|
|
49
|
-
* Directory
|
|
40
|
+
* Directory scanned to check the plugin is installed.
|
|
50
41
|
*
|
|
51
42
|
* @default process.cwd()
|
|
52
43
|
*/
|
|
53
44
|
cwd?: string;
|
|
54
45
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Tailwind linting via [`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss).
|
|
48
|
+
* Spread the result into {@link oxlintConfig}:
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* export default oxlintConfig({ ...tailwind({ entryPoint: 'app/globals.css' }) })
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* The plugin is an optional peer dependency — install it yourself
|
|
55
|
+
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing, a warning
|
|
56
|
+
* is logged and an empty config is returned so oxlint does not crash.
|
|
57
|
+
*/
|
|
58
|
+
declare function tailwind({ entryPoint, cwd }: TailwindOptions): OxlintOptions;
|
|
59
|
+
declare function oxfmtConfig(overrides?: OxfmtOptions): OxfmtOptions;
|
|
60
60
|
//#endregion
|
|
61
|
-
export { oxfmtConfig, oxlintConfig };
|
|
61
|
+
export { oxfmtConfig, oxlintConfig, tailwind };
|
package/dist/index.mjs
CHANGED
|
@@ -489,18 +489,19 @@ const basePlugins = [
|
|
|
489
489
|
"promise",
|
|
490
490
|
"oxc"
|
|
491
491
|
];
|
|
492
|
-
const
|
|
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
|
+
const pluginDetectors = {
|
|
493
498
|
typescript: {
|
|
494
499
|
packages: ["typescript"],
|
|
495
500
|
plugins: ["typescript"]
|
|
496
501
|
},
|
|
497
502
|
react: {
|
|
498
503
|
packages: ["react"],
|
|
499
|
-
plugins: [
|
|
500
|
-
"react",
|
|
501
|
-
"jsx-a11y",
|
|
502
|
-
"react-perf"
|
|
503
|
-
]
|
|
504
|
+
plugins: ["react", "jsx-a11y"]
|
|
504
505
|
},
|
|
505
506
|
vue: {
|
|
506
507
|
packages: ["vue"],
|
|
@@ -519,7 +520,6 @@ const pluginToggles = {
|
|
|
519
520
|
plugins: ["jest"]
|
|
520
521
|
}
|
|
521
522
|
};
|
|
522
|
-
const tailwindConfig = defineConfig$1({ jsPlugins: ["eslint-plugin-better-tailwindcss"] });
|
|
523
523
|
function getInstalledPackages(cwd) {
|
|
524
524
|
const names = /* @__PURE__ */ new Set();
|
|
525
525
|
try {
|
|
@@ -532,22 +532,21 @@ function getInstalledPackages(cwd) {
|
|
|
532
532
|
} catch {}
|
|
533
533
|
return names;
|
|
534
534
|
}
|
|
535
|
-
function resolvePlugins(
|
|
535
|
+
function resolvePlugins(cwd) {
|
|
536
|
+
const installed = getInstalledPackages(cwd);
|
|
536
537
|
const plugins = [...basePlugins];
|
|
537
|
-
for (const
|
|
538
|
-
const toggle = pluginToggles[name];
|
|
539
|
-
if (options[name] ?? toggle.packages.some((pkg) => installed.has(pkg))) plugins.push(...toggle.plugins);
|
|
540
|
-
}
|
|
538
|
+
for (const { packages, plugins: enabled } of Object.values(pluginDetectors)) if (packages.some((pkg) => installed.has(pkg))) plugins.push(...enabled);
|
|
541
539
|
return [...new Set(plugins)];
|
|
542
540
|
}
|
|
543
541
|
/**
|
|
544
542
|
* Build an oxlint config.
|
|
545
543
|
*
|
|
546
|
-
*
|
|
547
|
-
* `
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
544
|
+
* Plugins are auto-enabled by detecting their package (`typescript`, `react`,
|
|
545
|
+
* `vue`, `next`, `vitest`, `jest`) in the nearest `package.json`. To enable a
|
|
546
|
+
* plugin whose dependency lives elsewhere — e.g. a nested workspace like
|
|
547
|
+
* `apps/web/package.json` — add it through `overrides.plugins`.
|
|
548
|
+
*
|
|
549
|
+
* `overrides` is deep-merged over the base config via defu.
|
|
551
550
|
*
|
|
552
551
|
* @example
|
|
553
552
|
* ```ts
|
|
@@ -556,33 +555,52 @@ function resolvePlugins(options, installed) {
|
|
|
556
555
|
* ```
|
|
557
556
|
* @example
|
|
558
557
|
* ```ts
|
|
559
|
-
* //
|
|
560
|
-
* export default oxlintConfig({ vue:
|
|
558
|
+
* // enable a plugin by hand, tweak a rule
|
|
559
|
+
* export default oxlintConfig({ plugins: ['vue'], rules: { 'no-console': 'off' } })
|
|
561
560
|
* ```
|
|
562
561
|
* @example
|
|
563
562
|
* ```ts
|
|
564
|
-
* // Tailwind
|
|
565
|
-
* export default oxlintConfig({
|
|
566
|
-
* tailwind: true,
|
|
567
|
-
* override: {
|
|
568
|
-
* settings: { 'better-tailwindcss': { entryPoint: 'src/styles/globals.css' } },
|
|
569
|
-
* },
|
|
570
|
-
* })
|
|
563
|
+
* // add Tailwind linting
|
|
564
|
+
* export default oxlintConfig({ ...tailwind('app/globals.css') })
|
|
571
565
|
* ```
|
|
572
566
|
*/
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
567
|
+
function oxlintConfig(overrides = {}) {
|
|
568
|
+
return defu(overrides, { plugins: resolvePlugins(process.cwd()) }, baseOxlintConfig);
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Tailwind linting via [`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss).
|
|
572
|
+
* Spread the result into {@link oxlintConfig}:
|
|
573
|
+
*
|
|
574
|
+
* ```ts
|
|
575
|
+
* export default oxlintConfig({ ...tailwind({ entryPoint: 'app/globals.css' }) })
|
|
576
|
+
* ```
|
|
577
|
+
*
|
|
578
|
+
* The plugin is an optional peer dependency — install it yourself
|
|
579
|
+
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing, a warning
|
|
580
|
+
* is logged and an empty config is returned so oxlint does not crash.
|
|
581
|
+
*/
|
|
582
|
+
function tailwind({ entryPoint, cwd = process.cwd() }) {
|
|
583
|
+
if (!getInstalledPackages(cwd).has(TAILWIND_PLUGIN)) {
|
|
579
584
|
console.warn(`[@letstri/oxc-config] Tailwind linting needs "${TAILWIND_PLUGIN}". Install it: pnpm add -D ${TAILWIND_PLUGIN}`);
|
|
580
|
-
|
|
585
|
+
return {};
|
|
581
586
|
}
|
|
582
|
-
return
|
|
587
|
+
return defineConfig$1({
|
|
588
|
+
jsPlugins: [TAILWIND_PLUGIN],
|
|
589
|
+
settings: { "better-tailwindcss": { entryPoint } },
|
|
590
|
+
rules: {
|
|
591
|
+
"better-tailwindcss/enforce-consistent-class-order": "error",
|
|
592
|
+
"better-tailwindcss/enforce-consistent-line-wrapping": "off",
|
|
593
|
+
"better-tailwindcss/no-unnecessary-whitespace": "off",
|
|
594
|
+
"better-tailwindcss/enforce-canonical-classes": "error",
|
|
595
|
+
"better-tailwindcss/no-conflicting-classes": "error",
|
|
596
|
+
"better-tailwindcss/no-deprecated-classes": "error",
|
|
597
|
+
"better-tailwindcss/no-duplicate-classes": "error",
|
|
598
|
+
"better-tailwindcss/no-unknown-classes": "error"
|
|
599
|
+
}
|
|
600
|
+
});
|
|
583
601
|
}
|
|
584
|
-
function oxfmtConfig(
|
|
585
|
-
return defu(
|
|
602
|
+
function oxfmtConfig(overrides = {}) {
|
|
603
|
+
return defu(overrides, baseOxfmtConfig);
|
|
586
604
|
}
|
|
587
605
|
//#endregion
|
|
588
|
-
export { oxfmtConfig, oxlintConfig };
|
|
606
|
+
export { oxfmtConfig, oxlintConfig, tailwind };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letstri/oxc-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Opinionated Oxlint and Oxfmt configs",
|
|
5
5
|
"homepage": "https://github.com/letstri/oxc-config#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -27,19 +27,6 @@
|
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
|
-
"scripts": {
|
|
31
|
-
"build": "tsdown",
|
|
32
|
-
"dev": "tsdown --watch",
|
|
33
|
-
"check-types": "tsc --noEmit",
|
|
34
|
-
"lint": "oxlint -c oxlint.config.ts",
|
|
35
|
-
"lint:fix": "oxlint -c oxlint.config.ts --fix",
|
|
36
|
-
"format": "oxfmt -c oxfmt.config.ts",
|
|
37
|
-
"format:check": "oxfmt -c oxfmt.config.ts --check",
|
|
38
|
-
"check": "run-p lint check-types format:check",
|
|
39
|
-
"update": "taze -r -I major",
|
|
40
|
-
"prepare": "husky",
|
|
41
|
-
"prepublishOnly": "pnpm run build"
|
|
42
|
-
},
|
|
43
30
|
"dependencies": {
|
|
44
31
|
"defu": "^6.1.7"
|
|
45
32
|
},
|
|
@@ -66,5 +53,15 @@
|
|
|
66
53
|
"engines": {
|
|
67
54
|
"node": ">=22"
|
|
68
55
|
},
|
|
69
|
-
"
|
|
70
|
-
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsdown",
|
|
58
|
+
"dev": "tsdown --watch",
|
|
59
|
+
"check-types": "tsc --noEmit",
|
|
60
|
+
"lint": "oxlint -c oxlint.config.ts",
|
|
61
|
+
"lint:fix": "oxlint -c oxlint.config.ts --fix",
|
|
62
|
+
"format": "oxfmt -c oxfmt.config.ts",
|
|
63
|
+
"format:check": "oxfmt -c oxfmt.config.ts --check",
|
|
64
|
+
"check": "run-p lint check-types format:check",
|
|
65
|
+
"update": "taze -r -I major"
|
|
66
|
+
}
|
|
67
|
+
}
|