@xylex-group/athena 2.11.0 → 2.12.1
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.
- package/README.md +1 -1
- package/dist/browser.cjs +299 -240
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +9 -8
- package/dist/browser.d.ts +9 -8
- package/dist/browser.js +299 -240
- package/dist/browser.js.map +1 -1
- package/dist/cli/index.cjs +272 -240
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +4 -3
- package/dist/cli/index.d.ts +4 -3
- package/dist/cli/index.js +272 -240
- package/dist/cli/index.js.map +1 -1
- package/dist/{client-DD_UeF3Q.d.ts → client-CMtx5P4D.d.cts} +20 -9
- package/dist/{client-WqBuu60O.d.cts → client-Dre8H24u.d.ts} +20 -9
- package/dist/index.cjs +299 -240
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +299 -240
- package/dist/index.js.map +1 -1
- package/dist/{model-form-ByvyyvxB.d.ts → model-form-CU0mWrF9.d.ts} +2 -1
- package/dist/{model-form-DACdBLYG.d.cts → model-form-DfTi8-D1.d.cts} +2 -1
- package/dist/{module-DRkIHtY-.d.ts → module-DBGmbIuh.d.ts} +5 -4
- package/dist/{module-BFMyVmwX.d.cts → module-GoijrBXV.d.cts} +5 -4
- package/dist/next/client.cjs +299 -240
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.d.cts +4 -3
- package/dist/next/client.d.ts +4 -3
- package/dist/next/client.js +299 -240
- package/dist/next/client.js.map +1 -1
- package/dist/next/server.cjs +299 -240
- package/dist/next/server.cjs.map +1 -1
- package/dist/next/server.d.cts +4 -3
- package/dist/next/server.d.ts +4 -3
- package/dist/next/server.js +299 -240
- package/dist/next/server.js.map +1 -1
- package/dist/{pipeline-DZMsPxUg.d.ts → pipeline-DrjU2vNA.d.ts} +1 -1
- package/dist/{pipeline-CmUZsXsi.d.cts → pipeline-c7Gdm0qv.d.cts} +1 -1
- package/dist/react.cjs +237 -98
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +5 -4
- package/dist/react.d.ts +5 -4
- package/dist/react.js +237 -98
- package/dist/react.js.map +1 -1
- package/dist/{shared-B1ueL-Ox.d.cts → shared-DZSGAmXs.d.cts} +2 -2
- package/dist/{shared-GPAprhBb.d.ts → shared-MMnVBBfy.d.ts} +2 -2
- package/dist/{types-CRjDwmtJ.d.ts → types-BLizCLd1.d.cts} +2 -1
- package/dist/types-BRUHGXo2.d.cts +236 -0
- package/dist/types-BRUHGXo2.d.ts +236 -0
- package/dist/types-Bez4HSbI.d.cts +204 -0
- package/dist/{types-C-YvfgYh.d.cts → types-DRRb0Fd0.d.ts} +2 -1
- package/dist/types-kPaHUqUa.d.ts +204 -0
- package/dist/utils.cjs +279 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +58 -1
- package/dist/utils.d.ts +58 -1
- package/dist/utils.js +272 -1
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/dist/types-BeZIHduP.d.cts +0 -428
- package/dist/types-BeZIHduP.d.ts +0 -428
package/dist/utils.cjs
CHANGED
|
@@ -216,6 +216,277 @@ function proxyRequestHeaders(request) {
|
|
|
216
216
|
return headers;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
// src/cookies/cookie-utils.ts
|
|
220
|
+
var SECURE_COOKIE_PREFIX = "__Secure-";
|
|
221
|
+
function parseCookies(cookieHeader) {
|
|
222
|
+
const cookies = cookieHeader.split("; ");
|
|
223
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
224
|
+
cookies.forEach((cookie) => {
|
|
225
|
+
const [name, value] = cookie.split(/=(.*)/s);
|
|
226
|
+
cookieMap.set(name, value);
|
|
227
|
+
});
|
|
228
|
+
return cookieMap;
|
|
229
|
+
}
|
|
230
|
+
var getSessionCookie = (request, config) => {
|
|
231
|
+
const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
|
|
232
|
+
if (!cookies) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
const { cookieName = "session_token", cookiePrefix = "athena-auth" } = {};
|
|
236
|
+
const parsedCookie = parseCookies(cookies);
|
|
237
|
+
const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
|
|
238
|
+
const candidateCookieNames = Array.from(/* @__PURE__ */ new Set([
|
|
239
|
+
cookieName,
|
|
240
|
+
cookieName.replace(/_/g, "-"),
|
|
241
|
+
cookieName.replace(/-/g, "_")
|
|
242
|
+
])).filter(Boolean);
|
|
243
|
+
for (const candidateName of candidateCookieNames) {
|
|
244
|
+
const sessionToken = getCookie(`${cookiePrefix}.${candidateName}`) || getCookie(`${cookiePrefix}-${candidateName}`);
|
|
245
|
+
if (sessionToken) {
|
|
246
|
+
return sessionToken;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// src/utils/athena-request-headers.ts
|
|
253
|
+
var NO_CACHE_HEADER_VALUE = "no-cache";
|
|
254
|
+
var API_KEY_HEADER_CANDIDATES = ["X-Api-Key", "x-api-key", "apikey"];
|
|
255
|
+
var ATHENA_KEY_HEADER_CANDIDATES = ["X-Athena-Key", "x-athena-key"];
|
|
256
|
+
var SESSION_TOKEN_HEADER_CANDIDATES = ["X-Athena-Auth-Session-Token"];
|
|
257
|
+
var BEARER_MIRROR_HEADER_CANDIDATES = ["X-Athena-Auth-Bearer-Token"];
|
|
258
|
+
var CLIENT_HEADER_CANDIDATES = ["X-Athena-Client", "x-athena-client"];
|
|
259
|
+
var PG_URI_HEADER_CANDIDATES = ["x-pg-uri"];
|
|
260
|
+
var JDBC_URI_HEADER_CANDIDATES = ["x-athena-jdbc-url", "x-jdbc-url"];
|
|
261
|
+
var PROFILE_RULES = {
|
|
262
|
+
gateway: { apiKeys: true, routing: true, authMirror: true, authBearer: false, contentType: true, stripNullsDefault: true },
|
|
263
|
+
chat: { apiKeys: true, routing: true, authMirror: true, authBearer: true, accept: true },
|
|
264
|
+
storage: { apiKeys: true, routing: true, authMirror: true, authBearer: false, contentType: true },
|
|
265
|
+
auth: { apiKeys: true, routing: false, authMirror: false, authBearer: true, contentType: true },
|
|
266
|
+
minimal: { apiKeys: false, routing: false, authMirror: false, authBearer: false }
|
|
267
|
+
};
|
|
268
|
+
function normalizeHeaderValue(value) {
|
|
269
|
+
return value ? value : void 0;
|
|
270
|
+
}
|
|
271
|
+
function mergeExtraHeaders(configHeaders, callHeaders) {
|
|
272
|
+
return { ...configHeaders ?? {}, ...callHeaders ?? {} };
|
|
273
|
+
}
|
|
274
|
+
function hasHeaderIgnoreCase(headers, targetKey) {
|
|
275
|
+
const normalizedTargetKey = targetKey.toLowerCase();
|
|
276
|
+
return Object.keys(headers).some((key) => key.toLowerCase() === normalizedTargetKey);
|
|
277
|
+
}
|
|
278
|
+
function resolveHeaderValue(headers, candidates) {
|
|
279
|
+
for (const candidate of candidates) {
|
|
280
|
+
const direct = normalizeHeaderValue(headers[candidate]);
|
|
281
|
+
if (direct) return direct;
|
|
282
|
+
}
|
|
283
|
+
const loweredCandidates = new Set(candidates.map((candidate) => candidate.toLowerCase()));
|
|
284
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
285
|
+
if (!loweredCandidates.has(key.toLowerCase())) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const normalized = normalizeHeaderValue(value);
|
|
289
|
+
if (normalized) return normalized;
|
|
290
|
+
}
|
|
291
|
+
return void 0;
|
|
292
|
+
}
|
|
293
|
+
function isCacheControlHeaderName(name) {
|
|
294
|
+
return name.toLowerCase() === "cache-control";
|
|
295
|
+
}
|
|
296
|
+
function normalizeBearerToken(value) {
|
|
297
|
+
const trimmed = value.trim();
|
|
298
|
+
const match = trimmed.match(/^Bearer\s+(.+)$/i);
|
|
299
|
+
return match?.[1]?.trim() ?? trimmed;
|
|
300
|
+
}
|
|
301
|
+
function resolveBearerTokenFromAuthorizationHeader(headers) {
|
|
302
|
+
const authorization = resolveHeaderValue(headers, ["Authorization"]);
|
|
303
|
+
if (!authorization) {
|
|
304
|
+
return void 0;
|
|
305
|
+
}
|
|
306
|
+
const token = normalizeBearerToken(authorization);
|
|
307
|
+
return token ? token : void 0;
|
|
308
|
+
}
|
|
309
|
+
function resolveSessionTokenFromCookieHeader(headers) {
|
|
310
|
+
const cookie = resolveHeaderValue(headers, ["Cookie"]);
|
|
311
|
+
if (!cookie) {
|
|
312
|
+
return void 0;
|
|
313
|
+
}
|
|
314
|
+
return getSessionCookie(new Headers({ cookie })) ?? void 0;
|
|
315
|
+
}
|
|
316
|
+
function resolveBackendType(backend) {
|
|
317
|
+
if (!backend) {
|
|
318
|
+
return void 0;
|
|
319
|
+
}
|
|
320
|
+
return typeof backend === "string" ? backend : backend.type;
|
|
321
|
+
}
|
|
322
|
+
function resolveRequestHeaderOverrides(config, options, defaults) {
|
|
323
|
+
return {
|
|
324
|
+
apiKey: options?.apiKey ?? config.apiKey,
|
|
325
|
+
athenaKey: options?.athenaKey ?? config.athenaKey,
|
|
326
|
+
client: options?.client ?? config.client ?? defaults?.client,
|
|
327
|
+
userId: options?.userId ?? config.userId,
|
|
328
|
+
organizationId: options?.organizationId ?? config.organizationId,
|
|
329
|
+
backend: options?.backend ?? config.backend,
|
|
330
|
+
publishEvent: options?.publishEvent ?? config.publishEvent,
|
|
331
|
+
stripNulls: options?.stripNulls ?? config.stripNulls ?? defaults?.stripNulls,
|
|
332
|
+
bearerToken: options?.bearerToken ?? config.bearerToken,
|
|
333
|
+
cookie: options?.cookie ?? config.cookie,
|
|
334
|
+
sessionToken: options?.sessionToken ?? config.sessionToken,
|
|
335
|
+
pgUri: options?.pgUri ?? config.pgUri,
|
|
336
|
+
jdbcUrl: options?.jdbcUrl ?? config.jdbcUrl,
|
|
337
|
+
forceNoCache: Boolean(config.forceNoCache || options?.forceNoCache),
|
|
338
|
+
configHeaders: config.headers,
|
|
339
|
+
callHeaders: options?.headers
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
function buildServiceRequestHeaders(profile, sdkHeaderValue, config, options, extras) {
|
|
343
|
+
const rules = PROFILE_RULES[profile];
|
|
344
|
+
return buildAthenaRequestHeaders({
|
|
345
|
+
profile,
|
|
346
|
+
sdkHeaderValue,
|
|
347
|
+
...resolveRequestHeaderOverrides(config, options, {
|
|
348
|
+
client: extras?.client ?? void 0,
|
|
349
|
+
stripNulls: extras?.stripNulls ?? (rules.stripNullsDefault ? true : void 0)
|
|
350
|
+
}),
|
|
351
|
+
contentType: extras?.contentType ?? (rules.contentType ? "application/json" : void 0),
|
|
352
|
+
accept: extras?.accept ?? (rules.accept ? "application/json" : void 0)
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
function applyAthenaApiKeyHeaders(headers, apiKey, athenaKey) {
|
|
356
|
+
if (apiKey) {
|
|
357
|
+
if (!hasHeaderIgnoreCase(headers, "apikey")) {
|
|
358
|
+
headers.apikey = apiKey;
|
|
359
|
+
}
|
|
360
|
+
if (!Object.hasOwn(headers, "x-api-key")) {
|
|
361
|
+
headers["x-api-key"] = apiKey;
|
|
362
|
+
}
|
|
363
|
+
if (!Object.hasOwn(headers, "X-Api-Key")) {
|
|
364
|
+
headers["X-Api-Key"] = apiKey;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const resolvedAthenaKey = normalizeHeaderValue(athenaKey) ?? normalizeHeaderValue(apiKey);
|
|
368
|
+
if (resolvedAthenaKey && !hasHeaderIgnoreCase(headers, "X-Athena-Key")) {
|
|
369
|
+
headers["X-Athena-Key"] = resolvedAthenaKey;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function applyAthenaAuthContextHeaders(headers, input) {
|
|
373
|
+
const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders);
|
|
374
|
+
const rules = PROFILE_RULES[input.profile];
|
|
375
|
+
const explicitCookie = normalizeHeaderValue(input.cookie);
|
|
376
|
+
if (explicitCookie) {
|
|
377
|
+
mergedExtraHeaders.Cookie = explicitCookie;
|
|
378
|
+
}
|
|
379
|
+
const explicitSessionToken = normalizeHeaderValue(input.sessionToken) ?? resolveHeaderValue(mergedExtraHeaders, SESSION_TOKEN_HEADER_CANDIDATES);
|
|
380
|
+
const derivedSessionToken = explicitSessionToken ?? resolveSessionTokenFromCookieHeader(mergedExtraHeaders);
|
|
381
|
+
const cookieFromHeaders = resolveHeaderValue(mergedExtraHeaders, ["Cookie"]);
|
|
382
|
+
if (explicitCookie && !hasHeaderIgnoreCase(headers, "Cookie")) {
|
|
383
|
+
headers.Cookie = explicitCookie;
|
|
384
|
+
} else if (cookieFromHeaders && !hasHeaderIgnoreCase(headers, "Cookie")) {
|
|
385
|
+
headers.Cookie = cookieFromHeaders;
|
|
386
|
+
}
|
|
387
|
+
const explicitBearerToken = (() => {
|
|
388
|
+
const configured = normalizeHeaderValue(input.bearerToken);
|
|
389
|
+
if (configured) {
|
|
390
|
+
return normalizeBearerToken(configured);
|
|
391
|
+
}
|
|
392
|
+
const mirrored = resolveHeaderValue(mergedExtraHeaders, BEARER_MIRROR_HEADER_CANDIDATES);
|
|
393
|
+
return mirrored ? normalizeBearerToken(mirrored) : void 0;
|
|
394
|
+
})();
|
|
395
|
+
const derivedBearerToken = explicitBearerToken ?? resolveBearerTokenFromAuthorizationHeader(mergedExtraHeaders);
|
|
396
|
+
if (rules.authBearer && derivedBearerToken && !hasHeaderIgnoreCase(headers, "Authorization")) {
|
|
397
|
+
headers.Authorization = `Bearer ${derivedBearerToken}`;
|
|
398
|
+
}
|
|
399
|
+
if (rules.authMirror) {
|
|
400
|
+
if (derivedSessionToken && !hasHeaderIgnoreCase(headers, "X-Athena-Auth-Session-Token")) {
|
|
401
|
+
headers["X-Athena-Auth-Session-Token"] = derivedSessionToken;
|
|
402
|
+
}
|
|
403
|
+
if (derivedBearerToken && !hasHeaderIgnoreCase(headers, "X-Athena-Auth-Bearer-Token")) {
|
|
404
|
+
headers["X-Athena-Auth-Bearer-Token"] = derivedBearerToken;
|
|
405
|
+
}
|
|
406
|
+
} else if (derivedSessionToken && !hasHeaderIgnoreCase(headers, "X-Athena-Auth-Session-Token")) {
|
|
407
|
+
headers["X-Athena-Auth-Session-Token"] = derivedSessionToken;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function applyAthenaPgUriHeaders(headers, input) {
|
|
411
|
+
const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders);
|
|
412
|
+
const pgUri = normalizeHeaderValue(input.pgUri) ?? resolveHeaderValue(mergedExtraHeaders, PG_URI_HEADER_CANDIDATES);
|
|
413
|
+
if (pgUri && !hasHeaderIgnoreCase(headers, "x-pg-uri")) {
|
|
414
|
+
headers["x-pg-uri"] = pgUri;
|
|
415
|
+
}
|
|
416
|
+
const jdbcUrl = normalizeHeaderValue(input.jdbcUrl) ?? resolveHeaderValue(mergedExtraHeaders, JDBC_URI_HEADER_CANDIDATES);
|
|
417
|
+
if (jdbcUrl) {
|
|
418
|
+
if (!hasHeaderIgnoreCase(headers, "x-athena-jdbc-url")) {
|
|
419
|
+
headers["x-athena-jdbc-url"] = jdbcUrl;
|
|
420
|
+
}
|
|
421
|
+
if (!hasHeaderIgnoreCase(headers, "x-jdbc-url")) {
|
|
422
|
+
headers["x-jdbc-url"] = jdbcUrl;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
function buildAthenaRequestHeaders(input) {
|
|
427
|
+
const forceNoCache = Boolean(input.forceNoCache);
|
|
428
|
+
const mergedExtraHeaders = mergeExtraHeaders(input.configHeaders, input.callHeaders);
|
|
429
|
+
const rules = PROFILE_RULES[input.profile];
|
|
430
|
+
const headerClient = resolveHeaderValue(mergedExtraHeaders, CLIENT_HEADER_CANDIDATES);
|
|
431
|
+
const finalClient = normalizeHeaderValue(input.client) ?? headerClient;
|
|
432
|
+
const finalApiKey = normalizeHeaderValue(input.apiKey) ?? resolveHeaderValue(mergedExtraHeaders, API_KEY_HEADER_CANDIDATES);
|
|
433
|
+
const finalAthenaKey = normalizeHeaderValue(input.athenaKey) ?? resolveHeaderValue(mergedExtraHeaders, ATHENA_KEY_HEADER_CANDIDATES) ?? finalApiKey;
|
|
434
|
+
const headers = {
|
|
435
|
+
"X-Athena-Sdk": input.sdkHeaderValue
|
|
436
|
+
};
|
|
437
|
+
if (rules.contentType) {
|
|
438
|
+
headers["Content-Type"] = input.contentType ?? "application/json";
|
|
439
|
+
}
|
|
440
|
+
if (input.accept ?? rules.accept) {
|
|
441
|
+
headers.Accept = input.accept ?? "application/json";
|
|
442
|
+
}
|
|
443
|
+
if (rules.routing) {
|
|
444
|
+
if (normalizeHeaderValue(input.userId)) {
|
|
445
|
+
headers["X-User-Id"] = input.userId ?? "";
|
|
446
|
+
}
|
|
447
|
+
if (normalizeHeaderValue(input.organizationId)) {
|
|
448
|
+
headers["X-Organization-Id"] = input.organizationId ?? "";
|
|
449
|
+
}
|
|
450
|
+
if (finalClient) {
|
|
451
|
+
headers["X-Athena-Client"] = finalClient;
|
|
452
|
+
}
|
|
453
|
+
const backendType = resolveBackendType(input.backend);
|
|
454
|
+
if (backendType) {
|
|
455
|
+
headers["X-Backend-Type"] = backendType;
|
|
456
|
+
}
|
|
457
|
+
if (typeof input.stripNulls === "boolean") {
|
|
458
|
+
headers["X-Strip-Nulls"] = input.stripNulls ? "true" : "false";
|
|
459
|
+
} else if (rules.stripNullsDefault) {
|
|
460
|
+
headers["X-Strip-Nulls"] = "true";
|
|
461
|
+
}
|
|
462
|
+
if (normalizeHeaderValue(input.publishEvent)) {
|
|
463
|
+
headers["X-Publish-Event"] = input.publishEvent ?? "";
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (rules.apiKeys && (finalApiKey || finalAthenaKey)) {
|
|
467
|
+
applyAthenaApiKeyHeaders(headers, finalApiKey, finalAthenaKey);
|
|
468
|
+
}
|
|
469
|
+
applyAthenaAuthContextHeaders(headers, input);
|
|
470
|
+
applyAthenaPgUriHeaders(headers, input);
|
|
471
|
+
const reservedClientHeaderKeys = new Set(CLIENT_HEADER_CANDIDATES.map((key) => key.toLowerCase()));
|
|
472
|
+
Object.entries(mergedExtraHeaders).forEach(([key, value]) => {
|
|
473
|
+
if (reservedClientHeaderKeys.has(key.toLowerCase())) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
if (forceNoCache && isCacheControlHeaderName(key)) {
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const normalized = normalizeHeaderValue(value);
|
|
480
|
+
if (normalized) {
|
|
481
|
+
headers[key] = normalized;
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
if (forceNoCache) {
|
|
485
|
+
headers["Cache-Control"] = NO_CACHE_HEADER_VALUE;
|
|
486
|
+
}
|
|
487
|
+
return headers;
|
|
488
|
+
}
|
|
489
|
+
|
|
219
490
|
// src/utils/sql-literals.ts
|
|
220
491
|
function getRandomBytes(size) {
|
|
221
492
|
const bytes = new Uint8Array(size);
|
|
@@ -259,6 +530,9 @@ function sqlBigInt(value) {
|
|
|
259
530
|
return `${BigInt(value).toString()}::bigint`;
|
|
260
531
|
}
|
|
261
532
|
|
|
533
|
+
exports.applyAthenaApiKeyHeaders = applyAthenaApiKeyHeaders;
|
|
534
|
+
exports.applyAthenaAuthContextHeaders = applyAthenaAuthContextHeaders;
|
|
535
|
+
exports.applyAthenaPgUriHeaders = applyAthenaPgUriHeaders;
|
|
262
536
|
exports.asBoolean = asBoolean;
|
|
263
537
|
exports.asBooleanOrNull = asBooleanOrNull;
|
|
264
538
|
exports.asIdentifier = asIdentifier;
|
|
@@ -266,14 +540,19 @@ exports.asNumber = asNumber;
|
|
|
266
540
|
exports.asRecord = asRecord;
|
|
267
541
|
exports.asString = asString;
|
|
268
542
|
exports.asStringArray = asStringArray;
|
|
543
|
+
exports.buildAthenaRequestHeaders = buildAthenaRequestHeaders;
|
|
544
|
+
exports.buildServiceRequestHeaders = buildServiceRequestHeaders;
|
|
269
545
|
exports.clearAuthCookies = clearAuthCookies;
|
|
270
546
|
exports.escapeLikePatternValue = escapeLikePatternValue;
|
|
271
547
|
exports.firstString = firstString;
|
|
548
|
+
exports.hasHeaderIgnoreCase = hasHeaderIgnoreCase;
|
|
272
549
|
exports.isLocalHostname = isLocalHostname;
|
|
273
550
|
exports.parseBooleanFlag = parseBooleanFlag;
|
|
274
551
|
exports.proxyRequestHeaders = proxyRequestHeaders;
|
|
275
552
|
exports.quoteSqlStringLiteral = quoteSqlStringLiteral;
|
|
276
553
|
exports.readTrimmedString = readTrimmedString;
|
|
554
|
+
exports.resolveHeaderValue = resolveHeaderValue;
|
|
555
|
+
exports.resolveRequestHeaderOverrides = resolveRequestHeaderOverrides;
|
|
277
556
|
exports.slugify = slugify;
|
|
278
557
|
exports.sqlBigInt = sqlBigInt;
|
|
279
558
|
exports.sqlJsonbLiteral = sqlJsonbLiteral;
|
package/dist/utils.cjs.map
CHANGED
|
@@ -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/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","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/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', '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` / `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 (!Object.hasOwn(headers, 'x-api-key')) {\n headers['x-api-key'] = apiKey\n }\n if (!Object.hasOwn(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"]}
|
package/dist/utils.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { I as BackendOption } from './types-BRUHGXo2.cjs';
|
|
2
|
+
|
|
1
3
|
declare function slugify(input: string): string;
|
|
2
4
|
|
|
3
5
|
declare function trimTrailingSlashes(value: string): string;
|
|
@@ -30,6 +32,61 @@ declare function clearAuthCookies(options?: ClearAuthCookiesOptions): string[];
|
|
|
30
32
|
|
|
31
33
|
declare function proxyRequestHeaders(request: Request): Headers;
|
|
32
34
|
|
|
35
|
+
type AthenaRequestHeaderProfile = 'gateway' | 'auth' | 'chat' | 'storage' | 'minimal';
|
|
36
|
+
interface BuildAthenaRequestHeadersInput {
|
|
37
|
+
profile: AthenaRequestHeaderProfile;
|
|
38
|
+
sdkHeaderValue: string;
|
|
39
|
+
apiKey?: string | null;
|
|
40
|
+
/** Overrides `X-Athena-Key` while leaving `apikey` / `x-api-key` / `X-Api-Key` on `apiKey`. */
|
|
41
|
+
athenaKey?: string | null;
|
|
42
|
+
client?: string | null;
|
|
43
|
+
userId?: string | null;
|
|
44
|
+
organizationId?: string | null;
|
|
45
|
+
backend?: BackendOption;
|
|
46
|
+
publishEvent?: string | null;
|
|
47
|
+
stripNulls?: boolean;
|
|
48
|
+
bearerToken?: string | null;
|
|
49
|
+
cookie?: string | null;
|
|
50
|
+
sessionToken?: string | null;
|
|
51
|
+
pgUri?: string | null;
|
|
52
|
+
jdbcUrl?: string | null;
|
|
53
|
+
forceNoCache?: boolean;
|
|
54
|
+
configHeaders?: Record<string, string>;
|
|
55
|
+
callHeaders?: Record<string, string>;
|
|
56
|
+
contentType?: string | null;
|
|
57
|
+
accept?: string | null;
|
|
58
|
+
}
|
|
59
|
+
/** Shared config/call fields consumed by gateway, chat, auth, and `client.request(...)`. */
|
|
60
|
+
interface AthenaRequestHeaderOverrideFields {
|
|
61
|
+
apiKey?: string | null;
|
|
62
|
+
athenaKey?: string | null;
|
|
63
|
+
client?: string | null;
|
|
64
|
+
userId?: string | null;
|
|
65
|
+
organizationId?: string | null;
|
|
66
|
+
backend?: BackendOption;
|
|
67
|
+
publishEvent?: string | null;
|
|
68
|
+
stripNulls?: boolean;
|
|
69
|
+
bearerToken?: string | null;
|
|
70
|
+
cookie?: string | null;
|
|
71
|
+
sessionToken?: string | null;
|
|
72
|
+
pgUri?: string | null;
|
|
73
|
+
jdbcUrl?: string | null;
|
|
74
|
+
forceNoCache?: boolean;
|
|
75
|
+
headers?: Record<string, string>;
|
|
76
|
+
}
|
|
77
|
+
type ResolvedRequestHeaderOverrides = Omit<BuildAthenaRequestHeadersInput, 'profile' | 'sdkHeaderValue' | 'contentType' | 'accept'>;
|
|
78
|
+
declare function hasHeaderIgnoreCase(headers: Record<string, string>, targetKey: string): boolean;
|
|
79
|
+
declare function resolveHeaderValue(headers: Record<string, string>, candidates: readonly string[]): string | undefined;
|
|
80
|
+
declare function resolveRequestHeaderOverrides(config: AthenaRequestHeaderOverrideFields, options?: AthenaRequestHeaderOverrideFields, defaults?: Pick<AthenaRequestHeaderOverrideFields, 'client' | 'stripNulls'>): ResolvedRequestHeaderOverrides;
|
|
81
|
+
declare function buildServiceRequestHeaders(profile: Exclude<AthenaRequestHeaderProfile, 'minimal'>, sdkHeaderValue: string, config: AthenaRequestHeaderOverrideFields, options?: AthenaRequestHeaderOverrideFields, extras?: Pick<BuildAthenaRequestHeadersInput, 'contentType' | 'accept'> & {
|
|
82
|
+
client?: string | null;
|
|
83
|
+
stripNulls?: boolean;
|
|
84
|
+
}): Record<string, string>;
|
|
85
|
+
declare function applyAthenaApiKeyHeaders(headers: Record<string, string>, apiKey?: string | null, athenaKey?: string | null): void;
|
|
86
|
+
declare function applyAthenaAuthContextHeaders(headers: Record<string, string>, input: Pick<BuildAthenaRequestHeadersInput, 'bearerToken' | 'cookie' | 'sessionToken' | 'profile' | 'configHeaders' | 'callHeaders'>): void;
|
|
87
|
+
declare function applyAthenaPgUriHeaders(headers: Record<string, string>, input: Pick<BuildAthenaRequestHeadersInput, 'pgUri' | 'jdbcUrl' | 'configHeaders' | 'callHeaders'>): void;
|
|
88
|
+
declare function buildAthenaRequestHeaders(input: BuildAthenaRequestHeadersInput): Record<string, string>;
|
|
89
|
+
|
|
33
90
|
/**
|
|
34
91
|
* Wraps a string in a PostgreSQL dollar-quoted literal.
|
|
35
92
|
*
|
|
@@ -61,4 +118,4 @@ declare function sqlJsonbLiteral(value: unknown): string;
|
|
|
61
118
|
*/
|
|
62
119
|
declare function sqlBigInt(value: bigint | number): string;
|
|
63
120
|
|
|
64
|
-
export { type ClearAuthCookiesOptions, asBoolean, asBooleanOrNull, asIdentifier, asNumber, asRecord, asString, asStringArray, clearAuthCookies, escapeLikePatternValue, firstString, isLocalHostname, parseBooleanFlag, proxyRequestHeaders, quoteSqlStringLiteral, readTrimmedString, slugify, sqlBigInt, sqlJsonbLiteral, sqlNullableText, sqlText, trimTrailingSlashes };
|
|
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 };
|