Skip to content

Commit 457d1f9

Browse files
committed
更新 ESLint 配置,添加 TypeScript 和 React 插件,提升代码质量;在多个包中添加 lint 和类型检查脚本
1 parent f0ef37e commit 457d1f9

14 files changed

Lines changed: 215 additions & 29 deletions

File tree

eslint.config.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import js from '@eslint/js'
2+
import globals from 'globals'
3+
import reactHooks from 'eslint-plugin-react-hooks'
4+
import reactRefresh from 'eslint-plugin-react-refresh'
5+
import tseslint from 'typescript-eslint'
6+
7+
export default tseslint.config(
8+
{ ignores: ['**/dist', '**/.next', '**/node_modules', '**/public'] },
9+
{
10+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
11+
files: ['**/*.{ts,tsx}'],
12+
languageOptions: {
13+
ecmaVersion: 2020,
14+
globals: globals.browser,
15+
},
16+
plugins: {
17+
'react-hooks': reactHooks,
18+
'react-refresh': reactRefresh,
19+
},
20+
rules: {
21+
...reactHooks.configs.recommended.rules,
22+
'react-refresh/only-export-components': [
23+
'warn',
24+
{ allowConstantExport: true },
25+
],
26+
'@typescript-eslint/no-explicit-any': 'warn',
27+
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
28+
},
29+
},
30+
)

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"lint": "pnpm -r lint"
3131
},
3232
"devDependencies": {
33+
"@eslint/js": "^9.39.1",
3334
"@testing-library/dom": "^10.4.1",
3435
"@testing-library/jest-dom": "^6.9.1",
3536
"@testing-library/react": "^16.3.1",
@@ -39,7 +40,10 @@
3940
"@types/react-dom": "18.3.1",
4041
"@vitest/coverage-v8": "^2.1.8",
4142
"@vitest/ui": "^2.1.8",
42-
"eslint": "^8.0.0",
43+
"eslint": "^8.57.1",
44+
"eslint-plugin-react-hooks": "^7.0.1",
45+
"eslint-plugin-react-refresh": "^0.4.24",
46+
"globals": "^16.5.0",
4347
"happy-dom": "^20.1.0",
4448
"jsdom": "^27.4.0",
4549
"prettier": "^3.0.0",
@@ -49,6 +53,7 @@
4953
"tslib": "^2.6.0",
5054
"turbo": "^2.6.3",
5155
"typescript": "^5.0.0",
56+
"typescript-eslint": "^8.46.4",
5257
"vitest": "^2.1.8"
5358
},
5459
"pnpm": {

packages/components/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
"scripts": {
1818
"build": "vite build",
1919
"pretest": "pnpm --filter @object-ui/core build && pnpm --filter @object-ui/react build",
20-
"test": "vitest run"
20+
"test": "vitest run",
21+
"type-check": "tsc --noEmit",
22+
"lint": "eslint ."
2123
},
2224
"dependencies": {
2325
"@object-ui/core": "workspace:*",

packages/components/src/renderers/form/form.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ ComponentRegistry.register('form',
9797
setSubmitError(errorMessage);
9898

9999
// Log errors for debugging (dev environment only)
100-
// @ts-ignore - process may not be defined in all environments
100+
// @ts-expect-error - process may not be defined in all environments
101101
if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
102102
console.error('Form submission error:', error);
103103
}
@@ -356,7 +356,7 @@ function renderFieldComponent(type: string, props: RenderFieldProps) {
356356
case 'textarea':
357357
return <Textarea placeholder={placeholder} {...fieldProps} />;
358358

359-
case 'checkbox':
359+
case 'checkbox': {
360360
// For checkbox, we need to handle the value differently
361361
const { value, onChange, ...checkboxProps } = fieldProps;
362362
return (
@@ -368,8 +368,9 @@ function renderFieldComponent(type: string, props: RenderFieldProps) {
368368
/>
369369
</div>
370370
);
371+
}
371372

372-
case 'select':
373+
case 'select': {
373374
// For select with react-hook-form, we need to handle the onChange
374375
const { value: selectValue, onChange: selectOnChange, ...selectProps } = fieldProps;
375376

@@ -392,6 +393,7 @@ function renderFieldComponent(type: string, props: RenderFieldProps) {
392393
</SelectContent>
393394
</Select>
394395
);
396+
}
395397

396398
default:
397399
return <Input type={inputType || 'text'} placeholder={placeholder} {...fieldProps} />;

packages/components/src/renderers/layout/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ ComponentRegistry.register(
6262
name: 'body',
6363
type: 'array',
6464
label: 'Content',
65-
// @ts-ignore - itemType is experimental/extended metadata
65+
// @ts-expect-error - itemType is experimental/extended metadata
6666
itemType: 'component'
6767
}
6868
]

packages/components/src/ui/sidebar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,9 @@ function SidebarMenuSkeleton({
607607
showIcon?: boolean
608608
}) {
609609
// Random width between 50 to 90%.
610-
const width = React.useMemo(() => {
610+
const [width] = React.useState(() => {
611611
return `${Math.floor(Math.random() * 40) + 50}%`
612-
}, [])
612+
})
613613

614614
return (
615615
<div

packages/core/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"types": "dist/index.d.ts",
77
"scripts": {
88
"build": "tsc",
9-
"test": "vitest run"
9+
"test": "vitest run",
10+
"type-check": "tsc --noEmit",
11+
"lint": "eslint ."
1012
},
1113
"dependencies": {
1214
"lodash": "^4.17.21",

packages/data-objectql/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"clean": "rm -rf dist",
2424
"type-check": "tsc --noEmit",
2525
"test": "vitest run",
26+
"lint": "eslint .",
2627
"test:watch": "vitest"
2728
},
2829
"keywords": [

packages/data-objectql/src/hooks.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ export interface UseObjectQLMutationOptions {
7676
* ```
7777
*/
7878
export function useObjectQL(options: UseObjectQLOptions): ObjectQLDataSource {
79+
const { baseUrl, token, spaceId } = options.config;
7980
return useMemo(
80-
() => new ObjectQLDataSource(options.config),
81-
[options.config.baseUrl, options.config.token, options.config.spaceId]
81+
() => new ObjectQLDataSource({ baseUrl, token, spaceId }),
82+
[baseUrl, token, spaceId]
8283
);
8384
}
8485

@@ -127,14 +128,20 @@ export function useObjectQLQuery<T = any>(
127128
...queryParams
128129
} = options;
129130

131+
// Serialize params to string for stable dependency checking
132+
const queryParamsString = JSON.stringify(queryParams);
133+
130134
const fetchData = useCallback(async () => {
131135
if (!enabled) return;
132136

133137
setLoading(true);
134138
setError(null);
135139

136140
try {
137-
const queryResult = await dataSource.find(resource, queryParams);
141+
// Parse params back from string to ensure we use the version
142+
// corresponding to the dependency trigger
143+
const params = JSON.parse(queryParamsString);
144+
const queryResult = await dataSource.find(resource, params);
138145
setResult(queryResult);
139146
setData(queryResult.data);
140147
onSuccess?.(queryResult.data);
@@ -145,7 +152,7 @@ export function useObjectQLQuery<T = any>(
145152
} finally {
146153
setLoading(false);
147154
}
148-
}, [dataSource, resource, enabled, onSuccess, onError, JSON.stringify(queryParams)]);
155+
}, [dataSource, resource, enabled, onSuccess, onError, queryParamsString]);
149156

150157
useEffect(() => {
151158
fetchData();

packages/designer/src/components/PropertyPanel.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,20 @@ interface PropertyPanelProps {
2525
export const PropertyPanel: React.FC<PropertyPanelProps> = React.memo(({ className }) => {
2626
const { schema, selectedNodeId, updateNode, removeNode, copyNode, pasteNode, canPaste } = useDesigner();
2727

28-
// Recursive finder - memoized to prevent recreation on every render
29-
const findNode = useCallback((node: any, id: string): any => {
30-
if (!node) return null;
31-
if (node.id === id) return node;
32-
if (node.body) {
33-
if (Array.isArray(node.body)) {
34-
for (const child of node.body) {
35-
const found = findNode(child, id);
36-
if (found) return found;
28+
// Recursive finder
29+
const findNode = useCallback((root: any, id: string): any => {
30+
const queue = [root];
31+
while (queue.length > 0) {
32+
const node = queue.shift();
33+
if (!node) continue;
34+
if (node.id === id) return node;
35+
36+
if (node.body) {
37+
if (Array.isArray(node.body)) {
38+
queue.push(...node.body);
39+
} else if (typeof node.body === 'object') {
40+
queue.push(node.body);
3741
}
38-
} else if (typeof node.body === 'object') {
39-
return findNode(node.body, id);
4042
}
4143
}
4244
return null;
@@ -89,7 +91,7 @@ export const PropertyPanel: React.FC<PropertyPanelProps> = React.memo(({ classNa
8991
/>
9092
</div>
9193
);
92-
case 'enum':
94+
case 'enum': {
9395
const options = Array.isArray(input.enum)
9496
? input.enum.map(opt => typeof opt === 'string' ? { label: opt, value: opt } : opt)
9597
: [];
@@ -113,6 +115,7 @@ export const PropertyPanel: React.FC<PropertyPanelProps> = React.memo(({ classNa
113115
</Select>
114116
</div>
115117
);
118+
}
116119
case 'number':
117120
return (
118121
<div className="space-y-1.5">

0 commit comments

Comments
 (0)