From 12763ab7abab7801b4cdc418729fc9decda03c67 Mon Sep 17 00:00:00 2001 From: ramvignesh-b Date: Mon, 13 Apr 2026 14:30:17 +0530 Subject: [PATCH] refactor: enforce strict linting rules, replace forEach with for...of loops, and remove console logging throughout the frontend. --- biome.json | 21 +++++++++++++++++++- frontend/src/api/apiClient.ts | 2 -- frontend/src/components/ui/ComposeCanvas.tsx | 12 +++++------ frontend/src/config/endpoints.ts | 4 ++-- frontend/src/hooks/useAuth.ts | 3 +-- frontend/src/hooks/useLetters.tsx | 5 ++--- frontend/src/pages/Activate.tsx | 3 +-- frontend/src/pages/Editor.tsx | 10 +++------- frontend/src/pages/Login.tsx | 1 - frontend/src/pages/Reader.tsx | 1 - frontend/src/pages/Register.tsx | 1 - frontend/src/utils/letterLogic.ts | 12 +++-------- 12 files changed, 38 insertions(+), 37 deletions(-) diff --git a/biome.json b/biome.json index 1bb66c1..9824a61 100644 --- a/biome.json +++ b/biome.json @@ -17,7 +17,26 @@ "linter": { "enabled": true, "rules": { - "recommended": true + "recommended": true, + "complexity": { + "noForEach": "error", + "useLiteralKeys": "error" + }, + "style": { + "useConst": "error", + "noNonNullAssertion": "warn" + }, + "a11y": { + "useAltText": "error", + "noAutofocus": "warn" + }, + "suspicious": { + "noExplicitAny": "warn", + "noConsole": "warn" + }, + "correctness": { + "noUnusedVariables": "error" + } }, "includes": ["**", "!backend"] }, diff --git a/frontend/src/api/apiClient.ts b/frontend/src/api/apiClient.ts index 2835de2..93c3361 100644 --- a/frontend/src/api/apiClient.ts +++ b/frontend/src/api/apiClient.ts @@ -48,8 +48,6 @@ api.interceptors.response.use( originalRequest.headers.Authorization = `Bearer ${newAccessToken}`; return api(originalRequest); } catch (refreshError) { - // Refresh failed, perform logout to clear tokens - console.error("Session expired, logging out..."); useAuthStore.getState().clearAuth(); return Promise.reject(refreshError); } diff --git a/frontend/src/components/ui/ComposeCanvas.tsx b/frontend/src/components/ui/ComposeCanvas.tsx index 1614e53..d8ef1d6 100644 --- a/frontend/src/components/ui/ComposeCanvas.tsx +++ b/frontend/src/components/ui/ComposeCanvas.tsx @@ -67,10 +67,10 @@ export const ComposeCanvas = forwardRef< if (initialData) { await canvas.loadFromJSON(initialData); if (readOnly) { - canvas.getObjects().forEach((obj) => { + for (const obj of canvas.getObjects()) { obj.selectable = false; obj.evented = false; - }); + } } canvas.renderAll(); } else { @@ -119,11 +119,11 @@ export const ComposeCanvas = forwardRef< const hiddenTextareas = document.querySelectorAll( 'textarea[data-fabric="textarea"]', ); - hiddenTextareas.forEach((ta) => { - if (!ta.getAttribute("aria-label")) { - ta.setAttribute("aria-label", "Canvas text input"); + for (const textArea of hiddenTextareas) { + if (!textArea.getAttribute("aria-label")) { + textArea.setAttribute("aria-label", "Canvas text input"); } - }); + } }, 100); canvas.on("mouse:down", (opt) => { diff --git a/frontend/src/config/endpoints.ts b/frontend/src/config/endpoints.ts index 2712430..5107a53 100644 --- a/frontend/src/config/endpoints.ts +++ b/frontend/src/config/endpoints.ts @@ -15,8 +15,8 @@ export const replacePathParams = ( params: Record, ): string => { let result = url; - Object.entries(params).forEach(([key, value]) => { + for (const [key, value] of Object.entries(params)) { result = result.replace(`:${key}`, value); - }); + } return result; }; diff --git a/frontend/src/hooks/useAuth.ts b/frontend/src/hooks/useAuth.ts index 8425e25..07a2278 100644 --- a/frontend/src/hooks/useAuth.ts +++ b/frontend/src/hooks/useAuth.ts @@ -36,8 +36,7 @@ export const useAuth = () => { const logout = async () => { try { await api.post(endpoints.LOGOUT); - } catch (error) { - console.error("Logout failed:", error); + } catch (_error) { } finally { clearAuth(); setMasterKey(null); diff --git a/frontend/src/hooks/useLetters.tsx b/frontend/src/hooks/useLetters.tsx index 55a4cb4..d0fab38 100644 --- a/frontend/src/hooks/useLetters.tsx +++ b/frontend/src/hooks/useLetters.tsx @@ -43,8 +43,7 @@ async function decryptLetters( )) as LetterMetadata; return { ...letter, metadata }; - } catch (err) { - console.warn("Decryption failed for letter:", letter.public_id, err); + } catch (_err) { return { ...letter, metadata: { recipient: "Encrypted Letter" }, @@ -67,7 +66,7 @@ export function useLetters() { .get(endpoints.LETTERS) .then((res) => decryptLetters(res.data, masterKey)) .then(setLetters) - .catch((err) => console.error("Drawer load failed:", err)) + .catch((_err) => {}) .finally(() => setLoading(false)); }, [masterKey]); diff --git a/frontend/src/pages/Activate.tsx b/frontend/src/pages/Activate.tsx index fedb363..9e3a186 100644 --- a/frontend/src/pages/Activate.tsx +++ b/frontend/src/pages/Activate.tsx @@ -28,8 +28,7 @@ export default function Activate() { }); await publicApi.get(url); setStatus("success"); - } catch (err) { - console.error("Activation error:", err); + } catch (_err) { setStatus("error"); } }; diff --git a/frontend/src/pages/Editor.tsx b/frontend/src/pages/Editor.tsx index 3e8b31c..19f8b5e 100644 --- a/frontend/src/pages/Editor.tsx +++ b/frontend/src/pages/Editor.tsx @@ -79,8 +79,7 @@ export default function Editor() { requestAnimationFrame(() => { canvasRef.current?.loadData(canvasData); }); - } catch (err) { - console.error("Failed to load existing letter:", err); + } catch (_err) { } finally { setIsInitialLoading(false); } @@ -158,8 +157,7 @@ export default function Editor() { } setTimeout(() => setIsSaveSuccess(false), 5000); - } catch (error) { - console.error("Save failed:", error); + } catch (_error) { } finally { setIsSealing(false); } @@ -169,9 +167,7 @@ export default function Editor() { if (!shareLink) return; try { await navigator.clipboard.writeText(shareLink); - } catch (err) { - console.error("Failed to copy:", err); - } + } catch (_err) {} }; return ( diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx index 5fa3eda..5b73b13 100644 --- a/frontend/src/pages/Login.tsx +++ b/frontend/src/pages/Login.tsx @@ -46,7 +46,6 @@ export default function Login() { navigate(ROUTES.DRAWER); } catch (err) { - console.error("Login error:", err); let message = "Sorry, we're experiencing technical issues.\nPlease try again later."; if (axios.isAxiosError(err) && err.response?.status !== 500) { diff --git a/frontend/src/pages/Reader.tsx b/frontend/src/pages/Reader.tsx index e8eb543..ed3fdfd 100644 --- a/frontend/src/pages/Reader.tsx +++ b/frontend/src/pages/Reader.tsx @@ -52,7 +52,6 @@ export default function Reader() { setCanvasData(json); setIsDecrypting(false); } catch (err: any) { - console.error("Reader Error:", err); setError(`Failed to load letter: ${err.message || "Unknown error"}`); setIsDecrypting(false); } diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx index c6dfaed..7fffa88 100644 --- a/frontend/src/pages/Register.tsx +++ b/frontend/src/pages/Register.tsx @@ -50,7 +50,6 @@ export default function Register() { }); navigate(ROUTES.VERIFY_EMAIL); } catch (err) { - console.error("Registration error:", err); let message = "Registration failed. Please try again."; if (axios.isAxiosError(err)) { message = err.response?.data?.message || message; diff --git a/frontend/src/utils/letterLogic.ts b/frontend/src/utils/letterLogic.ts index dfef295..9713832 100644 --- a/frontend/src/utils/letterLogic.ts +++ b/frontend/src/utils/letterLogic.ts @@ -39,9 +39,7 @@ export async function decryptCanvasImages( // We need the raw file in the editor so we can re-encrypt it if the user saves again. obj._customRawFile = await blobUrlToFile(blobUrl, obj.src); } - } catch (err) { - console.error("Error decrypting image in canvas:", obj.src, err); - } + } catch (_err) {} } } } @@ -66,9 +64,7 @@ export async function decryptCanvasImagesWithSharingKey( try { const res = await api.get(remoteUrl, { responseType: "blob" }); obj.src = await crypto.decryptImageWithSharingKey(res.data, sharingKey); - } catch (err) { - console.error("Guest decryption failed for canvas image:", err); - } + } catch (_err) {} } } } @@ -96,9 +92,7 @@ export async function encryptCanvasImages( ); filenameMapping.set(img.src, filename); encryptedFiles.set(filename, encryptedBlob); - } catch (err) { - console.error("Failed to encrypt new canvas image:", err); - } + } catch (_err) {} } // Update the canvas JSON to use the new encrypted filenames instead of blob URLs.