Enable ESLint errors and suppress existing violations (#10490)
This commit is contained in:
@@ -21,7 +21,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job: [lint, prettier]
|
||||
job: [lint, prettier, typecheck]
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v5
|
||||
@@ -62,6 +62,8 @@ jobs:
|
||||
command: pnpm install --frozen-lockfile
|
||||
attempt_limit: 3
|
||||
attempt_delay: 2000
|
||||
- name: Check & compile i18n
|
||||
run: pnpm intl:build
|
||||
- name: Lint checks
|
||||
run: pnpm ${{ matrix.job }}
|
||||
# Aggregates the matrix results into a single stable check name so branch
|
||||
@@ -80,28 +82,6 @@ jobs:
|
||||
run: |
|
||||
echo "linting result: $RESULT"
|
||||
test "$RESULT" = "success"
|
||||
typechecking:
|
||||
name: Run typecheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v5
|
||||
- uses: pnpm/action-setup@v6
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: package.json
|
||||
cache: pnpm
|
||||
- name: pnpm install
|
||||
uses: Wandalen/wretry.action@master
|
||||
with:
|
||||
command: pnpm install --frozen-lockfile
|
||||
attempt_limit: 3
|
||||
attempt_delay: 2000
|
||||
- name: Check & compile i18n
|
||||
run: pnpm intl:build
|
||||
- name: Type check
|
||||
run: pnpm typecheck
|
||||
testing:
|
||||
name: Run tests
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
+1833
-1
File diff suppressed because it is too large
Load Diff
+18
-20
@@ -134,11 +134,10 @@ export default defineConfig(
|
||||
'react-native/no-inline-styles': 'off',
|
||||
...reactNativeA11y.configs.all.rules,
|
||||
'react-compiler/react-compiler': 'warn',
|
||||
// TODO: Fix these and set to error
|
||||
'react-hooks/set-state-in-effect': 'warn',
|
||||
'react-hooks/purity': 'warn',
|
||||
'react-hooks/refs': 'warn',
|
||||
'react-hooks/immutability': 'warn',
|
||||
'react-hooks/set-state-in-effect': 'error',
|
||||
'react-hooks/purity': 'error',
|
||||
'react-hooks/refs': 'error',
|
||||
'react-hooks/immutability': 'error',
|
||||
|
||||
/**
|
||||
* Import sorting
|
||||
@@ -235,9 +234,8 @@ export default defineConfig(
|
||||
},
|
||||
],
|
||||
/**
|
||||
* Maintain previous behavior - these are stricter in typescript-eslint
|
||||
* v8 `warn` ones are probably worth fixing. `off` ones are a bit too
|
||||
* nit-picky
|
||||
* Maintain previous behavior via eslint-suppressions.json - these are
|
||||
* stricter in typescript-eslint v8. `off` ones are a bit too nit-picky.
|
||||
*/
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
@@ -247,18 +245,18 @@ export default defineConfig(
|
||||
'@typescript-eslint/unbound-method': 'off',
|
||||
'@typescript-eslint/no-unsafe-argument': 'off',
|
||||
'@typescript-eslint/no-unsafe-return': 'off',
|
||||
'@typescript-eslint/no-unsafe-member-access': 'warn',
|
||||
'@typescript-eslint/no-unsafe-call': 'warn',
|
||||
'@typescript-eslint/no-floating-promises': 'warn',
|
||||
'@typescript-eslint/no-misused-promises': 'warn',
|
||||
'@typescript-eslint/require-await': 'warn',
|
||||
'@typescript-eslint/no-unsafe-enum-comparison': 'warn',
|
||||
'@typescript-eslint/no-unnecessary-type-assertion': 'warn',
|
||||
'@typescript-eslint/no-redundant-type-constituents': 'warn',
|
||||
'@typescript-eslint/no-duplicate-type-constituents': 'warn',
|
||||
'@typescript-eslint/no-base-to-string': 'warn',
|
||||
'@typescript-eslint/prefer-promise-reject-errors': 'warn',
|
||||
'@typescript-eslint/await-thenable': 'warn',
|
||||
'@typescript-eslint/no-unsafe-member-access': 'error',
|
||||
'@typescript-eslint/no-unsafe-call': 'error',
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'@typescript-eslint/no-misused-promises': 'error',
|
||||
'@typescript-eslint/require-await': 'error',
|
||||
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
||||
'@typescript-eslint/no-redundant-type-constituents': 'error',
|
||||
'@typescript-eslint/no-duplicate-type-constituents': 'error',
|
||||
'@typescript-eslint/no-base-to-string': 'error',
|
||||
'@typescript-eslint/prefer-promise-reject-errors': 'error',
|
||||
'@typescript-eslint/await-thenable': 'error',
|
||||
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
|
||||
@@ -8,8 +8,10 @@ import {
|
||||
type UninheritableButtonProps,
|
||||
} from '#/components/Button'
|
||||
import {CircleCheck_Stroke2_Corner0_Rounded as CircleCheck} from '#/components/icons/CircleCheck'
|
||||
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||
import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo'
|
||||
import {
|
||||
CircleInfo_Stroke2_Corner0_Rounded as CircleInfo,
|
||||
CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon,
|
||||
} from '#/components/icons/CircleInfo'
|
||||
import {type Props as SVGIconProps} from '#/components/icons/common'
|
||||
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
|
||||
import {dismiss} from '#/components/Toast/sonner'
|
||||
|
||||
@@ -58,12 +58,12 @@ export function dateDiff(
|
||||
if (diffSeconds < NOW) {
|
||||
diff = {
|
||||
value: 0,
|
||||
unit: 'now' as DateDiff['unit'],
|
||||
unit: 'now',
|
||||
}
|
||||
} else if (diffSeconds < MINUTE) {
|
||||
diff = {
|
||||
value: diffSeconds,
|
||||
unit: 'second' as DateDiff['unit'],
|
||||
unit: 'second',
|
||||
}
|
||||
} else if (diffSeconds < HOUR) {
|
||||
const value =
|
||||
@@ -72,7 +72,7 @@ export function dateDiff(
|
||||
: Math.floor(diffSeconds / MINUTE)
|
||||
diff = {
|
||||
value,
|
||||
unit: 'minute' as DateDiff['unit'],
|
||||
unit: 'minute',
|
||||
}
|
||||
} else if (diffSeconds < DAY) {
|
||||
const value =
|
||||
@@ -81,7 +81,7 @@ export function dateDiff(
|
||||
: Math.floor(diffSeconds / HOUR)
|
||||
diff = {
|
||||
value,
|
||||
unit: 'hour' as DateDiff['unit'],
|
||||
unit: 'hour',
|
||||
}
|
||||
} else if (diffSeconds < MONTH_30) {
|
||||
const value =
|
||||
@@ -90,7 +90,7 @@ export function dateDiff(
|
||||
: Math.floor(diffSeconds / DAY)
|
||||
diff = {
|
||||
value,
|
||||
unit: 'day' as DateDiff['unit'],
|
||||
unit: 'day',
|
||||
}
|
||||
} else {
|
||||
const value =
|
||||
@@ -99,7 +99,7 @@ export function dateDiff(
|
||||
: Math.floor(diffSeconds / MONTH_30)
|
||||
diff = {
|
||||
value,
|
||||
unit: 'month' as DateDiff['unit'],
|
||||
unit: 'month',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ export function makeProfileLink(
|
||||
export function makeCustomFeedLink(
|
||||
did: string,
|
||||
rkey: string,
|
||||
segment?: string | undefined,
|
||||
feedCacheKey?: 'discover' | 'explore' | undefined,
|
||||
segment?: string,
|
||||
feedCacheKey?: 'discover' | 'explore',
|
||||
) {
|
||||
return (
|
||||
[`/profile`, did, 'feed', rkey, ...(segment ? [segment] : [])].join('/') +
|
||||
|
||||
@@ -129,7 +129,7 @@ function getAppIconName(icon: string | false): DynamicAppIcon.IconName {
|
||||
if (!icon || icon === 'DEFAULT') {
|
||||
return 'default_light'
|
||||
} else {
|
||||
return icon as DynamicAppIcon.IconName
|
||||
return icon
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ function Group({
|
||||
values={[value]}
|
||||
maxSelections={1}
|
||||
onChange={vals => {
|
||||
if (vals[0]) onChange(vals[0] as DynamicAppIcon.IconName)
|
||||
if (vals[0]) onChange(vals[0])
|
||||
}}>
|
||||
<View style={[a.flex_1, a.rounded_md, a.overflow_hidden]}>
|
||||
{children}
|
||||
|
||||
@@ -23,8 +23,7 @@ import {
|
||||
import {useEventListener} from 'expo'
|
||||
import {type VideoPlayer} from 'expo-video'
|
||||
|
||||
import {tokens} from '#/alf'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {atoms as a, tokens} from '#/alf'
|
||||
import {formatTime} from '#/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/utils'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ export function* findAllPostsInQueryData(
|
||||
if (AppBskyFeedDefs.isPostView(item.subject)) {
|
||||
const quotedPost = getEmbeddedPost(item.subject?.embed)
|
||||
if (quotedPost && didOrHandleUriMatches(atUri, quotedPost)) {
|
||||
yield embedViewRecordToPostView(quotedPost!)
|
||||
yield embedViewRecordToPostView(quotedPost)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export function parseAppNux(nux: AppBskyActorDefs.Nux): AppNux | undefined {
|
||||
|
||||
export function serializeAppNux(nux: AppNux): AppBskyActorDefs.Nux {
|
||||
const {data, ...rest} = nux
|
||||
const schema = NuxSchemas[nux.id as Nux]
|
||||
const schema = NuxSchemas[nux.id]
|
||||
|
||||
const result: AppBskyActorDefs.Nux = {
|
||||
...rest,
|
||||
|
||||
@@ -85,7 +85,7 @@ export function useSuggestedFollowsByActorWithDismiss({
|
||||
|
||||
const profiles = useMemo(() => {
|
||||
return (data?.suggestions ?? []).map(profile => ({
|
||||
actor: profile as bsky.profile.AnyProfileView,
|
||||
actor: profile,
|
||||
recId: data?.recId,
|
||||
}))
|
||||
}, [data?.suggestions, data?.recId])
|
||||
|
||||
@@ -196,7 +196,7 @@ export function sortAndAnnotateThreadItems(
|
||||
* `repliesSeenCounter` later on, since `repliesSeenCounter`
|
||||
* is 1-indexed and `replyIndex` is 0-indexed.
|
||||
*/
|
||||
childMetadata!.replyIndex =
|
||||
childMetadata.replyIndex =
|
||||
childParentMetadata.repliesSeenCounter
|
||||
}
|
||||
|
||||
|
||||
@@ -470,11 +470,11 @@ export async function draftToComposerPosts(
|
||||
height,
|
||||
mime: 'image/jpeg',
|
||||
},
|
||||
} as ComposerImage
|
||||
} satisfies ComposerImage
|
||||
})
|
||||
|
||||
const images = (await Promise.all(imagePromises)).filter(
|
||||
(img): img is ComposerImage => img !== null,
|
||||
(img): img is NonNullable<typeof img> => img !== null,
|
||||
)
|
||||
if (images.length > 0) {
|
||||
embed.media = {type: 'images', images}
|
||||
@@ -511,7 +511,7 @@ export async function draftToComposerPosts(
|
||||
tinygif: mediaObject,
|
||||
preview: mediaObject,
|
||||
},
|
||||
} as Gif,
|
||||
},
|
||||
alt: gifData.alt,
|
||||
}
|
||||
break
|
||||
|
||||
@@ -55,7 +55,7 @@ export function TestCtrls() {
|
||||
accessibilityLabel="Text input field"
|
||||
accessibilityHint="Enter proxy header"
|
||||
testID="e2eProxyHeaderInput"
|
||||
onChangeText={val => setProxyHeader(val as any)}
|
||||
onChangeText={val => setProxyHeader(val)}
|
||||
autoComplete="off"
|
||||
autoCorrect={false}
|
||||
autoCapitalize="none"
|
||||
|
||||
@@ -3,9 +3,9 @@ import {
|
||||
Pressable,
|
||||
type PressableProps,
|
||||
type StyleProp,
|
||||
type View,
|
||||
type ViewStyle,
|
||||
} from 'react-native'
|
||||
import {type View} from 'react-native'
|
||||
|
||||
import {addStyle} from '#/lib/styles'
|
||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||
|
||||
@@ -171,7 +171,7 @@ function NativeStackNavigator({
|
||||
}
|
||||
|
||||
// Evicted screens get a lightweight placeholder instead of their full tree
|
||||
finalDescriptors = {} as typeof descriptors
|
||||
finalDescriptors = {}
|
||||
for (const key in descriptors) {
|
||||
if (mountSet.has(key)) {
|
||||
finalDescriptors[key] = descriptors[key]
|
||||
|
||||
Reference in New Issue
Block a user