Skip to content

Commit 80597fc

Browse files
authored
Merge pull request #38 from dev-five-git/fix-rule
Fix rule
2 parents f29132c + 370e6fb commit 80597fc

File tree

8 files changed

+284
-428
lines changed

8 files changed

+284
-428
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes":{"package.json":"Patch"},"note":"Improve performance","date":"2026-04-04T07:42:05.622193100Z"}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@ stats.html
5656
.nx/workspace-data
5757
**/vite.config.{js,ts,mjs,mts,cjs,cts}.timestamp*
5858

59-
.claude
59+
.claude
60+
.omc

bun.lock

Lines changed: 237 additions & 397 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

oxlintrc.json

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,19 @@
6868
"devup/unused-imports/no-unused-vars": "off",
6969

7070
"devup/query/exhaustive-deps": "error",
71+
"devup/query/stable-query-client": "error",
72+
"devup/query/no-rest-destructuring": "error",
73+
"devup/query/no-unstable-deps": "error",
74+
"devup/query/infinite-query-property-order": "error",
75+
"devup/query/no-void-query-fn": "error",
76+
"devup/query/mutation-property-order": "error",
77+
"devup/query/prefer-query-options": "error",
7178

7279
"no-console": ["error", { "allow": ["info", "debug", "warn", "error"] }],
7380
"no-constant-condition": ["error", { "checkLoops": false }],
7481
"no-debugger": "error",
7582
"no-empty": "error",
7683
"no-empty-pattern": "error",
77-
"no-trailing-spaces": "error",
7884
"no-unused-vars": [
7985
"error",
8086
{
@@ -94,17 +100,16 @@
94100
"allowTernary": true
95101
}
96102
],
97-
"spaced-comment": ["error", "always", { "markers": ["/"] }],
98103

