Skip to content

Commit 79894fd

Browse files
committed
stricter lint rules
1 parent 1c10ac7 commit 79894fd

File tree

16 files changed

+59
-36
lines changed

16 files changed

+59
-36
lines changed

packages/components/eslint.config.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import js from '@eslint/js'
2+
import react from 'eslint-plugin-react'
23
import reactHooks from 'eslint-plugin-react-hooks'
34
import reactRefresh from 'eslint-plugin-react-refresh'
45
import globals from 'globals'
@@ -7,17 +8,25 @@ import tseslint from 'typescript-eslint'
78
export default tseslint.config(
89
{ ignores: ['coverage/', 'dist/'] },
910
{
10-
extends: [js.configs.recommended, ...tseslint.configs.recommended],
11+
settings: { react: { version: '18.3' } },
12+
extends: [js.configs.recommended, ...tseslint.configs.strictTypeChecked, ...tseslint.configs.stylisticTypeChecked],
1113
files: ['**/*.{ts,tsx,js}'],
1214
languageOptions: {
1315
ecmaVersion: 2020,
1416
globals: globals.browser,
17+
parserOptions: {
18+
project: ['./tsconfig.json', './tsconfig.eslint.json'],
19+
tsconfigRootDir: import.meta.dirname,
20+
},
1521
},
1622
plugins: {
23+
'react': react,
1724
'react-hooks': reactHooks,
1825
'react-refresh': reactRefresh,
1926
},
2027
rules: {
28+
...react.configs.recommended.rules,
29+
...react.configs['jsx-runtime'].rules,
2130
...reactHooks.configs.recommended.rules,
2231
'react-refresh/only-export-components': [
2332
'warn',
@@ -74,4 +83,8 @@ export default tseslint.config(
7483
},
7584
},
7685
},
86+
{
87+
files: ['**/*.js'],
88+
...tseslint.configs.disableTypeChecked,
89+
},
7790
)

packages/components/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"@vitejs/plugin-react": "^4.3.3",
5555
"@vitest/coverage-v8": "2.1.4",
5656
"eslint": "^9.13.0",
57+
"eslint-plugin-react": "^7.37.2",
5758
"eslint-plugin-react-hooks": "^5.0.0",
5859
"eslint-plugin-react-refresh": "^0.4.14",
5960
"globals": "^15.11.0",

packages/components/src/components/Folder.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ interface FolderProps {
1414
export default function Folder({ folderKey }: FolderProps) {
1515
// State to hold file listing
1616
const [files, setFiles] = useState<FileMetadata[]>()
17-
const [error, setError] = useState<Error>()
17+
const [error, setError] = useState<unknown>()
1818
const listRef = useRef<HTMLUListElement>(null)
1919

2020
// Folder path from url
@@ -25,7 +25,7 @@ export default function Folder({ folderKey }: FolderProps) {
2525
useEffect(() => {
2626
listFiles(prefix)
2727
.then(setFiles)
28-
.catch(error => {
28+
.catch((error:unknown) => {
2929
setFiles([])
3030
setError(error)
3131
})
@@ -39,7 +39,7 @@ export default function Folder({ folderKey }: FolderProps) {
3939
<nav className='top-header'>
4040
<div className='path'>
4141
<a href='/files'>/</a>
42-
{prefix && prefix.split('/').map((sub, depth) =>
42+
{path.map((sub, depth) =>
4343
<a href={`/files?key=${path.slice(0, depth + 1).join('/')}/`} key={depth}>{sub}/</a>,
4444
)}
4545
</div>
@@ -53,9 +53,9 @@ export default function Folder({ folderKey }: FolderProps) {
5353
{file.key}
5454
</span>
5555
{!file.key.endsWith('/') && <>
56-
<span className='file-size' title={file.fileSize?.toLocaleString() + ' bytes'}>
56+
{file.fileSize !== undefined && <span className='file-size' title={file.fileSize.toLocaleString() + ' bytes'}>
5757
{getFileSize(file)}
58-
</span>
58+
</span>}
5959
<span className='file-date' title={getFileDate(file)}>
6060
{getFileDateShort(file)}
6161
</span>

packages/components/src/components/Layout.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ interface LayoutProps {
55
children: ReactNode
66
className?: string
77
progress?: number
8-
error?: Error
8+
error?: unknown
99
title?: string
1010
}
1111

@@ -34,11 +34,11 @@ export default function Layout({ children, className, progress, error, title }:
3434
<div className={cn('content', className)}>
3535
{children}
3636
</div>
37-
<div className={cn('error-bar', error && 'show-error')}>{errorMessage}</div>
37+
<div className={cn('error-bar', error !== undefined && 'show-error')}>{errorMessage}</div>
3838
</div>
3939
{progress !== undefined && progress < 1 &&
4040
<div className={'progress-bar'} role='progressbar'>
41-
<div style={{ width: `${100 * progress}%` }} />
41+
<div style={{ width: `${(100 * progress).toString()}%` }} />
4242
</div>
4343
}
4444
</main>

packages/components/src/components/Markdown.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default function Markdown({ text, className }: MarkdownProps) {
2323
// Code blocks
2424
if (line.startsWith('```')) {
2525
if (inCodeBlock) {
26-
elements.push(<pre key={`code-${i}`}>{codeBlock.join('\n')}</pre>)
26+
elements.push(<pre key={`code-${i.toString()}`}>{codeBlock.join('\n')}</pre>)
2727
inCodeBlock = false
2828
codeBlock = []
2929
} else {
@@ -62,13 +62,13 @@ export default function Markdown({ text, className }: MarkdownProps) {
6262
if (line.startsWith('#')) {
6363
const level = line.split(' ')[0].length
6464
const text = line.slice(level + 1)
65-
const HeaderTag = `h${level}` as keyof JSX.IntrinsicElements
65+
const HeaderTag = `h${level.toString()}` as keyof JSX.IntrinsicElements
6666
elements.push(<HeaderTag key={i}>{text}</HeaderTag>)
6767
continue
6868
}
6969

7070
// Images
71-
const imageMatch = line.match(/!\[(.*?)\]\((.*?)\)/)
71+
const imageMatch = /!\[(.*?)\]\((.*?)\)/.exec(line)
7272
if (imageMatch) {
7373
const [, alt, src] = imageMatch
7474
elements.push(<img key={i} src={src} alt={alt} />)
@@ -77,7 +77,7 @@ export default function Markdown({ text, className }: MarkdownProps) {
7777

7878
// Links
7979
if (line.includes('[') && line.includes(']') && line.includes('(') && line.includes(')')) {
80-
const linkedLine = line.replace(/\[(.*?)\]\((.*?)\)/g, (_, linkText, url) => {
80+
const linkedLine = line.replace(/\[(.*?)\]\((.*?)\)/g, (_, linkText: string, url: string) => {
8181
return `<a href="${url}">${linkText}</a>`
8282
})
8383
elements.push(<p dangerouslySetInnerHTML={{ __html: linkedLine }} key={i}></p>)
@@ -87,13 +87,13 @@ export default function Markdown({ text, className }: MarkdownProps) {
8787
// Lists
8888
if (line.startsWith('-') || line.startsWith('*') || line.startsWith('+')) {
8989
const listItem = line.slice(1).trim()
90-
listItems.push(<li key={`list-item-${i}`}>{listItem}</li>)
90+
listItems.push(<li key={`list-item-${i.toString()}`}>{listItem}</li>)
9191
inList = true
9292
continue
9393
}
9494

9595
if (inList && listItems.length > 0) {
96-
elements.push(<ul key={`list-${i}`}>{listItems}</ul>)
96+
elements.push(<ul key={`list-${i.toString()}`}>{listItems}</ul>)
9797
listItems = []
9898
inList = false
9999
}
@@ -104,12 +104,12 @@ export default function Markdown({ text, className }: MarkdownProps) {
104104

105105
// Flush any remaining code block
106106
if (inCodeBlock && codeBlock.length > 0) {
107-
elements.push(<pre key={`code-${lines.length}`}>{codeBlock.join('\n')}</pre>)
107+
elements.push(<pre key={`code-${lines.length.toString()}`}>{codeBlock.join('\n')}</pre>)
108108
}
109109

110110
// Flush any remaining list items
111111
if (inList && listItems.length > 0) {
112-
elements.push(<ul key={`list-${lines.length}`}>{listItems}</ul>)
112+
elements.push(<ul key={`list-${lines.length.toString()}`}>{listItems}</ul>)
113113
}
114114

115115
return <div className={className}>{elements}</div>

packages/components/src/components/Page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Folder from './Folder.tsx'
55

66
export default function Page() {
77
const search = new URLSearchParams(location.search)
8-
const key = decodeURIComponent(search.get('key') || '')
8+
const key = decodeURIComponent(search.get('key') ?? '')
99
if (Array.isArray(key)) throw new Error('key must be a string')
1010

1111
const parsedKey = parseKey(key)

packages/components/src/components/viewers/ParquetView.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ export default function ParquetView({ parsedKey, setProgress, setError }: Viewer
5757
}, [loading, resolveUrl, setError, setProgress])
5858

5959
const onDoubleClickCell = useCallback((col: number, row: number) => {
60-
location.href = '/files?key=' + raw + '&row=' + row + '&col=' + col
60+
location.href = '/files?key=' + raw + '&row=' + row.toString() + '&col=' + col.toString()
6161
}, [raw])
6262

6363
const onMouseDownCell = useCallback((event: React.MouseEvent, col: number, row: number) => {
6464
if (event.button === 1) {
6565
// Middle click open in new tab
6666
event.preventDefault()
67-
window.open('/files?key=' + raw + '&row=' + row + '&col=' + col, '_blank')
67+
window.open('/files?key=' + raw + '&row=' + row.toString() + '&col=' + col.toString(), '_blank')
6868
}
6969
}, [raw])
7070

packages/components/src/lib/files.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ export async function listFiles(prefix: string, recursive?: boolean): Promise<Fi
2727
prefix = encodeURIComponent(prefix)
2828
const res = await fetch(`/api/store/list?prefix=${prefix}${rec}`)
2929
if (res.ok) {
30-
return await res.json()
30+
return await res.json() as FileMetadata[]
3131
} else {
32-
throw new Error(`file list error ${res.status} ${await res.text()}`)
32+
throw new Error(`file list error ${res.status.toString()} ${await res.text()}`)
3333
}
3434
}
3535

packages/components/src/lib/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export async function asyncBufferFromUrl({
3737
headers,
3838
}: AsyncBufferFromUrlOptions): Promise<AsyncBuffer> {
3939
// byte length from HEAD request
40-
byteLength ||= await byteLengthFromUrl(url, { headers })
40+
byteLength ??= await byteLengthFromUrl(url, { headers })
4141
return {
4242
byteLength,
4343
async slice(start, end) {

packages/components/test/components/File.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { render } from '@testing-library/react'
2-
import { act } from 'react'
2+
import React, { act } from 'react'
33
import { describe, expect, it, vi } from 'vitest'
44
import File from '../../src/components/File.js'
55
import { FileKey, UrlKey, parseKey } from '../../src/lib/key.js'

0 commit comments

Comments
 (0)