From 7bc623b93c714b1aa853af51d5743598ef413b16 Mon Sep 17 00:00:00 2001 From: Sivert <316918682+grytchat@users.noreply.github.com> Date: Mon, 19 Oct 2026 10:04:26 +0200 Subject: [PATCH] Ban nested ternaries and non-null assertions in the client's lint (GRYT-1792) The rest of the rules the server, ui, core, voice and mobile now share: nested ternaries, non-null assertions, reassigned parameters, loose equality, else after return, let that could be const, and unmarked type-only imports. Existing debt is listed per rule in .eslintrc.cjs; no code file changes. Co-Authored-By: Claude Opus 5.5 --- .eslintrc.cjs | 221 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 4981acea3..7d1e7bce8 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -26,6 +26,13 @@ module.exports = { }, ], "@typescript-eslint/no-explicit-any": "error", + "no-nested-ternary": "error", + eqeqeq: ["error", "smart"], + "no-else-return": "error", + "prefer-const": "error", + "no-param-reassign": "error", + "@typescript-eslint/no-non-null-assertion": "error", + "@typescript-eslint/consistent-type-imports": ["error", { fixStyle: "inline-type-imports", disallowTypeAnnotations: false }], // Our own values get real types. A file that parses outside input carries a disable at the // top saying so, and the goal is to remove each one (GRYT-1792). "@typescript-eslint/ban-types": [ @@ -34,6 +41,220 @@ module.exports = { ], }, overrides: [ + // Non-null assertions from before the rule. + { + files: [ + "e2e/nightly/electron.spec.ts", + "e2e/support/app.ts", + "e2e/tests/approve-device.spec.ts", + "e2e/tests/dm.spec.ts", + "e2e/tests/link-device.spec.ts", + "e2e/tests/messages.spec.ts", + "e2e/tests/send-across-restart.spec.ts", + "e2e/tests/sidebar-folders.spec.ts", + "e2e/tests/whats-new.spec.ts", + "electron/main.ts", + "electron/mediaSandboxPage.ts", + "src/main.tsx", + "src/packages/settings/src/components/BannerCropDialog.tsx", + "src/packages/settings/src/components/profileSettings.tsx", + "src/packages/settings/src/hooks/useLanDiscovery.ts", + "src/packages/socket/src/components/ChannelList.tsx", + "src/packages/socket/src/components/ChatView.tsx", + "src/packages/socket/src/components/DmSpaceSidebar.tsx", + "src/packages/socket/src/components/EmojiText.tsx", + "src/packages/socket/src/components/FocusedVideoView.tsx", + "src/packages/socket/src/components/LinkPreviewCard.tsx", + "src/packages/socket/src/components/MarkdownRenderer.tsx", + "src/packages/socket/src/components/MediaContextMenu.tsx", + "src/packages/socket/src/components/MemberIdentityCard.tsx", + "src/packages/socket/src/components/MemberSidebar.tsx", + "src/packages/socket/src/components/MessageRow.tsx", + "src/packages/socket/src/components/MessagesHome.tsx", + "src/packages/socket/src/components/ServerRolesTab.tsx", + "src/packages/socket/src/components/ThreadPanel.tsx", + "src/packages/socket/src/components/VoiceParticipantCard.tsx", + "src/packages/socket/src/components/VoiceView.tsx", + "src/packages/socket/src/components/serverView.tsx", + "src/packages/socket/src/dev/fakeParticipants.ts", + "src/packages/socket/src/hooks/friendsStore.ts", + "src/packages/socket/src/hooks/useChat.ts", + "src/packages/socket/src/hooks/useChatActions.ts", + "src/packages/socket/src/hooks/useChatScroll.ts", + "src/packages/socket/src/hooks/useChatSend.ts", + "src/packages/socket/src/hooks/useRememberView.ts", + "src/packages/socket/src/mls/serverMls.ts", + "src/packages/socket/src/utils/friendList.ts", + "src/packages/socket/src/utils/mediaClipboard.ts", + "src/packages/socket/src/utils/remarkEmoji.ts", + "src/packages/socket/src/utils/syncAvatarToHost.ts", + "src/packages/webRTC/src/components/ScreenSharePickerModal.tsx", + ], + rules: { "@typescript-eslint/no-non-null-assertion": "off" }, + }, + // Nested ternaries from before the rule. + { + files: [ + "e2e/playwright.config.ts", + "e2e/soak/support/probes.ts", + "e2e/soak/support/tracker.ts", + "e2e/tests/send-across-restart.spec.ts", + "electron/embeddedServerManager.ts", + "electron/gameList.ts", + "electron/helperStartup.ts", + "electron/presenceHelper.ts", + "electron/processWatcher.ts", + "src/components/AuthLoadingOverlay.tsx", + "src/components/mainApp.tsx", + "src/components/microphoneDebugOverlay.tsx", + "src/components/onboarding/OnboardingTour.tsx", + "src/components/serviceStatusBanner.tsx", + "src/components/sidebar.tsx", + "src/components/updateToastState.ts", + "src/components/videoDebugOverlay.tsx", + "src/lib/reports/callTimeline.ts", + "src/packages/addons/src/pluginPanels.ts", + "src/packages/common/src/auth/keycloak.ts", + "src/packages/common/src/components/NotificationLevelMenu.tsx", + "src/packages/common/src/hooks/useCustomThemes.ts", + "src/packages/common/src/hooks/useTheme.ts", + "src/packages/settings/src/components/aboutSettings.tsx", + "src/packages/settings/src/components/accountSettings.tsx", + "src/packages/settings/src/components/addServer.tsx", + "src/packages/settings/src/components/addonsSettings.tsx", + "src/packages/settings/src/components/audioSettings.tsx", + "src/packages/settings/src/components/cameraSettings.tsx", + "src/packages/settings/src/components/cardSettings.tsx", + "src/packages/settings/src/components/embeddedServerLogs.tsx", + "src/packages/settings/src/components/latencyPanel.tsx", + "src/packages/settings/src/components/myServersSettings.tsx", + "src/packages/settings/src/components/profileSettings.tsx", + "src/packages/settings/src/components/securitySettings.tsx", + "src/packages/settings/src/components/serverNotificationList.tsx", + "src/packages/settings/src/components/theme/themePreview.tsx", + "src/packages/socket/src/components/ChannelList.tsx", + "src/packages/socket/src/components/ChatEditor.tsx", + "src/packages/socket/src/components/ChatMessage.tsx", + "src/packages/socket/src/components/ChatView.tsx", + "src/packages/socket/src/components/DirectMessagePrivacyNotice.tsx", + "src/packages/socket/src/components/DmSpaceList.tsx", + "src/packages/socket/src/components/DmSpaceSidebar.tsx", + "src/packages/socket/src/components/EmojiAutocomplete.tsx", + "src/packages/socket/src/components/EmojiList.tsx", + "src/packages/socket/src/components/EmojiPicker.tsx", + "src/packages/socket/src/components/EmoteRow.tsx", + "src/packages/socket/src/components/ForumView.tsx", + "src/packages/socket/src/components/GroupFace.tsx", + "src/packages/socket/src/components/ImageLightbox.tsx", + "src/packages/socket/src/components/LinkPreviewCard.tsx", + "src/packages/socket/src/components/MarkAsReadItem.tsx", + "src/packages/socket/src/components/MediaContextMenu.tsx", + "src/packages/socket/src/components/MemberSidebar.tsx", + "src/packages/socket/src/components/MessageKeyPrompt.tsx", + "src/packages/socket/src/components/MessageRow.tsx", + "src/packages/socket/src/components/NewMessageDialog.tsx", + "src/packages/socket/src/components/NotEncryptedPopover.tsx", + "src/packages/socket/src/components/PinsButton.tsx", + "src/packages/socket/src/components/ReportsPanel.tsx", + "src/packages/socket/src/components/RolePermissionGrid.tsx", + "src/packages/socket/src/components/SearchPanel.tsx", + "src/packages/socket/src/components/ServerDoctor.tsx", + "src/packages/socket/src/components/ServerOverviewTab.tsx", + "src/packages/socket/src/components/ServerPermissionTemplatesTab.tsx", + "src/packages/socket/src/components/ServerReleaseNotes.tsx", + "src/packages/socket/src/components/ServerRoleEditorTab.tsx", + "src/packages/socket/src/components/ServerStatusRing.tsx", + "src/packages/socket/src/components/SidebarEditDialog.tsx", + "src/packages/socket/src/components/ThreadPanel.tsx", + "src/packages/socket/src/components/UserContextMenu.tsx", + "src/packages/socket/src/components/VoiceParticipantCard.tsx", + "src/packages/socket/src/components/VoiceView.tsx", + "src/packages/socket/src/components/WhatsNewDialog.tsx", + "src/packages/socket/src/components/chatViewHelpers.ts", + "src/packages/socket/src/components/connectedUser.tsx", + "src/packages/socket/src/components/lightboxGallery.ts", + "src/packages/socket/src/components/memberInvite.ts", + "src/packages/socket/src/components/serverView.tsx", + "src/packages/socket/src/components/tileColor.ts", + "src/packages/socket/src/hooks/contactFilterStore.ts", + "src/packages/socket/src/hooks/dmDirectory.ts", + "src/packages/socket/src/hooks/mergeMessages.ts", + "src/packages/socket/src/hooks/useEmoteImport.ts", + "src/packages/socket/src/hooks/useHistoryWindow.ts", + "src/packages/socket/src/hooks/useOpenDmSpace.ts", + "src/packages/socket/src/hooks/useSidebarEditor.ts", + "src/packages/socket/src/lib/inviteDialog.ts", + "src/packages/socket/src/lib/newMessage.ts", + "src/packages/socket/src/lib/serverDoctor.ts", + "src/packages/socket/src/mls/deviceName.ts", + "src/packages/socket/src/mls/timeline.ts", + "src/packages/socket/src/utils/remarkMention.ts", + "src/packages/socket/src/utils/stageEmojiViaXhr.ts", + "src/packages/webRTC/src/adapters/useVoiceLifecycle.tsx", + "src/packages/webRTC/src/components/CallCapsuleFace.tsx", + "src/packages/webRTC/src/components/ScreenShareControl.tsx", + "src/packages/webRTC/src/components/controls.tsx", + "src/packages/webRTC/src/components/miniControls.tsx", + "src/packages/webRTC/src/utils/streamQuality.ts", + ], + rules: { "no-nested-ternary": "off" }, + }, + // Type-only imports not marked yet; a mechanical PR of its own fixes them. + { + files: [ + "electron/audioCaptureManager.ts", + "electron/embeddedServerManager.ts", + "electron/main.ts", + "electron/screenCaptureManager.ts", + "src/components/debugOverlay.tsx", + "src/components/sidebar.tsx", + "src/lib/electron.ts", + "src/packages/common/src/api/auth.ts", + "src/packages/settings/src/components/aboutSettings.tsx", + "src/packages/settings/src/hooks/useServerSettings.ts", + "src/packages/socket/src/components/ChannelList.tsx", + "src/packages/socket/src/components/ChatView.tsx", + "src/packages/socket/src/components/MemberSidebar.tsx", + "src/packages/socket/src/components/MemberSidebarPanel.tsx", + "src/packages/socket/src/components/ServerSidebar.tsx", + "src/packages/socket/src/components/UserContextMenu.tsx", + "src/packages/socket/src/components/serverView.tsx", + "src/packages/socket/src/hooks/chatEventHandlers.ts", + "src/packages/socket/src/hooks/registerServerSocketEvents.ts", + "src/packages/socket/src/hooks/useAdminActions.ts", + "src/packages/socket/src/hooks/useChannelSettings.tsx", + "src/packages/socket/src/hooks/useChat.ts", + "src/packages/socket/src/hooks/useChatSend.ts", + "src/packages/socket/src/hooks/useLatencyReporting.ts", + "src/packages/socket/src/hooks/usePeerLatency.ts", + "src/packages/socket/src/hooks/useServerManagement.ts", + "src/packages/socket/src/hooks/useServerReports.ts", + "src/packages/socket/src/hooks/useSidebarEditor.ts", + "src/packages/socket/src/hooks/useSocketEvents.ts", + "src/packages/socket/src/hooks/useSockets.ts", + "src/packages/socket/src/hooks/useTypingIndicator.ts", + "src/packages/socket/src/utils/syncAvatarToHost.ts", + "src/packages/webRTC/src/components/miniControls.tsx", + ], + rules: { "@typescript-eslint/consistent-type-imports": "off" }, + }, + // Reassigned parameters from before the rule. + { + files: [ + "src/packages/settings/src/components/profileSettings.tsx", + "src/packages/socket/src/lib/memberCard/cardPresets.ts", + ], + rules: { "no-param-reassign": "off" }, + }, + // else after return from before the rule. + { + files: [ + "src/packages/settings/src/hooks/useServerSettings.ts", + "src/packages/socket/src/hooks/registerServerSocketEvents.ts", + "src/packages/socket/src/hooks/useChat.ts", + ], + rules: { "no-else-return": "off" }, + }, // Files that still use unknown, by why. The goal is to empty these lists (GRYT-1792). // unknown: socket payloads arrive unchecked and are validated there. {