← back to jdy8739__glassbox

Function bodies 106 total

All specs Real LLM only Function bodies
buildPath function · typescript · L67-L84 (18 LOC)
apps/web/src/lib/i18n/paths.ts
export function buildPath(
  basePath: string,
  lang: Language,
  searchParams?: Record<string, string | number | boolean>
): string {
  const localizedPath = getLocalizedPath(basePath, lang);

  if (!searchParams || Object.keys(searchParams).length === 0) {
    return localizedPath;
  }

  const params = new URLSearchParams();
  Object.entries(searchParams).forEach(([key, value]) => {
    params.append(key, String(value));
  });

  return `${localizedPath}?${params.toString()}`;
}
logout function · typescript · L12-L40 (29 LOC)
apps/web/src/lib/logout.ts
export async function logout(options?: { redirect?: boolean; callbackUrl?: string }) {
  // Step 1: Backend logout - Clear backend session cookies (httpOnly accessToken)
  try {
    const backendUrl = process.env.NEXT_PUBLIC_API_URL;
    if (backendUrl) {
      const response = await fetch(`${backendUrl}/auth/logout`, {
        method: 'POST',
        credentials: 'include', // Sends httpOnly cookies to backend
      });

      if (!response.ok) {
        console.warn('[Logout] Backend logout returned error:', response.status);
      }
    }
  } catch (e) {
    console.warn('[Logout] Backend logout failed:', e);
    // Continue anyway - user still wants to logout from frontend
  }

  // Step 2: NextAuth signOut
  // In NextAuth v5, if redirect is false, we need to call signOut without redirect
  if (options?.redirect === false) {
    // Call signOut and prevent automatic redirect by catching the redirect
    await signOut({ redirect: false } as any);
  } else {
    // Default behavior:
validatePortfolioAnalysis function · typescript · L13-L56 (44 LOC)
apps/web/src/lib/portfolio-validation.ts
export function validatePortfolioAnalysis(
  items: PortfolioItem[],
  dateRange: DateRange,
  t: TFunction
): string | null {
  // Filter out zero quantities
  const nonZeroItems = items.filter((item) => item.quantity > 0);

  if (nonZeroItems.length === 0) {
    return t('portfolio.builder.validation.no-positive-quantity');
  }

  // Check if dates are missing
  if (!dateRange.startDate || !dateRange.endDate) {
    return t('portfolio.builder.analysis.dates-required');
  }

  // Validate date range order
  if (dateRange.startDate >= dateRange.endDate) {
    return t('portfolio.builder.validation.start-before-end');
  }

  // Check for future dates
  const endDate = new Date(dateRange.endDate);
  const startDate = new Date(dateRange.startDate);
  const todayDate = new Date();
  todayDate.setHours(0, 0, 0, 0);

  if (endDate > todayDate) {
    return t('portfolio.builder.validation.end-not-future');
  }

  if (startDate > todayDate) {
    return t('portfolio.builder.validation.start-no
isEndDateToday function · typescript · L61-L69 (9 LOC)
apps/web/src/lib/portfolio-validation.ts
export function isEndDateToday(dateRange: DateRange): boolean {
  if (!dateRange.endDate) return false;

  const endDate = new Date(dateRange.endDate);
  const todayDate = new Date();
  todayDate.setHours(0, 0, 0, 0);

  return endDate.getTime() === todayDate.getTime();
}
calculatePasswordStrength function · typescript · L25-L72 (48 LOC)
apps/web/src/lib/utils/password-strength.ts
export function calculatePasswordStrength(password: string): PasswordStrength {
  if (!password) {
    return {
      score: 0,
      label: 'very-weak',
      color: 'bg-red-500',
    };
  }

  let score = 0;

  // Length bonus
  if (password.length >= 8) score++;
  if (password.length >= 12) score++;

  // Character variety
  const hasLower = /[a-z]/.test(password);
  const hasUpper = /[A-Z]/.test(password);
  const hasNumber = /[0-9]/.test(password);
  const hasSpecial = /[^A-Za-z0-9]/.test(password);

  if (hasLower && hasUpper) score++;
  if (hasNumber) score++;
  if (hasSpecial) score++;

  // Penalize common patterns
  if (/^[a-z]+$/i.test(password)) score--; // Only letters
  if (/^[0-9]+$/.test(password)) score--; // Only numbers
  if (COMMON_PASSWORDS.includes(password.toLowerCase())) score -= 2;

  // Ensure score is within 0-4 range
  const finalScore = Math.max(0, Math.min(4, score));

  const labels = ['very-weak', 'weak', 'medium', 'strong', 'very-strong'];
  const color
detectLanguage function · typescript · L24-L40 (17 LOC)
apps/web/src/proxy.ts
function detectLanguage(request: NextRequest): Language {
  // Priority 1: Check if we have a saved preference in cookies
  const cookieLang = request.cookies.get('NEXT_LOCALE')?.value;
  if (cookieLang && SUPPORTED_LANGUAGES.includes(cookieLang as Language)) {
    return cookieLang as Language;
  }

  // Priority 2: Parse Accept-Language header with quality values
  const acceptLanguage = request.headers.get('accept-language') || '';
  const detectedLang = parseAcceptLanguage(
    acceptLanguage,
    [...SUPPORTED_LANGUAGES],
    DEFAULT_LANGUAGE
  );

  return detectedLang as Language;
}
‹ prevpage 3 / 3