import { CN_EXPIRATION_KEY, CN_INIT_COOKIE, CONSENT_DURATION_DAYS, } from "../Components/cookie/constants"; import type { CookieName, CookieStatusMap } from "../types/cookie"; /* ------------------------------------------------------------------ */ /* Utilitaires cookies */ /* ------------------------------------------------------------------ */ /** * Read a cookie * @param name string * @returns string | null */ export const getCookie = (name: string): string | null => { if (typeof document === "undefined") return null; const match = document.cookie .split("; ") .find((row) => row.startsWith(`${name}=`)); return match ? match.split("=").slice(1).join("=") : null; }; /** * Write a cookie * @param name string * @param value string * @param days number * @returns void */ export const setCookie = (name: string, value: string, days: number) => { if (typeof document === "undefined") return; const expires = new Date(Date.now() + days * 24 * 60 * 60 * 1000); document.cookie = `${name}=${value}; expires=${expires.toUTCString()}; path=/; SameSite=Lax`; }; /** * Revoke and delete cookie by his name * @returns void */ export const deleteCookie = (name: string) => { if (typeof document === "undefined") return; document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`; }; /** * Decpde cn-init cookie * @param raw * @returns Record */ export const parseCnInit = (raw: string | null): Record => { if (!raw) return {}; return Object.fromEntries( raw .split(",") .filter(Boolean) .map((pair) => pair.split("=") as [string, string]), ); }; /** * Encode statuses and expiration for cn-init cookie format * @param services CookieName[] * @param statuses CookieStatusMap * @param expiresAt Date * @returns string */ export const serializeCnInit = ( services: CookieName[], statuses: CookieStatusMap, expiresAt: Date, ): string => [ ...services.map((name) => `${name}=${statuses[name]}`), `${CN_EXPIRATION_KEY}=${String(expiresAt.getTime())}`, ].join(","); /** * Persist current statuses in cn-init cookie * @param services CookieName[] * @param statuses CookieStatusMap * @returns void */ export const persistCnInit = ( services: CookieName[], statuses: CookieStatusMap, ) => { const expiresAt = new Date( Date.now() + CONSENT_DURATION_DAYS * 24 * 60 * 60 * 1000, ); setCookie( CN_INIT_COOKIE, serializeCnInit(services, statuses, expiresAt), CONSENT_DURATION_DAYS, ); }; /** * If a service is in waiting status * @param services * @param statuses * @returns boolean */ export const hasPendingDecision = ( services: CookieName[], statuses: CookieStatusMap, ): boolean => services.some((name) => statuses[name] === "wait"); /* ------------------------------------------------------------------ */ /* Dynamic loading of scripts */ /* ------------------------------------------------------------------ */ /** * Inject a