@xylex-group/athena 2.12.0 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1190 -1184
  3. package/bin/athena-js.js +104 -76
  4. package/dist/admin.cjs +45 -0
  5. package/dist/admin.cjs.map +1 -0
  6. package/dist/admin.d.cts +64 -0
  7. package/dist/admin.d.ts +64 -0
  8. package/dist/admin.js +41 -0
  9. package/dist/admin.js.map +1 -0
  10. package/dist/athena-auth-url-oLux_57a.d.cts +377 -0
  11. package/dist/athena-auth-url-oLux_57a.d.ts +377 -0
  12. package/dist/browser.cjs +33 -46
  13. package/dist/browser.cjs.map +1 -1
  14. package/dist/browser.d.cts +12 -10
  15. package/dist/browser.d.ts +12 -10
  16. package/dist/browser.js +33 -46
  17. package/dist/browser.js.map +1 -1
  18. package/dist/cli/index.cjs +150 -48
  19. package/dist/cli/index.cjs.map +1 -1
  20. package/dist/cli/index.d.cts +14 -5
  21. package/dist/cli/index.d.ts +14 -5
  22. package/dist/cli/index.js +150 -49
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/{client-QUbAs7E8.d.ts → client-BJjUwDSg.d.cts} +109 -1448
  25. package/dist/{client-C3x75Zgn.d.cts → client-DVOKSYDI.d.ts} +109 -1448
  26. package/dist/cookies.cjs +18 -0
  27. package/dist/cookies.cjs.map +1 -1
  28. package/dist/cookies.d.cts +2 -1
  29. package/dist/cookies.d.ts +2 -1
  30. package/dist/cookies.js +17 -1
  31. package/dist/cookies.js.map +1 -1
  32. package/dist/{index-CVcQCGyG.d.ts → index-CFL9xbFR.d.cts} +2 -0
  33. package/dist/{index-CVcQCGyG.d.cts → index-UKJpunc6.d.ts} +2 -0
  34. package/dist/index.cjs +101 -46
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +13 -10
  37. package/dist/index.d.ts +13 -10
  38. package/dist/index.js +101 -47
  39. package/dist/index.js.map +1 -1
  40. package/dist/{model-form-CD1uhWSh.d.cts → model-form-Dw4zEL5a.d.cts} +2 -2
  41. package/dist/{model-form-Dm69I-oO.d.ts → model-form-yRg71q3H.d.ts} +2 -2
  42. package/dist/{module-CW3tWJ10.d.ts → module-DBteUIob.d.ts} +12 -9
  43. package/dist/{module-Cxcurfes.d.cts → module-yoX49uQC.d.cts} +12 -9
  44. package/dist/next/client.cjs +452 -46
  45. package/dist/next/client.cjs.map +1 -1
  46. package/dist/next/client.d.cts +7 -4
  47. package/dist/next/client.d.ts +7 -4
  48. package/dist/next/client.js +430 -47
  49. package/dist/next/client.js.map +1 -1
  50. package/dist/next/server.cjs +292 -46
  51. package/dist/next/server.cjs.map +1 -1
  52. package/dist/next/server.d.cts +81 -5
  53. package/dist/next/server.d.ts +81 -5
  54. package/dist/next/server.js +280 -47
  55. package/dist/next/server.js.map +1 -1
  56. package/dist/organization.cjs +72 -0
  57. package/dist/organization.cjs.map +1 -0
  58. package/dist/organization.d.cts +43 -0
  59. package/dist/organization.d.ts +43 -0
  60. package/dist/organization.js +70 -0
  61. package/dist/organization.js.map +1 -0
  62. package/dist/payload-BzVbUgY_.d.cts +219 -0
  63. package/dist/payload-DEOWN_oo.d.ts +219 -0
  64. package/dist/{pipeline-BAwb6Vzm.d.ts → pipeline-Bj6RWt1A.d.ts} +1 -1
  65. package/dist/{pipeline-B14jVK7J.d.cts → pipeline-Dwck-wZO.d.cts} +1 -1
  66. package/dist/react.cjs +2 -10
  67. package/dist/react.cjs.map +1 -1
  68. package/dist/react.d.cts +26 -7
  69. package/dist/react.d.ts +26 -7
  70. package/dist/react.js +2 -10
  71. package/dist/react.js.map +1 -1
  72. package/dist/session-cookie-detection-BqOp9mO6.d.cts +46 -0
  73. package/dist/session-cookie-detection-BqOp9mO6.d.ts +46 -0
  74. package/dist/social-providers.cjs +4189 -0
  75. package/dist/social-providers.cjs.map +1 -0
  76. package/dist/social-providers.d.cts +4948 -0
  77. package/dist/social-providers.d.ts +4948 -0
  78. package/dist/social-providers.js +4117 -0
  79. package/dist/social-providers.js.map +1 -0
  80. package/dist/{types-Cq4-NoB4.d.ts → types-BRP7sfSF.d.ts} +50 -2
  81. package/dist/{types-Dr849HD6.d.cts → types-BU8uJH_b.d.cts} +50 -2
  82. package/dist/{types-CwJCPpLD.d.ts → types-CH78O90i.d.cts} +2 -2
  83. package/dist/{types-CwJCPpLD.d.cts → types-CH78O90i.d.ts} +2 -2
  84. package/dist/{types-DMOoYnPS.d.cts → types-CjC9_5ZQ.d.cts} +3 -3
  85. package/dist/{types-BcVmPBP-.d.ts → types-DPgejxYC.d.ts} +3 -3
  86. package/dist/types-eAKAh71s.d.cts +1476 -0
  87. package/dist/types-eAKAh71s.d.ts +1476 -0
  88. package/dist/utils.cjs +438 -12
  89. package/dist/utils.cjs.map +1 -1
  90. package/dist/utils.d.cts +76 -11
  91. package/dist/utils.d.ts +76 -11
  92. package/dist/utils.js +390 -13
  93. package/dist/utils.js.map +1 -1
  94. package/package.json +49 -22
  95. package/dist/shared-0Kdc74lu.d.ts +0 -35
  96. package/dist/shared-C0wVICRv.d.cts +0 -35
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/slugify.ts","../src/utils/trim-trailing-slashes.ts","../src/utils/coercions.ts","../src/utils/parse-boolean-flag.ts","../src/utils/hostname.ts","../src/utils/auth-cookies.ts","../src/utils/proxy-request-headers.ts","../src/cookies/cookie-utils.ts","../src/cookies/index.ts","../src/utils/athena-request-headers.ts","../src/utils/sql-literals.ts"],"names":[],"mappings":"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","file":"utils.cjs","sourcesContent":["export function slugify(input: string): string {\n return input\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64)\n}\n","export function trimTrailingSlashes(value: string): string {\n return value.replace(/\\/+$/, '')\n}\n","const BOOLEAN_TRUE_TOKENS = new Set(['true', '1', 'yes', 'y', 'on'])\nconst BOOLEAN_FALSE_TOKENS = new Set(['false', '0', 'no', 'n', 'off'])\n\nfunction parseBooleanToken(value: string): boolean | null {\n const normalized = value.trim().toLowerCase()\n if (BOOLEAN_TRUE_TOKENS.has(normalized)) return true\n if (BOOLEAN_FALSE_TOKENS.has(normalized)) return false\n return null\n}\n\nexport function asString(value: unknown): string | null {\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n if (typeof value === 'bigint') return value.toString()\n if (typeof value !== 'string') return null\n\n const normalized = value.trim()\n return normalized.length > 0 ? normalized : null\n}\n\nexport function asBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value\n if (typeof value === 'number') return value !== 0\n if (typeof value === 'string') {\n return parseBooleanToken(value) ?? false\n }\n\n return false\n}\n\nexport function asBooleanOrNull(value: unknown): boolean | null {\n if (typeof value === 'boolean') return value\n if (typeof value === 'number') return value !== 0\n if (typeof value === 'string') {\n return parseBooleanToken(value)\n }\n\n return null\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n return value as Record<string, unknown>\n}\n\nexport function asIdentifier(value: unknown): string | null {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return String(value)\n }\n if (typeof value === 'bigint') {\n return value.toString()\n }\n return asString(value)\n}\n\nexport function firstString(\n record: Record<string, unknown> | null | undefined,\n keys: readonly string[],\n): string | null {\n if (!record) return null\n for (const key of keys) {\n const value = asString(record[key])\n if (value) return value\n }\n return null\n}\n\nexport function readTrimmedString(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : null\n}\n\nexport function asNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value)\n if (Number.isFinite(parsed)) return parsed\n }\n return null\n}\n\nexport function asStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n return value\n .map(entry => (typeof entry === 'string' ? entry.trim() : ''))\n .filter(entry => entry.length > 0)\n}\n","export function parseBooleanFlag(\n rawValue: string | undefined,\n fallback: boolean,\n): boolean {\n if (!rawValue) return fallback\n\n const normalized = rawValue.trim().toLowerCase()\n\n if (\n normalized === '1' ||\n normalized === 'true' ||\n normalized === 'yes' ||\n normalized === 'on'\n ) {\n return true\n }\n\n if (\n normalized === '0' ||\n normalized === 'false' ||\n normalized === 'no' ||\n normalized === 'off'\n ) {\n return false\n }\n\n return fallback\n}\n","const LOCAL_IPV4_PATTERN = /^127(?:\\.\\d{1,3}){3}$/\n\nexport function isLocalHostname(hostname: string): boolean {\n const normalized = hostname.trim().replace(/\\.$/, '').toLowerCase()\n if (!normalized) {\n return false\n }\n\n if (normalized === 'localhost' || normalized.endsWith('.localhost')) {\n return true\n }\n\n if (\n normalized === '127.0.0.1' ||\n LOCAL_IPV4_PATTERN.test(normalized) ||\n normalized === '::1' ||\n normalized === '[::1]' ||\n normalized === '0:0:0:0:0:0:0:1'\n ) {\n return true\n }\n\n return false\n}\n","import { isLocalHostname } from './hostname.ts'\n\nconst DEFAULT_AUTH_COOKIE_PREFIXES = [\n 'athena-auth',\n '__Secure-athena-auth',\n 'better-auth',\n '__Secure-better-auth',\n] as const\n\nexport interface ClearAuthCookiesOptions {\n prefixes?: string[]\n hostname?: string\n path?: string\n cookieHeader?: string\n}\n\ninterface BrowserCookieStore {\n cookie: string\n}\n\nfunction extractCookieNames(cookieHeader: string): string[] {\n const names = new Set<string>()\n for (const rawCookie of cookieHeader.split(';')) {\n const trimmed = rawCookie.trim()\n if (!trimmed) continue\n\n const eqPos = trimmed.indexOf('=')\n const name = (eqPos > -1 ? trimmed.slice(0, eqPos) : trimmed).trim()\n if (name) {\n names.add(name)\n }\n }\n return Array.from(names)\n}\n\nfunction buildCookieDomainCandidates(hostname: string): string[] {\n const normalized = hostname.trim().replace(/\\.$/, '').toLowerCase()\n if (!normalized || isLocalHostname(normalized)) {\n return []\n }\n\n const labels = normalized.split('.').filter(Boolean)\n if (labels.length < 2) {\n return [normalized, `.${normalized}`]\n }\n\n const domains = new Set<string>()\n for (let index = 0; index <= labels.length - 2; index += 1) {\n const domain = labels.slice(index).join('.')\n domains.add(domain)\n domains.add(`.${domain}`)\n }\n return Array.from(domains)\n}\n\nfunction getCookieStore(): BrowserCookieStore | null {\n const candidate = (globalThis as { document?: BrowserCookieStore }).document\n if (!candidate || typeof candidate.cookie !== 'string') {\n return null\n }\n return candidate\n}\n\nfunction getRuntimeHostname(): string {\n const fromWindow = (\n globalThis as { window?: { location?: { hostname?: string } } }\n ).window?.location?.hostname\n if (typeof fromWindow === 'string') {\n return fromWindow\n }\n\n const fromLocation = (\n globalThis as { location?: { hostname?: string } }\n ).location?.hostname\n if (typeof fromLocation === 'string') {\n return fromLocation\n }\n\n return ''\n}\n\nfunction writeExpiredCookie(\n cookieStore: BrowserCookieStore,\n name: string,\n path: string,\n domain?: string,\n) {\n const domainClause = domain ? ` domain=${domain};` : ''\n cookieStore.cookie =\n `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; path=${path};${domainClause}`\n}\n\n/**\n * Clears Athena/Better Auth browser cookies by prefix.\n * Returns the cookie names that matched and were targeted for deletion.\n */\nexport function clearAuthCookies(options: ClearAuthCookiesOptions = {}): string[] {\n const cookieStore = getCookieStore()\n if (!cookieStore) {\n return []\n }\n\n const cookieHeader = options.cookieHeader ?? cookieStore.cookie\n if (!cookieHeader?.trim()) {\n return []\n }\n\n const prefixes = options.prefixes?.length ? options.prefixes : [...DEFAULT_AUTH_COOKIE_PREFIXES]\n const cookieNames = extractCookieNames(cookieHeader)\n const namesToClear = cookieNames.filter(name => prefixes.some(prefix => name.startsWith(prefix)))\n if (namesToClear.length === 0) {\n return []\n }\n\n const path = options.path?.trim() || '/'\n const hostname = options.hostname ?? getRuntimeHostname()\n const domainCandidates = buildCookieDomainCandidates(hostname)\n\n for (const name of namesToClear) {\n writeExpiredCookie(cookieStore, name, path)\n for (const domain of domainCandidates) {\n writeExpiredCookie(cookieStore, name, path, domain)\n }\n }\n\n return namesToClear\n}\n","export function proxyRequestHeaders(request: Request): Headers {\n const headers = new Headers(request.headers)\n const requestUrl = new URL(request.url)\n const proto = requestUrl.protocol.replace(/:$/u, '') || 'https'\n\n // Let fetch set the upstream Host header, but keep the original public app\n // origin available for auth servers that need to validate or generate links\n // for Vercel preview domains behind this proxy.\n headers.delete('host')\n headers.set('x-forwarded-host', requestUrl.host)\n headers.set('x-forwarded-proto', proto)\n headers.set('x-forwarded-origin', requestUrl.origin)\n headers.set('x-forwarded-uri', `${requestUrl.pathname}${requestUrl.search}`)\n\n if (requestUrl.port) {\n headers.set('x-forwarded-port', requestUrl.port)\n } else {\n headers.delete('x-forwarded-port')\n }\n\n return headers\n}\n","import type { AthenaCookieOptions } from './types.ts'\n\nfunction tryDecode(str: string): string {\n if (str.indexOf('%') === -1) {\n return str\n }\n try {\n return decodeURIComponent(str)\n } catch {\n return str\n }\n}\n\nexport interface CookieAttributes {\n value: string\n 'max-age'?: number\n expires?: Date\n domain?: string\n path?: string\n secure?: boolean\n httponly?: boolean\n partitioned?: boolean\n samesite?: 'strict' | 'lax' | 'none'\n [key: string]: unknown\n}\n\nexport const SECURE_COOKIE_PREFIX = '__Secure-'\nexport const HOST_COOKIE_PREFIX = '__Host-'\n\n/**\n * Remove __Secure- or __Host- prefix from cookie name.\n */\nexport function stripSecureCookiePrefix(cookieName: string): string {\n if (cookieName.startsWith(SECURE_COOKIE_PREFIX)) {\n return cookieName.slice(SECURE_COOKIE_PREFIX.length)\n }\n if (cookieName.startsWith(HOST_COOKIE_PREFIX)) {\n return cookieName.slice(HOST_COOKIE_PREFIX.length)\n }\n return cookieName\n}\n\n/**\n * Split a comma-joined `Set-Cookie` header string into individual cookies.\n */\nexport function splitSetCookieHeader(setCookie: string): string[] {\n if (!setCookie) {\n return []\n }\n\n const result: string[] = []\n let start = 0\n let i = 0\n\n while (i < setCookie.length) {\n if (setCookie[i] === ',') {\n let j = i + 1\n while (j < setCookie.length && setCookie[j] === ' ') {\n j++\n }\n while (j < setCookie.length && setCookie[j] !== '=' && setCookie[j] !== ';' && setCookie[j] !== ',') {\n j++\n }\n\n if (j < setCookie.length && setCookie[j] === '=') {\n const part = setCookie.slice(start, i).trim()\n if (part) {\n result.push(part)\n }\n start = i + 1\n while (start < setCookie.length && setCookie[start] === ' ') {\n start++\n }\n i = start\n continue\n }\n }\n i++\n }\n\n const last = setCookie.slice(start).trim()\n if (last) {\n result.push(last)\n }\n\n return result\n}\n\nexport function parseSetCookieHeader(setCookie: string): Map<string, CookieAttributes> {\n const cookies = new Map<string, CookieAttributes>()\n const cookieArray = splitSetCookieHeader(setCookie)\n\n for (const cookieString of cookieArray) {\n const parts = cookieString.split(';').map((part) => part.trim())\n const [nameValue, ...attributes] = parts\n const [name, ...valueParts] = (nameValue || '').split('=')\n if (!name) {\n continue\n }\n\n const value = unquoteCookieValue(valueParts.join('='))\n const decodedValue = tryDecode(value)\n const attrObj: CookieAttributes = { value: decodedValue }\n\n for (const attribute of attributes) {\n const [attrName, ...attrValueParts] = attribute.split('=')\n const attrValue = attrValueParts.join('=')\n const normalizedAttrName = attrName.trim().toLowerCase()\n switch (normalizedAttrName) {\n case 'max-age':\n attrObj['max-age'] = attrValue ? parseInt(attrValue.trim(), 10) : undefined\n break\n case 'expires':\n attrObj.expires = attrValue ? new Date(attrValue.trim()) : undefined\n break\n case 'domain':\n attrObj.domain = attrValue ? attrValue.trim() : undefined\n break\n case 'path':\n attrObj.path = attrValue ? attrValue.trim() : undefined\n break\n case 'secure':\n attrObj.secure = true\n break\n case 'httponly':\n attrObj.httponly = true\n break\n case 'samesite':\n attrObj.samesite = attrValue ? (attrValue.trim().toLowerCase() as 'strict' | 'lax' | 'none') : undefined\n break\n case 'partitioned':\n attrObj.partitioned = true\n break\n default:\n attrObj[normalizedAttrName] = attrValue ? attrValue.trim() : true\n break\n }\n }\n\n cookies.set(name, attrObj)\n }\n\n return cookies\n}\n\nexport function toCookieOptions(attributes: CookieAttributes): AthenaCookieOptions {\n return {\n maxAge: attributes['max-age'],\n expires: attributes.expires,\n domain: attributes.domain,\n path: attributes.path,\n secure: attributes.secure,\n httpOnly: attributes.httponly,\n sameSite: attributes.samesite,\n partitioned: attributes.partitioned,\n }\n}\n\n/**\n * Cookie-name token char set per RFC 7230 §3.2.6.\n */\nexport const cookieNameRegex = /^[\\w!#$%&'*.^`|~+-]+$/\n\nfunction unquoteCookieValue(value: string): string {\n if (value.length < 2 || !value.startsWith('\"') || !value.endsWith('\"')) {\n return value\n }\n return value.slice(1, -1)\n}\n\n/**\n * Parse a `Cookie` header into a key/value map.\n */\nexport function parseCookies(cookieHeader: string): Map<string, string> {\n const cookies = cookieHeader.split('; ')\n const cookieMap = new Map<string, string>()\n cookies.forEach((cookie) => {\n const [name, value] = cookie.split(/=(.*)/s)\n cookieMap.set(name as string, value as string)\n })\n return cookieMap\n}\n\n/**\n * Add or replace a cookie in the request `Cookie` header.\n */\nexport function setRequestCookie(headers: Headers, name: string, value: string): void {\n const cookieMap = parseCookies(headers.get('cookie') || '')\n if (cookieNameRegex.test(name)) {\n cookieMap.set(name, value)\n }\n headers.set(\n 'cookie',\n Array.from(cookieMap, ([key, currentValue]) => `${key}=${encodeURIComponent(currentValue)}`).join('; '),\n )\n}\n\n/**\n * Merge `Set-Cookie` values into a `Cookie` header.\n */\nexport function applySetCookies(target: Headers, setCookieValues: Iterable<string>): void {\n const cookieMap = parseCookies(target.get('cookie') || '')\n for (const setCookie of setCookieValues) {\n for (const [name, attr] of parseSetCookieHeader(setCookie)) {\n if (cookieNameRegex.test(name)) {\n cookieMap.set(name, attr.value)\n }\n }\n }\n target.set(\n 'cookie',\n Array.from(cookieMap, ([key, currentValue]) => `${key}=${encodeURIComponent(currentValue)}`).join('; '),\n )\n}\n\nexport function setCookieToHeader(headers: Headers) {\n return (context: { response: Response }) => {\n const setCookieHeader = context.response.headers.get('set-cookie')\n if (!setCookieHeader) {\n return\n }\n applySetCookies(headers, [setCookieHeader])\n }\n}\n","import { decodeBase64UrlToString, encodeStringToBase64Url } from './base64.ts'\r\nimport {\r\n HOST_COOKIE_PREFIX,\r\n SECURE_COOKIE_PREFIX,\r\n parseCookies,\r\n parseSetCookieHeader,\r\n setCookieToHeader,\r\n setRequestCookie,\r\n splitSetCookieHeader,\r\n stripSecureCookiePrefix,\r\n toCookieOptions,\r\n} from './cookie-utils.ts'\r\nimport { signHmacBase64Url, signJwtHS256, verifyJwtHS256 } from './crypto.ts'\r\nimport { createAccountStore, createSessionStore, getAccountCookie, getChunkedCookie } from './session-store.ts'\r\nimport type {\r\n AthenaAuthCookie,\r\n AthenaAuthCookies,\r\n AthenaCookieContextRuntime,\r\n AthenaCookieOptions,\r\n AthenaCookiesOptions,\r\n AthenaCookieVersionResolver,\r\n AthenaGetCookieCacheConfig,\r\n AthenaSessionPair,\r\n} from './types.ts'\r\n\r\nconst DEFAULT_COOKIE_PREFIX = 'athena-auth'\r\nconst LEGACY_COOKIE_PREFIX = 'better-auth'\r\nconst DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60\r\nconst DEFAULT_CACHE_MAX_AGE = 60 * 5\r\n\r\nfunction isProductionRuntime(): boolean {\r\n return typeof process !== 'undefined' && process.env?.NODE_ENV === 'production'\r\n}\r\n\r\nfunction getEnvironmentSecret(): string | undefined {\r\n if (typeof process === 'undefined') {\r\n return undefined\r\n }\r\n return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET\r\n}\r\n\r\nfunction isDynamicBaseURLConfig(baseURL: AthenaCookiesOptions['baseURL']): boolean {\r\n return (\r\n typeof baseURL === 'object' &&\r\n baseURL !== null &&\r\n 'allowedHosts' in baseURL &&\r\n Array.isArray((baseURL as { allowedHosts?: unknown }).allowedHosts)\r\n )\r\n}\r\n\r\nfunction resolveCookiePrefixes(primaryPrefix: string): string[] {\r\n const prefixes = [primaryPrefix]\r\n if (!prefixes.includes(DEFAULT_COOKIE_PREFIX)) {\r\n prefixes.push(DEFAULT_COOKIE_PREFIX)\r\n }\r\n if (!prefixes.includes(LEGACY_COOKIE_PREFIX)) {\r\n prefixes.push(LEGACY_COOKIE_PREFIX)\r\n }\r\n return prefixes\r\n}\r\n\r\nfunction createError(message: string): Error {\r\n return new Error(`@xylex-group/athena/cookies: ${message}`)\r\n}\r\n\r\nfunction getSecretOrThrow(secret?: string): string {\r\n const resolved = secret || getEnvironmentSecret()\r\n if (!resolved) {\r\n throw createError(\r\n 'getCookieCache requires a secret. Pass `secret` or set ATHENA_AUTH_SECRET/BETTER_AUTH_SECRET/AUTH_SECRET.',\r\n )\r\n }\r\n return resolved\r\n}\r\n\r\nfunction asObject(value: unknown): Record<string, unknown> | null {\r\n if (!value || typeof value !== 'object') {\r\n return null\r\n }\r\n return value as Record<string, unknown>\r\n}\r\n\r\nfunction getSessionTokenFromPair(session: AthenaSessionPair): string {\r\n const token = session.session?.token\r\n if (typeof token !== 'string' || token.length === 0) {\r\n throw createError('setSessionCookie requires `session.session.token` to be a non-empty string.')\r\n }\r\n return token\r\n}\r\n\r\nasync function resolveCookieVersion(\r\n versionConfig: AthenaCookieVersionResolver | undefined,\r\n session: Record<string, unknown>,\r\n user: Record<string, unknown>,\r\n): Promise<string> {\r\n if (!versionConfig) {\r\n return '1'\r\n }\r\n if (typeof versionConfig === 'string') {\r\n return versionConfig\r\n }\r\n return versionConfig(session, user)\r\n}\r\n\r\nfunction getSessionCookieCacheName(cookiePrefix: string, cookieName: string, isSecure: boolean): string {\r\n return isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`\r\n}\r\n\r\nasync function setCookieValue(\r\n ctx: AthenaCookieContextRuntime,\r\n name: string,\r\n value: string,\r\n attributes: AthenaCookieOptions,\r\n): Promise<void> {\r\n const secret = ctx.context.secret\r\n if (secret && typeof ctx.setSignedCookie === 'function') {\r\n await ctx.setSignedCookie(name, value, secret, attributes)\r\n return\r\n }\r\n ctx.setCookie(name, value, attributes)\r\n}\r\n\r\nfunction parseJsonSafely<T>(value: string): T | null {\r\n try {\r\n return JSON.parse(value) as T\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nfunction getIsSecureCookie(config: { isSecure?: boolean } | undefined): boolean {\r\n if (config?.isSecure !== undefined) {\r\n return config.isSecure\r\n }\r\n return isProductionRuntime()\r\n}\r\n\r\nexport function createCookieGetter(options: AthenaCookiesOptions) {\r\n const baseURLString = typeof options.baseURL === 'string' ? options.baseURL : undefined\r\n const dynamicProtocol =\r\n typeof options.baseURL === 'object' && options.baseURL !== null ? options.baseURL.protocol : undefined\r\n\r\n const secure =\r\n options.advanced?.useSecureCookies !== undefined\r\n ? options.advanced.useSecureCookies\r\n : dynamicProtocol === 'https'\r\n ? true\r\n : dynamicProtocol === 'http'\r\n ? false\r\n : baseURLString\r\n ? baseURLString.startsWith('https://')\r\n : isProductionRuntime()\r\n\r\n const secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : ''\r\n const crossSubdomainEnabled = !!options.advanced?.crossSubDomainCookies?.enabled\r\n const domain = crossSubdomainEnabled\r\n ? options.advanced?.crossSubDomainCookies?.domain || (baseURLString ? new URL(baseURLString).hostname : undefined)\r\n : undefined\r\n\r\n if (crossSubdomainEnabled && !domain && !isDynamicBaseURLConfig(options.baseURL)) {\r\n throw createError('baseURL is required when `crossSubDomainCookies.enabled` is true.')\r\n }\r\n\r\n function createCookie(cookieName: string, overrideAttributes: Partial<AthenaCookieOptions> = {}): AthenaAuthCookie {\r\n const prefix = options.advanced?.cookiePrefix || DEFAULT_COOKIE_PREFIX\r\n const name = options.advanced?.cookies?.[cookieName]?.name || `${prefix}.${cookieName}`\r\n const attributes = options.advanced?.cookies?.[cookieName]?.attributes || {}\r\n\r\n return {\r\n name: `${secureCookiePrefix}${name}`,\r\n attributes: {\r\n secure: !!secureCookiePrefix,\r\n sameSite: 'lax',\r\n path: '/',\r\n httpOnly: true,\r\n ...(crossSubdomainEnabled ? { domain } : {}),\r\n ...options.advanced?.defaultCookieAttributes,\r\n ...overrideAttributes,\r\n ...attributes,\r\n },\r\n }\r\n }\r\n\r\n return createCookie\r\n}\r\n\r\nexport function getCookies(options: AthenaCookiesOptions): AthenaAuthCookies {\r\n const createCookie = createCookieGetter(options)\r\n const sessionToken = createCookie('session_token', { maxAge: options.session?.expiresIn || DEFAULT_SESSION_MAX_AGE })\r\n const sessionData = createCookie('session_data', { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE })\r\n const accountData = createCookie('account_data', { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE })\r\n const dontRememberToken = createCookie('dont_remember')\r\n\r\n return {\r\n sessionToken: {\r\n name: sessionToken.name,\r\n attributes: sessionToken.attributes,\r\n },\r\n sessionData: {\r\n name: sessionData.name,\r\n attributes: sessionData.attributes,\r\n },\r\n dontRememberToken: {\r\n name: dontRememberToken.name,\r\n attributes: dontRememberToken.attributes,\r\n },\r\n accountData: {\r\n name: accountData.name,\r\n attributes: accountData.attributes,\r\n },\r\n }\r\n}\r\n\r\nexport async function setCookieCache(\r\n ctx: AthenaCookieContextRuntime,\r\n session: AthenaSessionPair,\r\n dontRememberMe: boolean,\r\n): Promise<void> {\r\n const cookieCacheConfig = ctx.context.options?.session?.cookieCache\r\n if (!cookieCacheConfig?.enabled) {\r\n return\r\n }\r\n\r\n const version = await resolveCookieVersion(\r\n cookieCacheConfig.version,\r\n session.session as Record<string, unknown>,\r\n session.user as Record<string, unknown>,\r\n )\r\n\r\n const sessionData = {\r\n session: session.session,\r\n user: session.user,\r\n updatedAt: Date.now(),\r\n version,\r\n }\r\n\r\n const baseAttributes = ctx.context.authCookies.sessionData.attributes\r\n const maxAge = dontRememberMe ? undefined : baseAttributes.maxAge\r\n const options: AthenaCookieOptions = {\r\n ...baseAttributes,\r\n maxAge,\r\n }\r\n const expiresAt = Date.now() + ((options.maxAge || 60) * 1000)\r\n const strategy = cookieCacheConfig.strategy || 'compact'\r\n const secret = getSecretOrThrow(ctx.context.secret)\r\n\r\n let encoded: string\r\n if (strategy === 'jwt') {\r\n encoded = await signJwtHS256(sessionData, secret, options.maxAge || DEFAULT_CACHE_MAX_AGE)\r\n } else if (strategy === 'jwe') {\r\n throw createError('`jwe` strategy is not supported by the SDK cookie helper.')\r\n } else {\r\n const signature = await signHmacBase64Url(\r\n secret,\r\n JSON.stringify({\r\n ...sessionData,\r\n expiresAt,\r\n }),\r\n )\r\n encoded = encodeStringToBase64Url(\r\n JSON.stringify({\r\n session: sessionData,\r\n expiresAt,\r\n signature,\r\n }),\r\n )\r\n }\r\n\r\n if (encoded.length > 4093) {\r\n const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx)\r\n const cookies = store.chunk(encoded, options)\r\n store.setCookies(cookies)\r\n } else {\r\n const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx)\r\n if (store.hasChunks()) {\r\n store.setCookies(store.clean())\r\n }\r\n ctx.setCookie(ctx.context.authCookies.sessionData.name, encoded, options)\r\n }\r\n}\r\n\r\nexport async function setSessionCookie(\r\n ctx: AthenaCookieContextRuntime,\r\n session: AthenaSessionPair,\r\n dontRememberMe?: boolean,\r\n overrides?: Partial<AthenaCookieOptions>,\r\n): Promise<void> {\r\n if (dontRememberMe === undefined && typeof ctx.getSignedCookie === 'function' && ctx.context.secret) {\r\n const existingFlag = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret)\r\n dontRememberMe = !!existingFlag\r\n }\r\n\r\n const resolvedDontRememberMe = dontRememberMe ?? false\r\n const token = getSessionTokenFromPair(session)\r\n const options = ctx.context.authCookies.sessionToken.attributes\r\n const maxAge = resolvedDontRememberMe ? undefined : ctx.context.sessionConfig?.expiresIn\r\n await setCookieValue(ctx, ctx.context.authCookies.sessionToken.name, token, {\r\n ...options,\r\n maxAge,\r\n ...overrides,\r\n })\r\n\r\n if (resolvedDontRememberMe) {\r\n await setCookieValue(\r\n ctx,\r\n ctx.context.authCookies.dontRememberToken.name,\r\n 'true',\r\n ctx.context.authCookies.dontRememberToken.attributes,\r\n )\r\n }\r\n\r\n await setCookieCache(ctx, session, resolvedDontRememberMe)\r\n ctx.context.setNewSession?.(session)\r\n}\r\n\r\n/**\r\n * Expires a cookie by setting `maxAge: 0` while preserving attributes.\r\n */\r\nexport function expireCookie(ctx: AthenaCookieContextRuntime, cookie: AthenaAuthCookie): void {\r\n ctx.setCookie(cookie.name, '', {\r\n ...cookie.attributes,\r\n maxAge: 0,\r\n })\r\n}\r\n\r\nexport function deleteSessionCookie(ctx: AthenaCookieContextRuntime, skipDontRememberMe?: boolean): void {\r\n expireCookie(ctx, ctx.context.authCookies.sessionToken)\r\n expireCookie(ctx, ctx.context.authCookies.sessionData)\r\n\r\n if (ctx.context.options?.account?.storeAccountCookie) {\r\n expireCookie(ctx, ctx.context.authCookies.accountData)\r\n const accountStore = createAccountStore(\r\n ctx.context.authCookies.accountData.name,\r\n ctx.context.authCookies.accountData.attributes,\r\n ctx,\r\n )\r\n accountStore.setCookies(accountStore.clean())\r\n }\r\n\r\n const sessionStore = createSessionStore(\r\n ctx.context.authCookies.sessionData.name,\r\n ctx.context.authCookies.sessionData.attributes,\r\n ctx,\r\n )\r\n sessionStore.setCookies(sessionStore.clean())\r\n\r\n if (!skipDontRememberMe) {\r\n expireCookie(ctx, ctx.context.authCookies.dontRememberToken)\r\n }\r\n}\r\n\r\nexport const getSessionCookie = (\r\n request: Request | Headers,\r\n config?:\r\n | {\r\n cookiePrefix?: string\r\n cookieName?: string\r\n path?: string\r\n }\r\n | undefined,\r\n): string | null => {\r\n const cookies = (request instanceof Headers || !('headers' in request) ? request : request.headers).get('cookie')\r\n if (!cookies) {\r\n return null\r\n }\r\n\r\n const { cookieName = 'session_token', cookiePrefix = 'athena-auth' } = config || {}\r\n const parsedCookie = parseCookies(cookies)\r\n const getCookie = (name: string): string | undefined =>\r\n parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`)\r\n const candidateCookieNames = Array.from(new Set([\r\n cookieName,\r\n cookieName.replace(/_/g, '-'),\r\n cookieName.replace(/-/g, '_'),\r\n ])).filter(Boolean)\r\n for (const candidateName of candidateCookieNames) {\r\n const sessionToken =\r\n getCookie(`${cookiePrefix}.${candidateName}`) || getCookie(`${cookiePrefix}-${candidateName}`)\r\n if (sessionToken) {\r\n return sessionToken\r\n }\r\n }\r\n return null\r\n}\r\n\r\nexport const getCookieCache = async <\r\n SessionShape extends Record<string, unknown> = Record<string, unknown>,\r\n UserShape extends Record<string, unknown> = Record<string, unknown>,\r\n>(\r\n request: Request | Headers,\r\n config?: AthenaGetCookieCacheConfig<SessionShape, UserShape>,\r\n): Promise<{\r\n session: SessionShape\r\n user: UserShape\r\n updatedAt: number\r\n version?: string\r\n} | null> => {\r\n const headers = request instanceof Headers || !('headers' in request) ? request : request.headers\r\n const cookieHeader = headers.get('cookie')\r\n if (!cookieHeader) {\r\n return null\r\n }\r\n\r\n const parsedCookie = parseCookies(cookieHeader)\r\n const cookieName = config?.cookieName || 'session_data'\r\n const requestedPrefix = config?.cookiePrefix || DEFAULT_COOKIE_PREFIX\r\n const strategy = config?.strategy || 'compact'\r\n const cookiePrefixes = resolveCookiePrefixes(requestedPrefix)\r\n const isSecure = getIsSecureCookie(config)\r\n const secret = getSecretOrThrow(config?.secret)\r\n\r\n let sessionData: string | undefined\r\n\r\n for (const prefix of cookiePrefixes) {\r\n const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure)\r\n const cookieValue = parsedCookie.get(candidate)\r\n if (cookieValue) {\r\n sessionData = cookieValue\r\n break\r\n }\r\n }\r\n\r\n if (!sessionData) {\r\n const reconstructedChunks: Array<{ index: number; value: string }> = []\r\n for (const prefix of cookiePrefixes) {\r\n const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure)\r\n for (const [name, value] of parsedCookie.entries()) {\r\n if (!name.startsWith(`${candidate}.`)) {\r\n continue\r\n }\r\n const parts = name.split('.')\r\n const indexStr = parts[parts.length - 1]\r\n const index = parseInt(indexStr || '0', 10)\r\n if (!Number.isNaN(index)) {\r\n reconstructedChunks.push({ index, value })\r\n }\r\n }\r\n if (reconstructedChunks.length > 0) {\r\n break\r\n }\r\n }\r\n\r\n if (reconstructedChunks.length > 0) {\r\n reconstructedChunks.sort((left, right) => left.index - right.index)\r\n sessionData = reconstructedChunks.map((chunk) => chunk.value).join('')\r\n }\r\n }\r\n\r\n if (!sessionData) {\r\n return null\r\n }\r\n\r\n if (strategy === 'jwe') {\r\n throw createError(\r\n '`jwe` strategy is not supported by the SDK cookie helper. Use compact/jwt or pass cookie data through the auth server.',\r\n )\r\n }\r\n\r\n if (strategy === 'jwt') {\r\n const payload = await verifyJwtHS256<Record<string, unknown>>(sessionData, secret)\r\n if (!payload) {\r\n return null\r\n }\r\n const sessionRecord = asObject(payload.session)\r\n const userRecord = asObject(payload.user)\r\n const updatedAt = payload.updatedAt\r\n if (!sessionRecord || !userRecord || typeof updatedAt !== 'number') {\r\n return null\r\n }\r\n\r\n if (config?.version) {\r\n const cookieVersion = typeof payload.version === 'string' ? payload.version : '1'\r\n const expectedVersion =\r\n typeof config.version === 'string'\r\n ? config.version\r\n : await config.version(sessionRecord as SessionShape, userRecord as UserShape)\r\n if (cookieVersion !== expectedVersion) {\r\n return null\r\n }\r\n }\r\n\r\n return {\r\n session: sessionRecord as SessionShape,\r\n user: userRecord as UserShape,\r\n updatedAt,\r\n version: typeof payload.version === 'string' ? payload.version : undefined,\r\n }\r\n }\r\n\r\n const compactPayload = parseJsonSafely<{\r\n session: {\r\n session: SessionShape\r\n user: UserShape\r\n updatedAt: number\r\n version?: string\r\n }\r\n expiresAt: number\r\n signature: string\r\n }>(decodeBase64UrlToString(sessionData))\r\n\r\n if (!compactPayload) {\r\n return null\r\n }\r\n\r\n const expectedSignature = await signHmacBase64Url(\r\n secret,\r\n JSON.stringify({\r\n ...compactPayload.session,\r\n expiresAt: compactPayload.expiresAt,\r\n }),\r\n )\r\n\r\n if (expectedSignature !== compactPayload.signature) {\r\n return null\r\n }\r\n\r\n if (compactPayload.expiresAt <= Date.now()) {\r\n return null\r\n }\r\n\r\n const resolvedSession = compactPayload.session\r\n if (config?.version) {\r\n const cookieVersion = resolvedSession.version || '1'\r\n const expectedVersion =\r\n typeof config.version === 'string'\r\n ? config.version\r\n : await config.version(resolvedSession.session, resolvedSession.user)\r\n if (cookieVersion !== expectedVersion) {\r\n return null\r\n }\r\n }\r\n\r\n const sessionObject = asObject(resolvedSession.session)\r\n const userObject = asObject(resolvedSession.user)\r\n if (!sessionObject || !userObject) {\r\n return null\r\n }\r\n\r\n return {\r\n session: sessionObject as SessionShape,\r\n user: userObject as UserShape,\r\n updatedAt: resolvedSession.updatedAt,\r\n version: resolvedSession.version,\r\n }\r\n}\r\n\r\nexport {\r\n HOST_COOKIE_PREFIX,\r\n SECURE_COOKIE_PREFIX,\r\n createSessionStore,\r\n getAccountCookie,\r\n getChunkedCookie,\r\n parseCookies,\r\n parseSetCookieHeader,\r\n setCookieToHeader,\r\n setRequestCookie,\r\n splitSetCookieHeader,\r\n stripSecureCookiePrefix,\r\n toCookieOptions,\r\n}\r\n\r\nexport type {\r\n AthenaAuthCookie,\r\n AthenaAuthCookies,\r\n AthenaCookieContextRuntime,\r\n AthenaCookieOptions,\r\n AthenaCookiesOptions,\r\n AthenaGetCookieCacheConfig,\r\n}\r\n","import { getSessionCookie } from '../cookies/index.ts'\nimport type { BackendOption } from '../gateway/types.ts'\n\nexport type AthenaRequestHeaderProfile = 'gateway' | 'auth' | 'chat' | 'storage' | 'minimal'\n\nconst NO_CACHE_HEADER_VALUE = 'no-cache'\n\nconst API_KEY_HEADER_CANDIDATES = ['x-api-key', 'apikey'] as const\nconst ATHENA_KEY_HEADER_CANDIDATES = ['X-Athena-Key', 'x-athena-key'] as const\nconst SESSION_TOKEN_HEADER_CANDIDATES = ['X-Athena-Auth-Session-Token'] as const\nconst BEARER_MIRROR_HEADER_CANDIDATES = ['X-Athena-Auth-Bearer-Token'] as const\nconst CLIENT_HEADER_CANDIDATES = ['X-Athena-Client', 'x-athena-client'] as const\nconst PG_URI_HEADER_CANDIDATES = ['x-pg-uri'] as const\nconst JDBC_URI_HEADER_CANDIDATES = ['x-athena-jdbc-url', 'x-jdbc-url'] as const\n\ninterface AthenaRequestHeaderProfileRules {\n apiKeys: boolean\n routing: boolean\n authMirror: boolean\n authBearer: boolean\n contentType?: boolean\n accept?: boolean\n stripNullsDefault?: boolean\n}\n\nconst PROFILE_RULES: Record<AthenaRequestHeaderProfile, AthenaRequestHeaderProfileRules> = {\n gateway: { apiKeys: true, routing: true, authMirror: true, authBearer: false, contentType: true, stripNullsDefault: true },\n chat: { apiKeys: true, routing: true, authMirror: true, authBearer: true, accept: true },\n storage: { apiKeys: true, routing: true, authMirror: true, authBearer: false, contentType: true },\n auth: { apiKeys: true, routing: false, authMirror: false, authBearer: true, contentType: true },\n minimal: { apiKeys: false, routing: false, authMirror: false, authBearer: false },\n}\n\nexport interface BuildAthenaRequestHeadersInput {\n profile: AthenaRequestHeaderProfile\n sdkHeaderValue: string\n apiKey?: string | null\n /** Overrides `X-Athena-Key` while leaving `apikey` / `x-api-key` on `apiKey`. */\n athenaKey?: string | null\n client?: string | null\n userId?: string | null\n organizationId?: string | null\n backend?: BackendOption\n publishEvent?: string | null\n stripNulls?: boolean\n bearerToken?: string | null\n cookie?: string | null\n sessionToken?: string | null\n pgUri?: string | null\n jdbcUrl?: string | null\n forceNoCache?: boolean\n configHeaders?: Record<string, string>\n callHeaders?: Record<string, string>\n contentType?: string | null\n accept?: string | null\n}\n\n/** Shared config/call fields consumed by gateway, chat, auth, and `client.request(...)`. */\nexport interface AthenaRequestHeaderOverrideFields {\n apiKey?: string | null\n athenaKey?: string | null\n client?: string | null\n userId?: string | null\n organizationId?: string | null\n backend?: BackendOption\n publishEvent?: string | null\n stripNulls?: boolean\n bearerToken?: string | null\n cookie?: string | null\n sessionToken?: string | null\n pgUri?: string | null\n jdbcUrl?: string | null\n forceNoCache?: boolean\n headers?: Record<string, string>\n}\n\nexport type ResolvedRequestHeaderOverrides = Omit<\n BuildAthenaRequestHeadersInput,\n 'profile' | 'sdkHeaderValue' | 'contentType' | 'accept'\n>\n\nfunction normalizeHeaderValue(value?: string | null): string | undefined {\n return value ? value : undefined\n}\n\nfunction mergeExtraHeaders(\n configHeaders?: Record<string, string>,\n callHeaders?: Record<string, string>,\n): Record<string, string> {\n return { ...(configHeaders ?? {}), ...(callHeaders ?? {}) }\n}\n\nexport function hasHeaderIgnoreCase(\n headers: Record<string, string>,\n targetKey: string,\n): boolean {\n const normalizedTargetKey = targetKey.toLowerCase()\n return Object.keys(headers).some(key => key.toLowerCase() === normalizedTargetKey)\n}\n\nexport function resolveHeaderValue(\n headers: Record<string, string>,\n candidates: readonly string[],\n): string | undefined {\n for (const candidate of candidates) {\n const direct = normalizeHeaderValue(headers[candidate])\n if (direct) return direct\n }\n\n const loweredCandidates = new Set(candidates.map(candidate => candidate.toLowerCase()))\n for (const [key, value] of Object.entries(headers)) {\n if (!loweredCandidates.has(key.toLowerCase())) {\n continue\n }\n const normalized = normalizeHeaderValue(value)\n if (normalized) return normalized\n }\n\n return undefined\n}\n\nfunction isCacheControlHeaderName(name: string): boolean {\n return name.toLowerCase() === 'cache-control'\n}\n\nfunction normalizeBearerToken(value: string): string {\n const trimmed = value.trim()\n const match = trimmed.match(/^Bearer\\s+(.+)$/i)\n return match?.[1]?.trim() ?? trimmed\n}\n\nfunction resolveBearerTokenFromAuthorizationHeader(\n headers: Record<string, string>,\n): string | undefined {\n const authorization = resolveHeaderValue(headers, ['Authorization'])\n if (!authorization) {\n return undefined\n }\n\n const token = normalizeBearerToken(authorization)\n return token ? token : undefined\n}\n\nfunction resolveSessionTokenFromCookieHeader(\n headers: Record<string, string>,\n): string | undefined {\n const cookie = resolveHeaderValue(headers, ['Cookie'])\n if (!cookie) {\n return undefined\n }\n\n return getSessionCookie(new Headers({ cookie })) ?? undefined\n}\n\nfunction resolveBackendType(backend?: BackendOption): string | undefined {\n if (!backend) {\n return undefined\n }\n return typeof backend === 'string' ? backend : backend.type\n}\n\nexport function resolveRequestHeaderOverrides(\n config: AthenaRequestHeaderOverrideFields,\n options?: AthenaRequestHeaderOverrideFields,\n defaults?: Pick<AthenaRequestHeaderOverrideFields, 'client' | 'stripNulls'>,\n): ResolvedRequestHeaderOverrides {\n return {\n apiKey: options?.apiKey ?? config.apiKey,\n athenaKey: options?.athenaKey ?? config.athenaKey,\n client: options?.client ?? config.client ?? defaults?.client,\n userId: options?.userId ?? config.userId,\n organizationId: options?.organizationId ?? config.organizationId,\n backend: options?.backend ?? config.backend,\n publishEvent: options?.publishEvent ?? config.publishEvent,\n stripNulls: options?.stripNulls ?? config.stripNulls ?? defaults?.stripNulls,\n bearerToken: options?.bearerToken ?? config.bearerToken,\n cookie: options?.cookie ?? config.cookie,\n sessionToken: options?.sessionToken ?? config.sessionToken,\n pgUri: options?.pgUri ?? config.pgUri,\n jdbcUrl: options?.jdbcUrl ?? config.jdbcUrl,\n forceNoCache: Boolean(config.forceNoCache || options?.forceNoCache),\n configHeaders: config.headers,\n callHeaders: options?.headers,\n }\n}\n\nexport function buildServiceRequestHeaders(\n profile: Exclude<AthenaRequestHeaderProfile, 'minimal'>,\n sdkHeaderValue: string,\n config: AthenaRequestHeaderOverrideFields,\n options?: AthenaRequestHeaderOverrideFields,\n extras?: Pick<BuildAthenaRequestHeadersInput, 'contentType' | 'accept'> & {\n client?: string | null\n stripNulls?: boolean\n },\n): Record<string, string> {\n const rules = PROFILE_RULES[profile]\n return buildAthenaRequestHeaders({\n profile,\n sdkHeaderValue,\n ...resolveRequestHeaderOverrides(config, options, {\n client: extras?.client ?? undefined,\n stripNulls: extras?.stripNulls ?? (rules.stripNullsDefault ? true : undefined),\n }),\n contentType: extras?.contentType ?? (rules.contentType ? 'application/json' : undefined),\n accept: extras?.accept ?? (rules.accept ? 'application/json' : undefined),\n })\n}\n\nexport function applyAthenaApiKeyHeaders(\n headers: Record<string, string>,\n apiKey?: string | null,\n athenaKey?: string | null,\n): void {\n if (apiKey) {\n if (!hasHeaderIgnoreCase(headers, 'apikey')) {\n headers.apikey = apiKey\n }\n if (!hasHeaderIgnoreCase(headers, 'x-api-key')) {\n headers['x-api-key'] = apiKey\n }\n }\n\n const resolvedAthenaKey = normalizeHeaderValue(athenaKey) ?? normalizeHeaderValue(apiKey)\n if (resolvedAthenaKey && !hasHeaderIgnoreCase(headers, 'X-Athena-Key')) {\n headers['X-Athena-Key'] = resolvedAthenaKey\n }\n}\n\nexport function applyAthenaAuthContextHeaders(\n headers: Record<string, string>,\n input: Pick<\n BuildAthenaRequestHeadersInput,\n 'bearerToken' | 'cookie' | 'sessionToken' | 'profile' | 'configHeaders' | 'callHeaders'\n >,\n): void {\n const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders)\n const rules = PROFILE_RULES[input.profile]\n const explicitCookie = normalizeHeaderValue(input.cookie)\n if (explicitCookie) {\n mergedExtraHeaders.Cookie = explicitCookie\n }\n\n const explicitSessionToken =\n normalizeHeaderValue(input.sessionToken) ??\n resolveHeaderValue(mergedExtraHeaders, SESSION_TOKEN_HEADER_CANDIDATES)\n const derivedSessionToken =\n explicitSessionToken ?? resolveSessionTokenFromCookieHeader(mergedExtraHeaders)\n const cookieFromHeaders = resolveHeaderValue(mergedExtraHeaders, ['Cookie'])\n\n if (explicitCookie && !hasHeaderIgnoreCase(headers, 'Cookie')) {\n headers.Cookie = explicitCookie\n } else if (cookieFromHeaders && !hasHeaderIgnoreCase(headers, 'Cookie')) {\n headers.Cookie = cookieFromHeaders\n }\n\n const explicitBearerToken = (() => {\n const configured = normalizeHeaderValue(input.bearerToken)\n if (configured) {\n return normalizeBearerToken(configured)\n }\n const mirrored = resolveHeaderValue(mergedExtraHeaders, BEARER_MIRROR_HEADER_CANDIDATES)\n return mirrored ? normalizeBearerToken(mirrored) : undefined\n })()\n const derivedBearerToken =\n explicitBearerToken ?? resolveBearerTokenFromAuthorizationHeader(mergedExtraHeaders)\n\n if (rules.authBearer && derivedBearerToken && !hasHeaderIgnoreCase(headers, 'Authorization')) {\n headers.Authorization = `Bearer ${derivedBearerToken}`\n }\n\n if (rules.authMirror) {\n if (derivedSessionToken && !hasHeaderIgnoreCase(headers, 'X-Athena-Auth-Session-Token')) {\n headers['X-Athena-Auth-Session-Token'] = derivedSessionToken\n }\n if (derivedBearerToken && !hasHeaderIgnoreCase(headers, 'X-Athena-Auth-Bearer-Token')) {\n headers['X-Athena-Auth-Bearer-Token'] = derivedBearerToken\n }\n } else if (derivedSessionToken && !hasHeaderIgnoreCase(headers, 'X-Athena-Auth-Session-Token')) {\n headers['X-Athena-Auth-Session-Token'] = derivedSessionToken\n }\n}\n\nexport function applyAthenaPgUriHeaders(\n headers: Record<string, string>,\n input: Pick<BuildAthenaRequestHeadersInput, 'pgUri' | 'jdbcUrl' | 'configHeaders' | 'callHeaders'>,\n): void {\n const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders)\n\n const pgUri =\n normalizeHeaderValue(input.pgUri) ??\n resolveHeaderValue(mergedExtraHeaders, PG_URI_HEADER_CANDIDATES)\n if (pgUri && !hasHeaderIgnoreCase(headers, 'x-pg-uri')) {\n headers['x-pg-uri'] = pgUri\n }\n\n const jdbcUrl =\n normalizeHeaderValue(input.jdbcUrl) ??\n resolveHeaderValue(mergedExtraHeaders, JDBC_URI_HEADER_CANDIDATES)\n if (jdbcUrl) {\n if (!hasHeaderIgnoreCase(headers, 'x-athena-jdbc-url')) {\n headers['x-athena-jdbc-url'] = jdbcUrl\n }\n if (!hasHeaderIgnoreCase(headers, 'x-jdbc-url')) {\n headers['x-jdbc-url'] = jdbcUrl\n }\n }\n}\n\nexport function buildAthenaRequestHeaders(\n input: BuildAthenaRequestHeadersInput,\n): Record<string, string> {\n const forceNoCache = Boolean(input.forceNoCache)\n const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders)\n const rules = PROFILE_RULES[input.profile]\n\n const headerClient = resolveHeaderValue(mergedExtraHeaders, CLIENT_HEADER_CANDIDATES)\n const finalClient = normalizeHeaderValue(input.client) ?? headerClient\n const finalApiKey =\n normalizeHeaderValue(input.apiKey) ??\n resolveHeaderValue(mergedExtraHeaders, API_KEY_HEADER_CANDIDATES)\n const finalAthenaKey =\n normalizeHeaderValue(input.athenaKey) ??\n resolveHeaderValue(mergedExtraHeaders, ATHENA_KEY_HEADER_CANDIDATES) ??\n finalApiKey\n\n const headers: Record<string, string> = {\n 'X-Athena-Sdk': input.sdkHeaderValue,\n }\n\n if (rules.contentType) {\n headers['Content-Type'] = input.contentType ?? 'application/json'\n }\n\n if (input.accept ?? rules.accept) {\n headers.Accept = input.accept ?? 'application/json'\n }\n\n if (rules.routing) {\n if (normalizeHeaderValue(input.userId)) {\n headers['X-User-Id'] = input.userId ?? ''\n }\n if (normalizeHeaderValue(input.organizationId)) {\n headers['X-Organization-Id'] = input.organizationId ?? ''\n }\n if (finalClient) {\n headers['X-Athena-Client'] = finalClient\n }\n\n const backendType = resolveBackendType(input.backend)\n if (backendType) {\n headers['X-Backend-Type'] = backendType\n }\n\n if (typeof input.stripNulls === 'boolean') {\n headers['X-Strip-Nulls'] = input.stripNulls ? 'true' : 'false'\n } else if (rules.stripNullsDefault) {\n headers['X-Strip-Nulls'] = 'true'\n }\n\n if (normalizeHeaderValue(input.publishEvent)) {\n headers['X-Publish-Event'] = input.publishEvent ?? ''\n }\n }\n\n if (rules.apiKeys && (finalApiKey || finalAthenaKey)) {\n applyAthenaApiKeyHeaders(headers, finalApiKey, finalAthenaKey)\n }\n\n applyAthenaAuthContextHeaders(headers, input)\n applyAthenaPgUriHeaders(headers, input)\n\n const reservedClientHeaderKeys = new Set(CLIENT_HEADER_CANDIDATES.map(key => key.toLowerCase()))\n Object.entries(mergedExtraHeaders).forEach(([key, value]) => {\n if (reservedClientHeaderKeys.has(key.toLowerCase())) {\n return\n }\n if (forceNoCache && isCacheControlHeaderName(key)) {\n return\n }\n const normalized = normalizeHeaderValue(value)\n if (normalized) {\n headers[key] = normalized\n }\n })\n\n if (forceNoCache) {\n headers['Cache-Control'] = NO_CACHE_HEADER_VALUE\n }\n\n return headers\n}","interface CryptoLike {\n getRandomValues<T extends ArrayBufferView | null>(array: T): T\n}\n\nfunction getRandomBytes(size: number): Uint8Array {\n const bytes = new Uint8Array(size)\n const cryptoApi = (globalThis as { crypto?: CryptoLike }).crypto\n if (cryptoApi?.getRandomValues) {\n return cryptoApi.getRandomValues(bytes)\n }\n\n for (let index = 0; index < bytes.length; index += 1) {\n bytes[index] = Math.floor(Math.random() * 256)\n }\n return bytes\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, value => value.toString(16).padStart(2, '0')).join('')\n}\n\nfunction createDollarQuoteTag(value: string): string {\n let tag = `s${bytesToHex(getRandomBytes(6))}`\n while (value.includes(`$${tag}$`)) {\n tag = `${tag}_`\n }\n return tag\n}\n\n/**\n * Wraps a string in a PostgreSQL dollar-quoted literal.\n *\n * Use this for SQL values, not identifiers. Pair with `identifier(...)`\n * for table/column names.\n */\nexport function sqlText(value: string): string {\n const tag = createDollarQuoteTag(value)\n return `$${tag}$${value}$${tag}$`\n}\n\n/**\n * Escapes `%`, `_`, and `\\` for SQL `LIKE` / `ILIKE` patterns.\n */\nexport function escapeLikePatternValue(value: string): string {\n return value\n .replaceAll('\\\\', '\\\\\\\\')\n .replaceAll('%', '\\\\%')\n .replaceAll('_', '\\\\_')\n}\n\n/**\n * Wraps a string in a single-quoted SQL string literal.\n *\n * Prefer `sqlText(...)` for arbitrary raw SQL values when possible.\n */\nexport function quoteSqlStringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`\n}\n\n/**\n * Returns a dollar-quoted literal for strings, or the SQL keyword `NULL`\n * for nullish values.\n */\nexport function sqlNullableText(value: string | null | undefined): string {\n if (value == null) return 'NULL'\n return sqlText(value)\n}\n\n/**\n * Serializes a value and casts the result to `jsonb`.\n */\nexport function sqlJsonbLiteral(value: unknown): string {\n return `${sqlText(JSON.stringify(value ?? null))}::jsonb`\n}\n\n/**\n * Renders an explicit `bigint` SQL literal.\n */\nexport function sqlBigInt(value: bigint | number): string {\n return `${BigInt(value).toString()}::bigint`\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/slugify.ts","../src/utils/trim-trailing-slashes.ts","../src/utils/coercions.ts","../src/utils/parse-boolean-flag.ts","../src/utils/require-env.ts","../src/utils/hostname.ts","../src/utils/request-origin.ts","../src/utils/auth-cookies.ts","../src/cookies/session-cookie-detection.ts","../src/utils/athena-auth-url.ts","../src/utils/auth-routes.ts","../src/utils/proxy-request-headers.ts","../src/cookies/cookie-utils.ts","../src/cookies/index.ts","../src/utils/athena-request-headers.ts","../src/utils/sql-literals.ts"],"names":["readProcessEnv"],"mappings":"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","file":"utils.cjs","sourcesContent":["export function slugify(input: string): string {\n return input\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64)\n}\n","export function trimTrailingSlashes(value: string): string {\n return value.replace(/\\/+$/, '')\n}\n","const BOOLEAN_TRUE_TOKENS = new Set(['true', '1', 'yes', 'y', 'on'])\nconst BOOLEAN_FALSE_TOKENS = new Set(['false', '0', 'no', 'n', 'off'])\n\nfunction parseBooleanToken(value: string): boolean | null {\n const normalized = value.trim().toLowerCase()\n if (BOOLEAN_TRUE_TOKENS.has(normalized)) return true\n if (BOOLEAN_FALSE_TOKENS.has(normalized)) return false\n return null\n}\n\nexport function asString(value: unknown): string | null {\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n if (typeof value === 'bigint') return value.toString()\n if (typeof value !== 'string') return null\n\n const normalized = value.trim()\n return normalized.length > 0 ? normalized : null\n}\n\nexport function asBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value\n if (typeof value === 'number') return value !== 0\n if (typeof value === 'string') {\n return parseBooleanToken(value) ?? false\n }\n\n return false\n}\n\nexport function asBooleanOrNull(value: unknown): boolean | null {\n if (typeof value === 'boolean') return value\n if (typeof value === 'number') return value !== 0\n if (typeof value === 'string') {\n return parseBooleanToken(value)\n }\n\n return null\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n return value as Record<string, unknown>\n}\n\nexport function asIdentifier(value: unknown): string | null {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return String(value)\n }\n if (typeof value === 'bigint') {\n return value.toString()\n }\n return asString(value)\n}\n\nexport function firstString(\n record: Record<string, unknown> | null | undefined,\n keys: readonly string[],\n): string | null {\n if (!record) return null\n for (const key of keys) {\n const value = asString(record[key])\n if (value) return value\n }\n return null\n}\n\nexport function readTrimmedString(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : null\n}\n\n/**\n * Trim a string value; return `undefined` when not a non-empty string.\n *\n * Unlike {@link asString}, does not coerce numbers/bigints.\n * Unlike {@link readTrimmedString}, returns `undefined` instead of `null`\n * (handy for optional fields and `??` defaults).\n */\nexport function asNonEmptyString(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined\n }\n\n const normalized = value.trim()\n return normalized.length > 0 ? normalized : undefined\n}\n\nexport function asNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value)\n if (Number.isFinite(parsed)) return parsed\n }\n return null\n}\n\nexport function asStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n return value\n .map(entry => (typeof entry === 'string' ? entry.trim() : ''))\n .filter(entry => entry.length > 0)\n}\n","export function parseBooleanFlag(\n rawValue: string | undefined,\n fallback: boolean,\n): boolean {\n if (!rawValue) return fallback\n\n const normalized = rawValue.trim().toLowerCase()\n\n if (\n normalized === '1' ||\n normalized === 'true' ||\n normalized === 'yes' ||\n normalized === 'on'\n ) {\n return true\n }\n\n if (\n normalized === '0' ||\n normalized === 'false' ||\n normalized === 'no' ||\n normalized === 'off'\n ) {\n return false\n }\n\n return fallback\n}\n","import type { EnvLike } from './athena-auth-url.ts'\n\n/**\n * Read the first non-empty trimmed environment variable from a name list.\n *\n * @param names - Candidate env keys in priority order\n * @param env - Optional env map (defaults to `process.env`)\n * @returns Trimmed value of the first key that is set and non-empty\n * @throws {Error} When none of the keys yield a non-empty value\n *\n * @example\n * ```ts\n * import { requireEnv } from \"@xylex-group/athena/utils\"\n *\n * const authUrl = requireEnv([\n * \"ATHENA_AUTH_UPSTREAM_URL\",\n * \"ATHENA_AUTH_URL\",\n * \"NEXT_PUBLIC_ATHENA_AUTH_URL\",\n * ])\n * ```\n */\nexport function requireEnv(\n names: readonly string[],\n env?: EnvLike,\n): string {\n if (!names.length) {\n throw new Error(\n 'requireEnv() requires at least one environment variable name.',\n )\n }\n\n const source = env ?? readProcessEnv()\n for (const name of names) {\n const value = source[name]?.trim()\n if (value) {\n return value\n }\n }\n\n throw new Error(\n `Missing required environment variable. Expected one of: ${names.join(', ')}`,\n )\n}\n\n/**\n * Like {@link requireEnv}, but returns `undefined` instead of throwing when\n * none of the keys are set.\n */\nexport function readEnv(\n names: readonly string[],\n env?: EnvLike,\n): string | undefined {\n if (!names.length) {\n return undefined\n }\n\n const source = env ?? readProcessEnv()\n for (const name of names) {\n const value = source[name]?.trim()\n if (value) {\n return value\n }\n }\n return undefined\n}\n\nfunction readProcessEnv(): EnvLike {\n try {\n const processEnv = (\n globalThis as { process?: { env?: EnvLike } }\n ).process?.env\n return processEnv ?? {}\n } catch {\n return {}\n }\n}\n","const LOCAL_IPV4_PATTERN = /^127(?:\\.\\d{1,3}){3}$/\n\nexport function isLocalHostname(hostname: string): boolean {\n const normalized = hostname.trim().replace(/\\.$/, '').toLowerCase()\n if (!normalized) {\n return false\n }\n\n if (normalized === 'localhost' || normalized.endsWith('.localhost')) {\n return true\n }\n\n if (\n normalized === '127.0.0.1' ||\n LOCAL_IPV4_PATTERN.test(normalized) ||\n normalized === '::1' ||\n normalized === '[::1]' ||\n normalized === '0:0:0:0:0:0:0:1'\n ) {\n return true\n }\n\n return false\n}\n","/**\n * Request header / Next.js helpers used by middleware and RSC session loaders.\n * Framework-agnostic (no Next imports).\n */\n\n/**\n * True when Next.js threw because the route used dynamic APIs during static\n * generation (`DYNAMIC_SERVER_USAGE` digest or matching message).\n *\n * Catch and rethrow (or handle) so Next can mark the route dynamic.\n */\nexport function isDynamicServerUsageError(error: unknown): boolean {\n if (!error || typeof error !== 'object') {\n return false\n }\n\n const err = error as { digest?: unknown; message?: unknown }\n if (err.digest === 'DYNAMIC_SERVER_USAGE') {\n return true\n }\n\n return (\n typeof err.message === 'string' && err.message.includes('Dynamic server usage:')\n )\n}\n\nexport interface GetOriginFromHeadersOptions {\n /**\n * When `x-forwarded-proto` / scheme is missing, use `http` if true else `https`.\n * Typical: `process.env.NODE_ENV !== \"production\"`.\n */\n preferHttpWhenMissingProto?: boolean\n}\n\n/**\n * Reconstruct public origin from request headers (Origin, or Host + proto).\n *\n * Prefers `Origin`, then `x-forwarded-host` / `host` with\n * `x-forwarded-proto` (first value when comma-separated).\n */\nexport function getOriginFromHeaders(\n headersList: {\n get: (name: string) => string | null\n },\n options: GetOriginFromHeadersOptions = {},\n): string | null {\n const origin = headersList.get('origin')?.trim()\n if (origin) {\n return origin\n }\n\n const hostRaw =\n headersList.get('x-forwarded-host') ?? headersList.get('host')\n const host = hostRaw?.split(',')[0]?.trim()\n if (!host) {\n return null\n }\n\n const protoRaw = headersList.get('x-forwarded-proto')\n const protoFirst = protoRaw?.split(',')[0]?.trim().toLowerCase()\n const proto =\n protoFirst === 'http' || protoFirst === 'https'\n ? protoFirst\n : options.preferHttpWhenMissingProto\n ? 'http'\n : 'https'\n\n return `${proto}://${host}`\n}\n","import { isLocalHostname } from './hostname.ts'\n\n/**\n * Cookie name prefixes treated as Athena Auth / Better Auth session material.\n *\n * Used by {@link clearAuthCookies} when matching `document.cookie` names\n * (including `__Secure-` prefixed variants).\n *\n * | Prefix | Typical cookies |\n * |--------|-----------------|\n * | `athena-auth` | `athena-auth.session_token`, `athena-auth.session-token`, chunked `session_data.*` |\n * | `__Secure-athena-auth` | HTTPS-prefixed Athena cookies |\n * | `better-auth` | Legacy Better Auth session cookies |\n * | `__Secure-better-auth` | HTTPS-prefixed Better Auth cookies |\n *\n * @see {@link clearAuthCookies}\n * @see docs/auth-cookies.md\n */\nexport const ATHENA_AUTH_COOKIE_PREFIXES = [\n 'athena-auth',\n '__Secure-athena-auth',\n 'better-auth',\n '__Secure-better-auth',\n] as const\n\n/** @deprecated Prefer {@link ATHENA_AUTH_COOKIE_PREFIXES}. */\nexport const DEFAULT_AUTH_COOKIE_PREFIXES = ATHENA_AUTH_COOKIE_PREFIXES\n\nexport interface ClearAuthCookiesOptions {\n /**\n * Name prefixes to clear. Defaults to {@link ATHENA_AUTH_COOKIE_PREFIXES}.\n */\n prefixes?: string[]\n /**\n * Hostname used to build domain candidates (host + parent domains).\n * Defaults to `window.location.hostname` when available.\n */\n hostname?: string\n /**\n * Cookie path attribute when expiring cookies.\n * @default `/`\n */\n path?: string\n /**\n * Override cookie header to scan (tests). Defaults to `document.cookie`.\n */\n cookieHeader?: string\n}\n\ninterface BrowserCookieStore {\n cookie: string\n}\n\nfunction extractCookieNames(cookieHeader: string): string[] {\n const names = new Set<string>()\n for (const rawCookie of cookieHeader.split(';')) {\n const trimmed = rawCookie.trim()\n if (!trimmed) continue\n\n const eqPos = trimmed.indexOf('=')\n const name = (eqPos > -1 ? trimmed.slice(0, eqPos) : trimmed).trim()\n if (name) {\n names.add(name)\n }\n }\n return Array.from(names)\n}\n\nfunction buildCookieDomainCandidates(hostname: string): string[] {\n const normalized = hostname.trim().replace(/\\.$/, '').toLowerCase()\n if (!normalized || isLocalHostname(normalized)) {\n return []\n }\n\n const labels = normalized.split('.').filter(Boolean)\n if (labels.length < 2) {\n return [normalized, `.${normalized}`]\n }\n\n const domains = new Set<string>()\n for (let index = 0; index <= labels.length - 2; index += 1) {\n const domain = labels.slice(index).join('.')\n domains.add(domain)\n domains.add(`.${domain}`)\n }\n return Array.from(domains)\n}\n\nfunction getCookieStore(): BrowserCookieStore | null {\n const candidate = (globalThis as { document?: BrowserCookieStore }).document\n if (!candidate || typeof candidate.cookie !== 'string') {\n return null\n }\n return candidate\n}\n\nfunction getRuntimeHostname(): string {\n const fromWindow = (\n globalThis as { window?: { location?: { hostname?: string } } }\n ).window?.location?.hostname\n if (typeof fromWindow === 'string') {\n return fromWindow\n }\n\n const fromLocation = (\n globalThis as { location?: { hostname?: string } }\n ).location?.hostname\n if (typeof fromLocation === 'string') {\n return fromLocation\n }\n\n return ''\n}\n\nfunction writeExpiredCookie(\n cookieStore: BrowserCookieStore,\n name: string,\n path: string,\n domain?: string,\n) {\n const domainClause = domain ? ` domain=${domain};` : ''\n cookieStore.cookie =\n `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; path=${path};${domainClause}`\n}\n\n/**\n * Clears Athena Auth / Better Auth browser cookies by name prefix.\n *\n * Safe to call from server/SSR: returns `[]` when `document` is unavailable.\n * Prefer this over local copies of cookie-clearing loops in app `signOut`\n * helpers.\n *\n * Compared to a minimal `document.cookie = …; path=/` wipe, this helper also:\n * - expires with `Max-Age=0`\n * - tries host + parent domain attributes (for subdomain deployments)\n * - skips domain attributes on localhost / local hostnames\n *\n * For the **app-host bridge** httpOnly cookie written by\n * `createAthenaAuthSessionBridgeHandlers`, also call\n * `clearAthenaAuthSessionOnAppHost()` from `@xylex-group/athena/next/client`\n * (that cookie is not always visible to `document.cookie`).\n *\n * @param options - Optional prefixes, hostname, path, or cookie header override\n * @returns Cookie names that matched and were targeted for deletion\n *\n * @example\n * ```ts\n * import { clearAuthCookies } from \"@xylex-group/athena/utils\"\n *\n * export async function signOut(options?: { redirect?: boolean }) {\n * try {\n * await authClient.signOut({ fetchOptions: { throw: true } })\n * } catch (error) {\n * console.error(\"[auth] Sign out failed:\", error)\n * } finally {\n * clearAuthCookies()\n * if (options?.redirect !== false && typeof window !== \"undefined\") {\n * window.location.href = \"/sign-in\"\n * }\n * }\n * }\n * ```\n */\nexport function clearAuthCookies(options: ClearAuthCookiesOptions = {}): string[] {\n const cookieStore = getCookieStore()\n if (!cookieStore) {\n return []\n }\n\n const cookieHeader = options.cookieHeader ?? cookieStore.cookie\n if (!cookieHeader?.trim()) {\n return []\n }\n\n const prefixes = options.prefixes?.length\n ? options.prefixes\n : [...ATHENA_AUTH_COOKIE_PREFIXES]\n const cookieNames = extractCookieNames(cookieHeader)\n const namesToClear = cookieNames.filter((name) =>\n prefixes.some((prefix) => name.startsWith(prefix)),\n )\n if (namesToClear.length === 0) {\n return []\n }\n\n const path = options.path?.trim() || '/'\n const hostname = options.hostname ?? getRuntimeHostname()\n const domainCandidates = buildCookieDomainCandidates(hostname)\n\n for (const name of namesToClear) {\n writeExpiredCookie(cookieStore, name, path)\n for (const domain of domainCandidates) {\n writeExpiredCookie(cookieStore, name, path, domain)\n }\n }\n\n return namesToClear\n}\n","/**\n * Cookie-header detection for Athena Auth / Better Auth session cookies.\n *\n * Used by Next.js middleware and edge guards to decide whether a request\n * already carries a session token **without** parsing the full cookie map.\n */\n\n/**\n * Patterns that match a non-empty session token cookie assignment in a raw\n * `Cookie` request header.\n *\n * Covers:\n * - Better Auth: `better-auth.session_token`, `better-auth-session_token`\n * - Athena Auth (hyphen form): `athena-auth.session-token`, `athena-auth-session-token`\n * - Athena Auth (underscore form / default cookie helper): `athena-auth.session_token`,\n * `athena-auth-session_token`\n * - Optional `__Secure-` prefix (HTTPS cookie prefixing)\n *\n * Each pattern requires a leading start-of-string or `; ` boundary and a\n * trailing `=` so bare name fragments do not false-positive.\n */\nexport const SESSION_COOKIE_PATTERNS = [\n /(?:^|;\\s*)(?:__Secure-)?better-auth\\.session_token=/,\n /(?:^|;\\s*)(?:__Secure-)?better-auth-session_token=/,\n /(?:^|;\\s*)(?:__Secure-)?athena-auth\\.session-token=/,\n /(?:^|;\\s*)(?:__Secure-)?athena-auth-session-token=/,\n /(?:^|;\\s*)(?:__Secure-)?athena-auth\\.session_token=/,\n /(?:^|;\\s*)(?:__Secure-)?athena-auth-session_token=/,\n] as const\n\n/**\n * Returns whether a raw `Cookie` header appears to include an auth session\n * token cookie (Athena Auth or Better Auth naming).\n *\n * This is a **presence** check only — it does not validate the token value,\n * signature, or expiry. Prefer {@link getSessionCookie} when you need the\n * actual token string.\n *\n * @param cookieHeader - Value of the `Cookie` request header, or `null`/`undefined`\n * @returns `true` if any {@link SESSION_COOKIE_PATTERNS} matches\n *\n * @example\n * ```ts\n * import { hasAuthSessionCookie } from '@xylex-group/athena/cookies'\n *\n * export function middleware(request: Request) {\n * if (!hasAuthSessionCookie(request.headers.get('cookie'))) {\n * return Response.redirect(new URL('/sign-in', request.url))\n * }\n * }\n * ```\n */\nexport function hasAuthSessionCookie(\n cookieHeader: string | null | undefined,\n): boolean {\n if (!cookieHeader) {\n return false\n }\n\n return SESSION_COOKIE_PATTERNS.some((pattern) => pattern.test(cookieHeader))\n}\n","/**\n * Resolve Athena Auth base / upstream URLs from env or explicit config.\n *\n * Mirrors the Athena Auth UI base-url contract so apps and the SDK share one\n * precedence order for `ATHENA_AUTH_*` environment variables.\n */\n\n/** Default browser/proxy path for same-origin auth routing. */\nexport const ATHENA_AUTH_PATH = '/api/auth'\n\n/** Fallback origin when no absolute upstream is configured (server-side). */\nexport const LOCAL_DEV_ORIGIN = 'http://localhost:3000'\n\n/**\n * Hosted Athena Auth origin used when no upstream override is supplied.\n * Origin only — no `/api/auth` suffix.\n */\nexport const DEFAULT_ATHENA_AUTH_ORIGIN = 'https://auth.athena-auth.com'\n\n/**\n * @deprecated Prefer {@link DEFAULT_ATHENA_AUTH_ORIGIN}.\n * Kept for callers that used the older name.\n */\nexport const DEFAULT_ATHENA_AUTH_UPSTREAM_URL = DEFAULT_ATHENA_AUTH_ORIGIN\n\n/**\n * Environment keys checked (in order) for the Athena Auth upstream URL.\n *\n * Prefer server-only keys first so private upstream hosts are not forced to\n * rely on `NEXT_PUBLIC_*` values.\n */\nexport const ATHENA_AUTH_UPSTREAM_ENV_KEYS = [\n 'ATHENA_AUTH_UPSTREAM_URL',\n 'ATHENA_AUTH_URL',\n 'NEXT_PUBLIC_ATHENA_AUTH_UPSTREAM_URL',\n 'NEXT_PUBLIC_ATHENA_AUTH_URL',\n] as const\n\n/**\n * Auth UI naming parity (`base-url.ts`).\n * Same ordered list as {@link ATHENA_AUTH_UPSTREAM_ENV_KEYS}.\n */\nexport const ATHENA_AUTH_UPSTREAM_URL_ENV_NAMES = ATHENA_AUTH_UPSTREAM_ENV_KEYS\n\nexport type AthenaAuthUpstreamEnvKey =\n (typeof ATHENA_AUTH_UPSTREAM_ENV_KEYS)[number]\n\n/** Loose env map (Node `process.env` or a test fixture). */\nexport type EnvLike = Record<string, string | undefined>\n\nexport type AthenaAuthUpstreamEnv = Partial<\n Record<AthenaAuthUpstreamEnvKey, string | undefined>\n> &\n EnvLike\n\nexport interface AthenaAuthClientBaseUrlOptions {\n /**\n * When `true` (default), ensure the client base ends with `/api/auth`.\n * Set `false` when the auth server is mounted at a custom path or root.\n */\n appendAuthPath?: boolean\n}\n\nconst LEADING_SLASHES_REGEX = /^\\/+/\n\nfunction stripTrailingSlashes(value: string): string {\n return value.replace(/\\/+$/g, '')\n}\n\nfunction ensureLeadingSlash(value: string): string {\n return value.startsWith('/') ? value : `/${value}`\n}\n\nfunction ensureAthenaAuthPath(pathname: string): string {\n const normalizedPath = stripTrailingSlashes(\n ensureLeadingSlash(pathname.trim()),\n )\n\n if (!normalizedPath || normalizedPath === '/') {\n return ATHENA_AUTH_PATH\n }\n\n if (normalizedPath.endsWith(ATHENA_AUTH_PATH)) {\n return normalizedPath\n }\n\n return `${normalizedPath}${ATHENA_AUTH_PATH}`\n}\n\nfunction stripAthenaAuthPath(pathname: string): string {\n const normalizedPath = stripTrailingSlashes(\n ensureLeadingSlash(pathname.trim()),\n )\n\n if (!normalizedPath || normalizedPath === '/') {\n return '/'\n }\n\n if (normalizedPath === ATHENA_AUTH_PATH) {\n return '/'\n }\n\n if (normalizedPath.endsWith(ATHENA_AUTH_PATH)) {\n const withoutAuthPath = normalizedPath.slice(0, -ATHENA_AUTH_PATH.length)\n return withoutAuthPath ? ensureLeadingSlash(withoutAuthPath) : '/'\n }\n\n return normalizedPath\n}\n\nfunction readProcessEnv(): EnvLike | undefined {\n try {\n const maybeProcess = (\n globalThis as { process?: { env?: EnvLike } }\n ).process\n return maybeProcess?.env\n } catch {\n return undefined\n }\n}\n\nfunction getBrowserOrigin(): string | undefined {\n try {\n const origin = (\n globalThis as { window?: { location?: { origin?: string } } }\n ).window?.location?.origin\n return typeof origin === 'string' && origin.length > 0 ? origin : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Returns `true` when the value is an absolute `http://` or `https://` URL.\n */\nexport function isAbsoluteUrl(value: string): boolean {\n const trimmed = value.trim()\n return trimmed.startsWith('http://') || trimmed.startsWith('https://')\n}\n\n/**\n * Read the first non-empty Athena Auth upstream URL from an env-like map.\n *\n * @returns Trimmed URL string, or `undefined` when none of the keys are set\n */\nexport function readAthenaAuthUpstreamUrlFromEnv(\n env: EnvLike,\n): string | undefined {\n for (const key of ATHENA_AUTH_UPSTREAM_ENV_KEYS) {\n const value = env[key]?.trim()\n if (value) {\n return value\n }\n }\n return undefined\n}\n\nfunction resolveConfiguredAthenaAuthUpstreamUrl(\n rawUpstreamUrl?: string | AthenaAuthUpstreamEnv,\n): string | undefined {\n if (typeof rawUpstreamUrl === 'string') {\n const trimmed = rawUpstreamUrl.trim()\n return trimmed || undefined\n }\n\n if (rawUpstreamUrl) {\n return readAthenaAuthUpstreamUrlFromEnv(rawUpstreamUrl)\n }\n\n const processEnv = readProcessEnv()\n return processEnv ? readAthenaAuthUpstreamUrlFromEnv(processEnv) : undefined\n}\n\n/**\n * Normalize a consumer-supplied auth base URL so it targets `/api/auth`\n * (unless the path already ends with that segment).\n *\n * Absolute URLs keep origin and rewrite pathname; relative paths are ensured\n * to end with `/api/auth`.\n *\n * @example\n * ```ts\n * normalizeAthenaAuthBaseUrl('https://auth.example.com')\n * // => 'https://auth.example.com/api/auth'\n *\n * normalizeAthenaAuthBaseUrl('/api/auth')\n * // => '/api/auth'\n * ```\n */\nexport function normalizeAthenaAuthBaseUrl(urlOrPath: string): string {\n const trimmed = urlOrPath.trim()\n\n if (!trimmed) {\n return ATHENA_AUTH_PATH\n }\n\n if (isAbsoluteUrl(trimmed)) {\n const url = new URL(trimmed)\n url.pathname = ensureAthenaAuthPath(url.pathname)\n url.search = ''\n url.hash = ''\n return stripTrailingSlashes(url.toString())\n }\n\n return ensureAthenaAuthPath(trimmed)\n}\n\n/**\n * Resolve the **server-side** Athena Auth upstream origin (no `/api/auth` suffix).\n *\n * Used when proxying or calling the auth host directly from Node / edge.\n *\n * @param rawUpstreamUrl - Explicit URL, env map, or omit to read `process.env`\n * @returns Origin like `https://auth.example.com` (no trailing slash)\n */\nexport function resolveAthenaAuthUpstreamUrl(\n rawUpstreamUrl?: string | AthenaAuthUpstreamEnv,\n): string {\n const configuredUpstream =\n resolveConfiguredAthenaAuthUpstreamUrl(rawUpstreamUrl) ||\n DEFAULT_ATHENA_AUTH_ORIGIN\n\n if (isAbsoluteUrl(configuredUpstream)) {\n const upstreamUrl = new URL(configuredUpstream)\n upstreamUrl.pathname = stripAthenaAuthPath(upstreamUrl.pathname)\n upstreamUrl.search = ''\n upstreamUrl.hash = ''\n return stripTrailingSlashes(upstreamUrl.toString())\n }\n\n const normalizedPath = stripAthenaAuthPath(configuredUpstream)\n return stripTrailingSlashes(\n new URL(normalizedPath, LOCAL_DEV_ORIGIN).toString(),\n )\n}\n\nfunction resolveBrowserFacingOrigin(\n rawUpstreamUrl?: string | AthenaAuthUpstreamEnv,\n): string {\n if (resolveConfiguredAthenaAuthUpstreamUrl(rawUpstreamUrl)) {\n return `${resolveAthenaAuthUpstreamUrl(rawUpstreamUrl)}/`\n }\n\n const browserOrigin = getBrowserOrigin()\n if (browserOrigin) {\n return `${browserOrigin}/`\n }\n\n return `${LOCAL_DEV_ORIGIN}/`\n}\n\nfunction resolvePreservedAthenaAuthBaseUrl(\n configuredAuthBaseUrl: string,\n rawUpstreamUrl?: string | AthenaAuthUpstreamEnv,\n): string {\n const trimmed = configuredAuthBaseUrl.trim()\n const preservedConfiguredBaseUrl = trimmed || ATHENA_AUTH_PATH\n\n if (isAbsoluteUrl(preservedConfiguredBaseUrl)) {\n return stripTrailingSlashes(preservedConfiguredBaseUrl)\n }\n\n return stripTrailingSlashes(\n new URL(\n ensureLeadingSlash(preservedConfiguredBaseUrl),\n resolveBrowserFacingOrigin(rawUpstreamUrl),\n ).toString(),\n )\n}\n\n/**\n * Resolve the **browser-facing** auth client base URL.\n *\n * Default behavior appends `/api/auth` for same-origin proxying. Pass\n * `{ appendAuthPath: false }` to keep a custom path or root mount.\n *\n * Overloads match common call styles from Athena Auth UI and app code:\n * - `resolveAthenaAuthClientBaseUrl(\"https://auth.example.com\")`\n * - `resolveAthenaAuthClientBaseUrl(process.env)`\n * - `resolveAthenaAuthClientBaseUrl(undefined)` → env + defaults\n * - `resolveAthenaAuthClientBaseUrl(path, upstream, { appendAuthPath: false })`\n */\nexport function resolveAthenaAuthClientBaseUrl(\n configuredAuthBaseUrl?: string | EnvLike,\n rawUpstreamUrl?: string | AthenaAuthUpstreamEnv,\n options?: AthenaAuthClientBaseUrlOptions,\n): string\nexport function resolveAthenaAuthClientBaseUrl(\n configuredAuthBaseUrl: string,\n rawUpstreamUrl?: string | AthenaAuthUpstreamEnv,\n options?: AthenaAuthClientBaseUrlOptions,\n): string\nexport function resolveAthenaAuthClientBaseUrl(\n configuredAuthBaseUrl?: string | EnvLike,\n rawUpstreamUrl?: string | AthenaAuthUpstreamEnv,\n options: AthenaAuthClientBaseUrlOptions = {},\n): string {\n let baseInput: string\n\n if (typeof configuredAuthBaseUrl === 'string') {\n baseInput = configuredAuthBaseUrl\n } else if (configuredAuthBaseUrl) {\n baseInput =\n readAthenaAuthUpstreamUrlFromEnv(configuredAuthBaseUrl) ??\n ATHENA_AUTH_PATH\n } else {\n const fromEnv = resolveConfiguredAthenaAuthUpstreamUrl(rawUpstreamUrl)\n baseInput = fromEnv ?? ATHENA_AUTH_PATH\n }\n\n if (options.appendAuthPath === false) {\n return resolvePreservedAthenaAuthBaseUrl(baseInput, rawUpstreamUrl)\n }\n\n const normalizedConfiguredBaseUrl = normalizeAthenaAuthBaseUrl(baseInput)\n\n if (isAbsoluteUrl(normalizedConfiguredBaseUrl)) {\n return normalizedConfiguredBaseUrl\n }\n\n const browserOrigin = getBrowserOrigin()\n if (browserOrigin) {\n return stripTrailingSlashes(\n new URL(normalizedConfiguredBaseUrl, browserOrigin).toString(),\n )\n }\n\n if (resolveConfiguredAthenaAuthUpstreamUrl(rawUpstreamUrl)) {\n // Direct upstream without proxy path: origin only (no /api/auth) when\n // the configured base was relative — server-side absolute upstream.\n const upstream = resolveAthenaAuthUpstreamUrl(rawUpstreamUrl)\n return stripTrailingSlashes(\n new URL(ATHENA_AUTH_PATH, `${upstream}/`).toString(),\n )\n }\n\n return stripTrailingSlashes(\n new URL(normalizedConfiguredBaseUrl, LOCAL_DEV_ORIGIN).toString(),\n )\n}\n\n/**\n * Build an absolute Athena Auth request URL for a path under the client base.\n *\n * Resolves at **call time** (reads env when `rawBaseUrl` is omitted) so module\n * load order does not freeze a stale URL.\n *\n * @param path - Path relative to the auth base (leading slashes stripped)\n * @param rawBaseUrl - Optional base string or env map\n *\n * @example\n * ```ts\n * resolveAthenaAuthRequestUrl('get-session', 'https://auth.example.com')\n * // => 'https://auth.example.com/api/auth/get-session'\n * ```\n */\nexport function resolveAthenaAuthRequestUrl(\n path: string,\n rawBaseUrl?: string | EnvLike,\n): string {\n const normalizedPath = path.replace(LEADING_SLASHES_REGEX, '')\n const base = resolveAthenaAuthClientBaseUrl(rawBaseUrl)\n return new URL(normalizedPath, `${base}/`).toString()\n}\n\n/** Relative auth path for email verification (`GET /verify-email`). */\nexport const ATHENA_AUTH_VERIFY_EMAIL_PATH = 'verify-email'\n\n/**\n * Relative segment for session lookup (`GET /get-session`).\n * Prefer with {@link resolveAthenaAuthRequestUrl} when `base` already ends in `/api/auth`.\n */\nexport const ATHENA_AUTH_GET_SESSION_PATH = 'get-session'\n\n/**\n * Absolute app/proxy path for session lookup.\n * Use with `new URL(ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH, appOrigin)` when\n * `baseUrl` is the **app origin** (e.g. `https://app.example.com`), not the auth client base.\n */\nexport const ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH = `${ATHENA_AUTH_PATH}/get-session`\n\n/**\n * @deprecated Alias of {@link ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH} for drop-in\n * replacement of app-local `AUTH_SESSION_PATH` constants. Prefer the `ATHENA_` name.\n */\nexport const AUTH_SESSION_PATH = ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH\n\n/**\n * Query param that forces Athena Auth / Better Auth style session handlers to\n * skip cookie cache and re-read the live session cookie.\n */\nexport const ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM = 'disableCookieCache'\n\n/**\n * @deprecated Alias of {@link ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM}.\n */\nexport const DISABLE_COOKIE_CACHE_QUERY_PARAM =\n ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM\n\n/** Value paired with {@link ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM}. */\nexport const ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_VALUE = 'true'\n\n/**\n * @deprecated Alias of {@link ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_VALUE}.\n */\nexport const DISABLE_COOKIE_CACHE_QUERY_VALUE =\n ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_VALUE\n\n/**\n * Optional request/response header some apps use to pass serialized session\n * payload between edge middleware and the app (not set by the SDK itself).\n */\nexport const ATHENA_SESSION_DATA_HEADER = 'x-session-data'\n\n/**\n * @deprecated Alias of {@link ATHENA_SESSION_DATA_HEADER}.\n */\nexport const SESSION_DATA_HEADER = ATHENA_SESSION_DATA_HEADER\n\n/**\n * Absolute callback URL for email verification.\n *\n * Equivalent to `resolveAthenaAuthRequestUrl(\"verify-email\")` — use this in\n * sign-up / send-verification payloads as `callbackURL` instead of a local\n * wrapper around Auth UI `base-url` helpers.\n *\n * @param rawBaseUrl - Optional base string or env map (defaults to process env)\n * @returns e.g. `https://auth.example.com/api/auth/verify-email`\n *\n * @example\n * ```ts\n * import { resolveEmailVerificationCallbackUrl } from \"@xylex-group/athena/utils\"\n *\n * await client.auth.signUp.email({\n * email,\n * password,\n * name,\n * callbackURL: resolveEmailVerificationCallbackUrl(),\n * })\n * ```\n */\nexport function resolveEmailVerificationCallbackUrl(\n rawBaseUrl?: string | EnvLike,\n): string {\n return resolveAthenaAuthRequestUrl(ATHENA_AUTH_VERIFY_EMAIL_PATH, rawBaseUrl)\n}\n\n/**\n * Build a same-origin (or absolute) **fresh** get-session URL.\n *\n * Appends `disableCookieCache=true` so middleware / RSC session probes do not\n * reuse a stale cookie-cache entry.\n *\n * @param baseUrl - App origin (`https://app.example.com`) or any base accepted by\n * the `URL` constructor. Resolves {@link ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH}\n * (`/api/auth/get-session`) against that base.\n * @returns URL such as `https://app.example.com/api/auth/get-session?disableCookieCache=true`\n *\n * @example\n * ```ts\n * import { createFreshSessionLookupUrl } from \"@xylex-group/athena/utils\"\n *\n * const url = createFreshSessionLookupUrl(\"https://app.example.com\")\n * await fetch(url, { headers: { cookie: requestHeaders.get(\"cookie\") ?? \"\" } })\n * ```\n *\n * For auth-client base URLs that already include `/api/auth`, prefer:\n * `resolveAthenaAuthRequestUrl(\"get-session\", authBase) + \"?disableCookieCache=true\"`\n * or pass the **app** origin into this helper when you proxy `/api/auth/*` locally.\n */\nexport function createFreshSessionLookupUrl(baseUrl: string | URL): URL {\n const url = new URL(ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH, baseUrl)\n url.searchParams.set(\n ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM,\n ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_VALUE,\n )\n return url\n}\n","/**\n * Shared Athena Auth UI route segments, views, and redirect helpers.\n *\n * Aligned with `@xylex-group/athena-auth-ui` / Auth UI `routes.ts` so apps can\n * import from `@xylex-group/athena/utils` instead of copying route maps.\n */\n\n/**\n * Canonical auth screen ids used by UI routing and middleware.\n *\n * Note: the canonical forgot-password view id is `forgot-password`. The URL\n * segment `forget-password` is accepted as a legacy alias and maps to that view.\n */\nexport type AuthView =\n | 'sign-in'\n | 'sign-up'\n | 'forgot-password'\n | 'reset-password'\n | 'reset-email-sent'\n | 'check-email'\n | 'accept-invitation'\n | 'logout'\n\n/** Default view when no path segment is present. */\nexport const AUTH_DEFAULT_VIEW = 'sign-in' satisfies AuthView\n\n/** Optional two-factor path segment used by some app routers. */\nexport const AUTH_TWO_FACTOR_SEGMENT = 'two-factor'\n\n/**\n * Map of URL path segments → {@link AuthView}.\n *\n * Includes `forget-password` as a legacy alias for `forgot-password`.\n */\nexport const AUTH_VIEW_BY_SEGMENT: Readonly<Record<string, AuthView>> = {\n 'accept-invitation': 'accept-invitation',\n 'check-email': 'check-email',\n 'forget-password': 'forgot-password',\n 'forgot-password': 'forgot-password',\n logout: 'logout',\n 'reset-email-sent': 'reset-email-sent',\n 'reset-password': 'reset-password',\n 'sign-in': 'sign-in',\n 'sign-up': 'sign-up',\n} as const\n\n/**\n * Views that should bounce **authenticated** users away (e.g. to app home).\n * Reset/check-email/logout stay reachable while signed in.\n */\nexport const AUTHENTICATED_REDIRECT_VIEW_SET = new Set<AuthView>([\n 'sign-in',\n 'sign-up',\n 'forgot-password',\n])\n\n/**\n * Resolve an auth UI view from a single path segment.\n *\n * @param segment - e.g. `\"sign-in\"` from `/auth/[segment]`; `undefined` → default\n * @returns Canonical {@link AuthView}, or `null` when the segment is unknown\n *\n * @example\n * ```ts\n * resolveAuthViewFromSegment(undefined) // \"sign-in\"\n * resolveAuthViewFromSegment(\"forget-password\") // \"forgot-password\"\n * resolveAuthViewFromSegment(\"unknown\") // null\n * ```\n */\nexport function resolveAuthViewFromSegment(\n segment: string | undefined,\n): AuthView | null {\n if (!segment) {\n return AUTH_DEFAULT_VIEW\n }\n return AUTH_VIEW_BY_SEGMENT[segment] ?? null\n}\n\n/**\n * Whether an authenticated user should be redirected away from this auth view.\n *\n * @param view - Resolved auth view\n */\nexport function shouldRedirectAuthenticatedAuthView(view: AuthView): boolean {\n return AUTHENTICATED_REDIRECT_VIEW_SET.has(view)\n}\n\n/**\n * Default page routes under `/auth/*` for Next.js (or similar) apps.\n */\nexport const AUTH_ROUTES = {\n acceptInvitation: '/auth/accept-invitation',\n appHome: '/',\n checkEmail: '/auth/check-email',\n forgotPassword: '/auth/forgot-password',\n logout: '/auth/logout',\n resetEmailSent: '/auth/reset-email-sent',\n resetPassword: '/auth/reset-password',\n signIn: '/auth/sign-in',\n signUp: '/auth/sign-up',\n socialCallback: '/auth/social-callback',\n} as const\n\nexport type AuthRoutes = Record<keyof typeof AUTH_ROUTES, string>\n\n/**\n * Build an auth route map with optional path overrides.\n */\nexport function createAuthRoutes(\n overrides: Partial<AuthRoutes> = {},\n): AuthRoutes {\n return {\n ...AUTH_ROUTES,\n ...overrides,\n }\n}\n\n/**\n * Query/mode → path redirects used by legacy `?mode=` style entrypoints.\n */\nexport interface AuthModeRedirects {\n readonly 'forgot-password': string\n readonly login: string\n readonly logout: string\n readonly 'reset-password': string\n readonly signup: string\n}\n\nexport function createAuthModeRedirects(\n routes: AuthRoutes = AUTH_ROUTES,\n): AuthModeRedirects {\n return {\n 'forgot-password': routes.forgotPassword,\n login: routes.signIn,\n logout: routes.logout,\n 'reset-password': routes.resetPassword,\n signup: routes.signUp,\n }\n}\n\nexport const AUTH_MODE_REDIRECTS = createAuthModeRedirects()\n\nexport type AuthMode = keyof AuthModeRedirects\n\nexport const AUTH_MODE_SET = new Set<string>(Object.keys(AUTH_MODE_REDIRECTS))\n\nexport const AUTHENTICATED_REDIRECT_MODE_SET = new Set<AuthMode>([\n 'login',\n 'signup',\n 'forgot-password',\n])\n\n/**\n * Type guard for legacy auth `mode` query values (`login`, `signup`, …).\n */\nexport function isAuthMode(value: string): value is AuthMode {\n return AUTH_MODE_SET.has(value)\n}\n\n/**\n * Whether an authenticated user should be redirected away from this auth mode.\n */\nexport function shouldRedirectAuthenticatedAuthMode(mode: AuthMode): boolean {\n return AUTHENTICATED_REDIRECT_MODE_SET.has(mode)\n}\n\n/**\n * Resolve a path for a legacy auth mode string.\n *\n * @returns Path from {@link AUTH_MODE_REDIRECTS}, or `null` if unknown\n */\nexport function resolveAuthModeRedirect(\n mode: string | undefined,\n redirects: AuthModeRedirects = AUTH_MODE_REDIRECTS,\n): string | null {\n if (!mode || !isAuthMode(mode)) {\n return null\n }\n return redirects[mode]\n}\n","export function proxyRequestHeaders(request: Request): Headers {\n const headers = new Headers(request.headers)\n const requestUrl = new URL(request.url)\n const proto = requestUrl.protocol.replace(/:$/u, '') || 'https'\n\n // Let fetch set the upstream Host header, but keep the original public app\n // origin available for auth servers that need to validate or generate links\n // for Vercel preview domains behind this proxy.\n headers.delete('host')\n headers.set('x-forwarded-host', requestUrl.host)\n headers.set('x-forwarded-proto', proto)\n headers.set('x-forwarded-origin', requestUrl.origin)\n headers.set('x-forwarded-uri', `${requestUrl.pathname}${requestUrl.search}`)\n\n if (requestUrl.port) {\n headers.set('x-forwarded-port', requestUrl.port)\n } else {\n headers.delete('x-forwarded-port')\n }\n\n return headers\n}\n","import type { AthenaCookieOptions } from './types.ts'\n\nfunction tryDecode(str: string): string {\n if (str.indexOf('%') === -1) {\n return str\n }\n try {\n return decodeURIComponent(str)\n } catch {\n return str\n }\n}\n\nexport interface CookieAttributes {\n value: string\n 'max-age'?: number\n expires?: Date\n domain?: string\n path?: string\n secure?: boolean\n httponly?: boolean\n partitioned?: boolean\n samesite?: 'strict' | 'lax' | 'none'\n [key: string]: unknown\n}\n\nexport const SECURE_COOKIE_PREFIX = '__Secure-'\nexport const HOST_COOKIE_PREFIX = '__Host-'\n\n/**\n * Remove __Secure- or __Host- prefix from cookie name.\n */\nexport function stripSecureCookiePrefix(cookieName: string): string {\n if (cookieName.startsWith(SECURE_COOKIE_PREFIX)) {\n return cookieName.slice(SECURE_COOKIE_PREFIX.length)\n }\n if (cookieName.startsWith(HOST_COOKIE_PREFIX)) {\n return cookieName.slice(HOST_COOKIE_PREFIX.length)\n }\n return cookieName\n}\n\n/**\n * Split a comma-joined `Set-Cookie` header string into individual cookies.\n */\nexport function splitSetCookieHeader(setCookie: string): string[] {\n if (!setCookie) {\n return []\n }\n\n const result: string[] = []\n let start = 0\n let i = 0\n\n while (i < setCookie.length) {\n if (setCookie[i] === ',') {\n let j = i + 1\n while (j < setCookie.length && setCookie[j] === ' ') {\n j++\n }\n while (j < setCookie.length && setCookie[j] !== '=' && setCookie[j] !== ';' && setCookie[j] !== ',') {\n j++\n }\n\n if (j < setCookie.length && setCookie[j] === '=') {\n const part = setCookie.slice(start, i).trim()\n if (part) {\n result.push(part)\n }\n start = i + 1\n while (start < setCookie.length && setCookie[start] === ' ') {\n start++\n }\n i = start\n continue\n }\n }\n i++\n }\n\n const last = setCookie.slice(start).trim()\n if (last) {\n result.push(last)\n }\n\n return result\n}\n\nexport function parseSetCookieHeader(setCookie: string): Map<string, CookieAttributes> {\n const cookies = new Map<string, CookieAttributes>()\n const cookieArray = splitSetCookieHeader(setCookie)\n\n for (const cookieString of cookieArray) {\n const parts = cookieString.split(';').map((part) => part.trim())\n const [nameValue, ...attributes] = parts\n const [name, ...valueParts] = (nameValue || '').split('=')\n if (!name) {\n continue\n }\n\n const value = unquoteCookieValue(valueParts.join('='))\n const decodedValue = tryDecode(value)\n const attrObj: CookieAttributes = { value: decodedValue }\n\n for (const attribute of attributes) {\n const [attrName, ...attrValueParts] = attribute.split('=')\n const attrValue = attrValueParts.join('=')\n const normalizedAttrName = attrName.trim().toLowerCase()\n switch (normalizedAttrName) {\n case 'max-age':\n attrObj['max-age'] = attrValue ? parseInt(attrValue.trim(), 10) : undefined\n break\n case 'expires':\n attrObj.expires = attrValue ? new Date(attrValue.trim()) : undefined\n break\n case 'domain':\n attrObj.domain = attrValue ? attrValue.trim() : undefined\n break\n case 'path':\n attrObj.path = attrValue ? attrValue.trim() : undefined\n break\n case 'secure':\n attrObj.secure = true\n break\n case 'httponly':\n attrObj.httponly = true\n break\n case 'samesite':\n attrObj.samesite = attrValue ? (attrValue.trim().toLowerCase() as 'strict' | 'lax' | 'none') : undefined\n break\n case 'partitioned':\n attrObj.partitioned = true\n break\n default:\n attrObj[normalizedAttrName] = attrValue ? attrValue.trim() : true\n break\n }\n }\n\n cookies.set(name, attrObj)\n }\n\n return cookies\n}\n\nexport function toCookieOptions(attributes: CookieAttributes): AthenaCookieOptions {\n return {\n maxAge: attributes['max-age'],\n expires: attributes.expires,\n domain: attributes.domain,\n path: attributes.path,\n secure: attributes.secure,\n httpOnly: attributes.httponly,\n sameSite: attributes.samesite,\n partitioned: attributes.partitioned,\n }\n}\n\n/**\n * Cookie-name token char set per RFC 7230 §3.2.6.\n */\nexport const cookieNameRegex = /^[\\w!#$%&'*.^`|~+-]+$/\n\nfunction unquoteCookieValue(value: string): string {\n if (value.length < 2 || !value.startsWith('\"') || !value.endsWith('\"')) {\n return value\n }\n return value.slice(1, -1)\n}\n\n/**\n * Parse a `Cookie` header into a key/value map.\n */\nexport function parseCookies(cookieHeader: string): Map<string, string> {\n const cookies = cookieHeader.split('; ')\n const cookieMap = new Map<string, string>()\n cookies.forEach((cookie) => {\n const [name, value] = cookie.split(/=(.*)/s)\n cookieMap.set(name as string, value as string)\n })\n return cookieMap\n}\n\n/**\n * Add or replace a cookie in the request `Cookie` header.\n */\nexport function setRequestCookie(headers: Headers, name: string, value: string): void {\n const cookieMap = parseCookies(headers.get('cookie') || '')\n if (cookieNameRegex.test(name)) {\n cookieMap.set(name, value)\n }\n headers.set(\n 'cookie',\n Array.from(cookieMap, ([key, currentValue]) => `${key}=${encodeURIComponent(currentValue)}`).join('; '),\n )\n}\n\n/**\n * Merge `Set-Cookie` values into a `Cookie` header.\n */\nexport function applySetCookies(target: Headers, setCookieValues: Iterable<string>): void {\n const cookieMap = parseCookies(target.get('cookie') || '')\n for (const setCookie of setCookieValues) {\n for (const [name, attr] of parseSetCookieHeader(setCookie)) {\n if (cookieNameRegex.test(name)) {\n cookieMap.set(name, attr.value)\n }\n }\n }\n target.set(\n 'cookie',\n Array.from(cookieMap, ([key, currentValue]) => `${key}=${encodeURIComponent(currentValue)}`).join('; '),\n )\n}\n\nexport function setCookieToHeader(headers: Headers) {\n return (context: { response: Response }) => {\n const setCookieHeader = context.response.headers.get('set-cookie')\n if (!setCookieHeader) {\n return\n }\n applySetCookies(headers, [setCookieHeader])\n }\n}\n","import { decodeBase64UrlToString, encodeStringToBase64Url } from './base64.ts'\nimport {\n HOST_COOKIE_PREFIX,\n SECURE_COOKIE_PREFIX,\n parseCookies,\n parseSetCookieHeader,\n setCookieToHeader,\n setRequestCookie,\n splitSetCookieHeader,\n stripSecureCookiePrefix,\n toCookieOptions,\n} from './cookie-utils.ts'\nimport { signHmacBase64Url, signJwtHS256, verifyJwtHS256 } from './crypto.ts'\nimport { createAccountStore, createSessionStore, getAccountCookie, getChunkedCookie } from './session-store.ts'\nimport type {\n AthenaAuthCookie,\n AthenaAuthCookies,\n AthenaCookieContextRuntime,\n AthenaCookieOptions,\n AthenaCookiesOptions,\n AthenaCookieVersionResolver,\n AthenaGetCookieCacheConfig,\n AthenaSessionPair,\n} from './types.ts'\n\nconst DEFAULT_COOKIE_PREFIX = 'athena-auth'\nconst LEGACY_COOKIE_PREFIX = 'better-auth'\nconst DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60\nconst DEFAULT_CACHE_MAX_AGE = 60 * 5\n\nfunction isProductionRuntime(): boolean {\n return typeof process !== 'undefined' && process.env?.NODE_ENV === 'production'\n}\n\nfunction getEnvironmentSecret(): string | undefined {\n if (typeof process === 'undefined') {\n return undefined\n }\n return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET\n}\n\nfunction isDynamicBaseURLConfig(baseURL: AthenaCookiesOptions['baseURL']): boolean {\n return (\n typeof baseURL === 'object' &&\n baseURL !== null &&\n 'allowedHosts' in baseURL &&\n Array.isArray((baseURL as { allowedHosts?: unknown }).allowedHosts)\n )\n}\n\nfunction resolveCookiePrefixes(primaryPrefix: string): string[] {\n const prefixes = [primaryPrefix]\n if (!prefixes.includes(DEFAULT_COOKIE_PREFIX)) {\n prefixes.push(DEFAULT_COOKIE_PREFIX)\n }\n if (!prefixes.includes(LEGACY_COOKIE_PREFIX)) {\n prefixes.push(LEGACY_COOKIE_PREFIX)\n }\n return prefixes\n}\n\nfunction createError(message: string): Error {\n return new Error(`@xylex-group/athena/cookies: ${message}`)\n}\n\nfunction getSecretOrThrow(secret?: string): string {\n const resolved = secret || getEnvironmentSecret()\n if (!resolved) {\n throw createError(\n 'getCookieCache requires a secret. Pass `secret` or set ATHENA_AUTH_SECRET/BETTER_AUTH_SECRET/AUTH_SECRET.',\n )\n }\n return resolved\n}\n\nfunction asObject(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object') {\n return null\n }\n return value as Record<string, unknown>\n}\n\nfunction getSessionTokenFromPair(session: AthenaSessionPair): string {\n const token = session.session?.token\n if (typeof token !== 'string' || token.length === 0) {\n throw createError('setSessionCookie requires `session.session.token` to be a non-empty string.')\n }\n return token\n}\n\nasync function resolveCookieVersion(\n versionConfig: AthenaCookieVersionResolver | undefined,\n session: Record<string, unknown>,\n user: Record<string, unknown>,\n): Promise<string> {\n if (!versionConfig) {\n return '1'\n }\n if (typeof versionConfig === 'string') {\n return versionConfig\n }\n return versionConfig(session, user)\n}\n\nfunction getSessionCookieCacheName(cookiePrefix: string, cookieName: string, isSecure: boolean): string {\n return isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`\n}\n\nasync function setCookieValue(\n ctx: AthenaCookieContextRuntime,\n name: string,\n value: string,\n attributes: AthenaCookieOptions,\n): Promise<void> {\n const secret = ctx.context.secret\n if (secret && typeof ctx.setSignedCookie === 'function') {\n await ctx.setSignedCookie(name, value, secret, attributes)\n return\n }\n ctx.setCookie(name, value, attributes)\n}\n\nfunction parseJsonSafely<T>(value: string): T | null {\n try {\n return JSON.parse(value) as T\n } catch {\n return null\n }\n}\n\nfunction getIsSecureCookie(config: { isSecure?: boolean } | undefined): boolean {\n if (config?.isSecure !== undefined) {\n return config.isSecure\n }\n return isProductionRuntime()\n}\n\nexport function createCookieGetter(options: AthenaCookiesOptions) {\n const baseURLString = typeof options.baseURL === 'string' ? options.baseURL : undefined\n const dynamicProtocol =\n typeof options.baseURL === 'object' && options.baseURL !== null ? options.baseURL.protocol : undefined\n\n const secure =\n options.advanced?.useSecureCookies !== undefined\n ? options.advanced.useSecureCookies\n : dynamicProtocol === 'https'\n ? true\n : dynamicProtocol === 'http'\n ? false\n : baseURLString\n ? baseURLString.startsWith('https://')\n : isProductionRuntime()\n\n const secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : ''\n const crossSubdomainEnabled = !!options.advanced?.crossSubDomainCookies?.enabled\n const domain = crossSubdomainEnabled\n ? options.advanced?.crossSubDomainCookies?.domain || (baseURLString ? new URL(baseURLString).hostname : undefined)\n : undefined\n\n if (crossSubdomainEnabled && !domain && !isDynamicBaseURLConfig(options.baseURL)) {\n throw createError('baseURL is required when `crossSubDomainCookies.enabled` is true.')\n }\n\n function createCookie(cookieName: string, overrideAttributes: Partial<AthenaCookieOptions> = {}): AthenaAuthCookie {\n const prefix = options.advanced?.cookiePrefix || DEFAULT_COOKIE_PREFIX\n const name = options.advanced?.cookies?.[cookieName]?.name || `${prefix}.${cookieName}`\n const attributes = options.advanced?.cookies?.[cookieName]?.attributes || {}\n\n return {\n name: `${secureCookiePrefix}${name}`,\n attributes: {\n secure: !!secureCookiePrefix,\n sameSite: 'lax',\n path: '/',\n httpOnly: true,\n ...(crossSubdomainEnabled ? { domain } : {}),\n ...options.advanced?.defaultCookieAttributes,\n ...overrideAttributes,\n ...attributes,\n },\n }\n }\n\n return createCookie\n}\n\nexport function getCookies(options: AthenaCookiesOptions): AthenaAuthCookies {\n const createCookie = createCookieGetter(options)\n const sessionToken = createCookie('session_token', { maxAge: options.session?.expiresIn || DEFAULT_SESSION_MAX_AGE })\n const sessionData = createCookie('session_data', { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE })\n const accountData = createCookie('account_data', { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE })\n const dontRememberToken = createCookie('dont_remember')\n\n return {\n sessionToken: {\n name: sessionToken.name,\n attributes: sessionToken.attributes,\n },\n sessionData: {\n name: sessionData.name,\n attributes: sessionData.attributes,\n },\n dontRememberToken: {\n name: dontRememberToken.name,\n attributes: dontRememberToken.attributes,\n },\n accountData: {\n name: accountData.name,\n attributes: accountData.attributes,\n },\n }\n}\n\nexport async function setCookieCache(\n ctx: AthenaCookieContextRuntime,\n session: AthenaSessionPair,\n dontRememberMe: boolean,\n): Promise<void> {\n const cookieCacheConfig = ctx.context.options?.session?.cookieCache\n if (!cookieCacheConfig?.enabled) {\n return\n }\n\n const version = await resolveCookieVersion(\n cookieCacheConfig.version,\n session.session as Record<string, unknown>,\n session.user as Record<string, unknown>,\n )\n\n const sessionData = {\n session: session.session,\n user: session.user,\n updatedAt: Date.now(),\n version,\n }\n\n const baseAttributes = ctx.context.authCookies.sessionData.attributes\n const maxAge = dontRememberMe ? undefined : baseAttributes.maxAge\n const options: AthenaCookieOptions = {\n ...baseAttributes,\n maxAge,\n }\n const expiresAt = Date.now() + ((options.maxAge || 60) * 1000)\n const strategy = cookieCacheConfig.strategy || 'compact'\n const secret = getSecretOrThrow(ctx.context.secret)\n\n let encoded: string\n if (strategy === 'jwt') {\n encoded = await signJwtHS256(sessionData, secret, options.maxAge || DEFAULT_CACHE_MAX_AGE)\n } else if (strategy === 'jwe') {\n throw createError('`jwe` strategy is not supported by the SDK cookie helper.')\n } else {\n const signature = await signHmacBase64Url(\n secret,\n JSON.stringify({\n ...sessionData,\n expiresAt,\n }),\n )\n encoded = encodeStringToBase64Url(\n JSON.stringify({\n session: sessionData,\n expiresAt,\n signature,\n }),\n )\n }\n\n if (encoded.length > 4093) {\n const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx)\n const cookies = store.chunk(encoded, options)\n store.setCookies(cookies)\n } else {\n const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx)\n if (store.hasChunks()) {\n store.setCookies(store.clean())\n }\n ctx.setCookie(ctx.context.authCookies.sessionData.name, encoded, options)\n }\n}\n\nexport async function setSessionCookie(\n ctx: AthenaCookieContextRuntime,\n session: AthenaSessionPair,\n dontRememberMe?: boolean,\n overrides?: Partial<AthenaCookieOptions>,\n): Promise<void> {\n if (dontRememberMe === undefined && typeof ctx.getSignedCookie === 'function' && ctx.context.secret) {\n const existingFlag = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret)\n dontRememberMe = !!existingFlag\n }\n\n const resolvedDontRememberMe = dontRememberMe ?? false\n const token = getSessionTokenFromPair(session)\n const options = ctx.context.authCookies.sessionToken.attributes\n const maxAge = resolvedDontRememberMe ? undefined : ctx.context.sessionConfig?.expiresIn\n await setCookieValue(ctx, ctx.context.authCookies.sessionToken.name, token, {\n ...options,\n maxAge,\n ...overrides,\n })\n\n if (resolvedDontRememberMe) {\n await setCookieValue(\n ctx,\n ctx.context.authCookies.dontRememberToken.name,\n 'true',\n ctx.context.authCookies.dontRememberToken.attributes,\n )\n }\n\n await setCookieCache(ctx, session, resolvedDontRememberMe)\n ctx.context.setNewSession?.(session)\n}\n\n/**\n * Expires a cookie by setting `maxAge: 0` while preserving attributes.\n */\nexport function expireCookie(ctx: AthenaCookieContextRuntime, cookie: AthenaAuthCookie): void {\n ctx.setCookie(cookie.name, '', {\n ...cookie.attributes,\n maxAge: 0,\n })\n}\n\nexport function deleteSessionCookie(ctx: AthenaCookieContextRuntime, skipDontRememberMe?: boolean): void {\n expireCookie(ctx, ctx.context.authCookies.sessionToken)\n expireCookie(ctx, ctx.context.authCookies.sessionData)\n\n if (ctx.context.options?.account?.storeAccountCookie) {\n expireCookie(ctx, ctx.context.authCookies.accountData)\n const accountStore = createAccountStore(\n ctx.context.authCookies.accountData.name,\n ctx.context.authCookies.accountData.attributes,\n ctx,\n )\n accountStore.setCookies(accountStore.clean())\n }\n\n const sessionStore = createSessionStore(\n ctx.context.authCookies.sessionData.name,\n ctx.context.authCookies.sessionData.attributes,\n ctx,\n )\n sessionStore.setCookies(sessionStore.clean())\n\n if (!skipDontRememberMe) {\n expireCookie(ctx, ctx.context.authCookies.dontRememberToken)\n }\n}\n\nexport const getSessionCookie = (\n request: Request | Headers,\n config?:\n | {\n cookiePrefix?: string\n cookieName?: string\n path?: string\n }\n | undefined,\n): string | null => {\n const cookies = (request instanceof Headers || !('headers' in request) ? request : request.headers).get('cookie')\n if (!cookies) {\n return null\n }\n\n const { cookieName = 'session_token', cookiePrefix = 'athena-auth' } = config || {}\n const parsedCookie = parseCookies(cookies)\n const getCookie = (name: string): string | undefined =>\n parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`)\n const candidateCookieNames = Array.from(new Set([\n cookieName,\n cookieName.replace(/_/g, '-'),\n cookieName.replace(/-/g, '_'),\n ])).filter(Boolean)\n for (const candidateName of candidateCookieNames) {\n const sessionToken =\n getCookie(`${cookiePrefix}.${candidateName}`) || getCookie(`${cookiePrefix}-${candidateName}`)\n if (sessionToken) {\n return sessionToken\n }\n }\n return null\n}\n\nexport const getCookieCache = async <\n SessionShape extends Record<string, unknown> = Record<string, unknown>,\n UserShape extends Record<string, unknown> = Record<string, unknown>,\n>(\n request: Request | Headers,\n config?: AthenaGetCookieCacheConfig<SessionShape, UserShape>,\n): Promise<{\n session: SessionShape\n user: UserShape\n updatedAt: number\n version?: string\n} | null> => {\n const headers = request instanceof Headers || !('headers' in request) ? request : request.headers\n const cookieHeader = headers.get('cookie')\n if (!cookieHeader) {\n return null\n }\n\n const parsedCookie = parseCookies(cookieHeader)\n const cookieName = config?.cookieName || 'session_data'\n const requestedPrefix = config?.cookiePrefix || DEFAULT_COOKIE_PREFIX\n const strategy = config?.strategy || 'compact'\n const cookiePrefixes = resolveCookiePrefixes(requestedPrefix)\n const isSecure = getIsSecureCookie(config)\n const secret = getSecretOrThrow(config?.secret)\n\n let sessionData: string | undefined\n\n for (const prefix of cookiePrefixes) {\n const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure)\n const cookieValue = parsedCookie.get(candidate)\n if (cookieValue) {\n sessionData = cookieValue\n break\n }\n }\n\n if (!sessionData) {\n const reconstructedChunks: Array<{ index: number; value: string }> = []\n for (const prefix of cookiePrefixes) {\n const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure)\n for (const [name, value] of parsedCookie.entries()) {\n if (!name.startsWith(`${candidate}.`)) {\n continue\n }\n const parts = name.split('.')\n const indexStr = parts[parts.length - 1]\n const index = parseInt(indexStr || '0', 10)\n if (!Number.isNaN(index)) {\n reconstructedChunks.push({ index, value })\n }\n }\n if (reconstructedChunks.length > 0) {\n break\n }\n }\n\n if (reconstructedChunks.length > 0) {\n reconstructedChunks.sort((left, right) => left.index - right.index)\n sessionData = reconstructedChunks.map((chunk) => chunk.value).join('')\n }\n }\n\n if (!sessionData) {\n return null\n }\n\n if (strategy === 'jwe') {\n throw createError(\n '`jwe` strategy is not supported by the SDK cookie helper. Use compact/jwt or pass cookie data through the auth server.',\n )\n }\n\n if (strategy === 'jwt') {\n const payload = await verifyJwtHS256<Record<string, unknown>>(sessionData, secret)\n if (!payload) {\n return null\n }\n const sessionRecord = asObject(payload.session)\n const userRecord = asObject(payload.user)\n const updatedAt = payload.updatedAt\n if (!sessionRecord || !userRecord || typeof updatedAt !== 'number') {\n return null\n }\n\n if (config?.version) {\n const cookieVersion = typeof payload.version === 'string' ? payload.version : '1'\n const expectedVersion =\n typeof config.version === 'string'\n ? config.version\n : await config.version(sessionRecord as SessionShape, userRecord as UserShape)\n if (cookieVersion !== expectedVersion) {\n return null\n }\n }\n\n return {\n session: sessionRecord as SessionShape,\n user: userRecord as UserShape,\n updatedAt,\n version: typeof payload.version === 'string' ? payload.version : undefined,\n }\n }\n\n const compactPayload = parseJsonSafely<{\n session: {\n session: SessionShape\n user: UserShape\n updatedAt: number\n version?: string\n }\n expiresAt: number\n signature: string\n }>(decodeBase64UrlToString(sessionData))\n\n if (!compactPayload) {\n return null\n }\n\n const expectedSignature = await signHmacBase64Url(\n secret,\n JSON.stringify({\n ...compactPayload.session,\n expiresAt: compactPayload.expiresAt,\n }),\n )\n\n if (expectedSignature !== compactPayload.signature) {\n return null\n }\n\n if (compactPayload.expiresAt <= Date.now()) {\n return null\n }\n\n const resolvedSession = compactPayload.session\n if (config?.version) {\n const cookieVersion = resolvedSession.version || '1'\n const expectedVersion =\n typeof config.version === 'string'\n ? config.version\n : await config.version(resolvedSession.session, resolvedSession.user)\n if (cookieVersion !== expectedVersion) {\n return null\n }\n }\n\n const sessionObject = asObject(resolvedSession.session)\n const userObject = asObject(resolvedSession.user)\n if (!sessionObject || !userObject) {\n return null\n }\n\n return {\n session: sessionObject as SessionShape,\n user: userObject as UserShape,\n updatedAt: resolvedSession.updatedAt,\n version: resolvedSession.version,\n }\n}\n\nexport {\n SESSION_COOKIE_PATTERNS,\n hasAuthSessionCookie,\n} from './session-cookie-detection.ts'\n\nexport {\n HOST_COOKIE_PREFIX,\n SECURE_COOKIE_PREFIX,\n createSessionStore,\n getAccountCookie,\n getChunkedCookie,\n parseCookies,\n parseSetCookieHeader,\n setCookieToHeader,\n setRequestCookie,\n splitSetCookieHeader,\n stripSecureCookiePrefix,\n toCookieOptions,\n}\n\nexport type {\n AthenaAuthCookie,\n AthenaAuthCookies,\n AthenaCookieContextRuntime,\n AthenaCookieOptions,\n AthenaCookiesOptions,\n AthenaGetCookieCacheConfig,\n}\n","import { getSessionCookie } from '../cookies/index.ts'\nimport type { BackendOption } from '../gateway/types.ts'\n\nexport type AthenaRequestHeaderProfile = 'gateway' | 'auth' | 'chat' | 'storage' | 'minimal'\n\nconst NO_CACHE_HEADER_VALUE = 'no-cache'\n\nconst API_KEY_HEADER_CANDIDATES = ['X-Athena-Key', 'x-athena-key', 'X-Api-Key', 'x-api-key', 'apikey'] as const\nconst ATHENA_KEY_HEADER_CANDIDATES = ['X-Athena-Key', 'x-athena-key'] as const\nconst SESSION_TOKEN_HEADER_CANDIDATES = ['X-Athena-Auth-Session-Token'] as const\nconst BEARER_MIRROR_HEADER_CANDIDATES = ['X-Athena-Auth-Bearer-Token'] as const\nconst CLIENT_HEADER_CANDIDATES = ['X-Athena-Client', 'x-athena-client'] as const\nconst PG_URI_HEADER_CANDIDATES = ['x-pg-uri'] as const\nconst JDBC_URI_HEADER_CANDIDATES = ['x-athena-jdbc-url', 'x-jdbc-url'] as const\n\ninterface AthenaRequestHeaderProfileRules {\n apiKeys: boolean\n routing: boolean\n authMirror: boolean\n authBearer: boolean\n contentType?: boolean\n accept?: boolean\n stripNullsDefault?: boolean\n}\n\nconst PROFILE_RULES: Record<AthenaRequestHeaderProfile, AthenaRequestHeaderProfileRules> = {\n gateway: { apiKeys: true, routing: true, authMirror: true, authBearer: false, contentType: true, stripNullsDefault: true },\n chat: { apiKeys: true, routing: true, authMirror: true, authBearer: true, accept: true },\n storage: { apiKeys: true, routing: true, authMirror: true, authBearer: false, contentType: true },\n auth: { apiKeys: true, routing: false, authMirror: false, authBearer: true, contentType: true },\n minimal: { apiKeys: false, routing: false, authMirror: false, authBearer: false },\n}\n\nexport interface BuildAthenaRequestHeadersInput {\n profile: AthenaRequestHeaderProfile\n sdkHeaderValue: string\n apiKey?: string | null\n /** Overrides the canonical `X-Athena-Key` header value. */\n athenaKey?: string | null\n client?: string | null\n userId?: string | null\n organizationId?: string | null\n backend?: BackendOption\n publishEvent?: string | null\n stripNulls?: boolean\n bearerToken?: string | null\n cookie?: string | null\n sessionToken?: string | null\n pgUri?: string | null\n jdbcUrl?: string | null\n forceNoCache?: boolean\n configHeaders?: Record<string, string>\n callHeaders?: Record<string, string>\n contentType?: string | null\n accept?: string | null\n}\n\n/** Shared config/call fields consumed by gateway, chat, auth, and `client.request(...)`. */\nexport interface AthenaRequestHeaderOverrideFields {\n apiKey?: string | null\n athenaKey?: string | null\n client?: string | null\n userId?: string | null\n organizationId?: string | null\n backend?: BackendOption\n publishEvent?: string | null\n stripNulls?: boolean\n bearerToken?: string | null\n cookie?: string | null\n sessionToken?: string | null\n pgUri?: string | null\n jdbcUrl?: string | null\n forceNoCache?: boolean\n headers?: Record<string, string>\n}\n\nexport type ResolvedRequestHeaderOverrides = Omit<\n BuildAthenaRequestHeadersInput,\n 'profile' | 'sdkHeaderValue' | 'contentType' | 'accept'\n>\n\nfunction normalizeHeaderValue(value?: string | null): string | undefined {\n return value ? value : undefined\n}\n\nfunction mergeExtraHeaders(\n configHeaders?: Record<string, string>,\n callHeaders?: Record<string, string>,\n): Record<string, string> {\n return { ...(configHeaders ?? {}), ...(callHeaders ?? {}) }\n}\n\nexport function hasHeaderIgnoreCase(\n headers: Record<string, string>,\n targetKey: string,\n): boolean {\n const normalizedTargetKey = targetKey.toLowerCase()\n return Object.keys(headers).some(key => key.toLowerCase() === normalizedTargetKey)\n}\n\nexport function resolveHeaderValue(\n headers: Record<string, string>,\n candidates: readonly string[],\n): string | undefined {\n for (const candidate of candidates) {\n const direct = normalizeHeaderValue(headers[candidate])\n if (direct) return direct\n }\n\n const loweredCandidates = new Set(candidates.map(candidate => candidate.toLowerCase()))\n for (const [key, value] of Object.entries(headers)) {\n if (!loweredCandidates.has(key.toLowerCase())) {\n continue\n }\n const normalized = normalizeHeaderValue(value)\n if (normalized) return normalized\n }\n\n return undefined\n}\n\nfunction isCacheControlHeaderName(name: string): boolean {\n return name.toLowerCase() === 'cache-control'\n}\n\nfunction normalizeBearerToken(value: string): string {\n const trimmed = value.trim()\n const match = trimmed.match(/^Bearer\\s+(.+)$/i)\n return match?.[1]?.trim() ?? trimmed\n}\n\nfunction resolveBearerTokenFromAuthorizationHeader(\n headers: Record<string, string>,\n): string | undefined {\n const authorization = resolveHeaderValue(headers, ['Authorization'])\n if (!authorization) {\n return undefined\n }\n\n const token = normalizeBearerToken(authorization)\n return token ? token : undefined\n}\n\nfunction resolveSessionTokenFromCookieHeader(\n headers: Record<string, string>,\n): string | undefined {\n const cookie = resolveHeaderValue(headers, ['Cookie'])\n if (!cookie) {\n return undefined\n }\n\n return getSessionCookie(new Headers({ cookie })) ?? undefined\n}\n\nfunction resolveBackendType(backend?: BackendOption): string | undefined {\n if (!backend) {\n return undefined\n }\n return typeof backend === 'string' ? backend : backend.type\n}\n\nexport function resolveRequestHeaderOverrides(\n config: AthenaRequestHeaderOverrideFields,\n options?: AthenaRequestHeaderOverrideFields,\n defaults?: Pick<AthenaRequestHeaderOverrideFields, 'client' | 'stripNulls'>,\n): ResolvedRequestHeaderOverrides {\n return {\n apiKey: options?.apiKey ?? config.apiKey,\n athenaKey: options?.athenaKey ?? config.athenaKey,\n client: options?.client ?? config.client ?? defaults?.client,\n userId: options?.userId ?? config.userId,\n organizationId: options?.organizationId ?? config.organizationId,\n backend: options?.backend ?? config.backend,\n publishEvent: options?.publishEvent ?? config.publishEvent,\n stripNulls: options?.stripNulls ?? config.stripNulls ?? defaults?.stripNulls,\n bearerToken: options?.bearerToken ?? config.bearerToken,\n cookie: options?.cookie ?? config.cookie,\n sessionToken: options?.sessionToken ?? config.sessionToken,\n pgUri: options?.pgUri ?? config.pgUri,\n jdbcUrl: options?.jdbcUrl ?? config.jdbcUrl,\n forceNoCache: Boolean(config.forceNoCache || options?.forceNoCache),\n configHeaders: config.headers,\n callHeaders: options?.headers,\n }\n}\n\nexport function buildServiceRequestHeaders(\n profile: Exclude<AthenaRequestHeaderProfile, 'minimal'>,\n sdkHeaderValue: string,\n config: AthenaRequestHeaderOverrideFields,\n options?: AthenaRequestHeaderOverrideFields,\n extras?: Pick<BuildAthenaRequestHeadersInput, 'contentType' | 'accept'> & {\n client?: string | null\n stripNulls?: boolean\n },\n): Record<string, string> {\n const rules = PROFILE_RULES[profile]\n return buildAthenaRequestHeaders({\n profile,\n sdkHeaderValue,\n ...resolveRequestHeaderOverrides(config, options, {\n client: extras?.client ?? undefined,\n stripNulls: extras?.stripNulls ?? (rules.stripNullsDefault ? true : undefined),\n }),\n contentType: extras?.contentType ?? (rules.contentType ? 'application/json' : undefined),\n accept: extras?.accept ?? (rules.accept ? 'application/json' : undefined),\n })\n}\n\nexport function applyAthenaApiKeyHeaders(\n headers: Record<string, string>,\n apiKey?: string | null,\n athenaKey?: string | null,\n): void {\n const resolvedAthenaKey = normalizeHeaderValue(athenaKey) ?? normalizeHeaderValue(apiKey)\n if (resolvedAthenaKey && !hasHeaderIgnoreCase(headers, 'X-Athena-Key')) {\n headers['X-Athena-Key'] = resolvedAthenaKey\n }\n}\n\nexport function applyAthenaAuthContextHeaders(\n headers: Record<string, string>,\n input: Pick<\n BuildAthenaRequestHeadersInput,\n 'bearerToken' | 'cookie' | 'sessionToken' | 'profile' | 'configHeaders' | 'callHeaders'\n >,\n): void {\n const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders)\n const rules = PROFILE_RULES[input.profile]\n const explicitCookie = normalizeHeaderValue(input.cookie)\n if (explicitCookie) {\n mergedExtraHeaders.Cookie = explicitCookie\n }\n\n const explicitSessionToken =\n normalizeHeaderValue(input.sessionToken) ??\n resolveHeaderValue(mergedExtraHeaders, SESSION_TOKEN_HEADER_CANDIDATES)\n const derivedSessionToken =\n explicitSessionToken ?? resolveSessionTokenFromCookieHeader(mergedExtraHeaders)\n const cookieFromHeaders = resolveHeaderValue(mergedExtraHeaders, ['Cookie'])\n\n if (explicitCookie && !hasHeaderIgnoreCase(headers, 'Cookie')) {\n headers.Cookie = explicitCookie\n } else if (cookieFromHeaders && !hasHeaderIgnoreCase(headers, 'Cookie')) {\n headers.Cookie = cookieFromHeaders\n }\n\n const explicitBearerToken = (() => {\n const configured = normalizeHeaderValue(input.bearerToken)\n if (configured) {\n return normalizeBearerToken(configured)\n }\n const mirrored = resolveHeaderValue(mergedExtraHeaders, BEARER_MIRROR_HEADER_CANDIDATES)\n return mirrored ? normalizeBearerToken(mirrored) : undefined\n })()\n const derivedBearerToken =\n explicitBearerToken ?? resolveBearerTokenFromAuthorizationHeader(mergedExtraHeaders)\n\n if (rules.authBearer && derivedBearerToken && !hasHeaderIgnoreCase(headers, 'Authorization')) {\n headers.Authorization = `Bearer ${derivedBearerToken}`\n }\n\n if (rules.authMirror) {\n if (derivedSessionToken && !hasHeaderIgnoreCase(headers, 'X-Athena-Auth-Session-Token')) {\n headers['X-Athena-Auth-Session-Token'] = derivedSessionToken\n }\n if (derivedBearerToken && !hasHeaderIgnoreCase(headers, 'X-Athena-Auth-Bearer-Token')) {\n headers['X-Athena-Auth-Bearer-Token'] = derivedBearerToken\n }\n } else if (derivedSessionToken && !hasHeaderIgnoreCase(headers, 'X-Athena-Auth-Session-Token')) {\n headers['X-Athena-Auth-Session-Token'] = derivedSessionToken\n }\n}\n\nexport function applyAthenaPgUriHeaders(\n headers: Record<string, string>,\n input: Pick<BuildAthenaRequestHeadersInput, 'pgUri' | 'jdbcUrl' | 'configHeaders' | 'callHeaders'>,\n): void {\n const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders)\n\n const pgUri =\n normalizeHeaderValue(input.pgUri) ??\n resolveHeaderValue(mergedExtraHeaders, PG_URI_HEADER_CANDIDATES)\n if (pgUri && !hasHeaderIgnoreCase(headers, 'x-pg-uri')) {\n headers['x-pg-uri'] = pgUri\n }\n\n const jdbcUrl =\n normalizeHeaderValue(input.jdbcUrl) ??\n resolveHeaderValue(mergedExtraHeaders, JDBC_URI_HEADER_CANDIDATES)\n if (jdbcUrl) {\n if (!hasHeaderIgnoreCase(headers, 'x-athena-jdbc-url')) {\n headers['x-athena-jdbc-url'] = jdbcUrl\n }\n if (!hasHeaderIgnoreCase(headers, 'x-jdbc-url')) {\n headers['x-jdbc-url'] = jdbcUrl\n }\n }\n}\n\n/**\n * Minimal gateway/data request headers used by many apps before they adopt\n * the full {@link buildAthenaRequestHeaders} profile model.\n *\n * Additive convenience — does not replace client-built headers. Prefer\n * `createClient({ client, key })` so the SDK sets these on every call.\n */\nexport function buildAthenaGatewayHeaders(input: {\n clientName?: string | null\n gatewayKey?: string | null\n headers?: Record<string, string | null | undefined>\n}): Record<string, string> {\n const trimmedClientName = input.clientName?.trim()\n const trimmedGatewayKey = input.gatewayKey?.trim()\n const merged: Record<string, string | null | undefined> = {\n ...(trimmedClientName\n ? {\n 'X-Athena-Client': trimmedClientName,\n }\n : {}),\n ...(trimmedGatewayKey\n ? {\n 'X-Api-Key': trimmedGatewayKey,\n 'X-Athena-Key': trimmedGatewayKey,\n }\n : {}),\n ...input.headers,\n }\n\n return Object.fromEntries(\n Object.entries(merged).flatMap(([key, value]) =>\n typeof value === 'string' && value.trim()\n ? ([[key, value.trim()]] as const)\n : [],\n ),\n )\n}\n\nexport function buildAthenaRequestHeaders(\n input: BuildAthenaRequestHeadersInput,\n): Record<string, string> {\n const forceNoCache = Boolean(input.forceNoCache)\n const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders)\n const rules = PROFILE_RULES[input.profile]\n\n const headerClient = resolveHeaderValue(mergedExtraHeaders, CLIENT_HEADER_CANDIDATES)\n const finalClient = normalizeHeaderValue(input.client) ?? headerClient\n const finalApiKey =\n normalizeHeaderValue(input.apiKey) ??\n resolveHeaderValue(mergedExtraHeaders, API_KEY_HEADER_CANDIDATES)\n const finalAthenaKey =\n normalizeHeaderValue(input.athenaKey) ??\n resolveHeaderValue(mergedExtraHeaders, ATHENA_KEY_HEADER_CANDIDATES) ??\n finalApiKey\n\n const headers: Record<string, string> = {\n 'X-Athena-Sdk': input.sdkHeaderValue,\n }\n\n if (rules.contentType) {\n headers['Content-Type'] = input.contentType ?? 'application/json'\n }\n\n if (input.accept ?? rules.accept) {\n headers.Accept = input.accept ?? 'application/json'\n }\n\n if (rules.routing) {\n if (normalizeHeaderValue(input.userId)) {\n headers['X-User-Id'] = input.userId ?? ''\n }\n if (normalizeHeaderValue(input.organizationId)) {\n headers['X-Organization-Id'] = input.organizationId ?? ''\n }\n if (finalClient) {\n headers['X-Athena-Client'] = finalClient\n }\n\n const backendType = resolveBackendType(input.backend)\n if (backendType) {\n headers['X-Backend-Type'] = backendType\n }\n\n if (typeof input.stripNulls === 'boolean') {\n headers['X-Strip-Nulls'] = input.stripNulls ? 'true' : 'false'\n } else if (rules.stripNullsDefault) {\n headers['X-Strip-Nulls'] = 'true'\n }\n\n if (normalizeHeaderValue(input.publishEvent)) {\n headers['X-Publish-Event'] = input.publishEvent ?? ''\n }\n }\n\n if (rules.apiKeys && (finalApiKey || finalAthenaKey)) {\n applyAthenaApiKeyHeaders(headers, finalApiKey, finalAthenaKey)\n }\n\n applyAthenaAuthContextHeaders(headers, input)\n applyAthenaPgUriHeaders(headers, input)\n\n const reservedClientHeaderKeys = new Set(CLIENT_HEADER_CANDIDATES.map(key => key.toLowerCase()))\n Object.entries(mergedExtraHeaders).forEach(([key, value]) => {\n if (reservedClientHeaderKeys.has(key.toLowerCase())) {\n return\n }\n if (forceNoCache && isCacheControlHeaderName(key)) {\n return\n }\n const normalized = normalizeHeaderValue(value)\n if (normalized) {\n headers[key] = normalized\n }\n })\n\n if (forceNoCache) {\n headers['Cache-Control'] = NO_CACHE_HEADER_VALUE\n }\n\n return headers\n}\n","interface CryptoLike {\n getRandomValues<T extends ArrayBufferView | null>(array: T): T\n}\n\nfunction getRandomBytes(size: number): Uint8Array {\n const bytes = new Uint8Array(size)\n const cryptoApi = (globalThis as { crypto?: CryptoLike }).crypto\n if (cryptoApi?.getRandomValues) {\n return cryptoApi.getRandomValues(bytes)\n }\n\n for (let index = 0; index < bytes.length; index += 1) {\n bytes[index] = Math.floor(Math.random() * 256)\n }\n return bytes\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, value => value.toString(16).padStart(2, '0')).join('')\n}\n\nfunction createDollarQuoteTag(value: string): string {\n let tag = `s${bytesToHex(getRandomBytes(6))}`\n while (value.includes(`$${tag}$`)) {\n tag = `${tag}_`\n }\n return tag\n}\n\n/**\n * Wraps a string in a PostgreSQL dollar-quoted literal.\n *\n * Use this for SQL values, not identifiers. Pair with `identifier(...)`\n * for table/column names.\n */\nexport function sqlText(value: string): string {\n const tag = createDollarQuoteTag(value)\n return `$${tag}$${value}$${tag}$`\n}\n\n/**\n * Escapes `%`, `_`, and `\\` for SQL `LIKE` / `ILIKE` patterns.\n */\nexport function escapeLikePatternValue(value: string): string {\n return value\n .replaceAll('\\\\', '\\\\\\\\')\n .replaceAll('%', '\\\\%')\n .replaceAll('_', '\\\\_')\n}\n\n/**\n * Wraps a string in a single-quoted SQL string literal.\n *\n * Prefer `sqlText(...)` for arbitrary raw SQL values when possible.\n */\nexport function quoteSqlStringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`\n}\n\n/**\n * Returns a dollar-quoted literal for strings, or the SQL keyword `NULL`\n * for nullish values.\n */\nexport function sqlNullableText(value: string | null | undefined): string {\n if (value == null) return 'NULL'\n return sqlText(value)\n}\n\n/**\n * Serializes a value and casts the result to `jsonb`.\n */\nexport function sqlJsonbLiteral(value: unknown): string {\n return `${sqlText(JSON.stringify(value ?? null))}::jsonb`\n}\n\n/**\n * Renders an explicit `bigint` SQL literal.\n */\nexport function sqlBigInt(value: bigint | number): string {\n return `${BigInt(value).toString()}::bigint`\n}\n"]}
package/dist/utils.d.cts CHANGED
@@ -1,4 +1,7 @@
1
- import { I as BackendOption } from './types-CwJCPpLD.cjs';
1
+ import { E as EnvLike } from './athena-auth-url-oLux_57a.cjs';
2
+ export { A as ATHENA_AUTH_COOKIE_PREFIXES, o as ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM, p as ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_VALUE, q as ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH, t as ATHENA_AUTH_GET_SESSION_PATH, a as ATHENA_AUTH_PATH, b as ATHENA_AUTH_UPSTREAM_ENV_KEYS, c as ATHENA_AUTH_UPSTREAM_URL_ENV_NAMES, u as ATHENA_AUTH_VERIFY_EMAIL_PATH, v as ATHENA_SESSION_DATA_HEADER, w as AUTHENTICATED_REDIRECT_MODE_SET, x as AUTHENTICATED_REDIRECT_VIEW_SET, d as AUTH_DEFAULT_VIEW, y as AUTH_MODE_REDIRECTS, z as AUTH_MODE_SET, e as AUTH_ROUTES, B as AUTH_SESSION_PATH, F as AUTH_TWO_FACTOR_SEGMENT, f as AUTH_VIEW_BY_SEGMENT, G as AthenaAuthClientBaseUrlOptions, H as AthenaAuthUpstreamEnv, I as AthenaAuthUpstreamEnvKey, J as AuthMode, K as AuthModeRedirects, L as AuthRoutes, g as AuthView, C as ClearAuthCookiesOptions, D as DEFAULT_ATHENA_AUTH_ORIGIN, M as DEFAULT_ATHENA_AUTH_UPSTREAM_URL, N as DEFAULT_AUTH_COOKIE_PREFIXES, O as DISABLE_COOKIE_CACHE_QUERY_PARAM, P as DISABLE_COOKIE_CACHE_QUERY_VALUE, Q as LOCAL_DEV_ORIGIN, S as SESSION_DATA_HEADER, h as clearAuthCookies, R as createAuthModeRedirects, T as createAuthRoutes, U as createFreshSessionLookupUrl, i as isAbsoluteUrl, V as isAuthMode, n as normalizeAthenaAuthBaseUrl, W as readAthenaAuthUpstreamUrlFromEnv, r as resolveAthenaAuthClientBaseUrl, j as resolveAthenaAuthRequestUrl, k as resolveAthenaAuthUpstreamUrl, X as resolveAuthModeRedirect, l as resolveAuthViewFromSegment, m as resolveEmailVerificationCallbackUrl, Y as shouldRedirectAuthenticatedAuthMode, s as shouldRedirectAuthenticatedAuthView } from './athena-auth-url-oLux_57a.cjs';
3
+ export { S as SESSION_COOKIE_PATTERNS, h as hasAuthSessionCookie } from './session-cookie-detection-BqOp9mO6.cjs';
4
+ import { z as BackendOption } from './types-CH78O90i.cjs';
2
5
 
3
6
  declare function slugify(input: string): string;
4
7
 
@@ -11,24 +14,74 @@ declare function asRecord(value: unknown): Record<string, unknown> | null;
11
14
  declare function asIdentifier(value: unknown): string | null;
12
15
  declare function firstString(record: Record<string, unknown> | null | undefined, keys: readonly string[]): string | null;
13
16
  declare function readTrimmedString(value: unknown): string | null;
17
+ /**
18
+ * Trim a string value; return `undefined` when not a non-empty string.
19
+ *
20
+ * Unlike {@link asString}, does not coerce numbers/bigints.
21
+ * Unlike {@link readTrimmedString}, returns `undefined` instead of `null`
22
+ * (handy for optional fields and `??` defaults).
23
+ */
24
+ declare function asNonEmptyString(value: unknown): string | undefined;
14
25
  declare function asNumber(value: unknown): number | null;
15
26
  declare function asStringArray(value: unknown): string[];
16
27
 
17
28
  declare function parseBooleanFlag(rawValue: string | undefined, fallback: boolean): boolean;
18
29
 
30
+ /**
31
+ * Read the first non-empty trimmed environment variable from a name list.
32
+ *
33
+ * @param names - Candidate env keys in priority order
34
+ * @param env - Optional env map (defaults to `process.env`)
35
+ * @returns Trimmed value of the first key that is set and non-empty
36
+ * @throws {Error} When none of the keys yield a non-empty value
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import { requireEnv } from "@xylex-group/athena/utils"
41
+ *
42
+ * const authUrl = requireEnv([
43
+ * "ATHENA_AUTH_UPSTREAM_URL",
44
+ * "ATHENA_AUTH_URL",
45
+ * "NEXT_PUBLIC_ATHENA_AUTH_URL",
46
+ * ])
47
+ * ```
48
+ */
49
+ declare function requireEnv(names: readonly string[], env?: EnvLike): string;
50
+ /**
51
+ * Like {@link requireEnv}, but returns `undefined` instead of throwing when
52
+ * none of the keys are set.
53
+ */
54
+ declare function readEnv(names: readonly string[], env?: EnvLike): string | undefined;
55
+
19
56
  declare function isLocalHostname(hostname: string): boolean;
20
57
 
21
- interface ClearAuthCookiesOptions {
22
- prefixes?: string[];
23
- hostname?: string;
24
- path?: string;
25
- cookieHeader?: string;
58
+ /**
59
+ * Request header / Next.js helpers used by middleware and RSC session loaders.
60
+ * Framework-agnostic (no Next imports).
61
+ */
62
+ /**
63
+ * True when Next.js threw because the route used dynamic APIs during static
64
+ * generation (`DYNAMIC_SERVER_USAGE` digest or matching message).
65
+ *
66
+ * Catch and rethrow (or handle) so Next can mark the route dynamic.
67
+ */
68
+ declare function isDynamicServerUsageError(error: unknown): boolean;
69
+ interface GetOriginFromHeadersOptions {
70
+ /**
71
+ * When `x-forwarded-proto` / scheme is missing, use `http` if true else `https`.
72
+ * Typical: `process.env.NODE_ENV !== "production"`.
73
+ */
74
+ preferHttpWhenMissingProto?: boolean;
26
75
  }
27
76
  /**
28
- * Clears Athena/Better Auth browser cookies by prefix.
29
- * Returns the cookie names that matched and were targeted for deletion.
77
+ * Reconstruct public origin from request headers (Origin, or Host + proto).
78
+ *
79
+ * Prefers `Origin`, then `x-forwarded-host` / `host` with
80
+ * `x-forwarded-proto` (first value when comma-separated).
30
81
  */
31
- declare function clearAuthCookies(options?: ClearAuthCookiesOptions): string[];
82
+ declare function getOriginFromHeaders(headersList: {
83
+ get: (name: string) => string | null;
84
+ }, options?: GetOriginFromHeadersOptions): string | null;
32
85
 
33
86
  declare function proxyRequestHeaders(request: Request): Headers;
34
87
 
@@ -37,7 +90,7 @@ interface BuildAthenaRequestHeadersInput {
37
90
  profile: AthenaRequestHeaderProfile;
38
91
  sdkHeaderValue: string;
39
92
  apiKey?: string | null;
40
- /** Overrides `X-Athena-Key` while leaving `apikey` / `x-api-key` on `apiKey`. */
93
+ /** Overrides the canonical `X-Athena-Key` header value. */
41
94
  athenaKey?: string | null;
42
95
  client?: string | null;
43
96
  userId?: string | null;
@@ -85,6 +138,18 @@ declare function buildServiceRequestHeaders(profile: Exclude<AthenaRequestHeader
85
138
  declare function applyAthenaApiKeyHeaders(headers: Record<string, string>, apiKey?: string | null, athenaKey?: string | null): void;
86
139
  declare function applyAthenaAuthContextHeaders(headers: Record<string, string>, input: Pick<BuildAthenaRequestHeadersInput, 'bearerToken' | 'cookie' | 'sessionToken' | 'profile' | 'configHeaders' | 'callHeaders'>): void;
87
140
  declare function applyAthenaPgUriHeaders(headers: Record<string, string>, input: Pick<BuildAthenaRequestHeadersInput, 'pgUri' | 'jdbcUrl' | 'configHeaders' | 'callHeaders'>): void;
141
+ /**
142
+ * Minimal gateway/data request headers used by many apps before they adopt
143
+ * the full {@link buildAthenaRequestHeaders} profile model.
144
+ *
145
+ * Additive convenience — does not replace client-built headers. Prefer
146
+ * `createClient({ client, key })` so the SDK sets these on every call.
147
+ */
148
+ declare function buildAthenaGatewayHeaders(input: {
149
+ clientName?: string | null;
150
+ gatewayKey?: string | null;
151
+ headers?: Record<string, string | null | undefined>;
152
+ }): Record<string, string>;
88
153
  declare function buildAthenaRequestHeaders(input: BuildAthenaRequestHeadersInput): Record<string, string>;
89
154
 
90
155
  /**
@@ -118,4 +183,4 @@ declare function sqlJsonbLiteral(value: unknown): string;
118
183
  */
119
184
  declare function sqlBigInt(value: bigint | number): string;
120
185
 
121
- export { type AthenaRequestHeaderOverrideFields, type AthenaRequestHeaderProfile, type BuildAthenaRequestHeadersInput, type ClearAuthCookiesOptions, type ResolvedRequestHeaderOverrides, applyAthenaApiKeyHeaders, applyAthenaAuthContextHeaders, applyAthenaPgUriHeaders, asBoolean, asBooleanOrNull, asIdentifier, asNumber, asRecord, asString, asStringArray, buildAthenaRequestHeaders, buildServiceRequestHeaders, clearAuthCookies, escapeLikePatternValue, firstString, hasHeaderIgnoreCase, isLocalHostname, parseBooleanFlag, proxyRequestHeaders, quoteSqlStringLiteral, readTrimmedString, resolveHeaderValue, resolveRequestHeaderOverrides, slugify, sqlBigInt, sqlJsonbLiteral, sqlNullableText, sqlText, trimTrailingSlashes };
186
+ export { type AthenaRequestHeaderOverrideFields, type AthenaRequestHeaderProfile, type BuildAthenaRequestHeadersInput, EnvLike, type GetOriginFromHeadersOptions, type ResolvedRequestHeaderOverrides, applyAthenaApiKeyHeaders, applyAthenaAuthContextHeaders, applyAthenaPgUriHeaders, asBoolean, asBooleanOrNull, asIdentifier, asNonEmptyString, asNumber, asRecord, asString, asStringArray, buildAthenaGatewayHeaders, buildAthenaRequestHeaders, buildServiceRequestHeaders, escapeLikePatternValue, firstString, getOriginFromHeaders, hasHeaderIgnoreCase, isDynamicServerUsageError, isLocalHostname, parseBooleanFlag, proxyRequestHeaders, quoteSqlStringLiteral, readEnv, readTrimmedString, requireEnv, resolveHeaderValue, resolveRequestHeaderOverrides, slugify, sqlBigInt, sqlJsonbLiteral, sqlNullableText, sqlText, trimTrailingSlashes };