@jmlweb/oxlint-config-node 0.0.0-stage → 0.1.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/CHANGELOG.md +7 -0
- package/README.md +274 -2
- package/dist/index.cjs +93 -0
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +65 -0
- package/package.json +71 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# @jmlweb/oxlint-config-node
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a32dbc9: Add `@jmlweb/oxlint-config-node`, an Oxlint configuration that extends `@jmlweb/oxlint-config-base` and ports `@jmlweb/eslint-config-node`. It runs `eslint-plugin-n`'s `flat/recommended` rules and the same best-practice rules as a JS plugin, uses Oxlint's native `node/*` rules where they exist, and sets Node.js globals for JavaScript and TypeScript files. The naming convention rule is not ported.
|
package/README.md
CHANGED
|
@@ -1,3 +1,275 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @jmlweb/oxlint-config-node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@jmlweb/oxlint-config-node)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
|
|
7
|
+
> [Oxlint](https://oxc.rs/docs/guide/usage/linter.html) configuration for Node.js projects. Extends [`@jmlweb/oxlint-config-base`](../oxlint-config-base) and ports the rules of [`@jmlweb/eslint-config-node`](../eslint-config-node).
|
|
8
|
+
|
|
9
|
+
## ✨ Features
|
|
10
|
+
|
|
11
|
+
- 🟢 **eslint-plugin-n**: Its `flat/recommended` rules plus stricter best practices, run as an Oxlint JS plugin
|
|
12
|
+
- ⚡ **Native where possible**: Rules Oxlint implements itself run natively instead of through the plugin
|
|
13
|
+
- 📦 **Dependency checks**: Missing, extraneous and unpublished imports, resolved against your `package.json`
|
|
14
|
+
- 🌐 **Node.js globals**: `process`, `Buffer`, `__dirname` and the rest, for JavaScript and TypeScript files
|
|
15
|
+
- 🔒 **Everything from the base config**: Strict TypeScript rules, no enums, named exports only
|
|
16
|
+
|
|
17
|
+
## 📦 Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add -D @jmlweb/oxlint-config-node oxlint oxlint-tsgolint eslint-plugin-n
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 🚀 Quick Start
|
|
24
|
+
|
|
25
|
+
Create an `oxlint.config.ts` file in your project root:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import nodeConfig from '@jmlweb/oxlint-config-node';
|
|
29
|
+
import { defineConfig } from 'oxlint';
|
|
30
|
+
|
|
31
|
+
export default defineConfig({
|
|
32
|
+
extends: [nodeConfig],
|
|
33
|
+
options: {
|
|
34
|
+
typeAware: true,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> ⚠️ **`typeAware` must be set in your own config**: Oxlint only reads `options` from the root config file, so the base config's type-aware rules are skipped without it.
|
|
40
|
+
|
|
41
|
+
## 💡 Examples
|
|
42
|
+
|
|
43
|
+
### Before
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import fs from 'fs';
|
|
47
|
+
import { parse } from 'yaml';
|
|
48
|
+
|
|
49
|
+
export const loadConfig = (dir: string): unknown => {
|
|
50
|
+
const file = dir + '/config.yml';
|
|
51
|
+
if (!fs.existsSync(file)) {
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
fs.readFile(file, 'utf8', () => undefined);
|
|
55
|
+
return parse(fs.readFileSync(file, 'utf8'));
|
|
56
|
+
};
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Problems Reported
|
|
60
|
+
|
|
61
|
+
With `yaml` missing from `package.json`:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
src/config.ts:1:16: error n(prefer-node-protocol): Prefer `node:fs` over `fs`.
|
|
65
|
+
src/config.ts:2:23: error n(no-missing-import): Can't resolve 'yaml' in '/path/to/project/src'
|
|
66
|
+
src/config.ts:7:5: error n(no-process-exit): Don't use process.exit(); throw an error instead.
|
|
67
|
+
src/config.ts:9:3: error n(prefer-promises/fs): Use 'fs.promises.readFile()' instead.
|
|
68
|
+
src/config.ts:10:10: error typescript(no-unsafe-call): Unsafe call of a(n) `error` type typed value.
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 📋 Configuration Details
|
|
72
|
+
|
|
73
|
+
### All Files
|
|
74
|
+
|
|
75
|
+
- `eslint-plugin-n` `flat/recommended` rules: deprecated APIs, unsupported features for your `engines.node`, missing, extraneous and unpublished imports, hashbangs
|
|
76
|
+
- Node.js globals for `**/*.{js,mjs,cjs,ts,mts,cts}`
|
|
77
|
+
|
|
78
|
+
### Key Rules Enforced
|
|
79
|
+
|
|
80
|
+
| Rule | Level | Description |
|
|
81
|
+
| ------------------------- | ------- | --------------------------------------------------- |
|
|
82
|
+
| `n/no-process-exit` | `error` | Throw instead of calling `process.exit()` |
|
|
83
|
+
| `n/process-exit-as-throw` | `error` | Treats `process.exit()` as a throw for control flow |
|
|
84
|
+
| `n/no-deprecated-api` | `warn` | Flags deprecated Node.js APIs |
|
|
85
|
+
| `n/no-callback-literal` | `error` | Callbacks receive an error or `null` first |
|
|
86
|
+
| `n/prefer-node-protocol` | `error` | Use `node:` imports for built-in modules |
|
|
87
|
+
| `n/prefer-promises/fs` | `error` | Use `fs.promises` over callback APIs |
|
|
88
|
+
| `n/prefer-promises/dns` | `error` | Use `dns.promises` over callback APIs |
|
|
89
|
+
| `n/prefer-global/*` | `error` | Use `Buffer`, `console`, `process`, `URL` globals |
|
|
90
|
+
| `node/no-new-require` | `error` | Disallows `new require(...)` |
|
|
91
|
+
| `node/no-path-concat` | `error` | Use `path.join()` with `__dirname`/`__filename` |
|
|
92
|
+
| `node/no-exports-assign` | `error` | Disallows assigning to `exports` |
|
|
93
|
+
|
|
94
|
+
The `node/*` rules are Oxlint's native versions of the matching `n/*` rules.
|
|
95
|
+
|
|
96
|
+
### Differences from `@jmlweb/eslint-config-node`
|
|
97
|
+
|
|
98
|
+
- **No naming convention rule**: Same as [`@jmlweb/oxlint-config-base`](../oxlint-config-base#differences-from-jmlwebeslint-config-base)
|
|
99
|
+
- **No import sorting rule**: [`@jmlweb/oxfmt-config-base`](../oxfmt-config-base) sorts imports
|
|
100
|
+
|
|
101
|
+
## 🤔 Why Use This?
|
|
102
|
+
|
|
103
|
+
> **Philosophy**: The Node.js rules of the ESLint config, run by Oxlint.
|
|
104
|
+
|
|
105
|
+
### Design Decisions
|
|
106
|
+
|
|
107
|
+
**eslint-plugin-n as a JS plugin**: Oxlint's native `node` plugin only covers a few of its rules
|
|
108
|
+
|
|
109
|
+
- **Why**: Keeps the dependency checks and unsupported-feature rules, which have no native equivalent
|
|
110
|
+
- **Trade-off**: Runs through Oxlint's JS plugin support, which is still in alpha
|
|
111
|
+
- **When to override**: Turn off single `n/*` rules in your config
|
|
112
|
+
|
|
113
|
+
**Node.js globals through an override**: The globals are set for JavaScript and TypeScript files instead of with a top-level `env`
|
|
114
|
+
|
|
115
|
+
- **Why**: Oxlint ignores a top-level `env` in configs loaded through `extends`, but keeps it inside overrides
|
|
116
|
+
- **Trade-off**: None
|
|
117
|
+
- **When to override**: Not needed
|
|
118
|
+
|
|
119
|
+
## 🎯 When to Use
|
|
120
|
+
|
|
121
|
+
Use this package when you want:
|
|
122
|
+
|
|
123
|
+
- ✅ Fast linting for Node.js libraries, CLIs and servers (recommended over ESLint)
|
|
124
|
+
- ✅ Checks that every import is declared in `package.json`
|
|
125
|
+
- ✅ To migrate from `@jmlweb/eslint-config-node`
|
|
126
|
+
|
|
127
|
+
**For browser or React projects**, use [`@jmlweb/oxlint-config-base`](../oxlint-config-base) or [`@jmlweb/oxlint-config-react`](../oxlint-config-react) instead.
|
|
128
|
+
|
|
129
|
+
## 🔧 Extending the Configuration
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import nodeConfig from '@jmlweb/oxlint-config-node';
|
|
133
|
+
import { defineConfig } from 'oxlint';
|
|
134
|
+
|
|
135
|
+
export default defineConfig({
|
|
136
|
+
extends: [nodeConfig],
|
|
137
|
+
options: {
|
|
138
|
+
typeAware: true,
|
|
139
|
+
},
|
|
140
|
+
overrides: [
|
|
141
|
+
{
|
|
142
|
+
// CLIs may exit with a status code
|
|
143
|
+
files: ['src/cli.ts'],
|
|
144
|
+
rules: {
|
|
145
|
+
'n/no-process-exit': 'off',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
// Scripts and tests may import devDependencies
|
|
150
|
+
files: ['scripts/**', '**/*.test.ts'],
|
|
151
|
+
rules: {
|
|
152
|
+
'n/no-unpublished-import': 'off',
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 📝 Usage with Scripts
|
|
160
|
+
|
|
161
|
+
Add linting scripts to your `package.json`:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"scripts": {
|
|
166
|
+
"lint": "oxlint",
|
|
167
|
+
"lint:fix": "oxlint --fix"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Then run:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
pnpm lint # Lint all files
|
|
176
|
+
pnpm lint:fix # Fix auto-fixable problems
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## 📋 Requirements
|
|
180
|
+
|
|
181
|
+
- **Node.js** >= 22.12.0
|
|
182
|
+
- **Oxlint** >= 1.87.0
|
|
183
|
+
- **`engines.node`** in your `package.json` (used by the unsupported-feature rules)
|
|
184
|
+
- **TypeScript project** with a `tsconfig.json` (for type-aware rules)
|
|
185
|
+
|
|
186
|
+
## 📦 Peer Dependencies
|
|
187
|
+
|
|
188
|
+
This package requires the following peer dependencies:
|
|
189
|
+
|
|
190
|
+
- `oxlint` (>= 1.87.0)
|
|
191
|
+
- `oxlint-tsgolint` (>= 7.0.0, optional, enables type-aware rules)
|
|
192
|
+
- `eslint-plugin-n` (^17.0.0 || ^18.0.0)
|
|
193
|
+
|
|
194
|
+
**Note**: `@jmlweb/oxlint-config-base` is a regular dependency, so you do not need to install it.
|
|
195
|
+
|
|
196
|
+
## 📚 Examples
|
|
197
|
+
|
|
198
|
+
See real-world usage examples:
|
|
199
|
+
|
|
200
|
+
- [`@jmlweb/eslint-config-node`](../eslint-config-node) - The ESLint configuration this package ports
|
|
201
|
+
|
|
202
|
+
## 🔗 Related Packages
|
|
203
|
+
|
|
204
|
+
### Internal Packages
|
|
205
|
+
|
|
206
|
+
- [`@jmlweb/oxlint-config-base`](../oxlint-config-base) - Base Oxlint config this package extends
|
|
207
|
+
- [`@jmlweb/oxfmt-config-base`](../oxfmt-config-base) - Oxfmt config, the formatter to pair with this linter
|
|
208
|
+
- [`@jmlweb/eslint-config-node`](../eslint-config-node) - ESLint equivalent of this configuration
|
|
209
|
+
- [`@jmlweb/tsconfig-node`](../tsconfig-node) - TypeScript config for Node.js projects
|
|
210
|
+
|
|
211
|
+
### External Tools
|
|
212
|
+
|
|
213
|
+
- [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) - Node.js rules run as a JS plugin
|
|
214
|
+
- [Oxlint JS plugins](https://oxc.rs/docs/guide/usage/linter/js-plugins.html) - How Oxlint runs ESLint plugins
|
|
215
|
+
|
|
216
|
+
## ⚠️ Common Issues
|
|
217
|
+
|
|
218
|
+
> **Note:** This section documents known issues and their solutions. If you encounter a problem not listed here, please [open an issue](https://github.com/jmlweb/tooling/issues/new).
|
|
219
|
+
|
|
220
|
+
### Unpublished Import Errors in Scripts or Tests
|
|
221
|
+
|
|
222
|
+
**Symptoms:**
|
|
223
|
+
|
|
224
|
+
- `n/no-unpublished-import` reports `devDependencies` imported from tests or scripts
|
|
225
|
+
|
|
226
|
+
**Cause:**
|
|
227
|
+
|
|
228
|
+
- The tests or scripts sit inside a folder listed in the `files` field of `package.json`, so they count as published code, which must not import `devDependencies`
|
|
229
|
+
|
|
230
|
+
**Solution:**
|
|
231
|
+
|
|
232
|
+
Turn the rule off for those files (see [Extending the Configuration](#-extending-the-configuration)), or make sure the `files` field only lists published code.
|
|
233
|
+
|
|
234
|
+
### Oxlint Is Slow or Reports Problems in `node_modules`
|
|
235
|
+
|
|
236
|
+
**Symptoms:**
|
|
237
|
+
|
|
238
|
+
- Oxlint takes minutes or reports problems in dependencies
|
|
239
|
+
|
|
240
|
+
**Cause:**
|
|
241
|
+
|
|
242
|
+
- The project has no `.gitignore` listing `node_modules`, so Oxlint lints it
|
|
243
|
+
|
|
244
|
+
**Solution:**
|
|
245
|
+
|
|
246
|
+
Add `node_modules` to `.gitignore`, or to `ignorePatterns` in your Oxlint config.
|
|
247
|
+
|
|
248
|
+
## 🔄 Migration Guide
|
|
249
|
+
|
|
250
|
+
### Migrating from `@jmlweb/eslint-config-node`
|
|
251
|
+
|
|
252
|
+
1. Install this package and its peer dependencies
|
|
253
|
+
2. Create `oxlint.config.ts` as shown in [Quick Start](#-quick-start)
|
|
254
|
+
3. Format with [`@jmlweb/oxfmt-config-base`](../oxfmt-config-base), which sorts imports
|
|
255
|
+
4. Replace `eslint` with `oxlint` in your scripts and `lint-staged` config
|
|
256
|
+
5. Remove `eslint.config.*` and the ESLint packages, except `eslint-plugin-n`
|
|
257
|
+
6. Run `pnpm lint` and fix the reported problems
|
|
258
|
+
|
|
259
|
+
### Upgrading to a New Version
|
|
260
|
+
|
|
261
|
+
> **Note:** If no breaking changes were introduced in a version, it's safe to upgrade without additional steps.
|
|
262
|
+
|
|
263
|
+
**No breaking changes have been introduced yet.** This package follows semantic versioning. When breaking changes are introduced, detailed migration instructions will be provided here.
|
|
264
|
+
|
|
265
|
+
For version history, see the [Changelog](./CHANGELOG.md).
|
|
266
|
+
|
|
267
|
+
**Need Help?** If you encounter issues during migration, please [open an issue](https://github.com/jmlweb/tooling/issues/new).
|
|
268
|
+
|
|
269
|
+
## 📜 Changelog
|
|
270
|
+
|
|
271
|
+
See [CHANGELOG.md](./CHANGELOG.md) for version history and release notes.
|
|
272
|
+
|
|
273
|
+
## 📄 License
|
|
274
|
+
|
|
275
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __create = Object.create;
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
14
|
+
key = keys[i];
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
16
|
+
get: ((k) => from[k]).bind(null, key),
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
//#endregion
|
|
27
|
+
let _jmlweb_oxlint_config_base = require("@jmlweb/oxlint-config-base");
|
|
28
|
+
_jmlweb_oxlint_config_base = __toESM(_jmlweb_oxlint_config_base, 1);
|
|
29
|
+
let eslint_plugin_n = require("eslint-plugin-n");
|
|
30
|
+
eslint_plugin_n = __toESM(eslint_plugin_n, 1);
|
|
31
|
+
//#region src/index.ts
|
|
32
|
+
/** Stricter or extra eslint-plugin-n rules, as in @jmlweb/eslint-config-node */
|
|
33
|
+
const nodeBestPracticeRules = {
|
|
34
|
+
"n/no-process-exit": "error",
|
|
35
|
+
"n/no-missing-import": "error",
|
|
36
|
+
"n/no-missing-require": "error",
|
|
37
|
+
"n/no-unpublished-import": "error",
|
|
38
|
+
"n/no-unpublished-require": "error",
|
|
39
|
+
"n/no-extraneous-import": "error",
|
|
40
|
+
"n/no-extraneous-require": "error",
|
|
41
|
+
"n/no-deprecated-api": "warn",
|
|
42
|
+
"n/process-exit-as-throw": "error",
|
|
43
|
+
"n/no-callback-literal": "error",
|
|
44
|
+
"n/no-new-require": "error",
|
|
45
|
+
"n/no-path-concat": "error",
|
|
46
|
+
"n/prefer-global/buffer": ["error", "always"],
|
|
47
|
+
"n/prefer-global/console": ["error", "always"],
|
|
48
|
+
"n/prefer-global/process": ["error", "always"],
|
|
49
|
+
"n/prefer-global/url-search-params": ["error", "always"],
|
|
50
|
+
"n/prefer-global/url": ["error", "always"],
|
|
51
|
+
"n/prefer-promises/dns": "error",
|
|
52
|
+
"n/prefer-promises/fs": "error",
|
|
53
|
+
"n/prefer-node-protocol": "error"
|
|
54
|
+
};
|
|
55
|
+
/** eslint-plugin-n rules that Oxlint implements natively in its `node` plugin */
|
|
56
|
+
const NATIVE_NODE_RULES = /* @__PURE__ */ new Set([
|
|
57
|
+
"no-exports-assign",
|
|
58
|
+
"no-new-require",
|
|
59
|
+
"no-path-concat"
|
|
60
|
+
]);
|
|
61
|
+
/**
|
|
62
|
+
* eslint-plugin-n's `flat/recommended` rules plus the extra ones, run as an
|
|
63
|
+
* Oxlint JS plugin. Rules Oxlint implements natively use the faster `node/*`
|
|
64
|
+
* version instead. Derived from eslint-plugin-n's own preset so it follows new
|
|
65
|
+
* releases.
|
|
66
|
+
*/
|
|
67
|
+
const nodeRules = Object.fromEntries(Object.entries({
|
|
68
|
+
...eslint_plugin_n.default.configs["flat/recommended"].rules,
|
|
69
|
+
...nodeBestPracticeRules
|
|
70
|
+
}).map(([rule, value]) => {
|
|
71
|
+
const name = rule.replace(/^n\//, "");
|
|
72
|
+
return [NATIVE_NODE_RULES.has(name) ? `node/${name}` : rule, value];
|
|
73
|
+
}));
|
|
74
|
+
/**
|
|
75
|
+
* Node.js Oxlint configuration that extends @jmlweb/oxlint-config-base.
|
|
76
|
+
* Mirrors @jmlweb/eslint-config-node.
|
|
77
|
+
*/
|
|
78
|
+
const config = {
|
|
79
|
+
extends: [_jmlweb_oxlint_config_base.default],
|
|
80
|
+
plugins: [
|
|
81
|
+
"typescript",
|
|
82
|
+
"import",
|
|
83
|
+
"node"
|
|
84
|
+
],
|
|
85
|
+
jsPlugins: ["eslint-plugin-n"],
|
|
86
|
+
rules: nodeRules,
|
|
87
|
+
overrides: [{
|
|
88
|
+
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
|
|
89
|
+
env: { node: true }
|
|
90
|
+
}]
|
|
91
|
+
};
|
|
92
|
+
//#endregion
|
|
93
|
+
exports.default = config;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { OxlintConfig } from "oxlint";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Node.js Oxlint configuration that extends @jmlweb/oxlint-config-base.
|
|
5
|
+
* Mirrors @jmlweb/eslint-config-node.
|
|
6
|
+
*/
|
|
7
|
+
declare const config: OxlintConfig;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { config as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { OxlintConfig } from "oxlint";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Node.js Oxlint configuration that extends @jmlweb/oxlint-config-base.
|
|
5
|
+
* Mirrors @jmlweb/eslint-config-node.
|
|
6
|
+
*/
|
|
7
|
+
declare const config: OxlintConfig;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { config as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import baseConfig from "@jmlweb/oxlint-config-base";
|
|
2
|
+
import eslintPluginN from "eslint-plugin-n";
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
/** Stricter or extra eslint-plugin-n rules, as in @jmlweb/eslint-config-node */
|
|
5
|
+
const nodeBestPracticeRules = {
|
|
6
|
+
"n/no-process-exit": "error",
|
|
7
|
+
"n/no-missing-import": "error",
|
|
8
|
+
"n/no-missing-require": "error",
|
|
9
|
+
"n/no-unpublished-import": "error",
|
|
10
|
+
"n/no-unpublished-require": "error",
|
|
11
|
+
"n/no-extraneous-import": "error",
|
|
12
|
+
"n/no-extraneous-require": "error",
|
|
13
|
+
"n/no-deprecated-api": "warn",
|
|
14
|
+
"n/process-exit-as-throw": "error",
|
|
15
|
+
"n/no-callback-literal": "error",
|
|
16
|
+
"n/no-new-require": "error",
|
|
17
|
+
"n/no-path-concat": "error",
|
|
18
|
+
"n/prefer-global/buffer": ["error", "always"],
|
|
19
|
+
"n/prefer-global/console": ["error", "always"],
|
|
20
|
+
"n/prefer-global/process": ["error", "always"],
|
|
21
|
+
"n/prefer-global/url-search-params": ["error", "always"],
|
|
22
|
+
"n/prefer-global/url": ["error", "always"],
|
|
23
|
+
"n/prefer-promises/dns": "error",
|
|
24
|
+
"n/prefer-promises/fs": "error",
|
|
25
|
+
"n/prefer-node-protocol": "error"
|
|
26
|
+
};
|
|
27
|
+
/** eslint-plugin-n rules that Oxlint implements natively in its `node` plugin */
|
|
28
|
+
const NATIVE_NODE_RULES = /* @__PURE__ */ new Set([
|
|
29
|
+
"no-exports-assign",
|
|
30
|
+
"no-new-require",
|
|
31
|
+
"no-path-concat"
|
|
32
|
+
]);
|
|
33
|
+
/**
|
|
34
|
+
* eslint-plugin-n's `flat/recommended` rules plus the extra ones, run as an
|
|
35
|
+
* Oxlint JS plugin. Rules Oxlint implements natively use the faster `node/*`
|
|
36
|
+
* version instead. Derived from eslint-plugin-n's own preset so it follows new
|
|
37
|
+
* releases.
|
|
38
|
+
*/
|
|
39
|
+
const nodeRules = Object.fromEntries(Object.entries({
|
|
40
|
+
...eslintPluginN.configs["flat/recommended"].rules,
|
|
41
|
+
...nodeBestPracticeRules
|
|
42
|
+
}).map(([rule, value]) => {
|
|
43
|
+
const name = rule.replace(/^n\//, "");
|
|
44
|
+
return [NATIVE_NODE_RULES.has(name) ? `node/${name}` : rule, value];
|
|
45
|
+
}));
|
|
46
|
+
/**
|
|
47
|
+
* Node.js Oxlint configuration that extends @jmlweb/oxlint-config-base.
|
|
48
|
+
* Mirrors @jmlweb/eslint-config-node.
|
|
49
|
+
*/
|
|
50
|
+
const config = {
|
|
51
|
+
extends: [baseConfig],
|
|
52
|
+
plugins: [
|
|
53
|
+
"typescript",
|
|
54
|
+
"import",
|
|
55
|
+
"node"
|
|
56
|
+
],
|
|
57
|
+
jsPlugins: ["eslint-plugin-n"],
|
|
58
|
+
rules: nodeRules,
|
|
59
|
+
overrides: [{
|
|
60
|
+
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
|
|
61
|
+
env: { node: true }
|
|
62
|
+
}]
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
export { config as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jmlweb/oxlint-config-node",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Oxlint configuration for Node.js projects, extending @jmlweb/oxlint-config-base",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md",
|
|
24
|
+
"CHANGELOG.md"
|
|
25
|
+
],
|
|
26
|
+
"keywords": [
|
|
27
|
+
"linter",
|
|
28
|
+
"node",
|
|
29
|
+
"nodejs",
|
|
30
|
+
"oxc",
|
|
31
|
+
"oxlint",
|
|
32
|
+
"oxlint-config"
|
|
33
|
+
],
|
|
34
|
+
"author": "jmlweb",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/jmlweb/tooling.git"
|
|
39
|
+
},
|
|
40
|
+
"bugs": "https://github.com/jmlweb/tooling/issues",
|
|
41
|
+
"homepage": "https://github.com/jmlweb/tooling/tree/main/packages/oxlint-config-node#readme",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22.12.0"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"eslint-plugin-n": "^17.0.0 || ^18.0.0",
|
|
50
|
+
"oxlint": ">=1.87.0",
|
|
51
|
+
"oxlint-tsgolint": ">=7.0.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependenciesMeta": {
|
|
54
|
+
"oxlint-tsgolint": {
|
|
55
|
+
"optional": true
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@jmlweb/oxlint-config-base": "0.1.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"eslint-plugin-n": "^18.4.1",
|
|
63
|
+
"oxlint": "^1.87.0",
|
|
64
|
+
"oxlint-tsgolint": "^7.0.2003",
|
|
65
|
+
"tsdown": "~0.23.0",
|
|
66
|
+
"typescript": "^6.0.3",
|
|
67
|
+
"@jmlweb/tsconfig-internal": "0.0.1",
|
|
68
|
+
"@jmlweb/tsdown-config-base": "0.2.1"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsdown",
|
|
72
|
+
"clean": "rm -rf dist"
|
|
73
|
+
}
|
|
6
74
|
}
|