eslint-plugin-oxfmt 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -14
- package/dist/index.mjs +32 -6
- package/dts/rule-options.d.ts +2 -0
- package/package.json +7 -8
- package/workers/oxfmt.mjs +22 -3
package/README.md
CHANGED
|
@@ -5,31 +5,65 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/eslint-plugin-oxfmt)
|
|
6
6
|
[](https://github.com/ntnyq/eslint-plugin-oxfmt/blob/main/LICENSE)
|
|
7
7
|
|
|
8
|
-
An ESLint plugin
|
|
8
|
+
> An ESLint plugin for formatting code with [oxfmt](https://github.com/oxc-project/oxc) - A blazing fast formatter powered by Rust.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Features
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
- ⚡️ **Blazing Fast** - Powered by [oxfmt](https://github.com/oxc-project/oxc), written in Rust
|
|
13
|
+
- 🔧 **Auto-fix** - Automatically format code on save or via ESLint's fix command
|
|
14
|
+
- 🎯 **ESLint Integration** - Seamlessly integrates with ESLint v9+ flat config
|
|
15
|
+
- 📦 **Zero Config** - Works out of the box with sensible defaults
|
|
16
|
+
- 🎨 **Highly Configurable** - Support for all oxfmt formatting options
|
|
17
|
+
- 🌐 **Multi-language Support** - JavaScript, TypeScript, JSX, TSX and more
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- **ESLint**: `>= 9.0.0` (Only supports ESLint flat config)
|
|
22
|
+
- **Node.js**: `>= 18.0.0`
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -D eslint-plugin-oxfmt
|
|
14
30
|
```
|
|
15
31
|
|
|
16
|
-
```
|
|
17
|
-
yarn add eslint-plugin-oxfmt
|
|
32
|
+
```bash
|
|
33
|
+
yarn add -D eslint-plugin-oxfmt
|
|
18
34
|
```
|
|
19
35
|
|
|
20
|
-
```
|
|
21
|
-
pnpm add eslint-plugin-oxfmt
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add -D eslint-plugin-oxfmt
|
|
22
38
|
```
|
|
23
39
|
|
|
24
40
|
## Usage
|
|
25
41
|
|
|
26
|
-
|
|
42
|
+
### Quick Start
|
|
43
|
+
|
|
44
|
+
Add the plugin to your ESLint flat config file:
|
|
45
|
+
|
|
46
|
+
```js
|
|
27
47
|
// eslint.config.mjs
|
|
48
|
+
import pluginOxfmt from 'eslint-plugin-oxfmt'
|
|
49
|
+
|
|
50
|
+
export default [
|
|
51
|
+
{
|
|
52
|
+
...pluginOxfmt.configs.recommended,
|
|
53
|
+
files: ['**/*.{js,ts,mjs,cjs,jsx,tsx}'],
|
|
54
|
+
},
|
|
55
|
+
]
|
|
56
|
+
```
|
|
28
57
|
|
|
58
|
+
### Custom Configuration
|
|
59
|
+
|
|
60
|
+
You can customize the formatting options by configuring the rule:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
// eslint.config.mjs
|
|
29
64
|
import pluginOxfmt from 'eslint-plugin-oxfmt'
|
|
30
|
-
import { defineConfig } from 'eslint/config'
|
|
31
65
|
|
|
32
|
-
export default
|
|
66
|
+
export default [
|
|
33
67
|
{
|
|
34
68
|
...pluginOxfmt.configs.recommended,
|
|
35
69
|
files: ['**/*.{js,ts,mjs,cjs,jsx,tsx}'],
|
|
@@ -37,17 +71,148 @@ export default defineConfig([
|
|
|
37
71
|
'oxfmt/oxfmt': [
|
|
38
72
|
'error',
|
|
39
73
|
{
|
|
74
|
+
// Formatting options
|
|
40
75
|
semi: false,
|
|
41
|
-
|
|
42
|
-
|
|
76
|
+
singleQuote: true,
|
|
77
|
+
tabWidth: 2,
|
|
78
|
+
useTabs: false,
|
|
43
79
|
trailingComma: 'all',
|
|
80
|
+
printWidth: 100,
|
|
81
|
+
arrowParens: 'avoid',
|
|
82
|
+
|
|
83
|
+
// JSX specific options
|
|
84
|
+
jsxSingleQuote: false,
|
|
85
|
+
bracketSameLine: false,
|
|
86
|
+
singleAttributePerLine: false,
|
|
87
|
+
|
|
88
|
+
// Object formatting
|
|
89
|
+
bracketSpacing: true,
|
|
90
|
+
quoteProps: 'as-needed',
|
|
91
|
+
|
|
92
|
+
// Line endings
|
|
93
|
+
endOfLine: 'lf',
|
|
94
|
+
insertFinalNewline: true,
|
|
44
95
|
},
|
|
45
96
|
],
|
|
46
97
|
},
|
|
47
98
|
},
|
|
48
|
-
]
|
|
99
|
+
]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Configuration Options
|
|
103
|
+
|
|
104
|
+
All options are optional and default to sensible values.
|
|
105
|
+
|
|
106
|
+
### Basic Options
|
|
107
|
+
|
|
108
|
+
| Option | Type | Default | Description |
|
|
109
|
+
| ------------- | --------- | ------- | ------------------------------------------ |
|
|
110
|
+
| `semi` | `boolean` | `true` | Add semicolons at the end of statements |
|
|
111
|
+
| `singleQuote` | `boolean` | `false` | Use single quotes instead of double quotes |
|
|
112
|
+
| `tabWidth` | `number` | `2` | Number of spaces per indentation level |
|
|
113
|
+
| `useTabs` | `boolean` | `false` | Use tabs for indentation |
|
|
114
|
+
| `printWidth` | `number` | `100` | Maximum line length for wrapping |
|
|
115
|
+
|
|
116
|
+
### Trailing Commas
|
|
117
|
+
|
|
118
|
+
| Option | Type | Default | Description |
|
|
119
|
+
| --------------- | -------------------------- | ------- | ---------------------------- |
|
|
120
|
+
| `trailingComma` | `'all' \| 'es5' \| 'none'` | `'all'` | Where to add trailing commas |
|
|
121
|
+
|
|
122
|
+
### Arrow Functions
|
|
123
|
+
|
|
124
|
+
| Option | Type | Default | Description |
|
|
125
|
+
| ------------- | --------------------- | ---------- | -------------------------------------------------------- |
|
|
126
|
+
| `arrowParens` | `'always' \| 'avoid'` | `'always'` | Include parentheses around sole arrow function parameter |
|
|
127
|
+
|
|
128
|
+
### JSX Options
|
|
129
|
+
|
|
130
|
+
| Option | Type | Default | Description |
|
|
131
|
+
| ------------------------ | --------- | ------- | -------------------------------------- |
|
|
132
|
+
| `jsxSingleQuote` | `boolean` | `false` | Use single quotes in JSX attributes |
|
|
133
|
+
| `bracketSameLine` | `boolean` | `false` | Put `>` on the same line in JSX |
|
|
134
|
+
| `singleAttributePerLine` | `boolean` | `false` | Force single attribute per line in JSX |
|
|
135
|
+
|
|
136
|
+
### Object Formatting
|
|
137
|
+
|
|
138
|
+
| Option | Type | Default | Description |
|
|
139
|
+
| ---------------- | ------------------------------------------- | ------------- | ------------------------------------------------ |
|
|
140
|
+
| `bracketSpacing` | `boolean` | `true` | Print spaces between brackets in object literals |
|
|
141
|
+
| `quoteProps` | `'as-needed' \| 'consistent' \| 'preserve'` | `'as-needed'` | When to quote object property names |
|
|
142
|
+
| `objectWrap` | `'preserve' \| 'collapse' \| 'always'` | `'preserve'` | How to wrap object literals |
|
|
143
|
+
|
|
144
|
+
### Line Endings
|
|
145
|
+
|
|
146
|
+
| Option | Type | Default | Description |
|
|
147
|
+
| -------------------- | ------------------------ | ------- | ------------------------------------ |
|
|
148
|
+
| `endOfLine` | `'lf' \| 'crlf' \| 'cr'` | `'lf'` | Line ending character(s) |
|
|
149
|
+
| `insertFinalNewline` | `boolean` | `true` | Insert a newline at the end of files |
|
|
150
|
+
|
|
151
|
+
### Advanced Options
|
|
152
|
+
|
|
153
|
+
| Option | Type | Default | Description |
|
|
154
|
+
| ----------------------------- | ----------------- | -------- | ----------------------------------------- |
|
|
155
|
+
| `embeddedLanguageFormatting` | `'auto' \| 'off'` | `'auto'` | Control formatting of quoted code |
|
|
156
|
+
| `experimentalSortImports` | `object` | - | Experimental import sorting configuration |
|
|
157
|
+
| `experimentalSortPackageJson` | `boolean` | - | Experimental package.json sorting |
|
|
158
|
+
|
|
159
|
+
## Rules
|
|
160
|
+
|
|
161
|
+
### `oxfmt/oxfmt`
|
|
162
|
+
|
|
163
|
+
This plugin provides a single rule that formats your code using oxfmt.
|
|
164
|
+
|
|
165
|
+
- Recommended: `error`
|
|
166
|
+
- Fixable: Yes (automatically applies formatting)
|
|
167
|
+
- Type: Layout
|
|
168
|
+
|
|
169
|
+
## Examples
|
|
170
|
+
|
|
171
|
+
### Format on Save in VS Code
|
|
172
|
+
|
|
173
|
+
Add this to your `.vscode/settings.json`:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"editor.codeActionsOnSave": {
|
|
178
|
+
"source.fixAll.eslint": "explicit"
|
|
179
|
+
},
|
|
180
|
+
"eslint.validate": [
|
|
181
|
+
"javascript",
|
|
182
|
+
"javascriptreact",
|
|
183
|
+
"typescript",
|
|
184
|
+
"typescriptreact"
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Run from Command Line
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Check for formatting issues
|
|
193
|
+
npx eslint .
|
|
194
|
+
|
|
195
|
+
# Fix formatting issues
|
|
196
|
+
npx eslint . --fix
|
|
49
197
|
```
|
|
50
198
|
|
|
199
|
+
## Why oxfmt?
|
|
200
|
+
|
|
201
|
+
[oxfmt](https://github.com/oxc-project/oxc) is a modern, blazing-fast formatter written in Rust as part of the [Oxc project](https://oxc-project.github.io/). It aims to be a drop-in replacement for Prettier with significantly better performance.
|
|
202
|
+
|
|
203
|
+
### Benefits
|
|
204
|
+
|
|
205
|
+
- **Performance**: 50-100x faster than Prettier
|
|
206
|
+
- **Compatibility**: Designed to be Prettier-compatible
|
|
207
|
+
- **Modern**: Built with modern JavaScript/TypeScript in mind
|
|
208
|
+
- **Maintained**: Part of the actively developed Oxc project
|
|
209
|
+
|
|
210
|
+
## Related Projects
|
|
211
|
+
|
|
212
|
+
- [oxc](https://github.com/oxc-project/oxc) - The Oxidation Compiler
|
|
213
|
+
- [oxlint](https://github.com/oxc-project/oxc) - A fast linter
|
|
214
|
+
- [ESLint](https://eslint.org/) - Pluggable JavaScript linter
|
|
215
|
+
|
|
51
216
|
## License
|
|
52
217
|
|
|
53
218
|
[MIT](./LICENSE) License © 2025-PRESENT [ntnyq](https://github.com/ntnyq)
|
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { DIFFERENCE, generateDifferences } from "generate-differences";
|
|
|
5
5
|
|
|
6
6
|
//#region rolldown:runtime
|
|
7
7
|
var __defProp = Object.defineProperty;
|
|
8
|
-
var
|
|
8
|
+
var __exportAll = (all, symbols) => {
|
|
9
9
|
let target = {};
|
|
10
10
|
for (var name$2 in all) {
|
|
11
11
|
__defProp(target, name$2, {
|
|
@@ -21,7 +21,7 @@ var __export = (all, symbols) => {
|
|
|
21
21
|
|
|
22
22
|
//#endregion
|
|
23
23
|
//#region node_modules/.pnpm/eslint-parser-plain@0.1.1/node_modules/eslint-parser-plain/dist/index.mjs
|
|
24
|
-
var dist_exports = /* @__PURE__ */
|
|
24
|
+
var dist_exports = /* @__PURE__ */ __exportAll({
|
|
25
25
|
meta: () => meta$1,
|
|
26
26
|
parseForESLint: () => parseForESLint
|
|
27
27
|
});
|
|
@@ -67,7 +67,7 @@ const configs = { recommended };
|
|
|
67
67
|
//#endregion
|
|
68
68
|
//#region package.json
|
|
69
69
|
var name = "eslint-plugin-oxfmt";
|
|
70
|
-
var version = "0.0.
|
|
70
|
+
var version = "0.0.3";
|
|
71
71
|
|
|
72
72
|
//#endregion
|
|
73
73
|
//#region src/meta.ts
|
|
@@ -81,13 +81,32 @@ const meta = {
|
|
|
81
81
|
const dirWorkers = fileURLToPath(new URL("../workers", import.meta.url));
|
|
82
82
|
|
|
83
83
|
//#endregion
|
|
84
|
-
//#region node_modules/.pnpm/show-invisibles@0.0.
|
|
85
|
-
const DEFAULT_MAPPINGS =
|
|
84
|
+
//#region node_modules/.pnpm/show-invisibles@0.0.2/node_modules/show-invisibles/dist/index.js
|
|
85
|
+
const DEFAULT_MAPPINGS = new Map([
|
|
86
86
|
[" ", "·"],
|
|
87
87
|
["\n", "⏎"],
|
|
88
88
|
["\r", "␍"],
|
|
89
89
|
[" ", "↹"]
|
|
90
90
|
]);
|
|
91
|
+
/**
|
|
92
|
+
* Converts invisible characters to a commonly recognizable visible form
|
|
93
|
+
*
|
|
94
|
+
* @param input - The string with invisibles to convert
|
|
95
|
+
* @param options - options {@link Options}
|
|
96
|
+
* @returns The converted string
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
*
|
|
100
|
+
* ```ts
|
|
101
|
+
* import { showInvisibles } from 'show-invisibles'
|
|
102
|
+
*
|
|
103
|
+
* const input = `1 2\n3\t4\r5`
|
|
104
|
+
*
|
|
105
|
+
* console.log(showInvisibles(input))
|
|
106
|
+
*
|
|
107
|
+
* // => 1·2⏎3↹4␍5
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
91
110
|
function showInvisibles(input, options = {}) {
|
|
92
111
|
const { mappings = DEFAULT_MAPPINGS } = options;
|
|
93
112
|
if (typeof input !== "string") throw new TypeError(`Expected input to type string, got ${typeof input}`);
|
|
@@ -230,6 +249,10 @@ const oxfmt = {
|
|
|
230
249
|
type: "array",
|
|
231
250
|
items: { type: "string" }
|
|
232
251
|
},
|
|
252
|
+
insertFinalNewline: {
|
|
253
|
+
description: `Whether to insert a final newline at the end of the file. (Default: true)`,
|
|
254
|
+
type: "boolean"
|
|
255
|
+
},
|
|
233
256
|
jsxSingleQuote: {
|
|
234
257
|
description: `Use single quotes instead of double quotes in JSX. (Default: false)`,
|
|
235
258
|
type: "boolean"
|
|
@@ -293,7 +316,10 @@ const oxfmt = {
|
|
|
293
316
|
return { Program() {
|
|
294
317
|
const sourceText = context.sourceCode.text;
|
|
295
318
|
try {
|
|
296
|
-
const formatResult = formatViaOxfmt(context.filename, sourceText, {
|
|
319
|
+
const formatResult = formatViaOxfmt(context.filename, sourceText, {
|
|
320
|
+
...context.options?.[0],
|
|
321
|
+
cwd: context.cwd
|
|
322
|
+
});
|
|
297
323
|
if (formatResult.errors?.length) for (const error of formatResult.errors) {
|
|
298
324
|
const label = error.labels?.[0];
|
|
299
325
|
if (label) {
|
package/dts/rule-options.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-oxfmt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
5
|
-
"description": "An ESLint plugin
|
|
4
|
+
"version": "0.0.3",
|
|
5
|
+
"description": "An ESLint plugin for formatting code with oxfmt.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"eslint",
|
|
8
8
|
"eslint-plugin",
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
"eslint": "^9.5.0"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"generate-differences": "^0.1.
|
|
50
|
-
"oxfmt": "^0.
|
|
49
|
+
"generate-differences": "^0.1.1",
|
|
50
|
+
"load-oxfmt-config": "^0.0.3",
|
|
51
|
+
"oxfmt": "^0.21.0",
|
|
51
52
|
"synckit": "^0.11.11"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@ntnyq/eslint-config": "^5.8.0",
|
|
55
56
|
"@ntnyq/prettier-config": "^3.0.1",
|
|
56
|
-
"@types/json-schema": "^7.0.15",
|
|
57
57
|
"@types/node": "^25.0.3",
|
|
58
58
|
"@typescript/native-preview": "7.0.0-dev.20251204.1",
|
|
59
59
|
"bumpp": "^10.3.2",
|
|
@@ -62,13 +62,12 @@
|
|
|
62
62
|
"eslint-typegen": "^2.3.0",
|
|
63
63
|
"eslint-vitest-rule-tester": "^3.0.1",
|
|
64
64
|
"husky": "^9.1.7",
|
|
65
|
-
"json-schema": "^0.4.0",
|
|
66
65
|
"nano-staged": "^0.9.0",
|
|
67
66
|
"npm-run-all2": "^8.0.4",
|
|
68
67
|
"prettier": "^3.7.4",
|
|
69
|
-
"show-invisibles": "^0.0.
|
|
68
|
+
"show-invisibles": "^0.0.2",
|
|
70
69
|
"tinyglobby": "^0.2.15",
|
|
71
|
-
"tsdown": "^0.18.
|
|
70
|
+
"tsdown": "^0.18.4",
|
|
72
71
|
"tsx": "^4.21.0",
|
|
73
72
|
"typescript": "^5.9.3",
|
|
74
73
|
"vitest": "^4.0.16"
|
package/workers/oxfmt.mjs
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
+
import { loadOxfmtConfig } from 'load-oxfmt-config'
|
|
3
4
|
import { format } from 'oxfmt'
|
|
4
5
|
import { runAsWorker } from 'synckit'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* @
|
|
8
|
+
* @typedef {object} PluginOptions
|
|
9
|
+
* @property {boolean} [useConfig] - Whether to use oxfmt configuration file
|
|
10
|
+
* @property {string} cwd - Current working directory for resolving configuration
|
|
11
|
+
* @property {string} [configPath] - Custom path to oxfmt configuration file
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {import('oxfmt').FormatOptions & PluginOptions} Options
|
|
8
16
|
*/
|
|
9
17
|
|
|
10
18
|
runAsWorker(
|
|
@@ -18,11 +26,22 @@ runAsWorker(
|
|
|
18
26
|
*/
|
|
19
27
|
sourceText,
|
|
20
28
|
/**'
|
|
21
|
-
* @type {
|
|
29
|
+
* @type {Options} format options
|
|
22
30
|
*/
|
|
23
31
|
options,
|
|
24
32
|
) => {
|
|
25
|
-
const
|
|
33
|
+
const { configPath, cwd, useConfig = true, ...formatOptions } = options
|
|
34
|
+
const mergedOptions = {
|
|
35
|
+
...(useConfig
|
|
36
|
+
? await loadOxfmtConfig({
|
|
37
|
+
configPath,
|
|
38
|
+
cwd,
|
|
39
|
+
})
|
|
40
|
+
: {}),
|
|
41
|
+
...formatOptions,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const formatResult = await format(filename, sourceText, mergedOptions)
|
|
26
45
|
return formatResult
|
|
27
46
|
},
|
|
28
47
|
)
|