99104
"react/react-in-jsx-scope": "off",
100-
"react/prop-types": "off",
105+
"devup/react/prop-types": "off",
101106
"react/jsx-key": "error",
102107
"react/jsx-no-comment-textnodes": "error",
103108
"react/jsx-no-duplicate-props": "error",
104109
"react/jsx-no-target-blank": "error",
105110
"react/jsx-no-undef": "error",
106111
"react/jsx-curly-brace-presence": "error",
107-
"react/jsx-sort-props": [
112+
"devup/react/jsx-sort-props": [
108113
"error",
109114
{
110115
"callbacksLast": false,
@@ -124,7 +129,7 @@
124129
"react/no-string-refs": "error",
125130
"react/no-unescaped-entities": "error",
126131
"react/no-unknown-property": "error",
127-
"react/sort-default-props": "error",
132+
"devup/react/sort-default-props": "error",
128133
"react-hooks/rules-of-hooks": "error",
129134
"react-hooks/exhaustive-deps": [
130135
"warn",

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
"license": "ISC",
4141
"dependencies": {
4242
"@devup-ui/eslint-plugin": ">=1.0",
43-
"@eslint/js": ">=9.39",
43+
"@eslint/js": ">=10.0",
4444
"@tanstack/eslint-plugin-query": ">=5",
45-
"eslint": ">=9.39",
45+
"eslint": ">=10.2",
4646
"eslint-config-prettier": ">=10",
4747
"eslint-plugin-mdx": ">=3",
4848
"eslint-plugin-prettier": ">=5",
@@ -51,22 +51,22 @@
5151
"eslint-plugin-simple-import-sort": ">=12",
5252
"eslint-plugin-unused-imports": ">=4",
5353
"prettier": ">=3",
54-
"typescript-eslint": ">=8.53"
54+
"typescript-eslint": ">=8.58"
5555
},
5656
"peerDependencies": {
5757
"eslint": "*"
5858
},
5959
"devDependencies": {
60-
"@changesets/cli": "^2.29",
60+
"@changesets/cli": "^2.30",
6161
"@types/bun": "^1.3",
6262
"@types/eslint": "^9.6",
63-
"@typescript-eslint/rule-tester": "^8.53",
64-
"@typescript-eslint/utils": "^8.53",
63+
"@typescript-eslint/rule-tester": "^8.58",
64+
"@typescript-eslint/utils": "^8.58",
6565
"eslint-plugin-eslint-plugin": "^7.3",
6666
"husky": "^9.1",
67-
"oxlint": "^1.41.0",
68-
"typescript": "^5.9",
69-
"vite": "^7.3",
67+
"oxlint": "^1.58.0",
68+
"typescript": "^6.0",
69+
"vite": "^8.0",
7070
"vite-plugin-dts": "^4.5"
7171
}
7272
}

src/oxlint.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import type { Rule } from 'eslint'
1616
import { rules as mdxRules } from 'eslint-plugin-mdx'
1717
import eslintPluginPrettier from 'eslint-plugin-prettier'
1818
// @ts-ignore
19+
import reactPlugin from 'eslint-plugin-react'
20+
// @ts-ignore
1921
import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort'
2022
// @ts-ignore
2123
import unusedImportsPlugin from 'eslint-plugin-unused-imports'
@@ -25,23 +27,15 @@ import { appPage, component, componentInterface } from './rules'
2527
/**
2628
* Wrap a rule to handle unsupported context properties in oxlint
2729
* (e.g., context.parserPath throws in oxlint)
30+
* Uses Object.create for O(1) property lookup instead of Proxy trap on every access.
2831
*/
2932
function wrapRuleForOxlint(rule: Rule.RuleModule): Rule.RuleModule {
3033
return {
3134
...rule,
3235
create(context) {
33-
const proxiedContext = new Proxy(context, {
34-
get(target, prop) {
35-
// Return undefined for unsupported properties instead of throwing
36-
if (prop === 'parserPath') {
37-
return undefined
38-
}
39-
// Pass through all other properties directly to preserve Proxy invariants
40-
// (non-configurable properties must return their actual value)
41-
return target[prop as keyof typeof target]
42-
},
43-
})
44-
return rule.create(proxiedContext)
36+
const wrapped = Object.create(context) as typeof context
37+
Object.defineProperty(wrapped, 'parserPath', { value: undefined })
38+
return rule.create(wrapped)
4539
},
4640
}
4741
}
@@ -102,6 +96,15 @@ const plugin = {
10296

10397
// @tanstack/eslint-plugin-query rules (auto-wrapped for oxlint compatibility)
10498
...buildWrappedRules(tanstackQueryPlugin.rules!, 'query'),
99+
100+
// eslint-plugin-react rules not natively supported by oxlint
101+
'react/prop-types': wrapRuleForOxlint(reactPlugin.rules!['prop-types']),
102+
'react/jsx-sort-props': wrapRuleForOxlint(
103+
reactPlugin.rules!['jsx-sort-props'],
104+
),
105+
'react/sort-default-props': wrapRuleForOxlint(
106+
reactPlugin.rules!['sort-default-props'],
107+
),
105108
},
106109
}
107110

src/rules/component/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { ESLintUtils, TSESTree } from '@typescript-eslint/utils'
22
import { relative } from 'path'
33

4+
const KEBAB_SNAKE_PATTERN = /[-_](.)/g
5+
const FIRST_LOWER_PATTERN = /^[a-z]/
6+
47
function toPascal(str: string) {
58
return str
6-
.replace(/[-_](.)/g, (_, c: string) => c.toUpperCase())
7-
.replace(/^[a-z]/, (c) => c.toUpperCase())
9+
.replace(KEBAB_SNAKE_PATTERN, (_, c: string) => c.toUpperCase())
10+
.replace(FIRST_LOWER_PATTERN, (c) => c.toUpperCase())
811
}
912

1013
const createRule = ESLintUtils.RuleCreator(

tsconfig.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
"resolveJsonModule": true,
2020
"isolatedModules": true,
2121
"emitDeclarationOnly": true,
22+
"rootDir": "src",
2223
"outDir": "dist",
23-
"baseUrl": ".",
24+
"types": ["bun"],
2425
"jsx": "react-jsx"
25-
}
26+
},
27+
"include": ["src"],
28+
"exclude": ["src/**/__tests__/**"]
2629
}

0 commit comments

Comments
 (0)