@letstri/oxc-config 0.4.0 → 0.6.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 +24 -57
- package/dist/cli.mjs +72 -72
- package/dist/index.d.mts +23 -9
- package/dist/index.mjs +10 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,53 +13,24 @@ Opinionated, shared [oxlint](https://oxc.rs/docs/guide/usage/linter.html) and [o
|
|
|
13
13
|
npm i -D @letstri/oxc-config oxlint oxfmt
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
Then scaffold
|
|
16
|
+
Then scaffold everything with the `oxc-config` CLI:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
npx oxc-config
|
|
20
|
-
npx oxc-config editors # write .vscode + .zed settings
|
|
19
|
+
npx oxc-config init
|
|
21
20
|
```
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## AI setup prompt
|
|
27
|
-
|
|
28
|
-
Paste this into Claude Code, Cursor, or any coding agent to wire everything up:
|
|
29
|
-
|
|
30
|
-
<details>
|
|
31
|
-
<summary>Show prompt</summary>
|
|
32
|
-
|
|
33
|
-
````text
|
|
34
|
-
Set up @letstri/oxc-config (oxlint + oxfmt) in this project:
|
|
35
|
-
|
|
36
|
-
1. Install dev deps: `@letstri/oxc-config oxlint oxfmt`.
|
|
37
|
-
2. Remove ESLint and Prettier: their configs, deps, and scripts.
|
|
38
|
-
3. Create `oxlint.config.ts`:
|
|
39
|
-
```ts
|
|
40
|
-
import { oxlintConfig } from '@letstri/oxc-config'
|
|
22
|
+
`init` prompts you to pick what to set up — oxlint config, oxfmt config, VS Code,
|
|
23
|
+
Zed. Pass flags to skip the prompt (useful in CI/scripts):
|
|
41
24
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
import { oxfmtConfig } from '@letstri/oxc-config'
|
|
47
|
-
|
|
48
|
-
export default oxfmtConfig()
|
|
49
|
-
```
|
|
50
|
-
5. Add package.json scripts:
|
|
51
|
-
- "lint": "oxlint"
|
|
52
|
-
- "lint:fix": "oxlint --fix"
|
|
53
|
-
- "format": "oxfmt"
|
|
54
|
-
- "format:check": "oxfmt --check"
|
|
55
|
-
6. Framework plugins auto-enable from the nearest package.json. If a framework
|
|
56
|
-
dep (react/vue/next/vitest/jest/typescript) lives in a nested workspace,
|
|
57
|
-
enable it manually, e.g. `oxlintConfig({ plugins: ['vue'] })`.
|
|
58
|
-
7. Add the VS Code and Zed editor settings from the @letstri/oxc-config README.
|
|
59
|
-
8. Run `pnpm lint` and `pnpm format` and fix anything reported.
|
|
60
|
-
````
|
|
25
|
+
```bash
|
|
26
|
+
npx oxc-config init --oxlint --oxfmt # just the config files
|
|
27
|
+
npx oxc-config init --vscode --zed # just the editor settings
|
|
28
|
+
```
|
|
61
29
|
|
|
62
|
-
|
|
30
|
+
With flags, only the chosen targets run; with none in a non-interactive shell,
|
|
31
|
+
all four run. Config files are skipped if they already exist (`--force` to
|
|
32
|
+
overwrite); editor settings are deep-merged into any existing files. See
|
|
33
|
+
[Editor setup](#editor-setup).
|
|
63
34
|
|
|
64
35
|
## Usage
|
|
65
36
|
|
|
@@ -117,16 +88,16 @@ export default oxlintConfig({ rules: { 'no-console': 'off' } }, { plugins: ['vue
|
|
|
117
88
|
|
|
118
89
|
### Tailwind
|
|
119
90
|
|
|
120
|
-
`
|
|
91
|
+
`tailwindPlugin({ entryPoint })` returns a config chunk for
|
|
121
92
|
[`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss).
|
|
122
93
|
Pass it as an argument to `oxlintConfig`:
|
|
123
94
|
|
|
124
95
|
```ts
|
|
125
|
-
import { oxlintConfig,
|
|
96
|
+
import { oxlintConfig, tailwindPlugin } from '@letstri/oxc-config'
|
|
126
97
|
|
|
127
98
|
export default oxlintConfig(
|
|
128
99
|
{ plugins: ['react', 'jsx-a11y'] },
|
|
129
|
-
|
|
100
|
+
tailwindPlugin({ entryPoint: 'app/globals.css' }),
|
|
130
101
|
)
|
|
131
102
|
```
|
|
132
103
|
|
|
@@ -141,7 +112,7 @@ Options:
|
|
|
141
112
|
a component library generates that the plugin can't resolve):
|
|
142
113
|
|
|
143
114
|
```ts
|
|
144
|
-
|
|
115
|
+
tailwindPlugin({ entryPoint: 'app/globals.css', ignoreClasses: ['toaster'] })
|
|
145
116
|
```
|
|
146
117
|
|
|
147
118
|
The plugin is an **optional peer dependency** — install it yourself:
|
|
@@ -150,23 +121,19 @@ The plugin is an **optional peer dependency** — install it yourself:
|
|
|
150
121
|
pnpm add -D eslint-plugin-better-tailwindcss
|
|
151
122
|
```
|
|
152
123
|
|
|
153
|
-
If the plugin is missing, `
|
|
124
|
+
If the plugin is missing, `tailwindPlugin()` throws with an install hint.
|
|
154
125
|
|
|
155
126
|
## Editor setup
|
|
156
127
|
|
|
157
128
|
Both editors use the official [oxc](https://oxc.rs) tooling — `oxlint` for
|
|
158
129
|
linting and `oxfmt` for formatting — replacing ESLint and Prettier.
|
|
159
130
|
|
|
160
|
-
|
|
161
|
-
|
|
131
|
+
`oxc-config init` writes (or updates) the editor configs for you, deep-merging
|
|
132
|
+
into any existing files so your other settings are kept:
|
|
162
133
|
|
|
163
134
|
```bash
|
|
164
135
|
# both editors
|
|
165
|
-
pnpm exec oxc-config
|
|
166
|
-
|
|
167
|
-
# or just one
|
|
168
|
-
pnpm exec oxc-config editors --vscode
|
|
169
|
-
pnpm exec oxc-config editors --zed
|
|
136
|
+
pnpm exec oxc-config init --vscode --zed
|
|
170
137
|
```
|
|
171
138
|
|
|
172
139
|
It's idempotent — safe to re-run to pull the latest recommended settings.
|
|
@@ -174,13 +141,13 @@ It's idempotent — safe to re-run to pull the latest recommended settings.
|
|
|
174
141
|
### VS Code
|
|
175
142
|
|
|
176
143
|
Install the [`oxc.oxc-vscode`](https://marketplace.visualstudio.com/items?itemName=oxc.oxc-vscode)
|
|
177
|
-
extension (`
|
|
178
|
-
|
|
179
|
-
|
|
144
|
+
extension (`init --vscode` also adds it to `.vscode/extensions.json`). It writes
|
|
145
|
+
`.vscode/settings.json` — oxlint as linter, oxfmt as the default formatter with
|
|
146
|
+
format-on-save, and Prettier's import organization turned off.
|
|
180
147
|
|
|
181
148
|
### Zed
|
|
182
149
|
|
|
183
150
|
Zed ships with the oxc language servers built in, so no extension is needed.
|
|
184
|
-
`
|
|
151
|
+
`init --zed` writes `.zed/settings.json` — oxfmt as the formatter (with
|
|
185
152
|
`source.fixAll.oxc` on save for JS/TS) and Prettier disabled, across the file
|
|
186
153
|
types oxfmt supports.
|
package/dist/cli.mjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import { createDefu } from "defu";
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { dirname
|
|
6
|
-
import {
|
|
5
|
+
import { dirname } from "node:path";
|
|
6
|
+
import { cancel, isCI, isCancel, multiselect } from "@clack/prompts";
|
|
7
7
|
import { parse } from "jsonc-parser";
|
|
8
8
|
//#region src/editors.ts
|
|
9
9
|
/**
|
|
@@ -73,93 +73,93 @@ const zedSettings = {
|
|
|
73
73
|
};
|
|
74
74
|
//#endregion
|
|
75
75
|
//#region src/cli.ts
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
* concatenated — keeps updates idempotent and preserves user-added entries.
|
|
79
|
-
*/
|
|
80
|
-
const mergeConfig = createDefu((obj, key, value) => {
|
|
76
|
+
const log = (message) => process.stdout.write(`${message}\n`);
|
|
77
|
+
const merge = createDefu((obj, key, value) => {
|
|
81
78
|
const current = obj[key];
|
|
82
79
|
if (Array.isArray(current) && Array.isArray(value)) {
|
|
83
|
-
const
|
|
84
|
-
obj[key] = [...
|
|
85
|
-
const id = JSON.stringify(item);
|
|
86
|
-
if (seen.has(id)) return false;
|
|
87
|
-
seen.add(id);
|
|
88
|
-
return true;
|
|
89
|
-
});
|
|
80
|
+
const union = [...value, ...current].map((item) => JSON.stringify(item));
|
|
81
|
+
obj[key] = [...new Set(union)].map((item) => JSON.parse(item));
|
|
90
82
|
return true;
|
|
91
83
|
}
|
|
92
84
|
return false;
|
|
93
85
|
});
|
|
94
|
-
function
|
|
95
|
-
if (!existsSync(path)) return {};
|
|
96
|
-
return parse(readFileSync(path, "utf-8"), [], { allowTrailingComma: true }) ?? {};
|
|
97
|
-
}
|
|
98
|
-
/** Deep-merge `base` into the JSON(C) file at `path`, creating it if absent. */
|
|
99
|
-
function mergeJsonFile(path, base) {
|
|
86
|
+
function mergeJson(path, base) {
|
|
100
87
|
const existed = existsSync(path);
|
|
101
|
-
const
|
|
88
|
+
const current = existed ? parse(readFileSync(path, "utf-8"), [], { allowTrailingComma: true }) : {};
|
|
102
89
|
mkdirSync(dirname(path), { recursive: true });
|
|
103
|
-
writeFileSync(path, `${JSON.stringify(
|
|
90
|
+
writeFileSync(path, `${JSON.stringify(merge(base, current ?? {}), null, 2)}\n`);
|
|
104
91
|
return existed ? "updated" : "created";
|
|
105
92
|
}
|
|
106
|
-
|
|
107
|
-
function writeFile(path, content, force) {
|
|
93
|
+
function writeConfig(path, content, force) {
|
|
108
94
|
const existed = existsSync(path);
|
|
109
95
|
if (existed && !force) return "skipped";
|
|
110
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
111
96
|
writeFileSync(path, content);
|
|
112
97
|
return existed ? "overwritten" : "created";
|
|
113
98
|
}
|
|
114
|
-
const
|
|
99
|
+
const template = (fn) => `import { ${fn} } from '@letstri/oxc-config'\n\nexport default ${fn}()\n`;
|
|
100
|
+
const TARGETS = {
|
|
101
|
+
oxlint: {
|
|
102
|
+
label: "oxlint.config.ts",
|
|
103
|
+
run: (force) => `oxlint: ${writeConfig("oxlint.config.ts", template("oxlintConfig"), force)}`
|
|
104
|
+
},
|
|
105
|
+
oxfmt: {
|
|
106
|
+
label: "oxfmt.config.ts",
|
|
107
|
+
run: (force) => `oxfmt: ${writeConfig("oxfmt.config.ts", template("oxfmtConfig"), force)}`
|
|
108
|
+
},
|
|
109
|
+
vscode: {
|
|
110
|
+
label: "VS Code settings (.vscode)",
|
|
111
|
+
run: () => `vscode: ${mergeJson(".vscode/settings.json", vscodeSettings)} settings, ${mergeJson(".vscode/extensions.json", vscodeExtensions)} extensions`
|
|
112
|
+
},
|
|
113
|
+
zed: {
|
|
114
|
+
label: "Zed settings (.zed)",
|
|
115
|
+
run: () => `zed: ${mergeJson(".zed/settings.json", zedSettings)}`
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const ALL = Object.keys(TARGETS);
|
|
119
|
+
async function pickTargets(flags) {
|
|
120
|
+
const flagged = ALL.filter((target) => flags.has(`--${target}`));
|
|
121
|
+
if (flagged.length > 0) return flagged;
|
|
122
|
+
if (isCI() || !process.stdout.isTTY) return ALL;
|
|
123
|
+
const selected = await multiselect({
|
|
124
|
+
message: "What do you want to set up?",
|
|
125
|
+
options: ALL.map((value) => ({
|
|
126
|
+
value,
|
|
127
|
+
label: TARGETS[value].label
|
|
128
|
+
})),
|
|
129
|
+
initialValues: ALL,
|
|
130
|
+
required: true
|
|
131
|
+
});
|
|
132
|
+
if (isCancel(selected)) {
|
|
133
|
+
cancel("Cancelled.");
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return selected;
|
|
137
|
+
}
|
|
138
|
+
function version() {
|
|
139
|
+
const url = new URL("../package.json", import.meta.url);
|
|
140
|
+
return JSON.parse(readFileSync(url, "utf-8")).version;
|
|
141
|
+
}
|
|
142
|
+
const HELP = `oxc-config — set up @letstri/oxc-config in your project
|
|
115
143
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const OXFMT_CONFIG = `import { oxfmtConfig } from '@letstri/oxc-config'
|
|
144
|
+
Usage:
|
|
145
|
+
oxc-config [flags]
|
|
119
146
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
147
|
+
Flags (default: prompt for what to set up):
|
|
148
|
+
--oxlint create oxlint.config.ts
|
|
149
|
+
--oxfmt create oxfmt.config.ts
|
|
150
|
+
--vscode write .vscode settings
|
|
151
|
+
--zed write .zed settings
|
|
152
|
+
-f, --force overwrite existing config files
|
|
153
|
+
-h, --help show this help
|
|
154
|
+
-v, --version show version`;
|
|
155
|
+
const argv = process.argv.slice(2);
|
|
156
|
+
if (argv.includes("--help") || argv.includes("-h")) log(HELP);
|
|
157
|
+
else if (argv.includes("--version") || argv.includes("-v")) log(version());
|
|
158
|
+
else {
|
|
159
|
+
const flags = new Set(argv);
|
|
160
|
+
const force = flags.has("--force") || flags.has("-f");
|
|
161
|
+
const targets = await pickTargets(flags);
|
|
162
|
+
for (const target of targets ?? []) log(TARGETS[target].run(force));
|
|
128
163
|
}
|
|
129
|
-
run([command({
|
|
130
|
-
name: "config",
|
|
131
|
-
desc: "Create oxlint.config.ts and oxfmt.config.ts",
|
|
132
|
-
options: { force: boolean().alias("f").desc("Overwrite existing files").default(false) },
|
|
133
|
-
handler: ({ force }) => {
|
|
134
|
-
const cwd = process.cwd();
|
|
135
|
-
const lint = writeFile(resolve(cwd, "oxlint.config.ts"), OXLINT_CONFIG, force);
|
|
136
|
-
const fmt = writeFile(resolve(cwd, "oxfmt.config.ts"), OXFMT_CONFIG, force);
|
|
137
|
-
process.stdout.write(`config: ${lint} oxlint.config.ts, ${fmt} oxfmt.config.ts\n`);
|
|
138
|
-
}
|
|
139
|
-
}), command({
|
|
140
|
-
name: "editors",
|
|
141
|
-
desc: "Write/update VS Code and Zed editor configs (deep-merged into existing files)",
|
|
142
|
-
options: {
|
|
143
|
-
vscode: boolean().desc("Only VS Code").default(false),
|
|
144
|
-
zed: boolean().desc("Only Zed").default(false)
|
|
145
|
-
},
|
|
146
|
-
handler: ({ vscode, zed }) => {
|
|
147
|
-
const both = !vscode && !zed;
|
|
148
|
-
const cwd = process.cwd();
|
|
149
|
-
if (both || vscode) {
|
|
150
|
-
const s = mergeJsonFile(resolve(cwd, ".vscode/settings.json"), vscodeSettings);
|
|
151
|
-
const e = mergeJsonFile(resolve(cwd, ".vscode/extensions.json"), vscodeExtensions);
|
|
152
|
-
process.stdout.write(`vscode: ${s} .vscode/settings.json, ${e} .vscode/extensions.json\n`);
|
|
153
|
-
}
|
|
154
|
-
if (both || zed) {
|
|
155
|
-
const s = mergeJsonFile(resolve(cwd, ".zed/settings.json"), zedSettings);
|
|
156
|
-
process.stdout.write(`zed: ${s} .zed/settings.json\n`);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
})], {
|
|
160
|
-
name: "oxc-config",
|
|
161
|
-
description: "Set up @letstri/oxc-config in your project",
|
|
162
|
-
version: version()
|
|
163
|
-
});
|
|
164
164
|
//#endregion
|
|
165
165
|
export {};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { defineConfig } from "oxlint";
|
|
2
2
|
import { defineConfig as defineConfig$1 } from "oxfmt";
|
|
3
3
|
//#region src/oxlint.d.ts
|
|
4
|
-
type OxlintOptions
|
|
4
|
+
type OxlintOptions = Parameters<typeof defineConfig>[0];
|
|
5
|
+
type OxlintPlugin = NonNullable<NonNullable<OxlintOptions>['plugins']>[number];
|
|
6
|
+
declare const basePlugins: readonly ["import", "unicorn", "jsdoc", "node", "promise", "oxc"];
|
|
7
|
+
/**
|
|
8
|
+
* Plugins always enabled by the base config — excluded from the `plugins` you
|
|
9
|
+
* can add, since listing them again is redundant.
|
|
10
|
+
*/
|
|
11
|
+
type BasePlugin = (typeof basePlugins)[number];
|
|
12
|
+
/**
|
|
13
|
+
* Oxlint config accepted by {@link oxlintConfig}. Same as oxlint's own config,
|
|
14
|
+
* but `plugins` can't include the always-on base plugins.
|
|
15
|
+
*/
|
|
16
|
+
type OxlintConfig = Omit<NonNullable<OxlintOptions>, 'plugins'> & {
|
|
17
|
+
plugins?: Exclude<OxlintPlugin, BasePlugin>[];
|
|
18
|
+
};
|
|
5
19
|
/**
|
|
6
20
|
* Build an oxlint config.
|
|
7
21
|
*
|
|
@@ -10,8 +24,9 @@ type OxlintOptions$1 = Parameters<typeof defineConfig>[0];
|
|
|
10
24
|
* plugin whose dependency lives elsewhere — e.g. a nested workspace like
|
|
11
25
|
* `apps/web/package.json` — add it through `plugins`.
|
|
12
26
|
*
|
|
13
|
-
* Pass any number of config objects; they are deep-merged (arrays concatenated
|
|
14
|
-
* so pieces like {@link
|
|
27
|
+
* Pass any number of config objects; they are deep-merged (arrays concatenated,
|
|
28
|
+
* with `plugins` de-duplicated), so pieces like {@link tailwindPlugin} compose
|
|
29
|
+
* without clobbering each other.
|
|
15
30
|
*
|
|
16
31
|
* @example
|
|
17
32
|
* ```ts
|
|
@@ -28,11 +43,11 @@ type OxlintOptions$1 = Parameters<typeof defineConfig>[0];
|
|
|
28
43
|
* // compose Tailwind — its plugins merge with the ones above, not overwrite
|
|
29
44
|
* export default oxlintConfig(
|
|
30
45
|
* { plugins: ['react', 'jsx-a11y'] },
|
|
31
|
-
*
|
|
46
|
+
* tailwindPlugin({ entryPoint: 'app/globals.css' }),
|
|
32
47
|
* )
|
|
33
48
|
* ```
|
|
34
49
|
*/
|
|
35
|
-
declare function oxlintConfig(...overrides:
|
|
50
|
+
declare function oxlintConfig(...overrides: OxlintConfig[]): OxlintOptions;
|
|
36
51
|
//#endregion
|
|
37
52
|
//#region src/oxfmt.d.ts
|
|
38
53
|
type OxfmtOptions = Parameters<typeof defineConfig$1>[0];
|
|
@@ -43,7 +58,6 @@ type OxfmtOptions = Parameters<typeof defineConfig$1>[0];
|
|
|
43
58
|
declare function oxfmtConfig(...overrides: OxfmtOptions[]): OxfmtOptions;
|
|
44
59
|
//#endregion
|
|
45
60
|
//#region src/tailwind.d.ts
|
|
46
|
-
type OxlintOptions = Parameters<typeof defineConfig>[0];
|
|
47
61
|
interface TailwindOptions {
|
|
48
62
|
/**
|
|
49
63
|
* Path to the Tailwind entry CSS. Required — the plugin needs it to resolve
|
|
@@ -67,7 +81,7 @@ interface TailwindOptions {
|
|
|
67
81
|
* Pass the result as an argument to `oxlintConfig`:
|
|
68
82
|
*
|
|
69
83
|
* ```ts
|
|
70
|
-
* export default oxlintConfig(
|
|
84
|
+
* export default oxlintConfig(tailwindPlugin({
|
|
71
85
|
* entryPoint: 'app/globals.css',
|
|
72
86
|
* ignoreClasses: ['toaster'],
|
|
73
87
|
* }))
|
|
@@ -77,6 +91,6 @@ interface TailwindOptions {
|
|
|
77
91
|
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing, an error
|
|
78
92
|
* is thrown.
|
|
79
93
|
*/
|
|
80
|
-
declare function
|
|
94
|
+
declare function tailwindPlugin({ entryPoint, ignoreClasses, cwd }: TailwindOptions): OxlintConfig;
|
|
81
95
|
//#endregion
|
|
82
|
-
export { oxfmtConfig, oxlintConfig,
|
|
96
|
+
export { oxfmtConfig, oxlintConfig, tailwindPlugin };
|
package/dist/index.mjs
CHANGED
|
@@ -536,8 +536,9 @@ function resolvePlugins(cwd) {
|
|
|
536
536
|
* plugin whose dependency lives elsewhere — e.g. a nested workspace like
|
|
537
537
|
* `apps/web/package.json` — add it through `plugins`.
|
|
538
538
|
*
|
|
539
|
-
* Pass any number of config objects; they are deep-merged (arrays concatenated
|
|
540
|
-
* so pieces like {@link
|
|
539
|
+
* Pass any number of config objects; they are deep-merged (arrays concatenated,
|
|
540
|
+
* with `plugins` de-duplicated), so pieces like {@link tailwindPlugin} compose
|
|
541
|
+
* without clobbering each other.
|
|
541
542
|
*
|
|
542
543
|
* @example
|
|
543
544
|
* ```ts
|
|
@@ -554,12 +555,14 @@ function resolvePlugins(cwd) {
|
|
|
554
555
|
* // compose Tailwind — its plugins merge with the ones above, not overwrite
|
|
555
556
|
* export default oxlintConfig(
|
|
556
557
|
* { plugins: ['react', 'jsx-a11y'] },
|
|
557
|
-
*
|
|
558
|
+
* tailwindPlugin({ entryPoint: 'app/globals.css' }),
|
|
558
559
|
* )
|
|
559
560
|
* ```
|
|
560
561
|
*/
|
|
561
562
|
function oxlintConfig(...overrides) {
|
|
562
|
-
|
|
563
|
+
const merged = defu({}, ...overrides, { plugins: resolvePlugins(process.cwd()) }, baseOxlintConfig);
|
|
564
|
+
if (merged?.plugins) merged.plugins = [...new Set(merged.plugins)];
|
|
565
|
+
return merged;
|
|
563
566
|
}
|
|
564
567
|
//#endregion
|
|
565
568
|
//#region src/oxfmt.ts
|
|
@@ -586,7 +589,7 @@ const TAILWIND_PLUGIN = "eslint-plugin-better-tailwindcss";
|
|
|
586
589
|
* Pass the result as an argument to `oxlintConfig`:
|
|
587
590
|
*
|
|
588
591
|
* ```ts
|
|
589
|
-
* export default oxlintConfig(
|
|
592
|
+
* export default oxlintConfig(tailwindPlugin({
|
|
590
593
|
* entryPoint: 'app/globals.css',
|
|
591
594
|
* ignoreClasses: ['toaster'],
|
|
592
595
|
* }))
|
|
@@ -596,7 +599,7 @@ const TAILWIND_PLUGIN = "eslint-plugin-better-tailwindcss";
|
|
|
596
599
|
* (`pnpm add -D eslint-plugin-better-tailwindcss`). If it is missing, an error
|
|
597
600
|
* is thrown.
|
|
598
601
|
*/
|
|
599
|
-
function
|
|
602
|
+
function tailwindPlugin({ entryPoint, ignoreClasses = [], cwd = process.cwd() }) {
|
|
600
603
|
if (!getInstalledPackages(cwd).has(TAILWIND_PLUGIN)) throw new Error(`[@letstri/oxc-config] Tailwind linting needs "${TAILWIND_PLUGIN}". Install it: pnpm add -D ${TAILWIND_PLUGIN}`);
|
|
601
604
|
return defineConfig({
|
|
602
605
|
jsPlugins: [TAILWIND_PLUGIN],
|
|
@@ -614,4 +617,4 @@ function tailwind({ entryPoint, ignoreClasses = [], cwd = process.cwd() }) {
|
|
|
614
617
|
});
|
|
615
618
|
}
|
|
616
619
|
//#endregion
|
|
617
|
-
export { oxfmtConfig, oxlintConfig,
|
|
620
|
+
export { oxfmtConfig, oxlintConfig, tailwindPlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letstri/oxc-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Opinionated Oxlint and Oxfmt configs",
|
|
5
5
|
"homepage": "https://github.com/letstri/oxc-config#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@
|
|
34
|
+
"@clack/prompts": "^1.7.0",
|
|
35
35
|
"defu": "^6.1.7",
|
|
36
36
|
"jsonc-parser": "^3.3.1"
|
|
37
37
|
},
|