@evanpurkhiser/oxc-config 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +16 -0
- package/.github/workflows/main.yml +37 -0
- package/README.md +49 -0
- package/REPO_ANALYSIS.md +45 -0
- package/oxfmt.config.ts +5 -0
- package/oxlint.config.ts +7 -0
- package/package.json +37 -0
- package/profiles/all/oxlint.config.ts +7 -0
- package/src/common.mjs +81 -0
- package/src/index.mjs +6 -0
- package/src/oxfmt.mjs +33 -0
- package/src/react.mjs +19 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
check:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: actions/setup-node@v4
|
|
13
|
+
with:
|
|
14
|
+
node-version: '24'
|
|
15
|
+
- run: npm ci
|
|
16
|
+
- run: npm run check
|
|
17
|
+
|
|
18
|
+
publish:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
needs: check
|
|
21
|
+
permissions:
|
|
22
|
+
contents: write
|
|
23
|
+
id-token: write
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- uses: actions/setup-node@v4
|
|
27
|
+
with:
|
|
28
|
+
node-version: '24'
|
|
29
|
+
registry-url: 'https://registry.npmjs.org'
|
|
30
|
+
- run: npm ci
|
|
31
|
+
- name: bump version
|
|
32
|
+
run: |
|
|
33
|
+
git config user.name "GitHub Actions"
|
|
34
|
+
git config user.email "<>"
|
|
35
|
+
npm version minor
|
|
36
|
+
git push
|
|
37
|
+
- run: npm publish --provenance --access=public
|
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
## Evan Purkhiser's Personal Oxc config
|
|
2
|
+
|
|
3
|
+
[](https://github.com/evanpurkhiser/oxc-config/actions?query=workflow%3Apublish)
|
|
4
|
+
[](https://www.npmjs.com/package/@evanpurkhiser/oxc-config)
|
|
5
|
+
|
|
6
|
+
These are my Oxc linting and formatting configurations that I use across my
|
|
7
|
+
various personal
|
|
8
|
+
projects.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -D oxlint oxfmt @evanpurkhiser/oxc-config
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Create an `oxlint.config.ts` file with the contents:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import {defineConfig} from 'oxlint';
|
|
18
|
+
import {all} from '@evanpurkhiser/oxc-config';
|
|
19
|
+
|
|
20
|
+
export default defineConfig({
|
|
21
|
+
extends: all,
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The default configuration is for React apps, but you can select from the
|
|
26
|
+
following configurations:
|
|
27
|
+
|
|
28
|
+
- `common` - ES6 and Typescript rules
|
|
29
|
+
- `react` - React specific rules
|
|
30
|
+
|
|
31
|
+
For example:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import {defineConfig} from 'oxlint';
|
|
35
|
+
import {common} from '@evanpurkhiser/oxc-config';
|
|
36
|
+
|
|
37
|
+
export default defineConfig({
|
|
38
|
+
extends: [common],
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For Oxfmt, create an `oxfmt.config.ts` file:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import {defineConfig} from 'oxfmt';
|
|
46
|
+
import {oxfmt} from '@evanpurkhiser/oxc-config/oxfmt';
|
|
47
|
+
|
|
48
|
+
export default defineConfig(oxfmt);
|
|
49
|
+
```
|
package/REPO_ANALYSIS.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# ESLint to Oxlint migration analysis
|
|
2
|
+
|
|
3
|
+
## Scope reviewed
|
|
4
|
+
|
|
5
|
+
- `/home/evan/coding/recovery`
|
|
6
|
+
- `/home/evan/coding/instagram-saver`
|
|
7
|
+
- `/home/evan/coding/meal-log`
|
|
8
|
+
- `/home/evan/coding/atuin-abacus`
|
|
9
|
+
- `/home/evan/coding/prolink-connect`
|
|
10
|
+
- `/home/evan/coding/waitress`
|
|
11
|
+
- `/home/evan/coding/transmission-helper`
|
|
12
|
+
- `/home/evan/coding/email-to-lunchmoney`
|
|
13
|
+
- `/home/evan/coding/tooling-personal`
|
|
14
|
+
- `/home/evan/coding/rekordbox-parser`
|
|
15
|
+
- `/home/evan/coding/tune-manager`
|
|
16
|
+
- `/home/evan/coding/doppovich-bot`
|
|
17
|
+
- `/home/evan/coding/keyway-twilio`
|
|
18
|
+
- `/home/evan/coding/prolink-tools`
|
|
19
|
+
|
|
20
|
+
## Findings by repository
|
|
21
|
+
|
|
22
|
+
| Repository | Current ESLint setup | Recommended Oxlint preset | Special handling |
|
|
23
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------- | ------------------------------------------------------------------------------------ |
|
|
24
|
+
| `recovery` | Flat config: `common` + `prettier/prettier: off` | `common` | No custom lint rules needed. |
|
|
25
|
+
| `instagram-saver` | Flat config: `all` + `prettier/prettier: off` | `all` | No custom lint rules needed. |
|
|
26
|
+
| `meal-log` | Flat config: `common` + `prettier/prettier: off` | `common` | No custom lint rules needed. |
|
|
27
|
+
| `atuin-abacus` | Flat config: `common` + `prettier/prettier: off` | `common` | Deno repo; validate JS/TS file globs for CLI usage. |
|
|
28
|
+
| `prolink-connect` | Flat config: `common` + `prettier/prettier: off` | `common` | Keep test-specific overrides local if needed later. |
|
|
29
|
+
| `waitress` | Flat config: `all` + `prettier/prettier: off` | `all` | Browser React app. |
|
|
30
|
+
| `transmission-helper` | Flat config: `common` + `prettier/prettier: off` | `common` | No custom lint rules needed. |
|
|
31
|
+
| `email-to-lunchmoney` | Flat config: `common` + `prettier/prettier: off` | `common` | Cloudflare Worker; add env/global overrides only if diagnostics require it. |
|
|
32
|
+
| `tooling-personal` | Flat config: `all` + `prettier/prettier: off` | `all` | Tooling repo likely to become migration templates. |
|
|
33
|
+
| `rekordbox-parser` | Legacy `.eslintrc.js`: extends `common`, node env, prettier off | `common` | Add `env.node: true` in local config. |
|
|
34
|
+
| `tune-manager` | Legacy `.eslintrc.js`: extends default (`all`), browser env, prettier off | `all` | Add `env.browser: true` explicitly if needed. |
|
|
35
|
+
| `doppovich-bot` | Legacy `.eslintrc.js`: extends `common`, node env, prettier off | `common` | Add `env.node: true` in local config. |
|
|
36
|
+
| `keyway-twilio` | Legacy `.eslintrc.js`: extends `common`, node env, prettier off | `common` | Add `env.node: true` in local config. |
|
|
37
|
+
| `prolink-tools` | Legacy `.eslintrc.js`: extends default (`all`) with custom import groups and `typescript/no-unused-vars` ignore patterns | `all` | Keep repo-local overrides for import sorting groups and unused-vars ignore patterns. |
|
|
38
|
+
|
|
39
|
+
## Cross-repo migration notes
|
|
40
|
+
|
|
41
|
+
1. Every repo disables `prettier/prettier`; this is naturally removed in Oxlint.
|
|
42
|
+
2. Most repos can use only one line of config via `extends: [common]` or `extends: all`.
|
|
43
|
+
3. Legacy repos that currently set `env.node` should keep that as repo-local override.
|
|
44
|
+
4. `prolink-tools` should keep local customizations because the internal import groups differ from the shared default.
|
|
45
|
+
5. Run dual lint (`oxlint` + `eslint`) temporarily only for repos where any unsupported rule must be retained.
|
package/oxfmt.config.ts
ADDED
package/oxlint.config.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "@evanpurkhiser/oxc-config",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "Evan Purkhiser's personal Oxc configuration",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Evan Purkhiser",
|
|
8
|
+
"repository": "https://github.com/evanpurkhiser/oxc-config",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "src/index.mjs",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./src/index.mjs",
|
|
13
|
+
"./common": "./src/common.mjs",
|
|
14
|
+
"./react": "./src/react.mjs",
|
|
15
|
+
"./oxfmt": "./src/oxfmt.mjs"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"lint": "oxlint src oxlint.config.ts profiles/all/oxlint.config.ts",
|
|
19
|
+
"format": "oxfmt .",
|
|
20
|
+
"format:check": "oxfmt --check .",
|
|
21
|
+
"check": "npm run lint && npm run format:check"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"eslint-plugin-simple-import-sort": "^12.1.1"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"oxfmt": "^0.41.0",
|
|
28
|
+
"oxlint": "^1.56.0",
|
|
29
|
+
"typescript": "^5.9.2"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"oxlint": ">=1.56.0"
|
|
33
|
+
},
|
|
34
|
+
"volta": {
|
|
35
|
+
"node": "24.3.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/common.mjs
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {builtinModules} from 'node:module';
|
|
2
|
+
|
|
3
|
+
const common = {
|
|
4
|
+
plugins: ['eslint', 'typescript', 'unicorn', 'oxc', 'import', 'react'],
|
|
5
|
+
|
|
6
|
+
jsPlugins: ['eslint-plugin-simple-import-sort'],
|
|
7
|
+
|
|
8
|
+
rules: {
|
|
9
|
+
// Best practices
|
|
10
|
+
'array-callback-return': ['warn'],
|
|
11
|
+
'consistent-return': ['warn'],
|
|
12
|
+
'no-caller': ['warn'],
|
|
13
|
+
'no-else-return': ['error', {allowElseIf: false}],
|
|
14
|
+
'no-extra-label': ['error'],
|
|
15
|
+
'no-floating-decimal': ['error'],
|
|
16
|
+
'no-implied-eval': ['error'],
|
|
17
|
+
'no-lone-blocks': ['error'],
|
|
18
|
+
'no-return-await': ['error'],
|
|
19
|
+
'no-self-compare': ['error'],
|
|
20
|
+
'no-sequences': ['error'],
|
|
21
|
+
'no-useless-call': ['warn'],
|
|
22
|
+
'no-useless-concat': ['warn'],
|
|
23
|
+
'no-useless-return': ['warn'],
|
|
24
|
+
'require-await': ['warn'],
|
|
25
|
+
curly: ['error'],
|
|
26
|
+
eqeqeq: ['error'],
|
|
27
|
+
radix: ['warn'],
|
|
28
|
+
|
|
29
|
+
// Variables
|
|
30
|
+
'no-undef-init': ['warn'],
|
|
31
|
+
|
|
32
|
+
// Style (mostly handled by prettier/oxfmt)
|
|
33
|
+
'eol-last': ['error', 'always'],
|
|
34
|
+
'new-parens': ['error'],
|
|
35
|
+
'padded-blocks': ['warn', 'never'],
|
|
36
|
+
'spaced-comment': ['warn', 'always'],
|
|
37
|
+
|
|
38
|
+
// ECMAScript
|
|
39
|
+
'no-var': ['error'],
|
|
40
|
+
'prefer-arrow-callback': ['warn'],
|
|
41
|
+
'prefer-const': ['error'],
|
|
42
|
+
'prefer-destructuring': ['off'],
|
|
43
|
+
'prefer-numeric-literals': ['warn'],
|
|
44
|
+
'prefer-rest-params': ['warn'],
|
|
45
|
+
'prefer-spread': ['warn'],
|
|
46
|
+
'prefer-template': ['warn'],
|
|
47
|
+
'arrow-body-style': ['error', 'as-needed'],
|
|
48
|
+
|
|
49
|
+
// Disabled for TypeScript
|
|
50
|
+
'no-unused-expressions': ['off'],
|
|
51
|
+
|
|
52
|
+
// TypeScript
|
|
53
|
+
'typescript/explicit-function-return-type': ['off'],
|
|
54
|
+
'typescript/no-use-before-define': ['off'],
|
|
55
|
+
'typescript/no-explicit-any': ['off'],
|
|
56
|
+
'typescript/no-non-null-assertion': ['off'],
|
|
57
|
+
'typescript/explicit-module-boundary-types': ['off'],
|
|
58
|
+
'typescript/no-unused-vars': ['error', {argsIgnorePattern: '^_'}],
|
|
59
|
+
'typescript/no-unused-expressions': ['error'],
|
|
60
|
+
'typescript/no-useless-constructor': ['error'],
|
|
61
|
+
'typescript/array-type': ['error', {default: 'array-simple'}],
|
|
62
|
+
|
|
63
|
+
// Sort imports
|
|
64
|
+
'simple-import-sort/exports': 'error',
|
|
65
|
+
'simple-import-sort/imports': [
|
|
66
|
+
'error',
|
|
67
|
+
{
|
|
68
|
+
groups: [
|
|
69
|
+
['^\\u0000'],
|
|
70
|
+
['^react', '^@?\\w'],
|
|
71
|
+
[`^(${builtinModules.join('|')})(/|$)`],
|
|
72
|
+
['^(src|app)(/.*|$)'],
|
|
73
|
+
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
|
|
74
|
+
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export {common};
|
package/src/index.mjs
ADDED
package/src/oxfmt.mjs
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const oxfmt = {
|
|
2
|
+
bracketSpacing: false,
|
|
3
|
+
printWidth: 90,
|
|
4
|
+
singleQuote: true,
|
|
5
|
+
arrowParens: 'avoid',
|
|
6
|
+
sortImports: {
|
|
7
|
+
sortSideEffects: true,
|
|
8
|
+
customGroups: [
|
|
9
|
+
{
|
|
10
|
+
groupName: 'react-libs',
|
|
11
|
+
selector: 'external',
|
|
12
|
+
elementNamePattern: ['react', 'react-**'],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
groupName: 'project-internal',
|
|
16
|
+
selector: 'import',
|
|
17
|
+
elementNamePattern: ['src', 'src/**', 'app', 'app/**'],
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
groups: [
|
|
21
|
+
'side_effect',
|
|
22
|
+
'react-libs',
|
|
23
|
+
'external',
|
|
24
|
+
'builtin',
|
|
25
|
+
'project-internal',
|
|
26
|
+
'parent',
|
|
27
|
+
['sibling', 'index'],
|
|
28
|
+
'unknown',
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export {oxfmt};
|
package/src/react.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const react = {
|
|
2
|
+
env: {
|
|
3
|
+
browser: true,
|
|
4
|
+
},
|
|
5
|
+
|
|
6
|
+
rules: {
|
|
7
|
+
'react-hooks/rules-of-hooks': ['error'],
|
|
8
|
+
'react-hooks/exhaustive-deps': ['warn'],
|
|
9
|
+
'react/prop-types': ['off'],
|
|
10
|
+
'react/display-name': ['off'],
|
|
11
|
+
'react/no-access-state-in-setstate': ['warn'],
|
|
12
|
+
'react/no-this-in-sfc': ['warn'],
|
|
13
|
+
'react/prefer-stateless-function': ['warn'],
|
|
14
|
+
'react/jsx-boolean-value': ['warn'],
|
|
15
|
+
'react/jsx-pascal-case': ['warn'],
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export {react};
|