chore: fix oxlint errors - #309
Conversation
SafeDep Report SummaryPackage Details
This report is generated by SafeDep Github App |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
Walkthrough本次变更接入 Changes移动端运行时与类型整理
Estimated code review effort: 3 (Moderate) | ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
apps/mobile/src/hooks/queries/lyrics/index.ts (1)
22-22: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win请使用稳定的歌词输入构造查询键。
完整
track对象包含updatedAt、createdAt、artist 和来源元数据。任意与歌词无关的字段变化都会创建新的 React Query 缓存键,并再次执行lyricService.smartFetchLyrics。staleTime: 0会放大重复请求影响。请先确认
smartFetchLyrics实际读取的字段,再只把这些字段加入查询键。不要直接放入完整track对象。依据
apps/mobile/src/lib/services/trackService.ts提供的Track字段结构,以及本文件的staleTime: 0配置。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/mobile/src/hooks/queries/lyrics/index.ts` at line 22, Update the queryKey in the lyrics query using the fields actually read by smartFetchLyrics, rather than the full track object. Inspect smartFetchLyrics and the Track structure to include only the stable lyric-relevant inputs, while preserving the existing lyricsQueryKeys.smartFetchLyrics base key and staleTime behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/backend/src/routes/playlists.ts`:
- Line 143: Update the track_count assignment in the playlist response to
explicitly convert trackCount to a runtime number, using Number(trackCount ??
0), since the TypeScript sql<number> annotation does not alter node-postgres
string results.
In `@apps/mobile/src/features/player/components/lyrics/LyricLineItem.tsx`:
- Around line 149-153: Normalize the value passed to setIsVerbatim in the
LyricLineItem expression to an explicit boolean, preserving the existing
enableVerbatimLyrics, item.isDynamic, item.spans, and currentVal conditions
while ensuring missing spans produce false rather than undefined or null.
In `@apps/mobile/src/lib/facades/syncBilibiliPlaylist.ts`:
- Around line 847-859: 在同步播放列表的保存流程中,将仍引用外层 localPlaylist.value.id
的三处访问统一改为当前事务内 playlistResult.value.id,确保首次同步使用 findOrCreateRemotePlaylist
返回的播放列表 ID,避免访问未初始化的 localPlaylist。
In `@apps/mobile/src/lib/services/playlistService.ts`:
- Line 1275: Update the queries near trackIdSubq and the corresponding query at
the additionally referenced location to use this.db instead of the module-level
defaultDb, preserving the connection bound by PlaylistService.withDB(conn) and
ensuring searchTrackInPlaylist participates in the active transaction.
In `@oxlint.config.mts`:
- Around line 30-31: Remove the broad packages/react-native-bottom-tabs/**
ignore entry from the Oxlint configuration so source files such as SceneMap.tsx
and TabView.tsx are linted. If exclusions are still required, narrow them to
confirmed generated or third-party files only; leave the unrelated
packages/bottom-tabs-react-navigation/** entry unchanged.
---
Nitpick comments:
In `@apps/mobile/src/hooks/queries/lyrics/index.ts`:
- Line 22: Update the queryKey in the lyrics query using the fields actually
read by smartFetchLyrics, rather than the full track object. Inspect
smartFetchLyrics and the Track structure to include only the stable
lyric-relevant inputs, while preserving the existing
lyricsQueryKeys.smartFetchLyrics base key and staleTime behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 0081ee8b-b0ac-4eb6-a6d2-51b24f0997c9
📒 Files selected for processing (71)
apps/backend/src/routes/playlists.tsapps/mobile/src/app/(tabs)/index.tsxapps/mobile/src/app/(tabs)/library/[tab].tsxapps/mobile/src/app/(tabs)/settings/index.tsxapps/mobile/src/app/_layout.tsxapps/mobile/src/app/download.tsxapps/mobile/src/app/history/[date].tsxapps/mobile/src/app/onboarding.tsxapps/mobile/src/app/player.tsxapps/mobile/src/app/playlist/local/[id].tsxapps/mobile/src/app/playlist/recently/index.tsxapps/mobile/src/app/playlist/remote/collection/[id].tsxapps/mobile/src/app/playlist/remote/favorite/[id].tsxapps/mobile/src/app/playlist/remote/multipage/[bvid].tsxapps/mobile/src/app/playlist/remote/uploader/[mid].tsxapps/mobile/src/app/settings/about.tsxapps/mobile/src/app/settings/bilibili-account/index.tsxapps/mobile/src/app/settings/bilibili-account/qrcode-login.tsxapps/mobile/src/app/share/playlist.tsxapps/mobile/src/components/NowPlayingBar.tsxapps/mobile/src/components/modals/app/UpdateAppModal.tsxapps/mobile/src/components/modals/bilibili/AddVideoToBilibiliFavModal.tsxapps/mobile/src/components/modals/edit-metadata/editPlaylistMetadataModal.tsxapps/mobile/src/components/modals/edit-metadata/editTrackMetadataModal.tsxapps/mobile/src/components/modals/login/CookieLoginModal.tsxapps/mobile/src/components/modals/playlist/BatchAddTracksToLocalPlaylist.tsxapps/mobile/src/components/modals/playlist/CreatePlaylistModal.tsxapps/mobile/src/components/modals/playlist/DuplicateLocalPlaylistModal.tsxapps/mobile/src/components/modals/playlist/FavoriteSyncProgressModal.tsxapps/mobile/src/components/modals/playlist/ManualMatchExternalSync.tsxapps/mobile/src/components/modals/playlist/SyncLocalToBilibiliModal.tsxapps/mobile/src/components/modals/playlist/UpdateTrackLocalPlaylistsModal.tsxapps/mobile/src/features/downloads/DownloadTaskItem.tsxapps/mobile/src/features/home/SearchSuggestions.tsxapps/mobile/src/features/library/shared/TabDisabled.tsxapps/mobile/src/features/player/components/PlayerSlider.tsxapps/mobile/src/features/player/components/lyrics/LyricLineItem.tsxapps/mobile/src/features/playlist/local/components/SyncFailuresSheet.tsxapps/mobile/src/hooks/queries/bilibili/search.tsapps/mobile/src/hooks/queries/lyrics/index.tsapps/mobile/src/hooks/queries/playHistory.tsapps/mobile/src/hooks/stores/useSkinStore.tsapps/mobile/src/lib/api/bilibili/api.tsapps/mobile/src/lib/api/netease/crypto.tsapps/mobile/src/lib/api/netease/request.tsapps/mobile/src/lib/config/queryClient.tsapps/mobile/src/lib/facades/bilibili.tsapps/mobile/src/lib/facades/playlist.tsapps/mobile/src/lib/facades/sharedPlaylist.tsapps/mobile/src/lib/facades/syncBilibiliPlaylist.tsapps/mobile/src/lib/facades/syncExternalPlaylist.tsapps/mobile/src/lib/player/PlayerSideEffects.tsapps/mobile/src/lib/services/artistService.tsapps/mobile/src/lib/services/lyricService.tsapps/mobile/src/lib/services/playlistService.tsapps/mobile/src/lib/services/trackService.tsapps/mobile/src/utils/error-handling.tsapps/mobile/src/utils/log.tsapps/mobile/src/utils/sticky-mitt.tsapps/update-publisher/src/index.tseslint.config.mjsoxlint.config.mtspackages/expo-wavy-slider/src/hooks/useObservableStateAdapter.tspackages/expo-wavy-slider/src/utils/getStateId.tspackages/expo-wavy-slider/src/worklets.fx.tspackages/image-theme-colors/tsconfig.jsonpackages/orpheus/src/hooks/useCurrentTrack.tspackages/orpheus/tsconfig.jsonpackages/react-native-bottom-tabs/src/SceneMap.tsxpackages/react-native-bottom-tabs/src/TabView.tsxpackages/splash/tsconfig.json
| created_at: playlist.createdAt.getTime(), | ||
| updated_at: playlist.updatedAt.getTime(), | ||
| track_count: Number(trackCount ?? 0), | ||
| track_count: trackCount ?? 0, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 8 'createDb|DATABASE_URL|postgres|neon|sqlite|count\(\*\)' apps/backend/src
rg -n -C 5 '\btrack_count\b' apps/backend/src apps/mobile/srcRepository: bbplayer-app/BBPlayer
Length of output: 25673
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- database connection ---'
cat -n apps/backend/src/db/index.ts
printf '%s\n' '--- backend dependency manifests and lockfile references ---'
git ls-files | grep -E '(^|/)(package\.json|pnpm-lock\.yaml|yarn\.lock|package-lock\.json)$' | sort
rg -n -C 3 '"(pg|postgres|drizzle-orm)"|^ (pg|postgres|drizzle-orm)@|node-postgres' \
--glob 'package.json' --glob 'pnpm-lock.yaml' --glob 'yarn.lock' --glob 'package-lock.json' .
printf '%s\n' '--- API contract and route implementation ---'
cat -n apps/backend/src/routes/playlists.ts | sed -n '80,150p'
cat -n apps/mobile/src/lib/facades/sharedPlaylist.ts | sed -n '330,375p'
printf '%s\n' '--- read-only static invariant check ---'
python3 - <<'PY'
from pathlib import Path
route = Path("apps/backend/src/routes/playlists.ts").read_text()
db = Path("apps/backend/src/db/index.ts").read_text()
mobile = Path("apps/mobile/src/lib/facades/sharedPlaylist.ts").read_text()
print("uses_node_postgres:", "drizzle-orm/node-postgres" in db)
print("configures_pg_type_parser:", "setTypeParser" in db or "types:" in db)
print("count_expression_is_typed_only:", "sql<number>`count(*)`" in route)
print("track_count_is_explicitly_coerced:", "track_count: Number(trackCount ?? 0)" in route)
print("mobile_contract_requires_number:", "track_count: number" in mobile)
PYRepository: bbplayer-app/BBPlayer
Length of output: 9990
将 track_count 转换为数值。
createDb 使用 node-postgres,且未配置 count(*) 的数值解析。sql<number> 只提供 TypeScript 类型,不转换运行时值。pg 默认将 PostgreSQL count(*) 的 int8 结果返回为字符串,导致接口违反 track_count: number 契约。保留 Number(trackCount ?? 0),或配置显式数据库映射。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/backend/src/routes/playlists.ts` at line 143, Update the track_count
assignment in the playlist response to explicitly convert trackCount to a
runtime number, using Number(trackCount ?? 0), since the TypeScript sql<number>
annotation does not alter node-postgres string results.
| enableVerbatimLyrics && | ||
| item.isDynamic && | ||
| item.spans && | ||
| item.spans.length > 0 && | ||
| currentVal === index | ||
| ), | ||
| currentVal === index, |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
将 setIsVerbatim 的参数归一化为布尔值。
当 enableVerbatimLyrics 和 item.isDynamic 为真、但 item.spans 缺失时,当前表达式会产生 undefined 或 null。scheduleOnRN 会把该值传给 setIsVerbatim,使 isVerbatim 状态保存非布尔值。请保留布尔归一化。
建议修改
- enableVerbatimLyrics &&
- item.isDynamic &&
- item.spans &&
- item.spans.length > 0 &&
- currentVal === index,
+ Boolean(
+ enableVerbatimLyrics &&
+ item.isDynamic &&
+ item.spans?.length &&
+ currentVal === index,
+ ),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| enableVerbatimLyrics && | |
| item.isDynamic && | |
| item.spans && | |
| item.spans.length > 0 && | |
| currentVal === index | |
| ), | |
| currentVal === index, | |
| Boolean( | |
| enableVerbatimLyrics && | |
| item.isDynamic && | |
| item.spans?.length && | |
| currentVal === index, | |
| ), |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/mobile/src/features/player/components/lyrics/LyricLineItem.tsx` around
lines 149 - 153, Normalize the value passed to setIsVerbatim in the
LyricLineItem expression to an explicit boolean, preserving the existing
enableVerbatimLyrics, item.isDynamic, item.spans, and currentVal conditions
while ensuring missing spans produce false rather than undefined or null.
| const playlistResult = await playlistSvc.findOrCreateRemotePlaylist({ | ||
| title: bilibiliFavoriteListMetadata.info!.title, | ||
| description: bilibiliFavoriteListMetadata.info!.intro, | ||
| coverUrl: bilibiliFavoriteListMetadata.info!.cover, | ||
| type: 'favorite', | ||
| remoteSyncId: favoriteId, | ||
| authorId: playlistAuthor.value.id, | ||
| }) | ||
| if (localPlaylist.isErr()) { | ||
| throw localPlaylist.error | ||
| if (playlistResult.isErr()) { | ||
| throw playlistResult.error | ||
| } | ||
| logger.debug('step 5: 创建 playlist 和其对应的 author 信息完成', { | ||
| localPlaylistId: localPlaylist.value.id, | ||
| localPlaylistId: playlistResult.value.id, |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
统一使用事务内创建的播放列表 ID。
变量 playlistResult 替换了事务内原来的 localPlaylist,但 Line [1020]、Line [1029] 和 Line [1038] 仍访问外层的 localPlaylist.value.id。首次同步时,外层 localPlaylist.value 可以为空。保存阶段会触发 undefined.id,新收藏夹无法完成同步。
请将这三处改为 playlistResult.value.id。
建议修复
const replaceResult = await playlistSvc.replacePlaylistAllTracks(
- localPlaylist.value.id,
+ playlistResult.value.id,
finalOrderedTrackIds,
)
@@
logger.info('同步收藏夹完成', {
remoteId: favoriteId,
- playlistId: localPlaylist.value.id,
+ playlistId: playlistResult.value.id,
})
@@
- return localPlaylist.value.id
+ return playlistResult.value.id🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/mobile/src/lib/facades/syncBilibiliPlaylist.ts` around lines 847 - 859,
在同步播放列表的保存流程中,将仍引用外层 localPlaylist.value.id 的三处访问统一改为当前事务内
playlistResult.value.id,确保首次同步使用 findOrCreateRemotePlaylist 返回的播放列表 ID,避免访问未初始化的
localPlaylist。
| } | ||
|
|
||
| const trackIdSubq = db | ||
| const trackIdSubq = defaultDb |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
使用实例数据库连接,避免绕过事务。
PlaylistService.withDB(conn) 会创建绑定到 conn 的服务实例。但 Line 1275 和 Line 1287 使用模块级 defaultDb。当 searchTrackInPlaylist 运行在事务实例上时,这两个查询会绕过事务,并可能读取不一致的数据。请改用 this.db。
建议修改
- const trackIdSubq = defaultDb
+ const trackIdSubq = this.db
.select({ id: schema.tracks.id })
...
- defaultDb.query.playlistTracks.findMany({
+ this.db.query.playlistTracks.findMany({Also applies to: 1287-1287
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/mobile/src/lib/services/playlistService.ts` at line 1275, Update the
queries near trackIdSubq and the corresponding query at the additionally
referenced location to use this.db instead of the module-level defaultDb,
preserving the connection bound by PlaylistService.withDB(conn) and ensuring
searchTrackInPlaylist participates in the active transaction.
| "packages/bottom-tabs-react-navigation/**", | ||
| "packages/react-native-bottom-tabs/**", |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
不要忽略整个维护中的源代码包。
packages/react-native-bottom-tabs/** 包含当前 stack 中修改的 packages/react-native-bottom-tabs/src/SceneMap.tsx 和 packages/react-native-bottom-tabs/src/TabView.tsx。该目录级忽略会绕过这些文件的全部 Oxlint 规则。这样,生产源代码仍可能存在 Oxlint 错误,但 lint 步骤不会报告这些错误。请删除目录级忽略,或只忽略已确认的生成文件和第三方文件。
建议缩小忽略范围
- "packages/bottom-tabs-react-navigation/**",
- "packages/react-native-bottom-tabs/**",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "packages/bottom-tabs-react-navigation/**", | |
| "packages/react-native-bottom-tabs/**", |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@oxlint.config.mts` around lines 30 - 31, Remove the broad
packages/react-native-bottom-tabs/** ignore entry from the Oxlint configuration
so source files such as SceneMap.tsx and TabView.tsx are linted. If exclusions
are still required, narrow them to confirmed generated or third-party files
only; leave the unrelated packages/bottom-tabs-react-navigation/** entry
unchanged.




Summary by CodeRabbit
新功能
问题修复
维护