All files / src/utils serverUtils.ts

83.01% Statements 44/53
79.31% Branches 23/29
100% Functions 2/2
88.09% Lines 37/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 432x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x       13x 13x 4x 1x 1x 4x     4x 2x 2x 2x 2x 4x 2x 2x 2x 13x 2x 2x 13x 2x 2x 2x 2x 2x 12x 2x  
// src/utils/serverUtils.ts
import type { Logger } from 'pino';
 
/**
 * Constructs a fully qualified base URL for generating absolute URLs.
 * It prioritizes `FRONTEND_URL`, then `BASE_URL`, and falls back to a localhost URL
 * based on the `PORT` environment variable. It also logs a warning if the provided
 * URL is invalid or missing.
 *
 * @param logger - The logger instance to use for warnings.
 * @returns A validated, fully qualified base URL without a trailing slash.
 * @throws Error if the final URL doesn't match the http/https pattern required by database constraints.
 */
export function getBaseUrl(logger: Logger): string {
  let baseUrl = (process.env.FRONTEND_URL || process.env.BASE_URL || '').trim();
  if (!baseUrl || !baseUrl.startsWith('http')) {
    const port = process.env.PORT || 3000;
    // In test/staging/development, use http://localhost. In production, this should never be reached.
    const fallbackUrl =
      process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'staging'
        ? `http://localhost:${port}`
        : `http://example.com:${port}`;
    if (baseUrl) {
      logger.warn(
        `[getBaseUrl] FRONTEND_URL/BASE_URL is invalid or incomplete ('${baseUrl}'). Falling back to: ${fallbackUrl}`,
      );
    }
    baseUrl = fallbackUrl;
  }
 
  // Remove trailing slash
  const finalUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
 
  // Validate that the URL matches database constraint pattern (http:// or https://)
  if (!/^https?:\/\/.+/.test(finalUrl)) {
    throw new Error(
      `[getBaseUrl] Generated URL '${finalUrl}' does not match required pattern (must start with http:// or https://)`,
    );
  }
 
  return finalUrl;
}