From 1a24eb68c7bd82658267e21010bfdcd5b1c1cfcd Mon Sep 17 00:00:00 2001 From: Linus Flood Date: Fri, 7 Nov 2025 08:14:16 +0000 Subject: [PATCH] Merged in feat/sw-3596-console (pull request #3100) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(SW-3596): added lint rule for no console.log. Use logger instead. * feat(SW-3596): added lint rule for no console.log. Use logger instead. Approved-by: Joakim Jäderberg --- .../app/api/web/auth/scandic/refresh/route.ts | 2 +- apps/partner-sas/eslint.config.mjs | 1 + apps/redis-api/eslint.config.mjs | 1 + apps/redis-api/scripts/generateApiKeys.ts | 1 + apps/redis-api/src/env.ts | 3 -- .../Blocks/DynamicContent/Overview/index.tsx | 1 - apps/scandic-web/eslint.config.mjs | 1 + .../netlify/functions/warmup-background.mts | 39 +++++++++++-------- packages/booking-flow/eslint.config.mjs | 1 + .../lib/contexts/SelectRate/DebugButton.tsx | 1 + .../SelectRate/SelectRateContext/index.tsx | 8 ++-- packages/common/eslint.config.mjs | 1 + packages/common/logger/createLogger/index.ts | 1 + .../logger/createLogger/minimumLogLevel.ts | 1 + packages/tracking/eslint.config.mjs | 1 + packages/trpc/eslint.config.mjs | 1 + .../hotels/availability/enterDetails.ts | 2 +- .../trpc/lib/utils/getFiltersFromHotels.ts | 4 +- 18 files changed, 43 insertions(+), 27 deletions(-) diff --git a/apps/partner-sas/app/api/web/auth/scandic/refresh/route.ts b/apps/partner-sas/app/api/web/auth/scandic/refresh/route.ts index 799b22657..eeeadc8ae 100644 --- a/apps/partner-sas/app/api/web/auth/scandic/refresh/route.ts +++ b/apps/partner-sas/app/api/web/auth/scandic/refresh/route.ts @@ -35,7 +35,7 @@ export async function POST(_req: NextRequest) { ) if (!newTokens || error) { - console.error("Error refreshing token", error) + logger.error("Error refreshing token", error) if (isResponseError(error)) { if (error.status === 400 && error.cause === "invalid_grant") { diff --git a/apps/partner-sas/eslint.config.mjs b/apps/partner-sas/eslint.config.mjs index fb419121a..00e75a007 100644 --- a/apps/partner-sas/eslint.config.mjs +++ b/apps/partner-sas/eslint.config.mjs @@ -28,6 +28,7 @@ export default defineConfig([ }, rules: { + "no-console": "warn", "no-unused-vars": "off", "react/function-component-definition": "error", "import/no-relative-packages": "error", diff --git a/apps/redis-api/eslint.config.mjs b/apps/redis-api/eslint.config.mjs index 0aac54118..e9d0f6d7a 100644 --- a/apps/redis-api/eslint.config.mjs +++ b/apps/redis-api/eslint.config.mjs @@ -21,6 +21,7 @@ export default defineConfig([ parser: tsParser, }, rules: { + "no-console": "warn", "no-unused-vars": "off", "simple-import-sort/imports": "error", "simple-import-sort/exports": "error", diff --git a/apps/redis-api/scripts/generateApiKeys.ts b/apps/redis-api/scripts/generateApiKeys.ts index 4c16b6e4c..818710af4 100644 --- a/apps/redis-api/scripts/generateApiKeys.ts +++ b/apps/redis-api/scripts/generateApiKeys.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import crypto from "node:crypto"; function generateApiKey(length = 32): string { diff --git a/apps/redis-api/src/env.ts b/apps/redis-api/src/env.ts index 0dbb888fe..0ca309d96 100644 --- a/apps/redis-api/src/env.ts +++ b/apps/redis-api/src/env.ts @@ -80,6 +80,3 @@ export const redisConfig = { username: redisMatch.groups.username, password: redisMatch.groups.password, }; - -console.log("env", env); -console.log("redisConfig", redisConfig); diff --git a/apps/scandic-web/components/Blocks/DynamicContent/Overview/index.tsx b/apps/scandic-web/components/Blocks/DynamicContent/Overview/index.tsx index 3f23cc9ba..a4b413358 100644 --- a/apps/scandic-web/components/Blocks/DynamicContent/Overview/index.tsx +++ b/apps/scandic-web/components/Blocks/DynamicContent/Overview/index.tsx @@ -1,6 +1,5 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" -import { env } from "@/env/server" import { getProfile } from "@/lib/trpc/memoizedRequests" import { TeamMemberCardTrigger } from "@/components/DigitalTeamMemberCard/Trigger" diff --git a/apps/scandic-web/eslint.config.mjs b/apps/scandic-web/eslint.config.mjs index cc5db00cc..9cd0a2f91 100644 --- a/apps/scandic-web/eslint.config.mjs +++ b/apps/scandic-web/eslint.config.mjs @@ -28,6 +28,7 @@ export default defineConfig([ }, rules: { + "no-console": "warn", "no-unused-vars": "off", "react/function-component-definition": "error", "import/no-relative-packages": "error", diff --git a/apps/scandic-web/netlify/functions/warmup-background.mts b/apps/scandic-web/netlify/functions/warmup-background.mts index baba07c0f..64ca5688e 100644 --- a/apps/scandic-web/netlify/functions/warmup-background.mts +++ b/apps/scandic-web/netlify/functions/warmup-background.mts @@ -1,23 +1,26 @@ import crypto from "crypto" import jwt from "jsonwebtoken" +import { createLogger } from "@scandic-hotels/common/logger/createLogger" +import { safeTry } from "@scandic-hotels/common/utils/safeTry" + import { type WarmupFunctionsKey, warmupKeys, } from "@/services/warmup/warmupKeys" -import { safeTry } from "@scandic-hotels/common/utils/safeTry" import { timeout } from "@/utils/timeout" import type { Config, Context } from "@netlify/functions" async function WarmupHandler(request: Request, context: Context) { + const warmupLogger = createLogger("warmup") const [_, error] = await safeTry(validateRequest(request, context)) if (error) { if (error instanceof Error) { switch (error.message as ErrorCode) { case ErrorCodes.WARMUP_DISABLED: - console.warn("[WARMUP] Warmup is disabled") + warmupLogger.warn("Warmup is disabled") return case ErrorCodes.REQUEST_NOT_FOR_CURRENT_CONTEXT: // This is expected, this webhook will be called for all deployments @@ -26,19 +29,20 @@ async function WarmupHandler(request: Request, context: Context) { } } - console.error("[WARMUP] Warmup failed", error) + warmupLogger.error("Warmup failed", error) return } - console.log("[WARMUP] Request is valid, starting warmup") + warmupLogger.info("Request is valid, starting warmup") await performWarmup(context) - console.log("[WARMUP] Warmup completed") + warmupLogger.info("Warmup completed") } async function validateRequest( request: Request, context: Context ): Promise { + const warmupLogger = createLogger("warmup") if (request.method !== "POST") { throw new Error(ErrorCodes.METHOD_NOT_ALLOWED) } @@ -57,7 +61,7 @@ async function validateRequest( } const body = await request.text() - console.log("[WARMUP] Warmup body", body) + warmupLogger.info("Warmup body", body) const deployment = JSON.parse(body) as DeploymentInfo if (!deployment) { throw new Error(ErrorCodes.UNABLE_TO_PARSE_DEPLOYMENT_INFO) @@ -72,7 +76,7 @@ async function validateRequest( throw new Error(ErrorCodes.REQUEST_NOT_FOR_CURRENT_CONTEXT) } - console.log("[WARMUP] Warmup request", deployment) + warmupLogger.info("Warmup request", deployment) let signature: string try { const headerValue = request.headers.get("x-webhook-signature") @@ -81,7 +85,7 @@ async function validateRequest( } signature = headerValue } catch (e) { - console.warn("[WARMUP] Failed to parse signature", e) + warmupLogger.warn("Failed to parse signature", e) throw new Error(ErrorCodes.FAILED_TO_PARSE_SIGNATURE) } @@ -99,8 +103,9 @@ async function validateRequest( } export async function performWarmup(context: Context) { + const warmupLogger = createLogger("warmup") for (const key of warmupKeys) { - console.log("[WARMUP] Warming up cache", key) + warmupLogger.info("Warming up cache", key) await callWarmup(key, context) // allow api to catch up await timeout(1000) @@ -108,6 +113,7 @@ export async function performWarmup(context: Context) { } async function callWarmup(key: WarmupFunctionsKey, context: Context) { + const warmupLogger = createLogger("warmup") const baseUrl = context.url.origin const url = new URL("/api/web/warmup", baseUrl) @@ -126,13 +132,13 @@ async function callWarmup(key: WarmupFunctionsKey, context: Context) { }) if (!response.ok) { - console.error( - `[WARMUP] Warmup failed '${url.href}' with error: ${response.status}: ${response.statusText}` + warmupLogger.error( + `Warmup failed '${url.href}' with error: ${response.status}: ${response.statusText}` ) } } catch (error) { - console.error( - `[WARMUP] Warmup failed '${url.href}' with error: ${error instanceof Error ? error.message : error}` + warmupLogger.error( + `Warmup failed '${url.href}' with error: ${error instanceof Error ? error.message : error}` ) } } @@ -143,6 +149,7 @@ export const config: Config = { } async function validateSignature(token: string, buffer: string) { + const warmupLogger = createLogger("warmup") try { const secret = process.env.WARMUP_SIGNATURE_SECRET || @@ -160,15 +167,15 @@ async function validateSignature(token: string, buffer: string) { const hashedBody = crypto.createHash("sha256").update(buffer).digest("hex") if (!hasSha256(decoded)) { - console.error( - "[WARMUP] Decoded jwt does not contain sha256, unable to verify signature" + warmupLogger.error( + "Decoded jwt does not contain sha256, unable to verify signature" ) return false } return decoded.sha256 === hashedBody } catch (error) { - console.error("[WARMUP] Failed to validate signature", error) + warmupLogger.error("Failed to validate signature", error) return false } } diff --git a/packages/booking-flow/eslint.config.mjs b/packages/booking-flow/eslint.config.mjs index 6fe2b0f92..4495d934c 100644 --- a/packages/booking-flow/eslint.config.mjs +++ b/packages/booking-flow/eslint.config.mjs @@ -46,6 +46,7 @@ export default defineConfig([ }, rules: { + "no-console": "warn", "no-unused-vars": "off", "react/function-component-definition": "error", "import/no-relative-packages": "error", diff --git a/packages/booking-flow/lib/contexts/SelectRate/DebugButton.tsx b/packages/booking-flow/lib/contexts/SelectRate/DebugButton.tsx index 95c110f50..0477f7bb1 100644 --- a/packages/booking-flow/lib/contexts/SelectRate/DebugButton.tsx +++ b/packages/booking-flow/lib/contexts/SelectRate/DebugButton.tsx @@ -14,6 +14,7 @@ export function DebugButton() { const handleClick = () => { const allRoomAvailability = getAllRoomAvailability(context) const allRoomPackages = getAllRoomPackages(context) + // eslint-disable-next-line no-console console.log("%c SelectRateContext: ", "background: #AD0015; color: #FFF", { ...context, ...allRoomAvailability, diff --git a/packages/booking-flow/lib/contexts/SelectRate/SelectRateContext/index.tsx b/packages/booking-flow/lib/contexts/SelectRate/SelectRateContext/index.tsx index e217f1cb9..8c3baacf2 100644 --- a/packages/booking-flow/lib/contexts/SelectRate/SelectRateContext/index.tsx +++ b/packages/booking-flow/lib/contexts/SelectRate/SelectRateContext/index.tsx @@ -214,7 +214,7 @@ export function SelectRateProvider({ }) if (selectedRatesPerRoom && selectedRatesPerRoom.length > 1) { - console.error(`Multiple selected rates found for room index ${ix}:`) + logger.error(`Multiple selected rates found for room index ${ix}:`) } const selectedRate = selectedRatesPerRoom?.at(0) @@ -234,7 +234,7 @@ export function SelectRateProvider({ const getPriceForRoom = useCallback( (roomIndex: number): Price | null => { if (roomIndex < 0 || roomIndex >= selectedRates.length) { - console.warn("Room index out of bounds:", roomIndex) + logger.warn("Room index out of bounds:", roomIndex) return null } @@ -422,7 +422,7 @@ export function SelectRateProvider({ selectPackages: ({ roomIndex, packages }) => { const updatedRoom = selectRateBooking?.rooms?.[roomIndex] if (!updatedRoom) { - console.error("No room found at index", roomIndex) + logger.error("No room found at index", roomIndex) // TODO: What to do here? return } @@ -443,7 +443,7 @@ export function SelectRateProvider({ }) => { const updatedRoom = selectRateBooking?.rooms?.[roomIndex] if (!updatedRoom) { - console.error("No room found at index", roomIndex) + logger.error("No room found at index", roomIndex) // TODO: What to do here? return } diff --git a/packages/common/eslint.config.mjs b/packages/common/eslint.config.mjs index 2ddf3bd80..5dc3d4e93 100644 --- a/packages/common/eslint.config.mjs +++ b/packages/common/eslint.config.mjs @@ -30,6 +30,7 @@ export default defineConfig([ }, rules: { + "no-console": "warn", "no-unused-vars": "off", "import/no-relative-packages": "error", "simple-import-sort/imports": [ diff --git a/packages/common/logger/createLogger/index.ts b/packages/common/logger/createLogger/index.ts index 7c60c62ac..b7924bce9 100644 --- a/packages/common/logger/createLogger/index.ts +++ b/packages/common/logger/createLogger/index.ts @@ -47,6 +47,7 @@ export function createLogger(loggerPrefix: string | (() => Promise)) { `${await getLoggerPrefix()} ${message}`.trim(), logValue ) + // eslint-disable-next-line no-console console[level](`${await getLoggerPrefix()} ${message}`.trim(), ...args) } diff --git a/packages/common/logger/createLogger/minimumLogLevel.ts b/packages/common/logger/createLogger/minimumLogLevel.ts index b0b40e837..4c761c251 100644 --- a/packages/common/logger/createLogger/minimumLogLevel.ts +++ b/packages/common/logger/createLogger/minimumLogLevel.ts @@ -8,6 +8,7 @@ export const minimumLogLevel = (() => { ).toLowerCase() as (typeof logLevels)[number] if (!logLevels.includes(configuredMinimumLogLevel)) { + // eslint-disable-next-line no-console console.warn( `Invalid log level configured: ${configuredMinimumLogLevel}, defaulting to 'info'` ) diff --git a/packages/tracking/eslint.config.mjs b/packages/tracking/eslint.config.mjs index 2ddf3bd80..5dc3d4e93 100644 --- a/packages/tracking/eslint.config.mjs +++ b/packages/tracking/eslint.config.mjs @@ -30,6 +30,7 @@ export default defineConfig([ }, rules: { + "no-console": "warn", "no-unused-vars": "off", "import/no-relative-packages": "error", "simple-import-sort/imports": [ diff --git a/packages/trpc/eslint.config.mjs b/packages/trpc/eslint.config.mjs index 2ddf3bd80..5dc3d4e93 100644 --- a/packages/trpc/eslint.config.mjs +++ b/packages/trpc/eslint.config.mjs @@ -30,6 +30,7 @@ export default defineConfig([ }, rules: { + "no-console": "warn", "no-unused-vars": "off", "import/no-relative-packages": "error", "simple-import-sort/imports": [ diff --git a/packages/trpc/lib/routers/hotels/availability/enterDetails.ts b/packages/trpc/lib/routers/hotels/availability/enterDetails.ts index cba490623..8c0c583f4 100644 --- a/packages/trpc/lib/routers/hotels/availability/enterDetails.ts +++ b/packages/trpc/lib/routers/hotels/availability/enterDetails.ts @@ -177,7 +177,7 @@ export const enterDetails = safeProtectedServiceProcedure } if (selectedRooms.some((sr) => !sr)) { - console.log("DEBUG: REDIRECTING TO SELECT RATE", selectedRooms) + logger.debug("DEBUG: REDIRECTING TO SELECT RATE", selectedRooms) return selectRateRedirectURL(input, selectedRooms.map(Boolean)) } diff --git a/packages/trpc/lib/utils/getFiltersFromHotels.ts b/packages/trpc/lib/utils/getFiltersFromHotels.ts index 54a751ac0..48d639b9c 100644 --- a/packages/trpc/lib/utils/getFiltersFromHotels.ts +++ b/packages/trpc/lib/utils/getFiltersFromHotels.ts @@ -1,3 +1,5 @@ +import { logger } from "@scandic-hotels/common/logger" + import type { FacilityEnum } from "@scandic-hotels/common/constants/facilities" import type { Lang } from "@scandic-hotels/common/constants/language" @@ -140,7 +142,7 @@ function getLocalizedCountryByCountryCode( const country = new Intl.DisplayNames([lang], { type: "region" }) const localizedCountry = country.of(countryCode) if (!localizedCountry) { - console.error(`Could not map ${countryCode} to localized country.`) + logger.error(`Could not map ${countryCode} to localized country.`) return null }