From 82075304d2fce3de55d929abd1c0fa8b779a05bf Mon Sep 17 00:00:00 2001 From: Codemod Bot Date: Tue, 9 Jun 2026 18:45:36 +0000 Subject: [PATCH] Apply API v2 getEnv migration --- apps/api/v2/src/app.module.ts | 3 ++- apps/api/v2/src/bootstrap.ts | 7 ++++--- apps/api/v2/src/config/app.ts | 2 +- apps/api/v2/src/instrument.ts | 2 +- apps/api/v2/src/lib/logger.bridge.ts | 5 +++-- apps/api/v2/src/lib/logger.ts | 11 ++++++----- apps/api/v2/src/main.ts | 5 +++-- .../api/v2/src/middleware/app.redirects.middleware.ts | 5 +++-- apps/api/v2/src/modules/stripe/stripe.service.ts | 3 ++- .../v2/src/modules/stripe/utils/newStripeInstance.ts | 3 ++- .../calendars/services/apple-calendar.service.ts | 7 ++++--- .../platform/calendars/services/ics-feed.service.ts | 3 ++- .../services/private-links.service.ts | 7 ++++--- apps/api/v2/src/swagger/generate-swagger.ts | 2 +- apps/api/v2/src/vercel-webhook.controller.ts | 5 +++-- apps/api/v2/src/vercel-webhook.guard.ts | 3 ++- 16 files changed, 43 insertions(+), 30 deletions(-) diff --git a/apps/api/v2/src/app.module.ts b/apps/api/v2/src/app.module.ts index 5042292833171f..6b12cafb43b991 100644 --- a/apps/api/v2/src/app.module.ts +++ b/apps/api/v2/src/app.module.ts @@ -23,6 +23,7 @@ import { PrismaModule } from "@/modules/prisma/prisma.module"; import { RedisModule } from "@/modules/redis/redis.module"; import { RedisService } from "@/modules/redis/redis.service"; import { VercelWebhookController } from "@/vercel-webhook.controller"; +import { getEnv } from "@/env"; @Module({ imports: [ @@ -35,7 +36,7 @@ import { VercelWebhookController } from "@/vercel-webhook.controller"; RedisModule, BullModule.forRoot({ - redis: `${process.env.REDIS_URL}${process.env.NODE_ENV === "production" ? "?tls=true" : ""}`, + redis: `${getEnv("REDIS_URL")}${getEnv("NODE_ENV", "development") === "production" ? "?tls=true" : ""}`, }), ThrottlerModule.forRootAsync({ imports: [RedisModule], diff --git a/apps/api/v2/src/bootstrap.ts b/apps/api/v2/src/bootstrap.ts index 9311ceda9126cd..f4634734c33ee0 100644 --- a/apps/api/v2/src/bootstrap.ts +++ b/apps/api/v2/src/bootstrap.ts @@ -20,12 +20,13 @@ import { TRPCExceptionFilter } from "./filters/trpc-exception.filter"; import { HttpExceptionFilter } from "@/filters/http-exception.filter"; import { PrismaExceptionFilter } from "@/filters/prisma-exception.filter"; import { ZodExceptionFilter } from "@/filters/zod-exception.filter"; +import { getEnv } from "@/env"; const logger: Logger = new Logger("Bootstrap"); export const bootstrap = (app: NestExpressApplication): NestExpressApplication => { try { - if (!process.env.VERCEL) { + if (!getEnv("VERCEL", "")) { app.enableShutdownHooks(); } app.enableVersioning({ @@ -76,8 +77,8 @@ export const bootstrap = (app: NestExpressApplication): NestExpressApplication = app.useGlobalFilters(new CalendarServiceExceptionFilter()); app.use(cookieParser()); - if (process?.env?.API_GLOBAL_PREFIX) { - app.setGlobalPrefix(process?.env?.API_GLOBAL_PREFIX); + if (getEnv("API_GLOBAL_PREFIX", "")) { + app.setGlobalPrefix(getEnv("API_GLOBAL_PREFIX")); } return app; diff --git a/apps/api/v2/src/config/app.ts b/apps/api/v2/src/config/app.ts index adc6cfcf7ab2d0..ca5bed4cb172b9 100644 --- a/apps/api/v2/src/config/app.ts +++ b/apps/api/v2/src/config/app.ts @@ -6,7 +6,7 @@ const loadConfig = (): AppConfig => { const apiPort = Number(getEnv("API_PORT", "5555")); const apiUrl = getEnv("API_URL", "http://localhost"); let portSuffix = ""; - if (process.env.API_PORT && env === "development") { + if (getEnv("API_PORT", "") && env === "development") { portSuffix = `:${apiPort}`; } diff --git a/apps/api/v2/src/instrument.ts b/apps/api/v2/src/instrument.ts index 28ac453e169e87..a4ae0756322c72 100644 --- a/apps/api/v2/src/instrument.ts +++ b/apps/api/v2/src/instrument.ts @@ -2,7 +2,7 @@ import { getEnv } from "@/env"; import * as Sentry from "@sentry/nestjs"; import { nodeProfilingIntegration } from "@sentry/profiling-node"; -if (process.env.SENTRY_DSN) { +if (getEnv("SENTRY_DSN", "")) { // Ensure to call this before requiring any other modules! Sentry.init({ dsn: getEnv("SENTRY_DSN"), diff --git a/apps/api/v2/src/lib/logger.bridge.ts b/apps/api/v2/src/lib/logger.bridge.ts index bb2001f8cb85ba..69a3ae2f6a3480 100644 --- a/apps/api/v2/src/lib/logger.bridge.ts +++ b/apps/api/v2/src/lib/logger.bridge.ts @@ -1,5 +1,6 @@ import { Injectable, Logger as NestLogger, Scope } from "@nestjs/common"; import type { Logger as TsLogger } from "tslog"; +import { getEnv } from "@/env"; // 1. Define an interface for the settings interface IMyLoggerSettings { @@ -38,8 +39,8 @@ export class Logger // Define default settings private static readonly defaultSettings: IMyLoggerSettings = { - minLevel: process?.env?.LOGGER_BRIDGE_LOG_LEVEL - ? Number(process.env.LOGGER_BRIDGE_LOG_LEVEL) + minLevel: getEnv("LOGGER_BRIDGE_LOG_LEVEL", "") + ? Number(getEnv("LOGGER_BRIDGE_LOG_LEVEL", "")) : LogLevel.INFO, // Default to INFO level displayTimestamp: true, logFormat: "pretty", diff --git a/apps/api/v2/src/lib/logger.ts b/apps/api/v2/src/lib/logger.ts index b5950e51b72b10..d197cb1d0319f4 100644 --- a/apps/api/v2/src/lib/logger.ts +++ b/apps/api/v2/src/lib/logger.ts @@ -2,6 +2,7 @@ import { WinstonTransport as AxiomTransport } from "@axiomhq/winston"; import type { LoggerOptions } from "winston"; import { format, transports as Transports, config } from "winston"; import type Transport from "winston-transport"; +import { getEnv } from "@/env"; const formattedTimestamp = format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS", @@ -22,23 +23,23 @@ const WINSTON_PROD_FORMAT = format.combine(format.errors({ stack: true }), forma export const logLevels = config.npm.levels; export const loggerConfig = (): LoggerOptions => { - const isProduction = process.env.NODE_ENV === "production"; + const isProduction = getEnv("NODE_ENV", "development") === "production"; const transports: Transport[] = []; transports.push(new Transports.Console()); - if (!!process.env.AXIOM_TOKEN && !!process.env.AXIOM_DATASET) { + if (!!getEnv("AXIOM_TOKEN", "") && !!getEnv("AXIOM_DATASET", "")) { transports.push( new AxiomTransport({ - token: process.env.AXIOM_TOKEN, - dataset: process.env.AXIOM_DATASET, + token: getEnv("AXIOM_TOKEN"), + dataset: getEnv("AXIOM_DATASET"), }) ); } return { levels: logLevels, - level: process.env.LOG_LEVEL ?? "info", + level: getEnv("LOG_LEVEL", "info"), format: isProduction ? WINSTON_PROD_FORMAT : WINSTON_DEV_FORMAT, transports, exceptionHandlers: transports, diff --git a/apps/api/v2/src/main.ts b/apps/api/v2/src/main.ts index 9f5a3410673f41..c78c06dc86a32e 100644 --- a/apps/api/v2/src/main.ts +++ b/apps/api/v2/src/main.ts @@ -13,8 +13,9 @@ import { AppModule } from "./app.module"; import { bootstrap } from "./bootstrap"; import { loggerConfig } from "./lib/logger"; import type { AppConfig } from "@/config/type"; +import { getEnv } from "@/env"; -if (process.env.NODE_ENV === "production") { +if (getEnv("NODE_ENV", "development") === "production") { process.env.TRIGGER_VERSION = TRIGGER_VERSION; } const logger: Logger = new Logger("App"); @@ -52,7 +53,7 @@ class NestServer { // ----------------------------------------------------------------------------- // LOCAL DEVELOPMENT STARTUP // ----------------------------------------------------------------------------- -if (!process.env.VERCEL) { +if (!getEnv("VERCEL", "")) { run().catch((error: Error) => { logger.error("Failed to start Cal Platform API", { error: error.stack }); process.exit(1); diff --git a/apps/api/v2/src/middleware/app.redirects.middleware.ts b/apps/api/v2/src/middleware/app.redirects.middleware.ts index a4b12cdc5204b2..35c295ca04cc94 100644 --- a/apps/api/v2/src/middleware/app.redirects.middleware.ts +++ b/apps/api/v2/src/middleware/app.redirects.middleware.ts @@ -1,11 +1,12 @@ import { Injectable, NestMiddleware } from "@nestjs/common"; import { Request, Response } from "express"; +import { getEnv } from "@/env"; @Injectable() export class RedirectsMiddleware implements NestMiddleware { use(req: Request, res: Response, next: () => void) { - if (process.env.DOCS_URL && (req.url.startsWith("/v2/docs") || req.url.startsWith("/docs"))) { - return res.redirect(process.env.DOCS_URL); + if (getEnv("DOCS_URL", "") && (req.url.startsWith("/v2/docs") || req.url.startsWith("/docs"))) { + return res.redirect(getEnv("DOCS_URL")); } next(); } diff --git a/apps/api/v2/src/modules/stripe/stripe.service.ts b/apps/api/v2/src/modules/stripe/stripe.service.ts index 9302c716c18c32..f808e13d16ea1a 100644 --- a/apps/api/v2/src/modules/stripe/stripe.service.ts +++ b/apps/api/v2/src/modules/stripe/stripe.service.ts @@ -22,6 +22,7 @@ import type { Prisma, Credential, User } from "@calcom/prisma/client"; import { stripeKeysResponseSchema } from "./utils/stripeDataSchemas"; import stringify = require("qs-stringify"); +import { getEnv } from "@/env"; export type OAuthCallbackState = { accessToken: string; @@ -68,7 +69,7 @@ export class StripeService { email: userEmail, first_name: userName || undefined, /** We need this so E2E don't fail for international users */ - country: process.env.NEXT_PUBLIC_IS_E2E ? "US" : undefined, + country: getEnv("NEXT_PUBLIC_IS_E2E", "") ? "US" : undefined, }, redirect_uri: this.redirectUri, state: JSON.stringify(state), diff --git a/apps/api/v2/src/modules/stripe/utils/newStripeInstance.ts b/apps/api/v2/src/modules/stripe/utils/newStripeInstance.ts index 1784b78305403b..6b45b56f5fb6ec 100644 --- a/apps/api/v2/src/modules/stripe/utils/newStripeInstance.ts +++ b/apps/api/v2/src/modules/stripe/utils/newStripeInstance.ts @@ -1,6 +1,7 @@ import Stripe from "stripe"; +import { getEnv } from "@/env"; -const stripeApiKey = process.env.STRIPE_API_KEY || ""; +const stripeApiKey = getEnv("STRIPE_API_KEY", ""); export const stripeInstance = new Stripe(stripeApiKey, { apiVersion: "2020-08-27", }); diff --git a/apps/api/v2/src/platform/calendars/services/apple-calendar.service.ts b/apps/api/v2/src/platform/calendars/services/apple-calendar.service.ts index 5c83885ab95be7..e71a78bea68bec 100644 --- a/apps/api/v2/src/platform/calendars/services/apple-calendar.service.ts +++ b/apps/api/v2/src/platform/calendars/services/apple-calendar.service.ts @@ -8,6 +8,7 @@ import { SUCCESS_STATUS, APPLE_CALENDAR_TYPE, APPLE_CALENDAR_ID } from "@calcom/ import { symmetricEncrypt, symmetricDecrypt } from "@calcom/platform-libraries"; import { BuildCalendarService } from "@calcom/platform-libraries/app-store"; import type { Credential } from "@calcom/prisma/client"; +import { getEnv } from "@/env"; @Injectable() export class AppleCalendarService implements CredentialSyncCalendarApp { @@ -75,7 +76,7 @@ export class AppleCalendarService implements CredentialSyncCalendarApp { const hasCalendarWithGivenCredentials = existingAppleCalendarCredentials.find( (calendarCredential: Credential) => { const decryptedKey = JSON.parse( - symmetricDecrypt(calendarCredential.key as string, process.env.CALENDSO_ENCRYPTION_KEY || "") + symmetricDecrypt(calendarCredential.key as string, getEnv("CALENDSO_ENCRYPTION_KEY", "")) ); if (decryptedKey.username === username) { @@ -97,7 +98,7 @@ export class AppleCalendarService implements CredentialSyncCalendarApp { if (!!hasCalendarWithGivenCredentials && !hasMatchingUsernameAndPassword) { await this.credentialRepository.upsertUserAppCredential( APPLE_CALENDAR_TYPE, - symmetricEncrypt(JSON.stringify({ username, password }), process.env.CALENDSO_ENCRYPTION_KEY || ""), + symmetricEncrypt(JSON.stringify({ username, password }), getEnv("CALENDSO_ENCRYPTION_KEY", "")), userId, hasCalendarWithGivenCredentials.id ); @@ -113,7 +114,7 @@ export class AppleCalendarService implements CredentialSyncCalendarApp { type: APPLE_CALENDAR_TYPE, key: symmetricEncrypt( JSON.stringify({ username, password }), - process.env.CALENDSO_ENCRYPTION_KEY || "" + getEnv("CALENDSO_ENCRYPTION_KEY", "") ), userId: userId, teamId: null, diff --git a/apps/api/v2/src/platform/calendars/services/ics-feed.service.ts b/apps/api/v2/src/platform/calendars/services/ics-feed.service.ts index ab42e0283936fb..4901eb7cf2ef34 100644 --- a/apps/api/v2/src/platform/calendars/services/ics-feed.service.ts +++ b/apps/api/v2/src/platform/calendars/services/ics-feed.service.ts @@ -10,6 +10,7 @@ import { Injectable } from "@nestjs/common"; import { SUCCESS_STATUS, ICS_CALENDAR_TYPE, ICS_CALENDAR } from "@calcom/platform-constants"; import { symmetricEncrypt } from "@calcom/platform-libraries"; import { BuildIcsFeedCalendarService } from "@calcom/platform-libraries/app-store"; +import { getEnv } from "@/env"; @Injectable() export class IcsFeedService implements ICSFeedCalendarApp { @@ -33,7 +34,7 @@ export class IcsFeedService implements ICSFeedCalendarApp { ICS_CALENDAR, key: symmetricEncrypt( JSON.stringify({ urls, skipWriting: readonly }), - process.env.CALENDSO_ENCRYPTION_KEY || "" + getEnv("CALENDSO_ENCRYPTION_KEY", "") ), userId: userId, teamId: null, diff --git a/apps/api/v2/src/platform/event-types-private-links/services/private-links.service.ts b/apps/api/v2/src/platform/event-types-private-links/services/private-links.service.ts index 8d9cc2f1bd5b89..3b47d4fbd61dd6 100644 --- a/apps/api/v2/src/platform/event-types-private-links/services/private-links.service.ts +++ b/apps/api/v2/src/platform/event-types-private-links/services/private-links.service.ts @@ -8,6 +8,7 @@ import { Injectable, NotFoundException, BadRequestException } from "@nestjs/comm import { generateHashedLink, isLinkExpired } from "@calcom/platform-libraries/private-links"; import { CreatePrivateLinkInput, PrivateLinkOutput, UpdatePrivateLinkInput } from "@calcom/platform-types"; +import { getEnv } from "@/env"; @Injectable() export class PrivateLinksService { @@ -33,7 +34,7 @@ export class PrivateLinksService { id: created.link, eventTypeId, isExpired: isLinkExpired(created as any), - bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || "https://cal.com"}/d/${created.link}`, + bookingUrl: `${getEnv("NEXT_PUBLIC_WEBAPP_URL", "https://cal.com")}/d/${created.link}`, expiresAt: created.expiresAt ?? null, maxUsageCount: (created as any).maxUsageCount ?? null, usageCount: (created as any).usageCount ?? 0, @@ -54,7 +55,7 @@ export class PrivateLinksService { id: l.link, eventTypeId, isExpired: isLinkExpired(l as any), - bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || "https://cal.com"}/d/${l.link}`, + bookingUrl: `${getEnv("NEXT_PUBLIC_WEBAPP_URL", "https://cal.com")}/d/${l.link}`, expiresAt: l.expiresAt ?? null, maxUsageCount: l.maxUsageCount ?? null, usageCount: l.usageCount ?? 0, @@ -85,7 +86,7 @@ export class PrivateLinksService { id: updated.link, eventTypeId, isExpired: isLinkExpired(updated as any), - bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || "https://cal.com"}/d/${updated.link}`, + bookingUrl: `${getEnv("NEXT_PUBLIC_WEBAPP_URL", "https://cal.com")}/d/${updated.link}`, expiresAt: updated.expiresAt ?? null, maxUsageCount: updated.maxUsageCount ?? null, usageCount: updated.usageCount ?? 0, diff --git a/apps/api/v2/src/swagger/generate-swagger.ts b/apps/api/v2/src/swagger/generate-swagger.ts index b08a574cb288ef..a02c0d9f8d4b96 100644 --- a/apps/api/v2/src/swagger/generate-swagger.ts +++ b/apps/api/v2/src/swagger/generate-swagger.ts @@ -35,7 +35,7 @@ export async function generateSwaggerForApp(app: NestExpressApplication) spawnSync("node", [biomeBin, "format", "--write", docsOutputFile], { stdio: "inherit" }); } - if (!process.env.DOCS_URL) { + if (!getEnv("DOCS_URL", "")) { SwaggerModule.setup("docs", app, document, { customCss: ".swagger-ui .topbar { display: none }", }); diff --git a/apps/api/v2/src/vercel-webhook.controller.ts b/apps/api/v2/src/vercel-webhook.controller.ts index 2e81176809f5c6..cc609ad75b41ba 100644 --- a/apps/api/v2/src/vercel-webhook.controller.ts +++ b/apps/api/v2/src/vercel-webhook.controller.ts @@ -11,6 +11,7 @@ import { import { ApiExcludeController } from "@nestjs/swagger"; import { VercelWebhookGuard } from "./vercel-webhook.guard"; import { API_VERSIONS_VALUES } from "@/lib/api-versions"; +import { getEnv } from "@/env"; interface VercelWebhookPayload { type?: string; @@ -50,7 +51,7 @@ export class VercelWebhookController { } // biome-ignore lint/style/noProcessEnv: Environment variable access required for trigger.dev API - const TRIGGER_VERSION = process.env.TRIGGER_VERSION; + const TRIGGER_VERSION = getEnv("TRIGGER_VERSION"); if (!TRIGGER_VERSION) { this.logger.error("TRIGGER_VERSION is not defined"); @@ -66,7 +67,7 @@ export class VercelWebhookController { private async promoteTriggerDeployment(version: string, maxRetries: number = 3): Promise { // biome-ignore lint/style/noProcessEnv: Environment variable access required for trigger.dev API - const triggerSecretKey = process.env.TRIGGER_SECRET_KEY; + const triggerSecretKey = getEnv("TRIGGER_SECRET_KEY"); const url = `https://api.trigger.dev/api/v1/deployments/${version}/promote`; diff --git a/apps/api/v2/src/vercel-webhook.guard.ts b/apps/api/v2/src/vercel-webhook.guard.ts index 18868f03ce2f6b..5e8c9a415891d5 100644 --- a/apps/api/v2/src/vercel-webhook.guard.ts +++ b/apps/api/v2/src/vercel-webhook.guard.ts @@ -1,5 +1,6 @@ import * as crypto from "node:crypto"; import { CanActivate, ExecutionContext, Injectable, Logger, UnauthorizedException } from "@nestjs/common"; +import { getEnv } from "@/env"; @Injectable() export class VercelWebhookGuard implements CanActivate { @@ -9,7 +10,7 @@ export class VercelWebhookGuard implements CanActivate { const request = context.switchToHttp().getRequest(); const signature = request.headers["x-vercel-signature"]; // biome-ignore lint/style/noProcessEnv: Environment variable access required for webhook secret - const webhookSecret = process.env.VERCEL_PROMOTE_WEBHOOK_SECRET; + const webhookSecret = getEnv("VERCEL_PROMOTE_WEBHOOK_SECRET"); if (!webhookSecret) { this.logger.error("VERCEL_PROMOTE_WEBHOOK_SECRET is not defined");