@hooshid/ox-config 0.1.0 → 0.3.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/LICENSE +21 -0
- package/README.md +364 -0
- package/dist/format.d.mts.map +1 -1
- package/dist/format.mjs +37 -7
- package/dist/format.mjs.map +1 -1
- package/dist/lint.d.mts +23 -10
- package/dist/lint.d.mts.map +1 -1
- package/dist/lint.mjs +57 -23
- package/dist/lint.mjs.map +1 -1
- package/package.json +26 -27
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 hooshid
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# @hooshid/ox-config
|
|
2
|
+
|
|
3
|
+
Shared [Oxlint](https://oxc.rs/) + [Oxfmt](https://oxc.rs/docs/guide/usage/formatter) presets for my projects. One install, lint and format ready.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add -D @hooshid/ox-config
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> [!TIP]
|
|
12
|
+
> Works with pnpm strict mode out of the box — jsPlugin paths are resolved internally via `require.resolve()`, no hoisting hacks needed.
|
|
13
|
+
|
|
14
|
+
## Lint (Oxlint)
|
|
15
|
+
|
|
16
|
+
Create `oxlint.config.ts` in your project root:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { base, unicorn, depend, react, tailwind, vitest } from '@hooshid/ox-config/lint'
|
|
20
|
+
import { defineConfig } from 'oxlint'
|
|
21
|
+
|
|
22
|
+
export default defineConfig({
|
|
23
|
+
extends: [base(), unicorn(), depend(), react(), tailwind(), vitest()],
|
|
24
|
+
})
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Every preset is a function. Call without arguments for defaults, or pass overrides:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
export default defineConfig({
|
|
31
|
+
extends: [
|
|
32
|
+
base({ rules: { 'no-console': 'off' } }),
|
|
33
|
+
unicorn({ rules: { 'unicorn/no-array-for-each': 'off' } }),
|
|
34
|
+
vitest({ files: ['**/*.e2e-spec.ts', '**/*.spec.ts'] }),
|
|
35
|
+
],
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> [!IMPORTANT]
|
|
40
|
+
> Most presets use deep merge via `defu` — user values take priority. File scope options **replace** their defaults (e.g. `vitest({ files: [...] })` replaces the default test globs).
|
|
41
|
+
|
|
42
|
+
### Available presets
|
|
43
|
+
|
|
44
|
+
#### Core
|
|
45
|
+
|
|
46
|
+
| Preset | Description |
|
|
47
|
+
| ------------- | ------------------------------------------------------------------- |
|
|
48
|
+
| `base()` | TypeScript, Import, categories, env, ignores. Always include first. |
|
|
49
|
+
| `typeAware()` | 59 type-aware rules via tsgolint (requires TS-compatible tsconfig) |
|
|
50
|
+
| `unicorn()` | 100+ code quality rules |
|
|
51
|
+
| `depend()` | Flag packages replaceable with native APIs or micro-utilities |
|
|
52
|
+
|
|
53
|
+
#### Runtime
|
|
54
|
+
|
|
55
|
+
| Preset | Description |
|
|
56
|
+
| ----------- | ---------------------------------- |
|
|
57
|
+
| `node()` | Node.js specific rules |
|
|
58
|
+
| `promise()` | Promise best practices (16 rules) |
|
|
59
|
+
|
|
60
|
+
#### Frontend
|
|
61
|
+
|
|
62
|
+
| Preset | Description |
|
|
63
|
+
| ------------------ | -------------------------------------------------------- |
|
|
64
|
+
| `react()` | React + React Hooks |
|
|
65
|
+
| `reactVite()` | React + React Hooks + React Refresh (for Vite) |
|
|
66
|
+
| `nextjs()` | Next.js rules + Core Web Vitals |
|
|
67
|
+
| `tanstackRouter()` | TanStack Router — route param names + property ordering |
|
|
68
|
+
| `tailwind()` | Tailwind class consistency (better-tailwindcss plugin) |
|
|
69
|
+
|
|
70
|
+
#### Backend / ORM
|
|
71
|
+
|
|
72
|
+
| Preset | Description |
|
|
73
|
+
| ----------- | ---------------------------------------------------------------------- |
|
|
74
|
+
| `nestjs()` | NestJS DI validation, Swagger consistency, decorator checks (14 rules) |
|
|
75
|
+
| `drizzle()` | Drizzle ORM — enforce where clause on delete/update |
|
|
76
|
+
|
|
77
|
+
#### Quality
|
|
78
|
+
|
|
79
|
+
| Preset | Description |
|
|
80
|
+
| --------- | ------------------------ |
|
|
81
|
+
| `a11y()` | JSX accessibility (WCAG) |
|
|
82
|
+
| `jsdoc()` | JSDoc validation |
|
|
83
|
+
|
|
84
|
+
#### Testing
|
|
85
|
+
|
|
86
|
+
| Preset | Description |
|
|
87
|
+
| ---------- | ---------------------------------------- |
|
|
88
|
+
| `vitest()` | Vitest best practices, environment-aware |
|
|
89
|
+
|
|
90
|
+
### Which React preset should I use?
|
|
91
|
+
|
|
92
|
+
| Project type | Preset |
|
|
93
|
+
| ----------------------------- | ------------- |
|
|
94
|
+
| Next.js | `nextjs()` |
|
|
95
|
+
| Vite + React | `reactVite()` |
|
|
96
|
+
| TanStack Start | `reactVite()` |
|
|
97
|
+
| Plain React (CRA, custom) | `react()` |
|
|
98
|
+
|
|
99
|
+
> `reactVite()` adds `eslint-plugin-react-refresh` to warn about incorrect fast-refresh patterns — use it for any Vite-based setup.
|
|
100
|
+
|
|
101
|
+
### NestJS projects
|
|
102
|
+
|
|
103
|
+
> [!WARNING]
|
|
104
|
+
> NestJS must disable `typescript/consistent-type-imports` — NestJS DI uses runtime class references in constructor params, and without type-aware linting this rule incorrectly converts them to `import type`, breaking DI at runtime.
|
|
105
|
+
>
|
|
106
|
+
> ```ts
|
|
107
|
+
> export default defineConfig({
|
|
108
|
+
> extends: [base(), nestjs()],
|
|
109
|
+
> overrides: [
|
|
110
|
+
> {
|
|
111
|
+
> files: ['**/*.{ts,mts,cts,tsx}'],
|
|
112
|
+
> rules: {
|
|
113
|
+
> 'typescript/consistent-type-imports': 'off',
|
|
114
|
+
> 'typescript/no-extraneous-class': ['error', { allowWithDecorator: true }],
|
|
115
|
+
> },
|
|
116
|
+
> },
|
|
117
|
+
> ],
|
|
118
|
+
> })
|
|
119
|
+
> ```
|
|
120
|
+
|
|
121
|
+
### TanStack Router
|
|
122
|
+
|
|
123
|
+
The `tanstackRouter()` preset loads [`@tanstack/eslint-plugin-router`](https://www.npmjs.com/package/@tanstack/eslint-plugin-router):
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { base, tanstackRouter } from '@hooshid/ox-config/lint'
|
|
127
|
+
import { defineConfig } from 'oxlint'
|
|
128
|
+
|
|
129
|
+
export default defineConfig({
|
|
130
|
+
extends: [base(), tanstackRouter()],
|
|
131
|
+
})
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Covers:
|
|
135
|
+
- `route-param-names` — validates route param placeholders match
|
|
136
|
+
- `create-route-property-order` — enforces property ordering in `createRoute()`
|
|
137
|
+
|
|
138
|
+
### Full frontend example
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import {
|
|
142
|
+
base,
|
|
143
|
+
unicorn,
|
|
144
|
+
depend,
|
|
145
|
+
reactVite,
|
|
146
|
+
tanstackRouter,
|
|
147
|
+
tailwind,
|
|
148
|
+
vitest,
|
|
149
|
+
} from '@hooshid/ox-config/lint'
|
|
150
|
+
import { defineConfig } from 'oxlint'
|
|
151
|
+
|
|
152
|
+
export default defineConfig({
|
|
153
|
+
extends: [
|
|
154
|
+
base(),
|
|
155
|
+
unicorn(),
|
|
156
|
+
depend(),
|
|
157
|
+
reactVite(),
|
|
158
|
+
tanstackRouter(),
|
|
159
|
+
tailwind({ entryPoint: 'src/styles/globals.css', rootFontSize: 16 }),
|
|
160
|
+
vitest(),
|
|
161
|
+
],
|
|
162
|
+
})
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Full backend example
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { base, unicorn, depend, node, promise, nestjs, drizzle, vitest } from '@hooshid/ox-config/lint'
|
|
169
|
+
import { defineConfig } from 'oxlint'
|
|
170
|
+
|
|
171
|
+
export default defineConfig({
|
|
172
|
+
extends: [
|
|
173
|
+
base(),
|
|
174
|
+
unicorn(),
|
|
175
|
+
depend(),
|
|
176
|
+
node(),
|
|
177
|
+
promise(),
|
|
178
|
+
nestjs(),
|
|
179
|
+
drizzle({
|
|
180
|
+
rules: {
|
|
181
|
+
'drizzle/enforce-delete-with-where': ['error', { drizzleObjectName: 'db' }],
|
|
182
|
+
'drizzle/enforce-update-with-where': ['error', { drizzleObjectName: 'db' }],
|
|
183
|
+
},
|
|
184
|
+
}),
|
|
185
|
+
vitest({ files: ['**/*.spec.ts', '**/*.e2e-spec.ts'] }),
|
|
186
|
+
],
|
|
187
|
+
rules: {
|
|
188
|
+
// NestJS exception filter .catch() is not Promise.catch()
|
|
189
|
+
'promise/valid-params': 'off',
|
|
190
|
+
},
|
|
191
|
+
overrides: [
|
|
192
|
+
{
|
|
193
|
+
files: ['**/*.{ts,mts,cts,tsx}'],
|
|
194
|
+
rules: {
|
|
195
|
+
'typescript/consistent-type-imports': 'off',
|
|
196
|
+
'typescript/no-extraneous-class': ['error', { allowWithDecorator: true }],
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
})
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Type-aware linting
|
|
204
|
+
|
|
205
|
+
The `typeAware()` preset enables two options on oxlint:
|
|
206
|
+
|
|
207
|
+
- **`typeAware`** — turns on ~59 lint rules that need type information, implemented via [`oxlint-tsgolint`](https://www.npmjs.com/package/oxlint-tsgolint) (e.g. `no-floating-promises`, `no-misused-promises`, `consistent-type-imports`)
|
|
208
|
+
- **`typeCheck`** — pipes the TypeScript compiler's own diagnostics (`TS2322`, `TS6133`, `TS2307`, ...) through oxlint, so `oxlint` reports type errors alongside lint violations
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { base, typeAware, unicorn } from '@hooshid/ox-config/lint'
|
|
212
|
+
import { defineConfig } from 'oxlint'
|
|
213
|
+
|
|
214
|
+
export default defineConfig({
|
|
215
|
+
extends: [base(), typeAware(), unicorn()],
|
|
216
|
+
})
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
> [!IMPORTANT]
|
|
220
|
+
> `typeAware` and `typeCheck` are **root-config-only** options. Oxlint will error if either is set in a nested (per-package) config file. Always place `typeAware()` in the root config only.
|
|
221
|
+
|
|
222
|
+
Each package's own `tsconfig.json` is auto-detected by oxlint — no extra configuration needed.
|
|
223
|
+
|
|
224
|
+
#### Do I still need a separate `tsc --noEmit` step?
|
|
225
|
+
|
|
226
|
+
Short answer: **yes, keep it.** With `typeCheck` enabled, oxlint already surfaces tsc diagnostics for the files it lints, so during local development you'll usually catch type errors from `lint` alone. But a dedicated `typecheck` script is still worth keeping because:
|
|
227
|
+
|
|
228
|
+
- **Different file scope.** `tsc --noEmit` honors the tsconfig's `include` / `exclude`. `oxlint` walks the filesystem by its own rules and honors `ignorePatterns`. The two sets overlap but are not identical — a file covered by tsconfig but excluded from lint (or vice versa) will only be checked by one of them.
|
|
229
|
+
- **Project-level diagnostics.** tsc catches errors that aren't attached to a single source file: `tsconfig.json` misconfiguration (`TS5xxx`), broken project `references`, `paths` alias typos. Per-file type-aware linting can't see these.
|
|
230
|
+
- **Clearer CI failures.** Running `typecheck` and `lint` as separate steps makes it obvious whether a red build is a type error or a lint rule violation.
|
|
231
|
+
|
|
232
|
+
### Monorepo (nested configs)
|
|
233
|
+
|
|
234
|
+
Oxlint supports [nested configuration](https://oxc.rs/docs/guide/usage/linter/nested-config.html) for monorepos. Each package can have its own `oxlint.config.ts` that extends the root config and adds package-specific presets.
|
|
235
|
+
|
|
236
|
+
#### Root config
|
|
237
|
+
|
|
238
|
+
Keep shared baseline and `typeAware()` at the root:
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
// oxlint.config.ts (root)
|
|
242
|
+
import { base, typeAware, unicorn, depend } from '@hooshid/ox-config/lint'
|
|
243
|
+
import { defineConfig } from 'oxlint'
|
|
244
|
+
|
|
245
|
+
export default defineConfig({
|
|
246
|
+
extends: [base(), typeAware(), unicorn(), depend()],
|
|
247
|
+
})
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
#### Package configs
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
// packages/web/oxlint.config.ts
|
|
254
|
+
import rootConfig from '../../oxlint.config.ts'
|
|
255
|
+
import { reactVite, tanstackRouter, vitest, tailwind } from '@hooshid/ox-config/lint'
|
|
256
|
+
import { defineConfig } from 'oxlint'
|
|
257
|
+
|
|
258
|
+
export default defineConfig({
|
|
259
|
+
extends: [rootConfig, reactVite(), tanstackRouter(), vitest(), tailwind()],
|
|
260
|
+
})
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
// packages/api/oxlint.config.ts
|
|
265
|
+
import rootConfig from '../../oxlint.config.ts'
|
|
266
|
+
import { node, nestjs, drizzle, vitest } from '@hooshid/ox-config/lint'
|
|
267
|
+
import { defineConfig } from 'oxlint'
|
|
268
|
+
|
|
269
|
+
export default defineConfig({
|
|
270
|
+
extends: [rootConfig, node(), nestjs(), drizzle(), vitest()],
|
|
271
|
+
})
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
> [!TIP]
|
|
275
|
+
> Packages without their own `oxlint.config.ts` automatically use the root config — no setup needed for packages that only need the shared baseline.
|
|
276
|
+
|
|
277
|
+
> [!WARNING]
|
|
278
|
+
> Passing `-c` or `--config` explicitly on the CLI **disables** nested config lookup. Let oxlint auto-detect configs by running without `-c`.
|
|
279
|
+
|
|
280
|
+
## Format (Oxfmt)
|
|
281
|
+
|
|
282
|
+
Create `oxfmt.config.ts`:
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
import { format } from '@hooshid/ox-config/format'
|
|
286
|
+
import { defineConfig } from 'oxfmt'
|
|
287
|
+
|
|
288
|
+
export default defineConfig({ ...format() })
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Defaults
|
|
292
|
+
|
|
293
|
+
| Option | Value |
|
|
294
|
+
| -------------------- | --------------------- |
|
|
295
|
+
| `semi` | `false` |
|
|
296
|
+
| `singleQuote` | `true` |
|
|
297
|
+
| `trailingComma` | `all` |
|
|
298
|
+
| `printWidth` | `100` |
|
|
299
|
+
| `tabWidth` | `2` |
|
|
300
|
+
| `endOfLine` | `lf` |
|
|
301
|
+
| Import sorting | Grouped with newlines |
|
|
302
|
+
| Package.json sorting | Enabled |
|
|
303
|
+
|
|
304
|
+
### Override
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
export default defineConfig({
|
|
308
|
+
...format({ printWidth: 120, semi: true }),
|
|
309
|
+
})
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Tailwind class sorting
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
import { format, tailwindFormat } from '@hooshid/ox-config/format'
|
|
316
|
+
|
|
317
|
+
export default defineConfig({
|
|
318
|
+
...format(),
|
|
319
|
+
...tailwindFormat({ stylesheet: 'src/styles/globals.css' }),
|
|
320
|
+
})
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Editor setup (recommended)
|
|
324
|
+
|
|
325
|
+
To keep line endings consistent and avoid the "final newline flip-flop" problem, add an `.editorconfig` at the root of every project:
|
|
326
|
+
|
|
327
|
+
```ini
|
|
328
|
+
root = true
|
|
329
|
+
|
|
330
|
+
[*]
|
|
331
|
+
charset = utf-8
|
|
332
|
+
end_of_line = lf
|
|
333
|
+
insert_final_newline = true
|
|
334
|
+
trim_trailing_whitespace = true
|
|
335
|
+
indent_style = space
|
|
336
|
+
indent_size = 2
|
|
337
|
+
max_line_length = 100
|
|
338
|
+
|
|
339
|
+
[*.md]
|
|
340
|
+
trim_trailing_whitespace = false
|
|
341
|
+
|
|
342
|
+
[*.{yml,yaml}]
|
|
343
|
+
indent_size = 2
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Most modern editors support EditorConfig natively or via a plugin. This ensures LF endings and a single trailing newline across every file.
|
|
347
|
+
|
|
348
|
+
## Scripts
|
|
349
|
+
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"scripts": {
|
|
353
|
+
"lint": "oxlint .",
|
|
354
|
+
"lint:fix": "oxlint . --fix",
|
|
355
|
+
"format": "oxfmt .",
|
|
356
|
+
"format:check": "oxfmt --check .",
|
|
357
|
+
"typecheck": "tsc --noEmit"
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## License
|
|
363
|
+
|
|
364
|
+
MIT
|
package/dist/format.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.mts","names":[],"sources":["../src/format.ts"],"mappings":";;;wBAqBgB,OAAO,YAAY,0BAA0B;;;;;
|
|
1
|
+
{"version":3,"file":"format.d.mts","names":[],"sources":["../src/format.ts"],"mappings":";;;wBAqBgB,OAAO,YAAY,0BAA0B;;;;;wBA4E7C,eAAe;EAAW;IAA6B"}
|
package/dist/format.mjs
CHANGED
|
@@ -18,16 +18,19 @@ import { defu } from "defu";
|
|
|
18
18
|
/** Base format preset. Pass overrides to customize. */
|
|
19
19
|
function format(overrides) {
|
|
20
20
|
return defu(overrides, {
|
|
21
|
-
semi: false,
|
|
22
|
-
singleQuote: true,
|
|
23
|
-
trailingComma: "all",
|
|
24
21
|
printWidth: 100,
|
|
25
22
|
tabWidth: 2,
|
|
26
23
|
useTabs: false,
|
|
27
|
-
arrowParens: "always",
|
|
28
|
-
bracketSpacing: true,
|
|
29
24
|
endOfLine: "lf",
|
|
25
|
+
semi: false,
|
|
26
|
+
singleQuote: true,
|
|
27
|
+
jsxSingleQuote: false,
|
|
30
28
|
quoteProps: "consistent",
|
|
29
|
+
trailingComma: "all",
|
|
30
|
+
bracketSpacing: true,
|
|
31
|
+
bracketSameLine: false,
|
|
32
|
+
arrowParens: "always",
|
|
33
|
+
sortPackageJson: true,
|
|
31
34
|
sortImports: {
|
|
32
35
|
groups: [
|
|
33
36
|
"builtin",
|
|
@@ -42,9 +45,36 @@ function format(overrides) {
|
|
|
42
45
|
{ newlinesBetween: true },
|
|
43
46
|
"type"
|
|
44
47
|
],
|
|
45
|
-
internalPattern: [
|
|
48
|
+
internalPattern: [
|
|
49
|
+
"~/",
|
|
50
|
+
"@/",
|
|
51
|
+
"#/"
|
|
52
|
+
]
|
|
46
53
|
},
|
|
47
|
-
|
|
54
|
+
ignorePatterns: [
|
|
55
|
+
"dist/**",
|
|
56
|
+
"build/**",
|
|
57
|
+
"out/**",
|
|
58
|
+
".output/**",
|
|
59
|
+
".next/**",
|
|
60
|
+
".turbo/**",
|
|
61
|
+
".cache/**",
|
|
62
|
+
".nitro/**",
|
|
63
|
+
".tanstack/**",
|
|
64
|
+
".vinxi/**",
|
|
65
|
+
".content-collections/**",
|
|
66
|
+
"public/**",
|
|
67
|
+
"coverage/**",
|
|
68
|
+
"**/api",
|
|
69
|
+
"**/build",
|
|
70
|
+
"**/public",
|
|
71
|
+
"routeTree.gen.ts",
|
|
72
|
+
"*.min.js",
|
|
73
|
+
"*.min.css",
|
|
74
|
+
"pnpm-lock.yaml",
|
|
75
|
+
"package-lock.json",
|
|
76
|
+
"yarn.lock"
|
|
77
|
+
]
|
|
48
78
|
});
|
|
49
79
|
}
|
|
50
80
|
/**
|
package/dist/format.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.mjs","names":[],"sources":["../src/format.ts"],"sourcesContent":["/**\
|
|
1
|
+
{"version":3,"file":"format.mjs","names":[],"sources":["../src/format.ts"],"sourcesContent":["/**\n * Oxfmt format presets.\n *\n * @example\n * ```ts\n * // oxfmt.config.ts\n * import { format, tailwindFormat } from '@hooshid/ox-config/format'\n * import { defineConfig } from 'oxfmt'\n *\n * export default defineConfig({\n * ...format(),\n * ...tailwindFormat({ stylesheet: 'src/styles/globals.css' }),\n * })\n * ```\n */\n\nimport { defu } from 'defu'\n\nimport type { OxfmtConfig } from 'oxfmt'\n\n/** Base format preset. Pass overrides to customize. */\nexport function format(overrides?: Record<string, unknown>): OxfmtConfig {\n return defu(overrides, {\n // Layout\n printWidth: 100,\n tabWidth: 2,\n useTabs: false,\n endOfLine: 'lf' as const,\n\n // Quotes & Semicolons\n semi: false,\n singleQuote: true,\n jsxSingleQuote: false,\n quoteProps: 'consistent' as const,\n\n // Trailing & Spacing\n trailingComma: 'all' as const,\n bracketSpacing: true,\n bracketSameLine: false,\n arrowParens: 'always' as const,\n\n // Sorting\n sortPackageJson: true,\n sortImports: {\n groups: [\n 'builtin',\n { newlinesBetween: true },\n 'external',\n { newlinesBetween: true },\n 'internal',\n { newlinesBetween: true },\n ['parent', 'sibling'],\n { newlinesBetween: true },\n 'index',\n { newlinesBetween: true },\n 'type',\n ],\n internalPattern: ['~/', '@/', '#/'],\n },\n\n // Ignore\n ignorePatterns: [\n // Build outputs\n 'dist/**',\n 'build/**',\n 'out/**',\n '.output/**',\n '.next/**',\n '.turbo/**',\n '.cache/**',\n '.nitro/**',\n '.tanstack/**',\n '.vinxi/**',\n '.content-collections/**',\n\n // Generated / vendor\n 'public/**',\n 'coverage/**',\n '**/api',\n '**/build',\n '**/public',\n 'routeTree.gen.ts',\n '*.min.js',\n '*.min.css',\n\n // Lock files\n 'pnpm-lock.yaml',\n 'package-lock.json',\n 'yarn.lock',\n ],\n }) as OxfmtConfig\n}\n\n/**\n * Oxfmt Tailwind class-sorting preset.\n * Spread into your format config alongside `format()` to enable.\n */\nexport function tailwindFormat(options: { stylesheet?: string } = {}): OxfmtConfig {\n return {\n sortTailwindcss: {\n stylesheet: options.stylesheet ?? 'src/styles/globals.css',\n functions: ['cn', 'clsx', 'cva', 'tw'] as string[],\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,SAAgB,OAAO,WAAkD;CACvE,OAAO,KAAK,WAAW;EAErB,YAAY;EACZ,UAAU;EACV,SAAS;EACT,WAAW;EAGX,MAAM;EACN,aAAa;EACb,gBAAgB;EAChB,YAAY;EAGZ,eAAe;EACf,gBAAgB;EAChB,iBAAiB;EACjB,aAAa;EAGb,iBAAiB;EACjB,aAAa;GACX,QAAQ;IACN;IACA,EAAE,iBAAiB,KAAK;IACxB;IACA,EAAE,iBAAiB,KAAK;IACxB;IACA,EAAE,iBAAiB,KAAK;IACxB,CAAC,UAAU,SAAS;IACpB,EAAE,iBAAiB,KAAK;IACxB;IACA,EAAE,iBAAiB,KAAK;IACxB;GACF;GACA,iBAAiB;IAAC;IAAM;IAAM;GAAI;EACpC;EAGA,gBAAgB;GAEd;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;EACF;CACF,CAAC;AACH;;;;;AAMA,SAAgB,eAAe,UAAmC,CAAC,GAAgB;CACjF,OAAO,EACL,iBAAiB;EACf,YAAY,QAAQ,cAAc;EAClC,WAAW;GAAC;GAAM;GAAQ;GAAO;EAAI;CACvC,EACF;AACF"}
|
package/dist/lint.d.mts
CHANGED
|
@@ -21,7 +21,10 @@ export declare const GLOB_MARKDOWN = "**/*.md";
|
|
|
21
21
|
* Always include first.
|
|
22
22
|
*/
|
|
23
23
|
export declare function base(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
24
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Type-aware lint preset — enables 59 type-aware rules via tsgolint + type checking.
|
|
26
|
+
* Requires TypeScript 7.0+ and `oxlint-tsgolint` (bundled as dependency).
|
|
27
|
+
*/
|
|
25
28
|
export declare function typeAware(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
26
29
|
/** Unicorn lint preset — 100+ code quality rules. */
|
|
27
30
|
export declare function unicorn(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
@@ -31,15 +34,27 @@ export declare function depend(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
|
31
34
|
export declare function node(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
32
35
|
/** Promise lint preset — native promise plugin. */
|
|
33
36
|
export declare function promise(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
34
|
-
/**
|
|
35
|
-
* React lint preset — React + react-refresh (for Vite/TanStack Start).
|
|
36
|
-
*/
|
|
37
|
+
/** React lint preset — enables native react + react-hooks plugin. */
|
|
37
38
|
export declare function react(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
39
|
+
/** React + react-refresh preset (for Vite projects). Use instead of `react`. */
|
|
40
|
+
export declare function reactVite(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
41
|
+
/** Next.js lint preset — enables native nextjs plugin. */
|
|
42
|
+
export declare function nextjs(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
38
43
|
/**
|
|
39
44
|
* TanStack Router lint preset — loads @tanstack/eslint-plugin-router.
|
|
40
45
|
* Covers route-param-names and create-route-property-order.
|
|
41
46
|
*/
|
|
42
47
|
export declare function tanstackRouter(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
48
|
+
/** Accessibility lint preset — enables native jsx-a11y plugin. */
|
|
49
|
+
export declare function a11y(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
50
|
+
/** JSDoc lint preset — enables native jsdoc plugin. */
|
|
51
|
+
export declare function jsdoc(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
52
|
+
interface VitestOptions extends Partial<OxlintConfig> {
|
|
53
|
+
/** Test file glob patterns. Replaces the default GLOB_TESTS. */
|
|
54
|
+
files?: string[];
|
|
55
|
+
}
|
|
56
|
+
/** Vitest lint preset — native vitest plugin with test-file scoping. */
|
|
57
|
+
export declare function vitest(options?: VitestOptions): OxlintConfig;
|
|
43
58
|
interface TailwindOptions extends Partial<OxlintConfig> {
|
|
44
59
|
entryPoint?: string;
|
|
45
60
|
rootFontSize?: number;
|
|
@@ -48,12 +63,10 @@ interface TailwindOptions extends Partial<OxlintConfig> {
|
|
|
48
63
|
}
|
|
49
64
|
/** Tailwind CSS lint preset — eslint-plugin-better-tailwindcss. */
|
|
50
65
|
export declare function tailwind(options?: TailwindOptions): OxlintConfig;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
export declare function vitest(options?: VitestOptions): OxlintConfig;
|
|
56
|
-
/** NestJS lint preset — @darraghor/eslint-plugin-nestjs-typed. */
|
|
66
|
+
/**
|
|
67
|
+
* NestJS lint preset — loads @darraghor/eslint-plugin-nestjs-typed via jsPlugin.
|
|
68
|
+
* Covers DI validation, Swagger consistency, decorator bug prevention (19 AST rules).
|
|
69
|
+
*/
|
|
57
70
|
export declare function nestjs(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
|
58
71
|
/** Drizzle ORM lint preset — eslint-plugin-drizzle. */
|
|
59
72
|
export declare function drizzle(overrides?: Partial<OxlintConfig>): OxlintConfig;
|
package/dist/lint.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.d.mts","names":[],"sources":["../src/utils.ts","../src/lint.ts"],"mappings":";;;qBAgDa;;qBAGA;;qBAGA;;qBAGA;;qBAGA;;qBAMA;;qBAGA;;;;;;;
|
|
1
|
+
{"version":3,"file":"lint.d.mts","names":[],"sources":["../src/utils.ts","../src/lint.ts"],"mappings":";;;qBAgDa;;qBAGA;;qBAGA;;qBAGA;;qBAGA;;qBAMA;;qBAGA;;;;;;;wBCsCG,KAAK,YAAY,QAAQ,gBAAgB;;;;;wBAuHzC,UAAU,YAAY,QAAQ,gBAAgB;;wBAa9C,QAAQ,YAAY,QAAQ,gBAAgB;;wBA6B5C,OAAO,YAAY,QAAQ,gBAAgB;;wBAwB3C,KAAK,YAAY,QAAQ,gBAAgB;;wBAKzC,QAAQ,YAAY,QAAQ,gBAAgB;;wBAkB5C,MAAM,YAAY,QAAQ,gBAAgB;;wBAe1C,UAAU,YAAY,QAAQ,gBAAgB;;wBAe9C,OAAO,YAAY,QAAQ,gBAAgB;;;;;wBAQ3C,eAAe,YAAY,QAAQ,gBAAgB;;wBAoBnD,KAAK,YAAY,QAAQ,gBAAgB;;wBAKzC,MAAM,YAAY,QAAQ,gBAAgB;UAQhD,sBAAsB,QAAQ;;EAEtC;;;wBAIc,OAAO,UAAU,gBAAgB;UA0CvC,wBAAwB,QAAQ;EACxC;EACA;;EAEA;;;wBAIc,SAAS,UAAS,kBAAuB;;;;;wBA6BzC,OAAO,YAAY,QAAQ,gBAAgB;;wBA+B3C,QAAQ,YAAY,QAAQ,gBAAgB"}
|
package/dist/lint.mjs
CHANGED
|
@@ -70,6 +70,9 @@ const DEFAULT_IGNORES = [
|
|
|
70
70
|
"**/.tanstack/**",
|
|
71
71
|
"**/.vinxi/**",
|
|
72
72
|
"**/.git/**",
|
|
73
|
+
"**/.svn/**",
|
|
74
|
+
"**/.hg/**",
|
|
75
|
+
"**/.pnp.*",
|
|
73
76
|
"**/public/**",
|
|
74
77
|
"**/*.d.ts"
|
|
75
78
|
];
|
|
@@ -87,6 +90,11 @@ function loadGitignorePatterns() {
|
|
|
87
90
|
function preset(defaults, overrides) {
|
|
88
91
|
return defineConfig$1(defu(overrides ?? {}, defaults));
|
|
89
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Resolve a jsPlugin package name to its absolute path.
|
|
95
|
+
* This allows oxlint to load plugins directly without relying on
|
|
96
|
+
* Node module resolution from the consumer's CWD — fixes pnpm strict mode.
|
|
97
|
+
*/
|
|
90
98
|
function resolvePlugin(name) {
|
|
91
99
|
try {
|
|
92
100
|
return require.resolve(name);
|
|
@@ -195,7 +203,10 @@ function base(overrides) {
|
|
|
195
203
|
]
|
|
196
204
|
}, overrides);
|
|
197
205
|
}
|
|
198
|
-
/**
|
|
206
|
+
/**
|
|
207
|
+
* Type-aware lint preset — enables 59 type-aware rules via tsgolint + type checking.
|
|
208
|
+
* Requires TypeScript 7.0+ and `oxlint-tsgolint` (bundled as dependency).
|
|
209
|
+
*/
|
|
199
210
|
function typeAware(overrides) {
|
|
200
211
|
return preset({ options: {
|
|
201
212
|
typeAware: true,
|
|
@@ -258,10 +269,18 @@ const reactStyleRules = {
|
|
|
258
269
|
"react/self-closing-comp": "error",
|
|
259
270
|
"react/hook-use-state": "error"
|
|
260
271
|
};
|
|
261
|
-
/**
|
|
262
|
-
* React lint preset — React + react-refresh (for Vite/TanStack Start).
|
|
263
|
-
*/
|
|
272
|
+
/** React lint preset — enables native react + react-hooks plugin. */
|
|
264
273
|
function react(overrides) {
|
|
274
|
+
return preset({
|
|
275
|
+
plugins: ["react"],
|
|
276
|
+
rules: {
|
|
277
|
+
"react/react-in-jsx-scope": "off",
|
|
278
|
+
...reactStyleRules
|
|
279
|
+
}
|
|
280
|
+
}, overrides);
|
|
281
|
+
}
|
|
282
|
+
/** React + react-refresh preset (for Vite projects). Use instead of `react`. */
|
|
283
|
+
function reactVite(overrides) {
|
|
265
284
|
return preset({
|
|
266
285
|
plugins: ["react"],
|
|
267
286
|
jsPlugins: resolvePlugins(["eslint-plugin-react-refresh"]),
|
|
@@ -271,6 +290,10 @@ function react(overrides) {
|
|
|
271
290
|
}
|
|
272
291
|
}, overrides);
|
|
273
292
|
}
|
|
293
|
+
/** Next.js lint preset — enables native nextjs plugin. */
|
|
294
|
+
function nextjs(overrides) {
|
|
295
|
+
return preset({ plugins: ["nextjs"] }, overrides);
|
|
296
|
+
}
|
|
274
297
|
/**
|
|
275
298
|
* TanStack Router lint preset — loads @tanstack/eslint-plugin-router.
|
|
276
299
|
* Covers route-param-names and create-route-property-order.
|
|
@@ -287,23 +310,13 @@ function tanstackRouter(overrides) {
|
|
|
287
310
|
}
|
|
288
311
|
}, overrides);
|
|
289
312
|
}
|
|
290
|
-
/**
|
|
291
|
-
function
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
rootFontSize
|
|
298
|
-
} },
|
|
299
|
-
overrides: [{
|
|
300
|
-
files: files ?? ["**/*.{jsx,tsx}"],
|
|
301
|
-
rules: {
|
|
302
|
-
"better-tailwindcss/enforce-consistent-line-wrapping": ["error", { printWidth: 0 }],
|
|
303
|
-
"better-tailwindcss/enforce-canonical-classes": "error"
|
|
304
|
-
}
|
|
305
|
-
}]
|
|
306
|
-
}, overrides);
|
|
313
|
+
/** Accessibility lint preset — enables native jsx-a11y plugin. */
|
|
314
|
+
function a11y(overrides) {
|
|
315
|
+
return preset({ plugins: ["jsx-a11y"] }, overrides);
|
|
316
|
+
}
|
|
317
|
+
/** JSDoc lint preset — enables native jsdoc plugin. */
|
|
318
|
+
function jsdoc(overrides) {
|
|
319
|
+
return preset({ plugins: ["jsdoc"] }, overrides);
|
|
307
320
|
}
|
|
308
321
|
/** Vitest lint preset — native vitest plugin with test-file scoping. */
|
|
309
322
|
function vitest(options) {
|
|
@@ -340,7 +353,28 @@ function vitest(options) {
|
|
|
340
353
|
}]
|
|
341
354
|
}, overrides);
|
|
342
355
|
}
|
|
343
|
-
/**
|
|
356
|
+
/** Tailwind CSS lint preset — eslint-plugin-better-tailwindcss. */
|
|
357
|
+
function tailwind(options = {}) {
|
|
358
|
+
const { entryPoint = "src/styles/globals.css", rootFontSize = 16, files, ...overrides } = options;
|
|
359
|
+
return preset({
|
|
360
|
+
jsPlugins: resolvePlugins(["eslint-plugin-better-tailwindcss"]),
|
|
361
|
+
settings: { "better-tailwindcss": {
|
|
362
|
+
entryPoint,
|
|
363
|
+
rootFontSize
|
|
364
|
+
} },
|
|
365
|
+
overrides: [{
|
|
366
|
+
files: files ?? ["**/*.{jsx,tsx}"],
|
|
367
|
+
rules: {
|
|
368
|
+
"better-tailwindcss/enforce-consistent-line-wrapping": ["error", { printWidth: 0 }],
|
|
369
|
+
"better-tailwindcss/enforce-canonical-classes": "error"
|
|
370
|
+
}
|
|
371
|
+
}]
|
|
372
|
+
}, overrides);
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* NestJS lint preset — loads @darraghor/eslint-plugin-nestjs-typed via jsPlugin.
|
|
376
|
+
* Covers DI validation, Swagger consistency, decorator bug prevention (19 AST rules).
|
|
377
|
+
*/
|
|
344
378
|
function nestjs(overrides) {
|
|
345
379
|
return preset({
|
|
346
380
|
jsPlugins: resolvePlugins([{
|
|
@@ -376,6 +410,6 @@ function drizzle(overrides) {
|
|
|
376
410
|
}, overrides);
|
|
377
411
|
}
|
|
378
412
|
//#endregion
|
|
379
|
-
export { GLOB_JS, GLOB_JSON, GLOB_JSX, GLOB_MARKDOWN, GLOB_SRC, GLOB_TESTS, GLOB_TS, base, defineConfig, depend, drizzle, nestjs, node, promise, react, tailwind, tanstackRouter, typeAware, unicorn, vitest };
|
|
413
|
+
export { GLOB_JS, GLOB_JSON, GLOB_JSX, GLOB_MARKDOWN, GLOB_SRC, GLOB_TESTS, GLOB_TS, a11y, base, defineConfig, depend, drizzle, jsdoc, nestjs, nextjs, node, promise, react, reactVite, tailwind, tanstackRouter, typeAware, unicorn, vitest };
|
|
380
414
|
|
|
381
415
|
//# sourceMappingURL=lint.mjs.map
|
package/dist/lint.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.mjs","names":["defineConfig"],"sources":["../src/utils.ts","../src/lint.ts"],"sourcesContent":["/**\r\n * Utility functions and constants\r\n */\r\n\r\n// ============================================================================\r\n// Environment detection\r\n// ============================================================================\r\n\r\nconst env = process.env\r\n\r\nfunction isCI(): boolean {\r\n return !!(\r\n env['CI'] ||\r\n env['CONTINUOUS_INTEGRATION'] ||\r\n env['BUILD_ID'] ||\r\n env['BUILD_NUMBER'] ||\r\n env['RUN_ID']\r\n )\r\n}\r\n\r\nfunction isInGitHooksOrLintStaged(): boolean {\r\n return (\r\n !!(env['GIT_PARAMS'] || env['VSCODE_GIT_COMMAND']) ||\r\n env['npm_lifecycle_script']?.startsWith('lint-staged') === true\r\n )\r\n}\r\n\r\n/**\r\n * Detects whether running in an editor environment.\r\n * Returns false in CI, Git Hooks, or lint-staged.\r\n */\r\nexport function isInEditorEnv(): boolean {\r\n if (isCI()) return false\r\n if (isInGitHooksOrLintStaged()) return false\r\n return !!(\r\n env['VSCODE_PID'] ||\r\n env['VSCODE_CWD'] ||\r\n env['JETBRAINS_IDE'] ||\r\n env['VIM'] ||\r\n env['NVIM']\r\n )\r\n}\r\n\r\n// ============================================================================\r\n// File matching patterns (Globs)\r\n// ============================================================================\r\n\r\n/** All JS/TS source files */\r\nexport const GLOB_SRC = '**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}'\r\n\r\n/** JavaScript files only */\r\nexport const GLOB_JS = '**/*.{js,mjs,cjs,jsx}'\r\n\r\n/** TypeScript files only */\r\nexport const GLOB_TS = '**/*.{ts,mts,cts,tsx}'\r\n\r\n/** JSX/TSX files (React-related) */\r\nexport const GLOB_JSX = '**/*.{jsx,tsx}'\r\n\r\n/** Test files */\r\nexport const GLOB_TESTS: string[] = [\r\n '**/*.{test,spec}.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',\r\n '**/__tests__/**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',\r\n]\r\n\r\n/** JSON files */\r\nexport const GLOB_JSON = '**/*.json'\r\n\r\n/** Markdown files */\r\nexport const GLOB_MARKDOWN = '**/*.md'","/**\r\n * Oxlint lint presets.\r\n *\r\n * Every preset is a function that accepts optional overrides, merged via `defu`.\r\n * User overrides take priority over preset defaults.\r\n *\r\n * @example\r\n * ```ts\r\n * // oxlint.config.ts\r\n * import { base, unicorn, react, tailwind, vitest } from '@hooshid/ox-config/lint'\r\n * import { defineConfig } from 'oxlint'\r\n *\r\n * export default defineConfig({\r\n * extends: [base(), unicorn(), react(), tailwind(), vitest()],\r\n * })\r\n * ```\r\n */\r\nimport { existsSync, readFileSync } from 'node:fs'\r\nimport { createRequire } from 'node:module'\r\nimport path from 'node:path'\r\n\r\nimport { defu } from 'defu'\r\nimport { defineConfig } from 'oxlint'\r\n\r\nimport { GLOB_JSX, GLOB_SRC, GLOB_TESTS, GLOB_TS, isInEditorEnv } from './utils'\r\n\r\nimport type { ExternalPluginEntry, OxlintConfig } from 'oxlint'\r\n\r\nconst require = createRequire(import.meta.url)\r\n\r\n// ============================================================================\r\n// Ignore patterns\r\n// ============================================================================\r\n\r\nconst DEFAULT_IGNORES: string[] = [\r\n '**/node_modules/**',\r\n '**/dist/**',\r\n '**/build/**',\r\n '**/out/**',\r\n '**/.next/**',\r\n '**/.cache/**',\r\n '**/.turbo/**',\r\n '**/.output/**',\r\n '**/.nitro/**',\r\n '**/.tanstack/**',\r\n '**/.vinxi/**',\r\n '**/.git/**',\r\n '**/public/**',\r\n '**/*.d.ts',\r\n]\r\n\r\nfunction loadGitignorePatterns(): string[] {\r\n const gitignoreFile = path.resolve(process.cwd(), '.gitignore')\r\n if (!existsSync(gitignoreFile)) return []\r\n\r\n return readFileSync(gitignoreFile, 'utf8')\r\n .split(/\\r?\\n/u)\r\n .map((line) => line.trim())\r\n .filter((line) => line && !line.startsWith('#'))\r\n .map((pattern) => {\r\n let p = pattern.trimEnd()\r\n if (p.startsWith('/')) p = p.slice(1)\r\n if (!p.includes('/') && !p.includes('*')) p = `**/${p}`\r\n if (p.endsWith('/')) p = `${p}**`\r\n return p\r\n })\r\n}\r\n\r\n// ============================================================================\r\n// Helpers\r\n// ============================================================================\r\n\r\nfunction preset(defaults: OxlintConfig, overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return defineConfig(defu(overrides ?? {}, defaults))\r\n}\r\n\r\nfunction resolvePlugin(name: string): string {\r\n try {\r\n return require.resolve(name)\r\n } catch {\r\n return name\r\n }\r\n}\r\n\r\nfunction resolvePlugins(plugins: ExternalPluginEntry[]): ExternalPluginEntry[] {\r\n return plugins.map((p) => {\r\n if (typeof p === 'string') return resolvePlugin(p)\r\n return { ...p, specifier: resolvePlugin(p.specifier) }\r\n })\r\n}\r\n\r\n// ============================================================================\r\n// Core\r\n// ============================================================================\r\n\r\n/**\r\n * Base lint preset — TypeScript + Import plugins, categories, env, ignores.\r\n * Always include first.\r\n */\r\nexport function base(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset(\r\n {\r\n plugins: ['typescript', 'import'],\r\n categories: {\r\n correctness: 'error',\r\n suspicious: 'error',\r\n perf: 'error',\r\n pedantic: 'warn',\r\n },\r\n rules: {\r\n 'no-await-in-loop': 'off',\r\n 'typescript/prefer-readonly-parameter-types': 'off',\r\n 'typescript/strict-boolean-expressions': 'off',\r\n 'max-lines': 'off',\r\n 'max-lines-per-function': 'off',\r\n 'no-inline-comments': 'off',\r\n 'no-warning-comments': 'off',\r\n 'import/max-dependencies': 'off',\r\n 'react/no-unescaped-entities': 'off',\r\n 'require-await': 'off',\r\n },\r\n env: {\r\n browser: true,\r\n node: true,\r\n es2026: true,\r\n builtin: true,\r\n },\r\n ignorePatterns: [...DEFAULT_IGNORES, ...loadGitignorePatterns()],\r\n overrides: [\r\n {\r\n files: [GLOB_TS],\r\n rules: {\r\n 'typescript/consistent-type-definitions': 'off',\r\n 'typescript/consistent-type-imports': 'error',\r\n 'no-unused-vars': 'off',\r\n 'typescript/array-type': 'error',\r\n 'typescript/consistent-generic-constructors': 'error',\r\n 'typescript/consistent-indexed-object-style': 'error',\r\n 'typescript/consistent-type-assertions': 'error',\r\n 'typescript/ban-tslint-comment': 'error',\r\n 'typescript/no-empty-interface': 'error',\r\n 'typescript/no-inferrable-types': 'error',\r\n 'typescript/prefer-for-of': 'error',\r\n 'typescript/prefer-function-type': 'error',\r\n 'typescript/unified-signatures': 'error',\r\n },\r\n },\r\n {\r\n files: [GLOB_SRC],\r\n rules: {\r\n 'import/no-unassigned-import': 'off',\r\n 'import/no-relative-parent-imports': 'error',\r\n 'import/first': 'error',\r\n 'import/no-duplicates': 'error',\r\n 'import/consistent-type-specifier-style': 'error',\r\n 'import/no-mutable-exports': 'error',\r\n 'import/no-named-default': 'error',\r\n },\r\n },\r\n {\r\n files: ['**/*.config.{ts,mts,cts,js,mjs,cjs}'],\r\n rules: {\r\n 'import/no-relative-parent-imports': 'off',\r\n },\r\n },\r\n {\r\n files: GLOB_TESTS,\r\n rules: {\r\n 'import/first': 'off',\r\n 'import/no-duplicates': 'off',\r\n 'import/consistent-type-specifier-style': 'off',\r\n 'unicorn/no-useless-undefined': 'off',\r\n 'typescript/no-empty-function': 'off',\r\n 'unicorn/prefer-string-replace-all': 'off',\r\n 'unicorn/no-array-callback-reference': 'off',\r\n 'unicorn/prefer-spread': 'off',\r\n 'typescript/no-non-null-assertion': 'off',\r\n 'no-magic-numbers': 'off',\r\n 'typescript/no-explicit-any': 'off',\r\n 'typescript/no-unsafe-assignment': 'off',\r\n 'typescript/no-unsafe-call': 'off',\r\n 'typescript/no-unsafe-member-access': 'off',\r\n 'typescript/no-unsafe-return': 'off',\r\n 'typescript/no-unsafe-argument': 'off',\r\n 'react/no-array-index-key': 'off',\r\n },\r\n },\r\n ],\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n/** Type-aware lint preset — enables 59 type-aware rules via tsgolint. */\r\nexport function typeAware(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset(\r\n {\r\n options: {\r\n typeAware: true,\r\n typeCheck: true,\r\n },\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n/** Unicorn lint preset — 100+ code quality rules. */\r\nexport function unicorn(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset(\r\n {\r\n plugins: ['unicorn'],\r\n rules: {\r\n 'unicorn/no-null': 'off',\r\n 'unicorn/filename-case': ['error', { case: 'kebabCase' }],\r\n 'unicorn/catch-error-name': 'error',\r\n 'unicorn/error-message': 'error',\r\n 'unicorn/prefer-optional-catch-binding': 'error',\r\n 'unicorn/no-zero-fractions': 'error',\r\n 'unicorn/number-literal-case': 'error',\r\n 'unicorn/numeric-separators-style': 'error',\r\n 'unicorn/prefer-includes': 'error',\r\n 'unicorn/prefer-spread': 'error',\r\n 'unicorn/prefer-ternary': 'error',\r\n 'unicorn/prefer-string-trim-start-end': 'error',\r\n 'unicorn/prefer-structured-clone': 'error',\r\n 'unicorn/prefer-default-parameters': 'error',\r\n 'unicorn/no-console-spaces': 'error',\r\n 'unicorn/throw-new-error': 'error',\r\n 'unicorn/require-array-join-separator': 'error',\r\n },\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n/** Dependency optimization — flags packages replaceable with native APIs. */\r\nexport function depend(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset(\r\n {\r\n jsPlugins: resolvePlugins(['eslint-plugin-depend']),\r\n rules: {\r\n 'depend/ban-dependencies': [\r\n 'error',\r\n {\r\n presets: ['native', 'microutilities', 'preferred'],\r\n modules: [],\r\n allowed: ['dotenv'],\r\n },\r\n ],\r\n },\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n// ============================================================================\r\n// Runtime environments\r\n// ============================================================================\r\n\r\n/** Node.js lint preset — native node plugin. */\r\nexport function node(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset({ plugins: ['node'] }, overrides)\r\n}\r\n\r\n/** Promise lint preset — native promise plugin. */\r\nexport function promise(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset({ plugins: ['promise'] }, overrides)\r\n}\r\n\r\n// ============================================================================\r\n// Frontend\r\n// ============================================================================\r\n\r\nconst reactStyleRules = {\r\n 'react/jsx-pascal-case': 'error',\r\n 'react/jsx-boolean-value': 'error',\r\n 'react/jsx-curly-brace-presence': 'error',\r\n 'react/jsx-fragments': 'error',\r\n 'react/self-closing-comp': 'error',\r\n 'react/hook-use-state': 'error',\r\n} as const\r\n\r\n/**\r\n * React lint preset — React + react-refresh (for Vite/TanStack Start).\r\n */\r\nexport function react(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset(\r\n {\r\n plugins: ['react'],\r\n jsPlugins: resolvePlugins(['eslint-plugin-react-refresh']),\r\n rules: {\r\n 'react/react-in-jsx-scope': 'off',\r\n ...reactStyleRules,\r\n },\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n/**\r\n * TanStack Router lint preset — loads @tanstack/eslint-plugin-router.\r\n * Covers route-param-names and create-route-property-order.\r\n */\r\nexport function tanstackRouter(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset(\r\n {\r\n jsPlugins: resolvePlugins([\r\n { name: 'tanstack-router', specifier: '@tanstack/eslint-plugin-router' },\r\n ]),\r\n rules: {\r\n 'tanstack-router/route-param-names': 'error',\r\n 'tanstack-router/create-route-property-order': 'error',\r\n },\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n// ============================================================================\r\n// Tailwind\r\n// ============================================================================\r\n\r\ninterface TailwindOptions extends Partial<OxlintConfig> {\r\n entryPoint?: string\r\n rootFontSize?: number\r\n /** File glob patterns for tailwind rules. @default GLOB_JSX */\r\n files?: string[]\r\n}\r\n\r\n/** Tailwind CSS lint preset — eslint-plugin-better-tailwindcss. */\r\nexport function tailwind(options: TailwindOptions = {}): OxlintConfig {\r\n const { entryPoint = 'src/styles/globals.css', rootFontSize = 16, files, ...overrides } = options\r\n\r\n return preset(\r\n {\r\n jsPlugins: resolvePlugins(['eslint-plugin-better-tailwindcss']),\r\n settings: { 'better-tailwindcss': { entryPoint, rootFontSize } },\r\n overrides: [\r\n {\r\n files: files ?? [GLOB_JSX],\r\n rules: {\r\n 'better-tailwindcss/enforce-consistent-line-wrapping': ['error', { printWidth: 0 }],\r\n 'better-tailwindcss/enforce-canonical-classes': 'error',\r\n },\r\n },\r\n ],\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n// ============================================================================\r\n// Testing\r\n// ============================================================================\r\n\r\ninterface VitestOptions extends Partial<OxlintConfig> {\r\n files?: string[]\r\n}\r\n\r\n/** Vitest lint preset — native vitest plugin with test-file scoping. */\r\nexport function vitest(options?: VitestOptions): OxlintConfig {\r\n const { files, ...overrides } = options ?? {}\r\n\r\n return preset(\r\n {\r\n plugins: ['vitest'],\r\n settings: { vitest: { typecheck: true } },\r\n overrides: [\r\n {\r\n files: files ?? GLOB_TESTS,\r\n rules: {\r\n 'vitest/expect-expect': 'error',\r\n 'vitest/no-conditional-expect': 'error',\r\n 'vitest/no-identical-title': 'error',\r\n 'vitest/no-import-node-test': 'error',\r\n 'vitest/no-interpolation-in-snapshots': 'error',\r\n 'vitest/no-mocks-import': 'error',\r\n 'vitest/no-standalone-expect': 'error',\r\n 'vitest/valid-describe-callback': 'error',\r\n 'vitest/valid-expect': 'error',\r\n 'vitest/valid-title': 'error',\r\n 'vitest/consistent-test-it': ['error', { fn: 'it', withinDescribe: 'it' }],\r\n 'vitest/prefer-hooks-in-order': 'error',\r\n 'vitest/prefer-lowercase-title': 'error',\r\n 'vitest/no-disabled-tests': isInEditorEnv() ? 'warn' : 'error',\r\n 'vitest/no-focused-tests': isInEditorEnv() ? 'warn' : 'error',\r\n 'vitest/require-mock-type-parameters': 'off',\r\n 'no-console': 'off',\r\n 'unicorn/no-null': 'off',\r\n 'typescript/ban-ts-comment': 'off',\r\n },\r\n },\r\n ],\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n// ============================================================================\r\n// Backend / ORM\r\n// ============================================================================\r\n\r\n/** NestJS lint preset — @darraghor/eslint-plugin-nestjs-typed. */\r\nexport function nestjs(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset(\r\n {\r\n jsPlugins: resolvePlugins([\r\n { name: 'nestjs-typed', specifier: '@darraghor/eslint-plugin-nestjs-typed' },\r\n ]),\r\n rules: {\r\n 'nestjs-typed/injectable-should-be-provided': 'error',\r\n 'nestjs-typed/provided-injected-should-match-factory-parameters': 'error',\r\n 'nestjs-typed/use-injectable-provided-token': 'error',\r\n 'nestjs-typed/api-property-matches-property-optionality': 'error',\r\n 'nestjs-typed/controllers-should-supply-api-tags': 'error',\r\n 'nestjs-typed/api-method-should-specify-api-response': 'error',\r\n 'nestjs-typed/api-property-returning-array-should-set-array': 'error',\r\n 'nestjs-typed/api-property-should-have-api-extra-models': 'error',\r\n 'nestjs-typed/api-operation-summary-description-capitalized': 'error',\r\n 'nestjs-typed/param-decorator-name-matches-route-param': 'error',\r\n 'nestjs-typed/validate-nested-of-array-should-set-each': 'error',\r\n 'nestjs-typed/all-properties-are-whitelisted': 'error',\r\n 'nestjs-typed/no-duplicate-decorators': 'error',\r\n 'nestjs-typed/validation-pipe-should-use-forbid-unknown': 'error',\r\n },\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n/** Drizzle ORM lint preset — eslint-plugin-drizzle. */\r\nexport function drizzle(overrides?: Partial<OxlintConfig>): OxlintConfig {\r\n return preset(\r\n {\r\n jsPlugins: resolvePlugins(['eslint-plugin-drizzle']),\r\n rules: {\r\n 'drizzle/enforce-delete-with-where': 'error',\r\n 'drizzle/enforce-update-with-where': 'error',\r\n },\r\n },\r\n overrides,\r\n )\r\n}\r\n\r\n// ============================================================================\r\n// Re-exports\r\n// ============================================================================\r\n\r\nexport { defineConfig } from 'oxlint'\r\nexport {\r\n GLOB_SRC,\r\n GLOB_JS,\r\n GLOB_TS,\r\n GLOB_JSX,\r\n GLOB_TESTS,\r\n GLOB_JSON,\r\n GLOB_MARKDOWN,\r\n} from './utils'"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lint.mjs","names":["defineConfig"],"sources":["../src/utils.ts","../src/lint.ts"],"sourcesContent":["/**\n * Utility functions and constants\n */\n\n// ============================================================================\n// Environment detection\n// ============================================================================\n\nconst env = process.env\n\nfunction isCI(): boolean {\n return !!(\n env['CI'] ||\n env['CONTINUOUS_INTEGRATION'] ||\n env['BUILD_ID'] ||\n env['BUILD_NUMBER'] ||\n env['RUN_ID']\n )\n}\n\nfunction isInGitHooksOrLintStaged(): boolean {\n return (\n !!(env['GIT_PARAMS'] || env['VSCODE_GIT_COMMAND']) ||\n env['npm_lifecycle_script']?.startsWith('lint-staged') === true\n )\n}\n\n/**\n * Detects whether running in an editor environment.\n * Returns false in CI, Git Hooks, or lint-staged.\n */\nexport function isInEditorEnv(): boolean {\n if (isCI()) return false\n if (isInGitHooksOrLintStaged()) return false\n return !!(\n env['VSCODE_PID'] ||\n env['VSCODE_CWD'] ||\n env['JETBRAINS_IDE'] ||\n env['VIM'] ||\n env['NVIM']\n )\n}\n\n// ============================================================================\n// File matching patterns (Globs)\n// ============================================================================\n\n/** All JS/TS source files */\nexport const GLOB_SRC = '**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}'\n\n/** JavaScript files only */\nexport const GLOB_JS = '**/*.{js,mjs,cjs,jsx}'\n\n/** TypeScript files only */\nexport const GLOB_TS = '**/*.{ts,mts,cts,tsx}'\n\n/** JSX/TSX files (React-related) */\nexport const GLOB_JSX = '**/*.{jsx,tsx}'\n\n/** Test files */\nexport const GLOB_TESTS: string[] = [\n '**/*.{test,spec}.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',\n '**/__tests__/**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',\n]\n\n/** JSON files */\nexport const GLOB_JSON = '**/*.json'\n\n/** Markdown files */\nexport const GLOB_MARKDOWN = '**/*.md'\n","/**\n * Oxlint lint presets.\n *\n * Every preset is a function that accepts optional overrides, merged via `defu`.\n * User overrides take priority over preset defaults.\n *\n * @example\n * ```ts\n * // oxlint.config.ts\n * import { base, unicorn, react, tailwind, vitest } from '@hooshid/ox-config/lint'\n * import { defineConfig } from 'oxlint'\n *\n * export default defineConfig({\n * extends: [base(), unicorn(), react(), tailwind(), vitest()],\n * })\n * ```\n */\nimport { existsSync, readFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\n\nimport { defu } from 'defu'\nimport { defineConfig } from 'oxlint'\n\nimport { GLOB_JSX, GLOB_SRC, GLOB_TESTS, GLOB_TS, isInEditorEnv } from './utils'\n\nimport type { ExternalPluginEntry, OxlintConfig } from 'oxlint'\n\nconst require = createRequire(import.meta.url)\n\n// ============================================================================\n// Ignore patterns\n// ============================================================================\n\nconst DEFAULT_IGNORES: string[] = [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/out/**',\n '**/.next/**',\n '**/.cache/**',\n '**/.turbo/**',\n '**/.output/**',\n '**/.nitro/**',\n '**/.tanstack/**',\n '**/.vinxi/**',\n '**/.git/**',\n '**/.svn/**',\n '**/.hg/**',\n '**/.pnp.*',\n '**/public/**',\n '**/*.d.ts',\n]\n\nfunction loadGitignorePatterns(): string[] {\n const gitignoreFile = path.resolve(process.cwd(), '.gitignore')\n if (!existsSync(gitignoreFile)) return []\n\n return readFileSync(gitignoreFile, 'utf8')\n .split(/\\r?\\n/u)\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith('#'))\n .map((pattern) => {\n let p = pattern.trimEnd()\n if (p.startsWith('/')) p = p.slice(1)\n if (!p.includes('/') && !p.includes('*')) p = `**/${p}`\n if (p.endsWith('/')) p = `${p}**`\n return p\n })\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction preset(defaults: OxlintConfig, overrides?: Partial<OxlintConfig>): OxlintConfig {\n return defineConfig(defu(overrides ?? {}, defaults))\n}\n\n/**\n * Resolve a jsPlugin package name to its absolute path.\n * This allows oxlint to load plugins directly without relying on\n * Node module resolution from the consumer's CWD — fixes pnpm strict mode.\n */\nfunction resolvePlugin(name: string): string {\n try {\n return require.resolve(name)\n } catch {\n return name\n }\n}\n\nfunction resolvePlugins(plugins: ExternalPluginEntry[]): ExternalPluginEntry[] {\n return plugins.map((p) => {\n if (typeof p === 'string') return resolvePlugin(p)\n return { ...p, specifier: resolvePlugin(p.specifier) }\n })\n}\n\n// ============================================================================\n// Core\n// ============================================================================\n\n/**\n * Base lint preset — TypeScript + Import plugins, categories, env, ignores.\n * Always include first.\n */\nexport function base(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n plugins: ['typescript', 'import'],\n categories: {\n correctness: 'error',\n suspicious: 'error',\n perf: 'error',\n pedantic: 'warn',\n },\n rules: {\n // Shape-only check; necessary in interactive CLI and sequential workflows.\n 'no-await-in-loop': 'off',\n // High-noise; readonly intent better expressed via `const generics` or call-site.\n 'typescript/prefer-readonly-parameter-types': 'off',\n // Turns `if (str)` into ceremony for marginal safety gain.\n 'typescript/strict-boolean-expressions': 'off',\n // File/function size is a reviewer call, not a lint rule.\n 'max-lines': 'off',\n 'max-lines-per-function': 'off',\n // Misfires on `/* @__PURE__ */` and similar bundler annotations.\n 'no-inline-comments': 'off',\n // TODO/FIXME triage belongs in the issue tracker.\n 'no-warning-comments': 'off',\n // Default cap of 10 is too tight for modern React/Next component files.\n 'import/max-dependencies': 'off',\n // Modern React renders apostrophes correctly; legacy noise.\n 'react/no-unescaped-entities': 'off',\n // Misfires on Next.js Server Actions and placeholder async functions.\n 'require-await': 'off',\n },\n env: {\n browser: true,\n node: true,\n es2026: true,\n builtin: true,\n },\n ignorePatterns: [...DEFAULT_IGNORES, ...loadGitignorePatterns()],\n overrides: [\n {\n files: [GLOB_TS],\n rules: {\n // Only list rules that DIFFER from categories defaults\n 'typescript/consistent-type-definitions': 'off',\n 'typescript/consistent-type-imports': 'error',\n 'no-unused-vars': 'off',\n 'typescript/array-type': 'error',\n 'typescript/consistent-generic-constructors': 'error',\n 'typescript/consistent-indexed-object-style': 'error',\n 'typescript/consistent-type-assertions': 'error',\n 'typescript/ban-tslint-comment': 'error',\n 'typescript/no-empty-interface': 'error',\n 'typescript/no-inferrable-types': 'error',\n 'typescript/prefer-for-of': 'error',\n 'typescript/prefer-function-type': 'error',\n 'typescript/unified-signatures': 'error',\n },\n },\n {\n files: [GLOB_SRC],\n rules: {\n // CSS/style side-effect imports are standard in all frontend frameworks\n 'import/no-unassigned-import': 'off',\n 'import/no-relative-parent-imports': 'error',\n 'import/first': 'error',\n 'import/no-duplicates': 'error',\n 'import/consistent-type-specifier-style': 'error',\n 'import/no-mutable-exports': 'error',\n 'import/no-named-default': 'error',\n },\n },\n {\n // Config files commonly import shared roots via `../../config.ts`\n // in monorepos — intended pattern, not a smell.\n files: ['**/*.config.{ts,mts,cts,js,mjs,cjs}'],\n rules: {\n 'import/no-relative-parent-imports': 'off',\n },\n },\n {\n // Test files use mock setup patterns (vi.mock/vi.hoisted before imports),\n // explicit mock signatures, and fixture data that\n // legitimately violate strict style/safety rules.\n files: GLOB_TESTS,\n rules: {\n // Mock setup pattern breaks standard import ordering\n 'import/first': 'off',\n 'import/no-duplicates': 'off',\n 'import/consistent-type-specifier-style': 'off',\n // Mock signatures need explicit values / async without await\n 'unicorn/no-useless-undefined': 'off',\n 'typescript/no-empty-function': 'off',\n // Modernization hints aren't useful in tests\n 'unicorn/prefer-string-replace-all': 'off',\n 'unicorn/no-array-callback-reference': 'off',\n 'unicorn/prefer-spread': 'off',\n // Tests deliberately use non-null assertions, magic numbers, any\n 'typescript/no-non-null-assertion': 'off',\n 'no-magic-numbers': 'off',\n 'typescript/no-explicit-any': 'off',\n 'typescript/no-unsafe-assignment': 'off',\n 'typescript/no-unsafe-call': 'off',\n 'typescript/no-unsafe-member-access': 'off',\n 'typescript/no-unsafe-return': 'off',\n 'typescript/no-unsafe-argument': 'off',\n // Index keys are fine when rendering fixture lists\n 'react/no-array-index-key': 'off',\n },\n },\n ],\n },\n overrides,\n )\n}\n\n/**\n * Type-aware lint preset — enables 59 type-aware rules via tsgolint + type checking.\n * Requires TypeScript 7.0+ and `oxlint-tsgolint` (bundled as dependency).\n */\nexport function typeAware(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n options: {\n typeAware: true,\n typeCheck: true,\n },\n },\n overrides,\n )\n}\n\n/** Unicorn lint preset — 100+ code quality rules. */\nexport function unicorn(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n plugins: ['unicorn'],\n rules: {\n 'unicorn/no-null': 'off',\n 'unicorn/filename-case': ['error', { case: 'kebabCase' }],\n 'unicorn/catch-error-name': 'error',\n 'unicorn/error-message': 'error',\n 'unicorn/prefer-optional-catch-binding': 'error',\n 'unicorn/no-zero-fractions': 'error',\n 'unicorn/number-literal-case': 'error',\n 'unicorn/numeric-separators-style': 'error',\n 'unicorn/prefer-includes': 'error',\n 'unicorn/prefer-spread': 'error',\n 'unicorn/prefer-ternary': 'error',\n 'unicorn/prefer-string-trim-start-end': 'error',\n 'unicorn/prefer-structured-clone': 'error',\n 'unicorn/prefer-default-parameters': 'error',\n 'unicorn/no-console-spaces': 'error',\n 'unicorn/throw-new-error': 'error',\n 'unicorn/require-array-join-separator': 'error',\n },\n },\n overrides,\n )\n}\n\n/** Dependency optimization — flags packages replaceable with native APIs. */\nexport function depend(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n jsPlugins: resolvePlugins(['eslint-plugin-depend']),\n rules: {\n 'depend/ban-dependencies': [\n 'error',\n {\n presets: ['native', 'microutilities', 'preferred'],\n modules: [],\n allowed: ['dotenv'],\n },\n ],\n },\n },\n overrides,\n )\n}\n\n// ============================================================================\n// Runtime environments\n// ============================================================================\n\n/** Node.js lint preset — native node plugin. */\nexport function node(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset({ plugins: ['node'] }, overrides)\n}\n\n/** Promise lint preset — native promise plugin. */\nexport function promise(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset({ plugins: ['promise'] }, overrides)\n}\n\n// ============================================================================\n// Frontend\n// ============================================================================\n\nconst reactStyleRules = {\n 'react/jsx-pascal-case': 'error',\n 'react/jsx-boolean-value': 'error',\n 'react/jsx-curly-brace-presence': 'error',\n 'react/jsx-fragments': 'error',\n 'react/self-closing-comp': 'error',\n 'react/hook-use-state': 'error',\n} as const\n\n/** React lint preset — enables native react + react-hooks plugin. */\nexport function react(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n plugins: ['react'],\n rules: {\n // Automatic JSX runtime (React 17+) does not require explicit React import\n 'react/react-in-jsx-scope': 'off',\n ...reactStyleRules,\n },\n },\n overrides,\n )\n}\n\n/** React + react-refresh preset (for Vite projects). Use instead of `react`. */\nexport function reactVite(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n plugins: ['react'],\n jsPlugins: resolvePlugins(['eslint-plugin-react-refresh']),\n rules: {\n 'react/react-in-jsx-scope': 'off',\n ...reactStyleRules,\n },\n },\n overrides,\n )\n}\n\n/** Next.js lint preset — enables native nextjs plugin. */\nexport function nextjs(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset({ plugins: ['nextjs'] }, overrides)\n}\n\n/**\n * TanStack Router lint preset — loads @tanstack/eslint-plugin-router.\n * Covers route-param-names and create-route-property-order.\n */\nexport function tanstackRouter(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n jsPlugins: resolvePlugins([\n { name: 'tanstack-router', specifier: '@tanstack/eslint-plugin-router' },\n ]),\n rules: {\n 'tanstack-router/route-param-names': 'error',\n 'tanstack-router/create-route-property-order': 'error',\n },\n },\n overrides,\n )\n}\n\n// ============================================================================\n// Quality\n// ============================================================================\n\n/** Accessibility lint preset — enables native jsx-a11y plugin. */\nexport function a11y(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset({ plugins: ['jsx-a11y'] }, overrides)\n}\n\n/** JSDoc lint preset — enables native jsdoc plugin. */\nexport function jsdoc(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset({ plugins: ['jsdoc'] }, overrides)\n}\n\n// ============================================================================\n// Testing\n// ============================================================================\n\ninterface VitestOptions extends Partial<OxlintConfig> {\n /** Test file glob patterns. Replaces the default GLOB_TESTS. */\n files?: string[]\n}\n\n/** Vitest lint preset — native vitest plugin with test-file scoping. */\nexport function vitest(options?: VitestOptions): OxlintConfig {\n const { files, ...overrides } = options ?? {}\n\n return preset(\n {\n plugins: ['vitest'],\n settings: { vitest: { typecheck: true } },\n overrides: [\n {\n files: files ?? GLOB_TESTS,\n rules: {\n 'vitest/expect-expect': 'error',\n 'vitest/no-conditional-expect': 'error',\n 'vitest/no-identical-title': 'error',\n 'vitest/no-import-node-test': 'error',\n 'vitest/no-interpolation-in-snapshots': 'error',\n 'vitest/no-mocks-import': 'error',\n 'vitest/no-standalone-expect': 'error',\n 'vitest/valid-describe-callback': 'error',\n 'vitest/valid-expect': 'error',\n 'vitest/valid-title': 'error',\n 'vitest/consistent-test-it': ['error', { fn: 'it', withinDescribe: 'it' }],\n 'vitest/prefer-hooks-in-order': 'error',\n 'vitest/prefer-lowercase-title': 'error',\n 'vitest/no-disabled-tests': isInEditorEnv() ? 'warn' : 'error',\n 'vitest/no-focused-tests': isInEditorEnv() ? 'warn' : 'error',\n 'vitest/require-mock-type-parameters': 'off',\n 'no-console': 'off',\n 'unicorn/no-null': 'off',\n 'typescript/ban-ts-comment': 'off',\n },\n },\n ],\n },\n overrides,\n )\n}\n\n// ============================================================================\n// Tailwind\n// ============================================================================\n\ninterface TailwindOptions extends Partial<OxlintConfig> {\n entryPoint?: string\n rootFontSize?: number\n /** File glob patterns for tailwind rules. @default GLOB_JSX */\n files?: string[]\n}\n\n/** Tailwind CSS lint preset — eslint-plugin-better-tailwindcss. */\nexport function tailwind(options: TailwindOptions = {}): OxlintConfig {\n const { entryPoint = 'src/styles/globals.css', rootFontSize = 16, files, ...overrides } = options\n\n return preset(\n {\n jsPlugins: resolvePlugins(['eslint-plugin-better-tailwindcss']),\n settings: { 'better-tailwindcss': { entryPoint, rootFontSize } },\n overrides: [\n {\n files: files ?? [GLOB_JSX],\n rules: {\n 'better-tailwindcss/enforce-consistent-line-wrapping': ['error', { printWidth: 0 }],\n 'better-tailwindcss/enforce-canonical-classes': 'error',\n },\n },\n ],\n },\n overrides,\n )\n}\n\n// ============================================================================\n// Backend / ORM\n// ============================================================================\n\n/**\n * NestJS lint preset — loads @darraghor/eslint-plugin-nestjs-typed via jsPlugin.\n * Covers DI validation, Swagger consistency, decorator bug prevention (19 AST rules).\n */\nexport function nestjs(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n jsPlugins: resolvePlugins([\n { name: 'nestjs-typed', specifier: '@darraghor/eslint-plugin-nestjs-typed' },\n ]),\n rules: {\n // DI\n 'nestjs-typed/injectable-should-be-provided': 'error',\n 'nestjs-typed/provided-injected-should-match-factory-parameters': 'error',\n 'nestjs-typed/use-injectable-provided-token': 'error',\n // Swagger\n 'nestjs-typed/api-property-matches-property-optionality': 'error',\n 'nestjs-typed/controllers-should-supply-api-tags': 'error',\n 'nestjs-typed/api-method-should-specify-api-response': 'error',\n 'nestjs-typed/api-property-returning-array-should-set-array': 'error',\n 'nestjs-typed/api-property-should-have-api-extra-models': 'error',\n 'nestjs-typed/api-operation-summary-description-capitalized': 'error',\n // Bug prevention\n 'nestjs-typed/param-decorator-name-matches-route-param': 'error',\n 'nestjs-typed/validate-nested-of-array-should-set-each': 'error',\n 'nestjs-typed/all-properties-are-whitelisted': 'error',\n 'nestjs-typed/no-duplicate-decorators': 'error',\n 'nestjs-typed/validation-pipe-should-use-forbid-unknown': 'error',\n },\n },\n overrides,\n )\n}\n\n/** Drizzle ORM lint preset — eslint-plugin-drizzle. */\nexport function drizzle(overrides?: Partial<OxlintConfig>): OxlintConfig {\n return preset(\n {\n jsPlugins: resolvePlugins(['eslint-plugin-drizzle']),\n rules: {\n 'drizzle/enforce-delete-with-where': 'error',\n 'drizzle/enforce-update-with-where': 'error',\n },\n },\n overrides,\n )\n}\n\n// ============================================================================\n// Re-exports\n// ============================================================================\n\nexport { defineConfig } from 'oxlint'\nexport { GLOB_SRC, GLOB_JS, GLOB_TS, GLOB_JSX, GLOB_TESTS, GLOB_JSON, GLOB_MARKDOWN } from './utils'\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hooshid/ox-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared Oxlint + Oxfmt presets — one install for lint and format.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"config",
|
|
7
|
+
"format",
|
|
8
|
+
"lint",
|
|
9
|
+
"oxfmt",
|
|
10
|
+
"oxlint",
|
|
11
|
+
"preset"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/hooshid/ox-config#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/hooshid/ox-config/issues"
|
|
16
|
+
},
|
|
5
17
|
"license": "MIT",
|
|
6
18
|
"author": "hooshid",
|
|
7
19
|
"repository": {
|
|
8
20
|
"type": "git",
|
|
9
21
|
"url": "git+https://github.com/hooshid/ox-config.git"
|
|
10
22
|
},
|
|
11
|
-
"homepage": "https://github.com/hooshid/ox-config#readme",
|
|
12
|
-
"bugs": {
|
|
13
|
-
"url": "https://github.com/hooshid/ox-config/issues"
|
|
14
|
-
},
|
|
15
|
-
"keywords": [
|
|
16
|
-
"oxlint",
|
|
17
|
-
"oxfmt",
|
|
18
|
-
"lint",
|
|
19
|
-
"format",
|
|
20
|
-
"preset",
|
|
21
|
-
"config"
|
|
22
|
-
],
|
|
23
23
|
"files": [
|
|
24
24
|
"dist"
|
|
25
25
|
],
|
|
@@ -38,20 +38,6 @@
|
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"build": "tsdown",
|
|
43
|
-
"dev": "tsdown --watch",
|
|
44
|
-
"lint": "oxlint .",
|
|
45
|
-
"lint:fix": "oxlint . --fix",
|
|
46
|
-
"format": "oxfmt .",
|
|
47
|
-
"format:check": "oxfmt --check .",
|
|
48
|
-
"typecheck": "tsc --noEmit",
|
|
49
|
-
"changeset": "changeset",
|
|
50
|
-
"changeset:version": "changeset version",
|
|
51
|
-
"changeset:publish": "changeset publish",
|
|
52
|
-
"changeset:release": "pnpm build && changeset publish",
|
|
53
|
-
"prepublishOnly": "pnpm build"
|
|
54
|
-
},
|
|
55
41
|
"dependencies": {
|
|
56
42
|
"@darraghor/eslint-plugin-nestjs-typed": "^7.5.6",
|
|
57
43
|
"@tanstack/eslint-plugin-router": "^1.162.0",
|
|
@@ -77,5 +63,18 @@
|
|
|
77
63
|
},
|
|
78
64
|
"engines": {
|
|
79
65
|
"node": ">=20"
|
|
66
|
+
},
|
|
67
|
+
"scripts": {
|
|
68
|
+
"build": "tsdown",
|
|
69
|
+
"dev": "tsdown --watch",
|
|
70
|
+
"lint": "oxlint .",
|
|
71
|
+
"lint:fix": "oxlint . --fix",
|
|
72
|
+
"format": "oxfmt .",
|
|
73
|
+
"format:check": "oxfmt --check .",
|
|
74
|
+
"typecheck": "tsc --noEmit",
|
|
75
|
+
"changeset": "changeset",
|
|
76
|
+
"changeset:version": "changeset version",
|
|
77
|
+
"changeset:publish": "changeset publish",
|
|
78
|
+
"changeset:release": "pnpm build && changeset publish"
|
|
80
79
|
}
|
|
81
80
|
}
|