UNPKG

@intlayer/config

Version:

Retrieve Intlayer configurations and manage environment variables for both server-side and client-side environments.

112 lines (110 loc) 5.04 kB
import { COOKIE_NAME, HEADER_NAME, LOCALE_STORAGE_NAME } from "../defaultValues/routing.mjs"; //#region src/utils/getStorageAttributes.ts /** Number of seconds in a day, used to convert a `number` of days. */ const SECONDS_PER_DAY = 3600 * 24; /** * Merges the user-facing `expires` and `maxAge` into a single, normalized and * serialization-safe expiry consumed by the client runtime. * * Precedence and normalization: * - `maxAge` (seconds) wins when set and is the internal unit (relative); * - `expires` as a `number` is interpreted as **days** and converted to * seconds (relative); * - `expires` as a `Date` (possibly a cross-realm instance, since config files * run in a `node:vm` sandbox) or an ISO string becomes an ISO **string** * (absolute). Strings survive `JSON.stringify`, unlike a `Date`. * * The result is therefore: a `number` = seconds from creation, a `string` = * absolute ISO date, or `undefined` for a session cookie. */ const normalizeCookieExpiry = (expires, maxAge) => { if (typeof maxAge === "number") return maxAge; if (expires === void 0) return void 0; if (expires instanceof Date || Object.prototype.toString.call(expires) === "[object Date]") return expires.toISOString(); if (typeof expires === "string") return expires; return expires * SECONDS_PER_DAY; }; const createCookieEntry = (options) => { const { name, path = "/", expires, maxAge, domain, secure, sameSite, httpOnly } = options ?? {}; return { name: name ?? "INTLAYER_LOCALE", attributes: { path, expires: normalizeCookieExpiry(expires, maxAge), domain, secure, sameSite, httpOnly } }; }; const createWebStorageEntry = (options) => ({ name: options?.name ?? "INTLAYER_LOCALE" }); const createHeaderEntry = (options) => ({ name: options?.name ?? "x-intlayer-locale" }); const isCookieEntry = (entry) => { if (typeof entry !== "object" || entry === null) return false; const e = entry; return e["type"] === "cookie" || "sameSite" in e || "httpOnly" in e || "secure" in e; }; const isStorageType = (value) => value === "cookie" || value === "localStorage" || value === "sessionStorage" || value === "header"; const processStorageEntry = (entry) => { if (typeof entry === "string") { if (!isStorageType(entry)) return { cookies: [], localStorage: [], sessionStorage: [], headers: [] }; if (entry === "cookie") return { cookies: [createCookieEntry()] }; if (entry === "localStorage") return { localStorage: [createWebStorageEntry()] }; if (entry === "sessionStorage") return { sessionStorage: [createWebStorageEntry()] }; if (entry === "header") return { headers: [createHeaderEntry()] }; } if (typeof entry === "object" && entry !== null) { const typedEntry = entry; if (isCookieEntry(typedEntry)) return { cookies: [createCookieEntry(typedEntry)] }; if ("type" in typedEntry && typedEntry.type === "localStorage") return { localStorage: [createWebStorageEntry(typedEntry)] }; if ("type" in typedEntry && typedEntry.type === "sessionStorage") return { sessionStorage: [createWebStorageEntry(typedEntry)] }; if ("type" in typedEntry && typedEntry.type === "header") return { headers: [createHeaderEntry(typedEntry)] }; return { localStorage: [createWebStorageEntry(typedEntry)] }; } return { cookies: [], localStorage: [], sessionStorage: [], headers: [] }; }; const mergeStorageAttributes = (accumulated, partial) => ({ cookies: [...accumulated.cookies ?? [], ...partial.cookies ?? []], localStorage: [...accumulated.localStorage ?? [], ...partial.localStorage ?? []], sessionStorage: [...accumulated.sessionStorage ?? [], ...partial.sessionStorage ?? []], headers: [...accumulated.headers ?? [], ...partial.headers ?? []] }); /** * Extracts and normalizes storage configuration into separate arrays for each storage type. * Called at config-build time so the result is pre-computed and stored in the config. * * @param options - The storage configuration from IntlayerConfig * @returns An object containing arrays for cookies, localStorage, sessionStorage and headers */ const getStorageAttributes = (options) => { const emptyResult = { cookies: [], localStorage: [], sessionStorage: [], headers: [] }; if (options === false || options === void 0) return {}; const result = Array.isArray(options) ? options.reduce((acc, entry) => { return mergeStorageAttributes(acc, processStorageEntry(entry)); }, emptyResult) : mergeStorageAttributes(emptyResult, processStorageEntry(options)); const cleanedResult = {}; if (result.cookies && result.cookies.length > 0) cleanedResult.cookies = result.cookies; if (result.localStorage && result.localStorage.length > 0) cleanedResult.localStorage = result.localStorage; if (result.sessionStorage && result.sessionStorage.length > 0) cleanedResult.sessionStorage = result.sessionStorage; if (result.headers && result.headers.length > 0) cleanedResult.headers = result.headers; return cleanedResult; }; //#endregion export { getStorageAttributes }; //# sourceMappingURL=getStorageAttributes.mjs.map