@xylex-group/athena 2.4.1 → 2.6.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 (41) hide show
  1. package/README.md +52 -1
  2. package/bin/athena-js.js +0 -0
  3. package/dist/browser.cjs +1912 -49
  4. package/dist/browser.cjs.map +1 -1
  5. package/dist/browser.d.cts +8 -7
  6. package/dist/browser.d.ts +8 -7
  7. package/dist/browser.js +1905 -50
  8. package/dist/browser.js.map +1 -1
  9. package/dist/cli/index.cjs +708 -22
  10. package/dist/cli/index.cjs.map +1 -1
  11. package/dist/cli/index.d.cts +3 -3
  12. package/dist/cli/index.d.ts +3 -3
  13. package/dist/cli/index.js +708 -22
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cookies.d.cts +1 -174
  16. package/dist/cookies.d.ts +1 -174
  17. package/dist/index-CVcQCGyG.d.cts +174 -0
  18. package/dist/index-CVcQCGyG.d.ts +174 -0
  19. package/dist/index.cjs +1912 -49
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +8 -7
  22. package/dist/index.d.ts +8 -7
  23. package/dist/index.js +1905 -50
  24. package/dist/index.js.map +1 -1
  25. package/dist/{model-form-4LPnOPAF.d.cts → model-form-BaHWi3gm.d.cts} +1 -1
  26. package/dist/{model-form-CO4-LmNC.d.ts → model-form-Dh6gWjL0.d.ts} +1 -1
  27. package/dist/{pipeline-CR4V15jF.d.ts → pipeline-Ce3pTw5h.d.ts} +1 -1
  28. package/dist/{pipeline-DZeExYMA.d.cts → pipeline-D1ZYeoH7.d.cts} +1 -1
  29. package/dist/{react-email-Buhcpglm.d.ts → react-email-B8O1Jeff.d.cts} +596 -23
  30. package/dist/{react-email-6mOyxBo4.d.cts → react-email-CDEF0jij.d.ts} +596 -23
  31. package/dist/react.cjs +1 -1
  32. package/dist/react.cjs.map +1 -1
  33. package/dist/react.d.cts +4 -4
  34. package/dist/react.d.ts +4 -4
  35. package/dist/react.js +1 -1
  36. package/dist/react.js.map +1 -1
  37. package/dist/{types-D1JvL21V.d.cts → types-CUuo4NDi.d.cts} +1 -1
  38. package/dist/{types-09Q4D86N.d.cts → types-DSX6AT5B.d.cts} +3 -3
  39. package/dist/{types-09Q4D86N.d.ts → types-DSX6AT5B.d.ts} +3 -3
  40. package/dist/{types-DU3gNdFv.d.ts → types-DapchQY5.d.ts} +1 -1
  41. package/package.json +193 -192
package/dist/browser.js CHANGED
@@ -125,6 +125,60 @@ function buildAthenaGatewayUrl(baseUrl, path) {
125
125
  return `${baseUrl}${path}`;
126
126
  }
127
127
 
128
+ // src/cookies/base64.ts
129
+ function getAtob() {
130
+ const candidate = globalThis.atob;
131
+ return typeof candidate === "function" ? candidate : void 0;
132
+ }
133
+ function getBtoa() {
134
+ const candidate = globalThis.btoa;
135
+ return typeof candidate === "function" ? candidate : void 0;
136
+ }
137
+ function bytesToBinaryString(bytes) {
138
+ let result = "";
139
+ for (const byte of bytes) {
140
+ result += String.fromCharCode(byte);
141
+ }
142
+ return result;
143
+ }
144
+ function binaryStringToBytes(binary) {
145
+ const bytes = new Uint8Array(binary.length);
146
+ for (let i = 0; i < binary.length; i++) {
147
+ bytes[i] = binary.charCodeAt(i);
148
+ }
149
+ return bytes;
150
+ }
151
+ function encodeBase64(bytes) {
152
+ const btoaFn = getBtoa();
153
+ if (btoaFn) {
154
+ return btoaFn(bytesToBinaryString(bytes));
155
+ }
156
+ return Buffer.from(bytes).toString("base64");
157
+ }
158
+ function decodeBase64(base64) {
159
+ const atobFn = getAtob();
160
+ if (atobFn) {
161
+ return binaryStringToBytes(atobFn(base64));
162
+ }
163
+ return new Uint8Array(Buffer.from(base64, "base64"));
164
+ }
165
+ function encodeBytesToBase64Url(bytes) {
166
+ return encodeBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
167
+ }
168
+ function encodeStringToBase64Url(value) {
169
+ const bytes = new TextEncoder().encode(value);
170
+ return encodeBytesToBase64Url(bytes);
171
+ }
172
+ function decodeBase64UrlToBytes(value) {
173
+ const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
174
+ const paddingLength = normalized.length % 4;
175
+ const padded = paddingLength === 0 ? normalized : `${normalized}${"=".repeat(4 - paddingLength)}`;
176
+ return decodeBase64(padded);
177
+ }
178
+ function decodeBase64UrlToString(value) {
179
+ return new TextDecoder().decode(decodeBase64UrlToBytes(value));
180
+ }
181
+
128
182
  // src/cookies/cookie-utils.ts
129
183
  var SECURE_COOKIE_PREFIX = "__Secure-";
130
184
  function parseCookies(cookieHeader) {
@@ -136,12 +190,480 @@ function parseCookies(cookieHeader) {
136
190
  });
137
191
  return cookieMap;
138
192
  }
193
+
194
+ // src/cookies/crypto.ts
195
+ var HS256_ALG = "HS256";
196
+ async function getSubtleCrypto() {
197
+ const globalCrypto = globalThis.crypto;
198
+ if (globalCrypto?.subtle) {
199
+ return globalCrypto.subtle;
200
+ }
201
+ const { webcrypto } = await import('crypto');
202
+ const subtle = webcrypto.subtle;
203
+ if (!subtle) {
204
+ throw new Error("Web Crypto subtle API is unavailable.");
205
+ }
206
+ return subtle;
207
+ }
208
+ async function importHmacKey(secret, usage) {
209
+ const subtle = await getSubtleCrypto();
210
+ return subtle.importKey(
211
+ "raw",
212
+ new TextEncoder().encode(secret),
213
+ {
214
+ name: "HMAC",
215
+ hash: "SHA-256"
216
+ },
217
+ false,
218
+ [usage]
219
+ );
220
+ }
221
+ function bufferToBytes(buffer) {
222
+ return new Uint8Array(buffer);
223
+ }
224
+ function parseJwtPayload(payloadSegment) {
225
+ try {
226
+ const decoded = decodeBase64UrlToString(payloadSegment);
227
+ const payload = JSON.parse(decoded);
228
+ if (!payload || typeof payload !== "object") {
229
+ return null;
230
+ }
231
+ return payload;
232
+ } catch {
233
+ return null;
234
+ }
235
+ }
236
+ function isJwtExpired(payload) {
237
+ const exp = payload.exp;
238
+ if (typeof exp !== "number") {
239
+ return false;
240
+ }
241
+ return exp < Math.floor(Date.now() / 1e3);
242
+ }
243
+ async function signHmacBase64Url(secret, value) {
244
+ const subtle = await getSubtleCrypto();
245
+ const key = await importHmacKey(secret, "sign");
246
+ const signature = await subtle.sign("HMAC", key, new TextEncoder().encode(value));
247
+ return encodeBytesToBase64Url(bufferToBytes(signature));
248
+ }
249
+ async function signJwtHS256(payload, secret, expiresIn = 60 * 5) {
250
+ const now = Math.floor(Date.now() / 1e3);
251
+ const header = { alg: HS256_ALG, typ: "JWT" };
252
+ const fullPayload = {
253
+ ...payload,
254
+ iat: now,
255
+ exp: now + expiresIn
256
+ };
257
+ const headerPart = encodeStringToBase64Url(JSON.stringify(header));
258
+ const payloadPart = encodeStringToBase64Url(JSON.stringify(fullPayload));
259
+ const message = `${headerPart}.${payloadPart}`;
260
+ const signature = await signHmacBase64Url(secret, message);
261
+ return `${message}.${signature}`;
262
+ }
263
+ async function verifyJwtHS256(token, secret) {
264
+ const parts = token.split(".");
265
+ if (parts.length !== 3) {
266
+ return null;
267
+ }
268
+ const [headerPart, payloadPart, signaturePart] = parts;
269
+ if (!headerPart || !payloadPart || !signaturePart) {
270
+ return null;
271
+ }
272
+ let header = null;
273
+ try {
274
+ header = JSON.parse(decodeBase64UrlToString(headerPart));
275
+ } catch {
276
+ return null;
277
+ }
278
+ if (!header || header.alg !== HS256_ALG) {
279
+ return null;
280
+ }
281
+ const payload = parseJwtPayload(payloadPart);
282
+ if (!payload) {
283
+ return null;
284
+ }
285
+ const expectedSignature = await signHmacBase64Url(secret, `${headerPart}.${payloadPart}`);
286
+ if (expectedSignature !== signaturePart) {
287
+ return null;
288
+ }
289
+ if (isJwtExpired(payload)) {
290
+ return null;
291
+ }
292
+ return payload;
293
+ }
294
+
295
+ // src/cookies/session-store.ts
296
+ var ALLOWED_COOKIE_SIZE = 4096;
297
+ var ESTIMATED_EMPTY_COOKIE_SIZE = 200;
298
+ var CHUNK_SIZE = ALLOWED_COOKIE_SIZE - ESTIMATED_EMPTY_COOKIE_SIZE;
299
+ function getChunkIndex(cookieName) {
300
+ const parts = cookieName.split(".");
301
+ const lastPart = parts[parts.length - 1];
302
+ const index = parseInt(lastPart || "0", 10);
303
+ return Number.isNaN(index) ? 0 : index;
304
+ }
305
+ function readExistingChunks(cookieName, ctx) {
306
+ const chunks = {};
307
+ const cookies = parseCookies(ctx.headers?.get("cookie") || "");
308
+ for (const [name, value] of cookies) {
309
+ if (name.startsWith(cookieName)) {
310
+ chunks[name] = value;
311
+ }
312
+ }
313
+ return chunks;
314
+ }
315
+ function joinChunks(chunks) {
316
+ const sortedKeys = Object.keys(chunks).sort((left, right) => getChunkIndex(left) - getChunkIndex(right));
317
+ return sortedKeys.map((key) => chunks[key]).join("");
318
+ }
319
+ function chunkCookie(storeName, cookie, chunks, ctx) {
320
+ const chunkCount = Math.ceil(cookie.value.length / CHUNK_SIZE);
321
+ if (chunkCount === 1) {
322
+ chunks[cookie.name] = cookie.value;
323
+ return [cookie];
324
+ }
325
+ const cookies = [];
326
+ for (let index = 0; index < chunkCount; index++) {
327
+ const name = `${cookie.name}.${index}`;
328
+ const start = index * CHUNK_SIZE;
329
+ const value = cookie.value.substring(start, start + CHUNK_SIZE);
330
+ cookies.push({
331
+ ...cookie,
332
+ name,
333
+ value
334
+ });
335
+ chunks[name] = value;
336
+ }
337
+ ctx.logger?.debug?.(`CHUNKING_${storeName.toUpperCase()}_COOKIE`, {
338
+ message: `${storeName} cookie exceeds allowed ${ALLOWED_COOKIE_SIZE} bytes.`,
339
+ emptyCookieSize: ESTIMATED_EMPTY_COOKIE_SIZE,
340
+ valueSize: cookie.value.length,
341
+ chunkCount,
342
+ chunks: cookies.map((entry) => entry.value.length + ESTIMATED_EMPTY_COOKIE_SIZE)
343
+ });
344
+ return cookies;
345
+ }
346
+ function getCleanCookies(chunks, cookieOptions) {
347
+ const cleanedChunks = {};
348
+ for (const name in chunks) {
349
+ cleanedChunks[name] = {
350
+ name,
351
+ value: "",
352
+ attributes: {
353
+ ...cookieOptions,
354
+ maxAge: 0
355
+ }
356
+ };
357
+ }
358
+ return cleanedChunks;
359
+ }
360
+ var storeFactory = (storeName) => (cookieName, cookieOptions, ctx) => {
361
+ const chunks = readExistingChunks(cookieName, ctx);
362
+ return {
363
+ getValue() {
364
+ return joinChunks(chunks);
365
+ },
366
+ hasChunks() {
367
+ return Object.keys(chunks).length > 0;
368
+ },
369
+ chunk(value, options) {
370
+ const cleanedChunks = getCleanCookies(chunks, cookieOptions);
371
+ for (const name in chunks) {
372
+ delete chunks[name];
373
+ }
374
+ const cookies = cleanedChunks;
375
+ const chunked = chunkCookie(
376
+ storeName,
377
+ {
378
+ name: cookieName,
379
+ value,
380
+ attributes: {
381
+ ...cookieOptions,
382
+ ...options
383
+ }
384
+ },
385
+ chunks,
386
+ ctx
387
+ );
388
+ for (const chunk of chunked) {
389
+ cookies[chunk.name] = chunk;
390
+ }
391
+ return Object.values(cookies);
392
+ },
393
+ clean() {
394
+ const cleanedChunks = getCleanCookies(chunks, cookieOptions);
395
+ for (const name in chunks) {
396
+ delete chunks[name];
397
+ }
398
+ return Object.values(cleanedChunks);
399
+ },
400
+ setCookies(cookies) {
401
+ for (const cookie of cookies) {
402
+ ctx.setCookie(cookie.name, cookie.value, cookie.attributes);
403
+ }
404
+ }
405
+ };
406
+ };
407
+ var createSessionStore = storeFactory("Session");
408
+ var createAccountStore = storeFactory("Account");
409
+
410
+ // src/cookies/index.ts
411
+ var DEFAULT_COOKIE_PREFIX = "athena-auth";
412
+ var LEGACY_COOKIE_PREFIX = "better-auth";
413
+ var DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60;
414
+ var DEFAULT_CACHE_MAX_AGE = 60 * 5;
415
+ function isProductionRuntime() {
416
+ return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
417
+ }
418
+ function getEnvironmentSecret() {
419
+ if (typeof process === "undefined") {
420
+ return void 0;
421
+ }
422
+ return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET;
423
+ }
424
+ function isDynamicBaseURLConfig(baseURL) {
425
+ return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
426
+ }
427
+ function resolveCookiePrefixes(primaryPrefix) {
428
+ const prefixes = [primaryPrefix];
429
+ if (!prefixes.includes(DEFAULT_COOKIE_PREFIX)) {
430
+ prefixes.push(DEFAULT_COOKIE_PREFIX);
431
+ }
432
+ if (!prefixes.includes(LEGACY_COOKIE_PREFIX)) {
433
+ prefixes.push(LEGACY_COOKIE_PREFIX);
434
+ }
435
+ return prefixes;
436
+ }
437
+ function createError(message) {
438
+ return new Error(`@xylex-group/athena/cookies: ${message}`);
439
+ }
440
+ function getSecretOrThrow(secret) {
441
+ const resolved = secret || getEnvironmentSecret();
442
+ if (!resolved) {
443
+ throw createError(
444
+ "getCookieCache requires a secret. Pass `secret` or set ATHENA_AUTH_SECRET/BETTER_AUTH_SECRET/AUTH_SECRET."
445
+ );
446
+ }
447
+ return resolved;
448
+ }
449
+ function asObject(value) {
450
+ if (!value || typeof value !== "object") {
451
+ return null;
452
+ }
453
+ return value;
454
+ }
455
+ function getSessionTokenFromPair(session) {
456
+ const token = session.session?.token;
457
+ if (typeof token !== "string" || token.length === 0) {
458
+ throw createError("setSessionCookie requires `session.session.token` to be a non-empty string.");
459
+ }
460
+ return token;
461
+ }
462
+ async function resolveCookieVersion(versionConfig, session, user) {
463
+ if (!versionConfig) {
464
+ return "1";
465
+ }
466
+ if (typeof versionConfig === "string") {
467
+ return versionConfig;
468
+ }
469
+ return versionConfig(session, user);
470
+ }
471
+ function getSessionCookieCacheName(cookiePrefix, cookieName, isSecure) {
472
+ return isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`;
473
+ }
474
+ async function setCookieValue(ctx, name, value, attributes) {
475
+ const secret = ctx.context.secret;
476
+ if (secret && typeof ctx.setSignedCookie === "function") {
477
+ await ctx.setSignedCookie(name, value, secret, attributes);
478
+ return;
479
+ }
480
+ ctx.setCookie(name, value, attributes);
481
+ }
482
+ function parseJsonSafely(value) {
483
+ try {
484
+ return JSON.parse(value);
485
+ } catch {
486
+ return null;
487
+ }
488
+ }
489
+ function getIsSecureCookie(config) {
490
+ if (config?.isSecure !== void 0) {
491
+ return config.isSecure;
492
+ }
493
+ return isProductionRuntime();
494
+ }
495
+ function createCookieGetter(options) {
496
+ const baseURLString = typeof options.baseURL === "string" ? options.baseURL : void 0;
497
+ const dynamicProtocol = typeof options.baseURL === "object" && options.baseURL !== null ? options.baseURL.protocol : void 0;
498
+ const secure = options.advanced?.useSecureCookies !== void 0 ? options.advanced.useSecureCookies : dynamicProtocol === "https" ? true : dynamicProtocol === "http" ? false : baseURLString ? baseURLString.startsWith("https://") : isProductionRuntime();
499
+ const secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : "";
500
+ const crossSubdomainEnabled = !!options.advanced?.crossSubDomainCookies?.enabled;
501
+ const domain = crossSubdomainEnabled ? options.advanced?.crossSubDomainCookies?.domain || (baseURLString ? new URL(baseURLString).hostname : void 0) : void 0;
502
+ if (crossSubdomainEnabled && !domain && !isDynamicBaseURLConfig(options.baseURL)) {
503
+ throw createError("baseURL is required when `crossSubDomainCookies.enabled` is true.");
504
+ }
505
+ function createCookie(cookieName, overrideAttributes = {}) {
506
+ const prefix = options.advanced?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
507
+ const name = options.advanced?.cookies?.[cookieName]?.name || `${prefix}.${cookieName}`;
508
+ const attributes = options.advanced?.cookies?.[cookieName]?.attributes || {};
509
+ return {
510
+ name: `${secureCookiePrefix}${name}`,
511
+ attributes: {
512
+ secure: !!secureCookiePrefix,
513
+ sameSite: "lax",
514
+ path: "/",
515
+ httpOnly: true,
516
+ ...crossSubdomainEnabled ? { domain } : {},
517
+ ...options.advanced?.defaultCookieAttributes,
518
+ ...overrideAttributes,
519
+ ...attributes
520
+ }
521
+ };
522
+ }
523
+ return createCookie;
524
+ }
525
+ function getCookies(options) {
526
+ const createCookie = createCookieGetter(options);
527
+ const sessionToken = createCookie("session_token", { maxAge: options.session?.expiresIn || DEFAULT_SESSION_MAX_AGE });
528
+ const sessionData = createCookie("session_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
529
+ const accountData = createCookie("account_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
530
+ const dontRememberToken = createCookie("dont_remember");
531
+ return {
532
+ sessionToken: {
533
+ name: sessionToken.name,
534
+ attributes: sessionToken.attributes
535
+ },
536
+ sessionData: {
537
+ name: sessionData.name,
538
+ attributes: sessionData.attributes
539
+ },
540
+ dontRememberToken: {
541
+ name: dontRememberToken.name,
542
+ attributes: dontRememberToken.attributes
543
+ },
544
+ accountData: {
545
+ name: accountData.name,
546
+ attributes: accountData.attributes
547
+ }
548
+ };
549
+ }
550
+ async function setCookieCache(ctx, session, dontRememberMe) {
551
+ const cookieCacheConfig = ctx.context.options?.session?.cookieCache;
552
+ if (!cookieCacheConfig?.enabled) {
553
+ return;
554
+ }
555
+ const version = await resolveCookieVersion(
556
+ cookieCacheConfig.version,
557
+ session.session,
558
+ session.user
559
+ );
560
+ const sessionData = {
561
+ session: session.session,
562
+ user: session.user,
563
+ updatedAt: Date.now(),
564
+ version
565
+ };
566
+ const baseAttributes = ctx.context.authCookies.sessionData.attributes;
567
+ const maxAge = dontRememberMe ? void 0 : baseAttributes.maxAge;
568
+ const options = {
569
+ ...baseAttributes,
570
+ maxAge
571
+ };
572
+ const expiresAt = Date.now() + (options.maxAge || 60) * 1e3;
573
+ const strategy = cookieCacheConfig.strategy || "compact";
574
+ const secret = getSecretOrThrow(ctx.context.secret);
575
+ let encoded;
576
+ if (strategy === "jwt") {
577
+ encoded = await signJwtHS256(sessionData, secret, options.maxAge || DEFAULT_CACHE_MAX_AGE);
578
+ } else if (strategy === "jwe") {
579
+ throw createError("`jwe` strategy is not supported by the SDK cookie helper.");
580
+ } else {
581
+ const signature = await signHmacBase64Url(
582
+ secret,
583
+ JSON.stringify({
584
+ ...sessionData,
585
+ expiresAt
586
+ })
587
+ );
588
+ encoded = encodeStringToBase64Url(
589
+ JSON.stringify({
590
+ session: sessionData,
591
+ expiresAt,
592
+ signature
593
+ })
594
+ );
595
+ }
596
+ if (encoded.length > 4093) {
597
+ const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
598
+ const cookies = store.chunk(encoded, options);
599
+ store.setCookies(cookies);
600
+ } else {
601
+ const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
602
+ if (store.hasChunks()) {
603
+ store.setCookies(store.clean());
604
+ }
605
+ ctx.setCookie(ctx.context.authCookies.sessionData.name, encoded, options);
606
+ }
607
+ }
608
+ async function setSessionCookie(ctx, session, dontRememberMe, overrides) {
609
+ if (dontRememberMe === void 0 && typeof ctx.getSignedCookie === "function" && ctx.context.secret) {
610
+ const existingFlag = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
611
+ dontRememberMe = !!existingFlag;
612
+ }
613
+ const resolvedDontRememberMe = dontRememberMe ?? false;
614
+ const token = getSessionTokenFromPair(session);
615
+ const options = ctx.context.authCookies.sessionToken.attributes;
616
+ const maxAge = resolvedDontRememberMe ? void 0 : ctx.context.sessionConfig?.expiresIn;
617
+ await setCookieValue(ctx, ctx.context.authCookies.sessionToken.name, token, {
618
+ ...options,
619
+ maxAge,
620
+ ...overrides
621
+ });
622
+ if (resolvedDontRememberMe) {
623
+ await setCookieValue(
624
+ ctx,
625
+ ctx.context.authCookies.dontRememberToken.name,
626
+ "true",
627
+ ctx.context.authCookies.dontRememberToken.attributes
628
+ );
629
+ }
630
+ await setCookieCache(ctx, session, resolvedDontRememberMe);
631
+ ctx.context.setNewSession?.(session);
632
+ }
633
+ function expireCookie(ctx, cookie) {
634
+ ctx.setCookie(cookie.name, "", {
635
+ ...cookie.attributes,
636
+ maxAge: 0
637
+ });
638
+ }
639
+ function deleteSessionCookie(ctx, skipDontRememberMe) {
640
+ expireCookie(ctx, ctx.context.authCookies.sessionToken);
641
+ expireCookie(ctx, ctx.context.authCookies.sessionData);
642
+ if (ctx.context.options?.account?.storeAccountCookie) {
643
+ expireCookie(ctx, ctx.context.authCookies.accountData);
644
+ const accountStore = createAccountStore(
645
+ ctx.context.authCookies.accountData.name,
646
+ ctx.context.authCookies.accountData.attributes,
647
+ ctx
648
+ );
649
+ accountStore.setCookies(accountStore.clean());
650
+ }
651
+ const sessionStore = createSessionStore(
652
+ ctx.context.authCookies.sessionData.name,
653
+ ctx.context.authCookies.sessionData.attributes,
654
+ ctx
655
+ );
656
+ sessionStore.setCookies(sessionStore.clean());
657
+ if (!skipDontRememberMe) {
658
+ expireCookie(ctx, ctx.context.authCookies.dontRememberToken);
659
+ }
660
+ }
139
661
  var getSessionCookie = (request, config) => {
140
662
  const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
141
663
  if (!cookies) {
142
664
  return null;
143
665
  }
144
- const { cookieName = "session_token", cookiePrefix = "athena-auth" } = {};
666
+ const { cookieName = "session_token", cookiePrefix = "athena-auth" } = config || {};
145
667
  const parsedCookie = parseCookies(cookies);
146
668
  const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
147
669
  const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
@@ -150,10 +672,126 @@ var getSessionCookie = (request, config) => {
150
672
  }
151
673
  return null;
152
674
  };
675
+ var getCookieCache = async (request, config) => {
676
+ const headers = request instanceof Headers || !("headers" in request) ? request : request.headers;
677
+ const cookieHeader = headers.get("cookie");
678
+ if (!cookieHeader) {
679
+ return null;
680
+ }
681
+ const parsedCookie = parseCookies(cookieHeader);
682
+ const cookieName = config?.cookieName || "session_data";
683
+ const requestedPrefix = config?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
684
+ const strategy = config?.strategy || "compact";
685
+ const cookiePrefixes = resolveCookiePrefixes(requestedPrefix);
686
+ const isSecure = getIsSecureCookie(config);
687
+ const secret = getSecretOrThrow(config?.secret);
688
+ let sessionData;
689
+ for (const prefix of cookiePrefixes) {
690
+ const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
691
+ const cookieValue = parsedCookie.get(candidate);
692
+ if (cookieValue) {
693
+ sessionData = cookieValue;
694
+ break;
695
+ }
696
+ }
697
+ if (!sessionData) {
698
+ const reconstructedChunks = [];
699
+ for (const prefix of cookiePrefixes) {
700
+ const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
701
+ for (const [name, value] of parsedCookie.entries()) {
702
+ if (!name.startsWith(`${candidate}.`)) {
703
+ continue;
704
+ }
705
+ const parts = name.split(".");
706
+ const indexStr = parts[parts.length - 1];
707
+ const index = parseInt(indexStr || "0", 10);
708
+ if (!Number.isNaN(index)) {
709
+ reconstructedChunks.push({ index, value });
710
+ }
711
+ }
712
+ if (reconstructedChunks.length > 0) {
713
+ break;
714
+ }
715
+ }
716
+ if (reconstructedChunks.length > 0) {
717
+ reconstructedChunks.sort((left, right) => left.index - right.index);
718
+ sessionData = reconstructedChunks.map((chunk) => chunk.value).join("");
719
+ }
720
+ }
721
+ if (!sessionData) {
722
+ return null;
723
+ }
724
+ if (strategy === "jwe") {
725
+ throw createError(
726
+ "`jwe` strategy is not supported by the SDK cookie helper. Use compact/jwt or pass cookie data through the auth server."
727
+ );
728
+ }
729
+ if (strategy === "jwt") {
730
+ const payload = await verifyJwtHS256(sessionData, secret);
731
+ if (!payload) {
732
+ return null;
733
+ }
734
+ const sessionRecord = asObject(payload.session);
735
+ const userRecord = asObject(payload.user);
736
+ const updatedAt = payload.updatedAt;
737
+ if (!sessionRecord || !userRecord || typeof updatedAt !== "number") {
738
+ return null;
739
+ }
740
+ if (config?.version) {
741
+ const cookieVersion = typeof payload.version === "string" ? payload.version : "1";
742
+ const expectedVersion = typeof config.version === "string" ? config.version : await config.version(sessionRecord, userRecord);
743
+ if (cookieVersion !== expectedVersion) {
744
+ return null;
745
+ }
746
+ }
747
+ return {
748
+ session: sessionRecord,
749
+ user: userRecord,
750
+ updatedAt,
751
+ version: typeof payload.version === "string" ? payload.version : void 0
752
+ };
753
+ }
754
+ const compactPayload = parseJsonSafely(decodeBase64UrlToString(sessionData));
755
+ if (!compactPayload) {
756
+ return null;
757
+ }
758
+ const expectedSignature = await signHmacBase64Url(
759
+ secret,
760
+ JSON.stringify({
761
+ ...compactPayload.session,
762
+ expiresAt: compactPayload.expiresAt
763
+ })
764
+ );
765
+ if (expectedSignature !== compactPayload.signature) {
766
+ return null;
767
+ }
768
+ if (compactPayload.expiresAt <= Date.now()) {
769
+ return null;
770
+ }
771
+ const resolvedSession = compactPayload.session;
772
+ if (config?.version) {
773
+ const cookieVersion = resolvedSession.version || "1";
774
+ const expectedVersion = typeof config.version === "string" ? config.version : await config.version(resolvedSession.session, resolvedSession.user);
775
+ if (cookieVersion !== expectedVersion) {
776
+ return null;
777
+ }
778
+ }
779
+ const sessionObject = asObject(resolvedSession.session);
780
+ const userObject = asObject(resolvedSession.user);
781
+ if (!sessionObject || !userObject) {
782
+ return null;
783
+ }
784
+ return {
785
+ session: sessionObject,
786
+ user: userObject,
787
+ updatedAt: resolvedSession.updatedAt,
788
+ version: resolvedSession.version
789
+ };
790
+ };
153
791
 
154
792
  // package.json
155
793
  var package_default = {
156
- version: "2.4.1"
794
+ version: "2.6.0"
157
795
  };
158
796
 
159
797
  // src/sdk-version.ts
@@ -2694,38 +3332,730 @@ async function withRetry(config, fn) {
2694
3332
  await sleep(delay);
2695
3333
  }
2696
3334
  }
2697
- throw new Error("withRetry reached an unexpected state");
3335
+ throw new Error("withRetry reached an unexpected state");
3336
+ }
3337
+
3338
+ // src/db/module.ts
3339
+ function createDbModule(input) {
3340
+ const db = {
3341
+ from(table, options) {
3342
+ return input.from(table, options);
3343
+ },
3344
+ select(table, columns, options) {
3345
+ return input.from(table).select(columns, options);
3346
+ },
3347
+ insert(table, values, options) {
3348
+ return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
3349
+ },
3350
+ upsert(table, values, options) {
3351
+ return Array.isArray(values) ? input.from(table).upsert(values, options) : input.from(table).upsert(values, options);
3352
+ },
3353
+ update(table, values, options) {
3354
+ return input.from(table).update(values, options);
3355
+ },
3356
+ delete(table, options) {
3357
+ return input.from(table).delete(options);
3358
+ },
3359
+ rpc(fn, args, options) {
3360
+ return input.rpc(fn, args, options);
3361
+ },
3362
+ query(query, options) {
3363
+ return input.query(query, options);
3364
+ }
3365
+ };
3366
+ return db;
3367
+ }
3368
+
3369
+ // src/storage/module.ts
3370
+ var storageSdkManifest = {
3371
+ namespace: "storage",
3372
+ basePath: "/storage",
3373
+ envelopeKinds: {
3374
+ raw: "response body is the payload",
3375
+ athena: "response body is { status, message, data }"
3376
+ },
3377
+ methods: [
3378
+ {
3379
+ name: "listStorageCatalogs",
3380
+ method: "GET",
3381
+ path: "/storage/catalogs",
3382
+ responseEnvelope: "raw",
3383
+ responseType: "{ data: S3CatalogItem[] }"
3384
+ },
3385
+ {
3386
+ name: "createStorageCatalog",
3387
+ method: "POST",
3388
+ path: "/storage/catalogs",
3389
+ requestType: "CreateStorageCatalogRequest",
3390
+ responseEnvelope: "raw",
3391
+ responseType: "S3CatalogItem"
3392
+ },
3393
+ {
3394
+ name: "updateStorageCatalog",
3395
+ method: "PATCH",
3396
+ path: "/storage/catalogs/{id}",
3397
+ pathParams: ["id"],
3398
+ requestType: "UpdateStorageCatalogRequest",
3399
+ responseEnvelope: "raw",
3400
+ responseType: "S3CatalogItem"
3401
+ },
3402
+ {
3403
+ name: "deleteStorageCatalog",
3404
+ method: "DELETE",
3405
+ path: "/storage/catalogs/{id}",
3406
+ pathParams: ["id"],
3407
+ responseEnvelope: "raw",
3408
+ responseType: "{ id: string; deleted: boolean }"
3409
+ },
3410
+ {
3411
+ name: "listStorageCredentials",
3412
+ method: "GET",
3413
+ path: "/storage/credentials",
3414
+ responseEnvelope: "raw",
3415
+ responseType: "{ data: S3CredentialListItem[] }"
3416
+ },
3417
+ {
3418
+ name: "createStorageUploadUrl",
3419
+ method: "POST",
3420
+ path: "/storage/files/upload-url",
3421
+ requestType: "CreateStorageUploadUrlRequest",
3422
+ responseEnvelope: "athena",
3423
+ responseType: "StorageUploadUrlResponse"
3424
+ },
3425
+ {
3426
+ name: "createStorageUploadUrls",
3427
+ method: "POST",
3428
+ path: "/storage/files/upload-urls",
3429
+ requestType: "CreateStorageUploadUrlsRequest",
3430
+ responseEnvelope: "athena",
3431
+ responseType: "StorageBatchUploadUrlResponse"
3432
+ },
3433
+ {
3434
+ name: "listStorageFiles",
3435
+ method: "POST",
3436
+ path: "/storage/files/list",
3437
+ requestType: "ListStorageFilesRequest",
3438
+ responseEnvelope: "athena",
3439
+ responseType: "StorageListFilesResponse"
3440
+ },
3441
+ {
3442
+ name: "getStorageFile",
3443
+ method: "GET",
3444
+ path: "/storage/files/{file_id}",
3445
+ pathParams: ["file_id"],
3446
+ responseEnvelope: "athena",
3447
+ responseType: "StorageFileMutationResponse"
3448
+ },
3449
+ {
3450
+ name: "getStorageFileUrl",
3451
+ method: "GET",
3452
+ path: "/storage/files/{file_id}/url",
3453
+ pathParams: ["file_id"],
3454
+ queryParams: ["purpose"],
3455
+ responseEnvelope: "athena",
3456
+ responseType: "PresignedFileUrlResponse"
3457
+ },
3458
+ {
3459
+ name: "getStorageFileProxy",
3460
+ method: "GET",
3461
+ path: "/storage/files/{file_id}/proxy",
3462
+ pathParams: ["file_id"],
3463
+ queryParams: ["purpose"],
3464
+ responseEnvelope: "raw",
3465
+ responseType: "Response",
3466
+ binary: true
3467
+ },
3468
+ {
3469
+ name: "updateStorageFile",
3470
+ method: "PATCH",
3471
+ path: "/storage/files/{file_id}",
3472
+ pathParams: ["file_id"],
3473
+ requestType: "UpdateStorageFileRequest",
3474
+ responseEnvelope: "athena",
3475
+ responseType: "StorageFileMutationResponse"
3476
+ },
3477
+ {
3478
+ name: "deleteStorageFile",
3479
+ method: "DELETE",
3480
+ path: "/storage/files/{file_id}",
3481
+ pathParams: ["file_id"],
3482
+ responseEnvelope: "athena",
3483
+ responseType: "StorageFileMutationResponse"
3484
+ },
3485
+ {
3486
+ name: "setStorageFileVisibility",
3487
+ method: "PATCH",
3488
+ path: "/storage/files/{file_id}/visibility",
3489
+ pathParams: ["file_id"],
3490
+ requestType: "SetStorageFileVisibilityRequest",
3491
+ responseEnvelope: "athena",
3492
+ responseType: "StorageFileMutationResponse"
3493
+ },
3494
+ {
3495
+ name: "deleteStorageFolder",
3496
+ method: "POST",
3497
+ path: "/storage/folders/delete",
3498
+ requestType: "DeleteStorageFolderRequest",
3499
+ responseEnvelope: "athena",
3500
+ responseType: "StorageFolderMutationResponse"
3501
+ },
3502
+ {
3503
+ name: "moveStorageFolder",
3504
+ method: "POST",
3505
+ path: "/storage/folders/move",
3506
+ requestType: "MoveStorageFolderRequest",
3507
+ responseEnvelope: "athena",
3508
+ responseType: "StorageFolderMutationResponse"
3509
+ }
3510
+ ]
3511
+ };
3512
+ var AthenaStorageErrorCode = {
3513
+ InvalidUrl: "INVALID_URL",
3514
+ NetworkError: "NETWORK_ERROR",
3515
+ HttpError: "HTTP_ERROR",
3516
+ InvalidJson: "INVALID_JSON",
3517
+ InvalidAthenaEnvelope: "INVALID_ATHENA_ENVELOPE",
3518
+ UnknownError: "UNKNOWN_ERROR"
3519
+ };
3520
+ var AthenaStorageError = class extends Error {
3521
+ code;
3522
+ athenaCode;
3523
+ kind;
3524
+ category;
3525
+ retryable;
3526
+ status;
3527
+ endpoint;
3528
+ method;
3529
+ requestId;
3530
+ hint;
3531
+ causeDetail;
3532
+ raw;
3533
+ normalized;
3534
+ __athenaNormalizedError;
3535
+ constructor(input) {
3536
+ super(input.message, { cause: input.cause });
3537
+ this.name = "AthenaStorageError";
3538
+ this.code = input.code;
3539
+ this.status = input.status;
3540
+ this.endpoint = input.endpoint;
3541
+ this.method = input.method;
3542
+ this.requestId = input.requestId;
3543
+ this.hint = input.hint;
3544
+ this.causeDetail = causeToString(input.cause);
3545
+ this.raw = input.raw ?? null;
3546
+ this.normalized = normalizeStorageErrorInput(input);
3547
+ this.__athenaNormalizedError = this.normalized;
3548
+ this.athenaCode = this.normalized.code;
3549
+ this.kind = this.normalized.kind;
3550
+ this.category = this.normalized.category;
3551
+ this.retryable = this.normalized.retryable;
3552
+ Object.defineProperty(this, "__athenaNormalizedError", {
3553
+ value: this.normalized,
3554
+ enumerable: false,
3555
+ configurable: false,
3556
+ writable: false
3557
+ });
3558
+ }
3559
+ toDetails() {
3560
+ return {
3561
+ code: this.code,
3562
+ athenaCode: this.athenaCode,
3563
+ kind: this.kind,
3564
+ category: this.category,
3565
+ retryable: this.retryable,
3566
+ message: this.message,
3567
+ status: this.status,
3568
+ endpoint: this.endpoint,
3569
+ method: this.method,
3570
+ requestId: this.requestId,
3571
+ hint: this.hint,
3572
+ cause: this.causeDetail,
3573
+ raw: this.raw
3574
+ };
3575
+ }
3576
+ };
3577
+ function isRecord5(value) {
3578
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3579
+ }
3580
+ function causeToString(cause) {
3581
+ if (cause === void 0 || cause === null) return void 0;
3582
+ if (typeof cause === "string") return cause;
3583
+ if (cause instanceof Error && cause.message.trim()) return cause.message.trim();
3584
+ try {
3585
+ return JSON.stringify(cause);
3586
+ } catch {
3587
+ return String(cause);
3588
+ }
3589
+ }
3590
+ function storageGatewayCode(code) {
3591
+ if (code === "INVALID_URL") return "INVALID_URL";
3592
+ if (code === "NETWORK_ERROR") return "NETWORK_ERROR";
3593
+ if (code === "INVALID_JSON" || code === "INVALID_ATHENA_ENVELOPE") return "INVALID_JSON";
3594
+ if (code === "HTTP_ERROR") return "HTTP_ERROR";
3595
+ return "UNKNOWN_ERROR";
3596
+ }
3597
+ function headerValue(headers, names) {
3598
+ for (const name of names) {
3599
+ const value = headers.get(name);
3600
+ if (value?.trim()) return value.trim();
3601
+ }
3602
+ return void 0;
3603
+ }
3604
+ function storageOperationFromEndpoint(endpoint, method) {
3605
+ const endpointPath = String(endpoint).split("?")[0];
3606
+ for (const candidate of storageSdkManifest.methods) {
3607
+ if (candidate.method !== method) continue;
3608
+ const pattern = `^${candidate.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\\\{[^/]+\\\}/g, "[^/]+")}$`;
3609
+ if (new RegExp(pattern).test(endpointPath)) {
3610
+ return candidate.name;
3611
+ }
3612
+ }
3613
+ return `storage:${method.toLowerCase()}`;
3614
+ }
3615
+ function normalizeStorageErrorInput(input) {
3616
+ return normalizeAthenaError(
3617
+ {
3618
+ data: null,
3619
+ error: {
3620
+ message: input.message,
3621
+ gatewayCode: storageGatewayCode(input.code),
3622
+ status: input.status,
3623
+ raw: input.raw ?? input.cause ?? null
3624
+ },
3625
+ errorDetails: {
3626
+ code: storageGatewayCode(input.code),
3627
+ message: input.message,
3628
+ status: input.status,
3629
+ endpoint: input.endpoint,
3630
+ method: input.method,
3631
+ requestId: input.requestId,
3632
+ hint: input.hint,
3633
+ cause: causeToString(input.cause)
3634
+ },
3635
+ raw: input.raw ?? input.cause ?? null,
3636
+ status: input.status
3637
+ },
3638
+ { operation: storageOperationFromEndpoint(input.endpoint, input.method) }
3639
+ );
3640
+ }
3641
+ function createAthenaStorageError(input) {
3642
+ return new AthenaStorageError(input);
3643
+ }
3644
+ async function notifyStorageError(error, options, runtimeOptions) {
3645
+ const handlers = [runtimeOptions?.onError, options?.onError].filter(
3646
+ (handler) => typeof handler === "function"
3647
+ );
3648
+ for (const handler of handlers) {
3649
+ try {
3650
+ await handler(error);
3651
+ } catch {
3652
+ }
3653
+ }
3654
+ }
3655
+ async function rejectStorageError(input, options, runtimeOptions) {
3656
+ const error = createAthenaStorageError(input);
3657
+ await notifyStorageError(error, options, runtimeOptions);
3658
+ throw error;
3659
+ }
3660
+ function parseResponseBody3(rawText, contentType) {
3661
+ if (!rawText) {
3662
+ return { parsed: null, parseFailed: false };
3663
+ }
3664
+ const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
3665
+ const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
3666
+ if (!looksJson) {
3667
+ return { parsed: rawText, parseFailed: false };
3668
+ }
3669
+ try {
3670
+ return { parsed: JSON.parse(rawText), parseFailed: false };
3671
+ } catch {
3672
+ return { parsed: rawText, parseFailed: true };
3673
+ }
3674
+ }
3675
+ function appendQuery(path, query) {
3676
+ if (!query) return path;
3677
+ const params = new URLSearchParams();
3678
+ for (const [key, value] of Object.entries(query)) {
3679
+ if (value === void 0 || value === null) continue;
3680
+ params.set(key, String(value));
3681
+ }
3682
+ const queryText = params.toString();
3683
+ return queryText ? `${path}?${queryText}` : path;
3684
+ }
3685
+ function storagePath(path) {
3686
+ return path;
3687
+ }
3688
+ function withPathParam(path, name, value) {
3689
+ return path.replace(`{${name}}`, encodeURIComponent(value));
3690
+ }
3691
+ function resolveErrorMessage3(payload, fallback) {
3692
+ if (isRecord5(payload)) {
3693
+ const message = payload.message ?? payload.error ?? payload.details;
3694
+ if (typeof message === "string" && message.trim()) {
3695
+ return message.trim();
3696
+ }
3697
+ }
3698
+ if (typeof payload === "string" && payload.trim()) {
3699
+ return payload.trim();
3700
+ }
3701
+ return fallback;
3702
+ }
3703
+ function resolveErrorHint2(payload) {
3704
+ if (!isRecord5(payload)) return void 0;
3705
+ const hint = payload.hint ?? payload.suggestion;
3706
+ return typeof hint === "string" && hint.trim() ? hint.trim() : void 0;
3707
+ }
3708
+ function resolveErrorCause(payload) {
3709
+ if (!isRecord5(payload)) return void 0;
3710
+ const cause = payload.cause ?? payload.reason;
3711
+ return typeof cause === "string" && cause.trim() ? cause.trim() : void 0;
3712
+ }
3713
+ function storageCodeFromUnknown(error) {
3714
+ if (isAthenaGatewayError(error)) {
3715
+ if (error.code === "INVALID_URL") return "INVALID_URL";
3716
+ if (error.code === "NETWORK_ERROR") return "NETWORK_ERROR";
3717
+ if (error.code === "INVALID_JSON") return "INVALID_JSON";
3718
+ if (error.code === "HTTP_ERROR") return "HTTP_ERROR";
3719
+ }
3720
+ return "UNKNOWN_ERROR";
3721
+ }
3722
+ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload, options, runtimeOptions) {
3723
+ let url;
3724
+ let headers;
3725
+ try {
3726
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3727
+ url = buildAthenaGatewayUrl(baseUrl, endpoint);
3728
+ headers = gateway.buildHeaders(options);
3729
+ } catch (error) {
3730
+ return rejectStorageError(
3731
+ {
3732
+ code: storageCodeFromUnknown(error),
3733
+ message: error instanceof Error ? error.message : `Athena storage ${method} ${endpoint} failed before sending the request`,
3734
+ status: isAthenaGatewayError(error) ? error.status : 0,
3735
+ endpoint,
3736
+ method,
3737
+ raw: error,
3738
+ requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
3739
+ hint: isAthenaGatewayError(error) ? error.hint : void 0,
3740
+ cause: error
3741
+ },
3742
+ options,
3743
+ runtimeOptions
3744
+ );
3745
+ }
3746
+ const requestInit = {
3747
+ method,
3748
+ headers,
3749
+ signal: options?.signal
3750
+ };
3751
+ if (payload !== void 0 && method !== "GET") {
3752
+ requestInit.body = JSON.stringify(payload);
3753
+ }
3754
+ let response;
3755
+ try {
3756
+ response = await fetch(url, requestInit);
3757
+ } catch (error) {
3758
+ const message = error instanceof Error ? error.message : String(error);
3759
+ return rejectStorageError(
3760
+ {
3761
+ code: "NETWORK_ERROR",
3762
+ message: `Network error while calling Athena storage ${method} ${endpoint}: ${message}`,
3763
+ status: 0,
3764
+ endpoint,
3765
+ method,
3766
+ cause: error
3767
+ },
3768
+ options,
3769
+ runtimeOptions
3770
+ );
3771
+ }
3772
+ let rawText;
3773
+ try {
3774
+ rawText = await response.text();
3775
+ } catch (error) {
3776
+ return rejectStorageError(
3777
+ {
3778
+ code: "NETWORK_ERROR",
3779
+ message: `Athena storage ${method} ${endpoint} response body could not be read`,
3780
+ status: response.status,
3781
+ endpoint,
3782
+ method,
3783
+ requestId: headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]),
3784
+ cause: error
3785
+ },
3786
+ options,
3787
+ runtimeOptions
3788
+ );
3789
+ }
3790
+ const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
3791
+ const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
3792
+ if (parsedBody.parseFailed) {
3793
+ return rejectStorageError(
3794
+ {
3795
+ code: "INVALID_JSON",
3796
+ message: `Athena storage ${method} ${endpoint} returned malformed JSON`,
3797
+ status: response.status,
3798
+ endpoint,
3799
+ method,
3800
+ requestId,
3801
+ raw: parsedBody.parsed
3802
+ },
3803
+ options,
3804
+ runtimeOptions
3805
+ );
3806
+ }
3807
+ if (!response.ok) {
3808
+ return rejectStorageError(
3809
+ {
3810
+ code: "HTTP_ERROR",
3811
+ message: resolveErrorMessage3(
3812
+ parsedBody.parsed,
3813
+ `Athena storage ${method} ${endpoint} failed with status ${response.status}`
3814
+ ),
3815
+ status: response.status,
3816
+ endpoint,
3817
+ method,
3818
+ requestId,
3819
+ hint: resolveErrorHint2(parsedBody.parsed),
3820
+ cause: resolveErrorCause(parsedBody.parsed),
3821
+ raw: parsedBody.parsed
3822
+ },
3823
+ options,
3824
+ runtimeOptions
3825
+ );
3826
+ }
3827
+ if (envelope === "athena") {
3828
+ if (!isRecord5(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
3829
+ return rejectStorageError(
3830
+ {
3831
+ code: "INVALID_ATHENA_ENVELOPE",
3832
+ message: `Athena storage ${method} ${endpoint} returned an invalid Athena envelope`,
3833
+ status: response.status,
3834
+ endpoint,
3835
+ method,
3836
+ requestId,
3837
+ raw: parsedBody.parsed
3838
+ },
3839
+ options,
3840
+ runtimeOptions
3841
+ );
3842
+ }
3843
+ return parsedBody.parsed.data;
3844
+ }
3845
+ return parsedBody.parsed;
3846
+ }
3847
+ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, runtimeOptions) {
3848
+ let url;
3849
+ let headers;
3850
+ try {
3851
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3852
+ url = buildAthenaGatewayUrl(baseUrl, endpoint);
3853
+ headers = gateway.buildHeaders(options);
3854
+ } catch (error) {
3855
+ return rejectStorageError(
3856
+ {
3857
+ code: storageCodeFromUnknown(error),
3858
+ message: error instanceof Error ? error.message : `Athena storage ${method} ${endpoint} failed before sending the request`,
3859
+ status: isAthenaGatewayError(error) ? error.status : 0,
3860
+ endpoint,
3861
+ method,
3862
+ raw: error,
3863
+ requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
3864
+ hint: isAthenaGatewayError(error) ? error.hint : void 0,
3865
+ cause: error
3866
+ },
3867
+ options,
3868
+ runtimeOptions
3869
+ );
3870
+ }
3871
+ let response;
3872
+ try {
3873
+ response = await fetch(url, {
3874
+ method,
3875
+ headers,
3876
+ signal: options?.signal
3877
+ });
3878
+ } catch (error) {
3879
+ const message = error instanceof Error ? error.message : String(error);
3880
+ return rejectStorageError(
3881
+ {
3882
+ code: "NETWORK_ERROR",
3883
+ message: `Network error while calling Athena storage ${method} ${endpoint}: ${message}`,
3884
+ status: 0,
3885
+ endpoint,
3886
+ method,
3887
+ cause: error
3888
+ },
3889
+ options,
3890
+ runtimeOptions
3891
+ );
3892
+ }
3893
+ if (response.ok) {
3894
+ return response;
3895
+ }
3896
+ const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
3897
+ let rawErrorBody = null;
3898
+ try {
3899
+ const rawText = await response.text();
3900
+ const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
3901
+ rawErrorBody = parsedBody.parsed;
3902
+ } catch (error) {
3903
+ return rejectStorageError(
3904
+ {
3905
+ code: "NETWORK_ERROR",
3906
+ message: `Athena storage ${method} ${endpoint} error response body could not be read`,
3907
+ status: response.status,
3908
+ endpoint,
3909
+ method,
3910
+ requestId,
3911
+ cause: error
3912
+ },
3913
+ options,
3914
+ runtimeOptions
3915
+ );
3916
+ }
3917
+ return rejectStorageError(
3918
+ {
3919
+ code: "HTTP_ERROR",
3920
+ message: resolveErrorMessage3(
3921
+ rawErrorBody,
3922
+ `Athena storage ${method} ${endpoint} failed with status ${response.status}`
3923
+ ),
3924
+ status: response.status,
3925
+ endpoint,
3926
+ method,
3927
+ requestId,
3928
+ hint: resolveErrorHint2(rawErrorBody),
3929
+ cause: resolveErrorCause(rawErrorBody),
3930
+ raw: rawErrorBody
3931
+ },
3932
+ options,
3933
+ runtimeOptions
3934
+ );
2698
3935
  }
2699
-
2700
- // src/db/module.ts
2701
- function createDbModule(input) {
2702
- const db = {
2703
- from(table, options) {
2704
- return input.from(table, options);
3936
+ function createStorageModule(gateway, runtimeOptions) {
3937
+ return {
3938
+ listStorageCatalogs(options) {
3939
+ return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "GET", "raw", void 0, options, runtimeOptions);
2705
3940
  },
2706
- select(table, columns, options) {
2707
- return input.from(table).select(columns, options);
3941
+ createStorageCatalog(input, options) {
3942
+ return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "POST", "raw", input, options, runtimeOptions);
2708
3943
  },
2709
- insert(table, values, options) {
2710
- return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
3944
+ updateStorageCatalog(id, input, options) {
3945
+ return callStorageEndpoint(
3946
+ gateway,
3947
+ storagePath(withPathParam("/storage/catalogs/{id}", "id", id)),
3948
+ "PATCH",
3949
+ "raw",
3950
+ input,
3951
+ options,
3952
+ runtimeOptions
3953
+ );
2711
3954
  },
2712
- upsert(table, values, options) {
2713
- return Array.isArray(values) ? input.from(table).upsert(values, options) : input.from(table).upsert(values, options);
3955
+ deleteStorageCatalog(id, options) {
3956
+ return callStorageEndpoint(
3957
+ gateway,
3958
+ storagePath(withPathParam("/storage/catalogs/{id}", "id", id)),
3959
+ "DELETE",
3960
+ "raw",
3961
+ void 0,
3962
+ options,
3963
+ runtimeOptions
3964
+ );
2714
3965
  },
2715
- update(table, values, options) {
2716
- return input.from(table).update(values, options);
3966
+ listStorageCredentials(options) {
3967
+ return callStorageEndpoint(gateway, storagePath("/storage/credentials"), "GET", "raw", void 0, options, runtimeOptions);
2717
3968
  },
2718
- delete(table, options) {
2719
- return input.from(table).delete(options);
3969
+ createStorageUploadUrl(input, options) {
3970
+ return callStorageEndpoint(
3971
+ gateway,
3972
+ storagePath("/storage/files/upload-url"),
3973
+ "POST",
3974
+ "athena",
3975
+ input,
3976
+ options,
3977
+ runtimeOptions
3978
+ );
2720
3979
  },
2721
- rpc(fn, args, options) {
2722
- return input.rpc(fn, args, options);
3980
+ createStorageUploadUrls(input, options) {
3981
+ return callStorageEndpoint(
3982
+ gateway,
3983
+ storagePath("/storage/files/upload-urls"),
3984
+ "POST",
3985
+ "athena",
3986
+ input,
3987
+ options,
3988
+ runtimeOptions
3989
+ );
2723
3990
  },
2724
- query(query, options) {
2725
- return input.query(query, options);
3991
+ listStorageFiles(input, options) {
3992
+ return callStorageEndpoint(gateway, storagePath("/storage/files/list"), "POST", "athena", input, options, runtimeOptions);
3993
+ },
3994
+ getStorageFile(fileId, options) {
3995
+ return callStorageEndpoint(
3996
+ gateway,
3997
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
3998
+ "GET",
3999
+ "athena",
4000
+ void 0,
4001
+ options,
4002
+ runtimeOptions
4003
+ );
4004
+ },
4005
+ getStorageFileUrl(fileId, query, options) {
4006
+ const path = appendQuery(
4007
+ withPathParam("/storage/files/{file_id}/url", "file_id", fileId),
4008
+ query
4009
+ );
4010
+ return callStorageEndpoint(gateway, storagePath(path), "GET", "athena", void 0, options, runtimeOptions);
4011
+ },
4012
+ getStorageFileProxy(fileId, query, options) {
4013
+ const path = appendQuery(
4014
+ withPathParam("/storage/files/{file_id}/proxy", "file_id", fileId),
4015
+ query
4016
+ );
4017
+ return callStorageBinaryEndpoint(gateway, storagePath(path), "GET", options, runtimeOptions);
4018
+ },
4019
+ updateStorageFile(fileId, input, options) {
4020
+ return callStorageEndpoint(
4021
+ gateway,
4022
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4023
+ "PATCH",
4024
+ "athena",
4025
+ input,
4026
+ options,
4027
+ runtimeOptions
4028
+ );
4029
+ },
4030
+ deleteStorageFile(fileId, options) {
4031
+ return callStorageEndpoint(
4032
+ gateway,
4033
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4034
+ "DELETE",
4035
+ "athena",
4036
+ void 0,
4037
+ options,
4038
+ runtimeOptions
4039
+ );
4040
+ },
4041
+ setStorageFileVisibility(fileId, input, options) {
4042
+ return callStorageEndpoint(
4043
+ gateway,
4044
+ storagePath(withPathParam("/storage/files/{file_id}/visibility", "file_id", fileId)),
4045
+ "PATCH",
4046
+ "athena",
4047
+ input,
4048
+ options,
4049
+ runtimeOptions
4050
+ );
4051
+ },
4052
+ deleteStorageFolder(input, options) {
4053
+ return callStorageEndpoint(gateway, storagePath("/storage/folders/delete"), "POST", "athena", input, options, runtimeOptions);
4054
+ },
4055
+ moveStorageFolder(input, options) {
4056
+ return callStorageEndpoint(gateway, storagePath("/storage/folders/move"), "POST", "athena", input, options, runtimeOptions);
2726
4057
  }
2727
4058
  };
2728
- return db;
2729
4059
  }
2730
4060
 
2731
4061
  // src/query-ast.ts
@@ -2755,7 +4085,7 @@ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
2755
4085
  "ilike",
2756
4086
  "is"
2757
4087
  ]);
2758
- function isRecord5(value) {
4088
+ function isRecord6(value) {
2759
4089
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2760
4090
  }
2761
4091
  function isUuidString(value) {
@@ -2768,7 +4098,7 @@ function shouldUseUuidTextComparison(column, value) {
2768
4098
  return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
2769
4099
  }
2770
4100
  function isRelationSelectNode(value) {
2771
- return isRecord5(value) && isRecord5(value.select);
4101
+ return isRecord6(value) && isRecord6(value.select);
2772
4102
  }
2773
4103
  function normalizeIdentifier(value, label) {
2774
4104
  const normalized = value.trim();
@@ -2824,7 +4154,7 @@ function compileRelationToken(key, node) {
2824
4154
  return `${prefix}${relationToken}(${nested})`;
2825
4155
  }
2826
4156
  function compileSelectShape(select) {
2827
- if (!isRecord5(select)) {
4157
+ if (!isRecord6(select)) {
2828
4158
  throw new Error("findMany select must be an object");
2829
4159
  }
2830
4160
  const tokens = [];
@@ -2848,7 +4178,7 @@ function compileSelectShape(select) {
2848
4178
  return tokens.join(",");
2849
4179
  }
2850
4180
  function selectShapeUsesRelationSchema(select) {
2851
- if (!isRecord5(select)) {
4181
+ if (!isRecord6(select)) {
2852
4182
  return false;
2853
4183
  }
2854
4184
  for (const rawValue of Object.values(select)) {
@@ -2866,7 +4196,7 @@ function selectShapeUsesRelationSchema(select) {
2866
4196
  }
2867
4197
  function compileColumnWhere(column, input) {
2868
4198
  const normalizedColumn = normalizeIdentifier(column, "where column");
2869
- if (!isRecord5(input)) {
4199
+ if (!isRecord6(input)) {
2870
4200
  return [buildGatewayCondition("eq", normalizedColumn, input)];
2871
4201
  }
2872
4202
  const conditions = [];
@@ -2894,7 +4224,7 @@ function compileColumnWhere(column, input) {
2894
4224
  return conditions;
2895
4225
  }
2896
4226
  function compileBooleanExpressionTerms(clause, label) {
2897
- if (!isRecord5(clause)) {
4227
+ if (!isRecord6(clause)) {
2898
4228
  throw new Error(`findMany where.${label} clauses must be objects`);
2899
4229
  }
2900
4230
  const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
@@ -2903,7 +4233,7 @@ function compileBooleanExpressionTerms(clause, label) {
2903
4233
  }
2904
4234
  const [rawColumn, rawValue] = entries[0];
2905
4235
  const column = normalizeIdentifier(rawColumn, `where.${label} column`);
2906
- if (!isRecord5(rawValue)) {
4236
+ if (!isRecord6(rawValue)) {
2907
4237
  return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
2908
4238
  }
2909
4239
  const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
@@ -2927,7 +4257,7 @@ function compileWhere(where) {
2927
4257
  if (where === void 0) {
2928
4258
  return void 0;
2929
4259
  }
2930
- if (!isRecord5(where)) {
4260
+ if (!isRecord6(where)) {
2931
4261
  throw new Error("findMany where must be an object");
2932
4262
  }
2933
4263
  const conditions = [];
@@ -2977,7 +4307,7 @@ function compileOrderBy(orderBy) {
2977
4307
  if (orderBy === void 0) {
2978
4308
  return void 0;
2979
4309
  }
2980
- if (!isRecord5(orderBy)) {
4310
+ if (!isRecord6(orderBy)) {
2981
4311
  throw new Error("findMany orderBy must be an object");
2982
4312
  }
2983
4313
  if ("column" in orderBy) {
@@ -3152,11 +4482,11 @@ function toFindManyAstOrder(order) {
3152
4482
  ascending: order.direction !== "descending"
3153
4483
  };
3154
4484
  }
3155
- function isRecord6(value) {
4485
+ function isRecord7(value) {
3156
4486
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3157
4487
  }
3158
4488
  function normalizeFindManyAstColumnPredicate(value) {
3159
- if (!isRecord6(value)) {
4489
+ if (!isRecord7(value)) {
3160
4490
  return {
3161
4491
  eq: value
3162
4492
  };
@@ -3180,7 +4510,7 @@ function normalizeFindManyAstBooleanOperand(clause) {
3180
4510
  return normalized;
3181
4511
  }
3182
4512
  function normalizeFindManyAstWhere(where) {
3183
- if (!where || !isRecord6(where)) {
4513
+ if (!where || !isRecord7(where)) {
3184
4514
  return where;
3185
4515
  }
3186
4516
  const normalized = {};
@@ -3194,7 +4524,7 @@ function normalizeFindManyAstWhere(where) {
3194
4524
  );
3195
4525
  continue;
3196
4526
  }
3197
- if (key === "not" && isRecord6(value)) {
4527
+ if (key === "not" && isRecord7(value)) {
3198
4528
  normalized.not = normalizeFindManyAstBooleanOperand(
3199
4529
  value
3200
4530
  );
@@ -3205,7 +4535,7 @@ function normalizeFindManyAstWhere(where) {
3205
4535
  return normalized;
3206
4536
  }
3207
4537
  function predicateRequiresUuidQueryFallback(column, value) {
3208
- if (!isRecord6(value)) {
4538
+ if (!isRecord7(value)) {
3209
4539
  return shouldUseUuidTextComparison(column, value);
3210
4540
  }
3211
4541
  const eqValue = value.eq;
@@ -3223,7 +4553,7 @@ function booleanOperandRequiresUuidQueryFallback(clause) {
3223
4553
  return false;
3224
4554
  }
3225
4555
  function findManyAstWhereRequiresLegacyTransport(where) {
3226
- if (!where || !isRecord6(where)) {
4556
+ if (!where || !isRecord7(where)) {
3227
4557
  return false;
3228
4558
  }
3229
4559
  for (const [key, value] of Object.entries(where)) {
@@ -3238,7 +4568,7 @@ function findManyAstWhereRequiresLegacyTransport(where) {
3238
4568
  }
3239
4569
  continue;
3240
4570
  }
3241
- if (key === "not" && isRecord6(value)) {
4571
+ if (key === "not" && isRecord7(value)) {
3242
4572
  if (booleanOperandRequiresUuidQueryFallback(value)) {
3243
4573
  return true;
3244
4574
  }
@@ -3440,7 +4770,7 @@ async function executeExperimentalRead(experimental, runner) {
3440
4770
  throw error;
3441
4771
  }
3442
4772
  }
3443
- function isRecord7(value) {
4773
+ function isRecord8(value) {
3444
4774
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3445
4775
  }
3446
4776
  function firstNonEmptyString2(...values) {
@@ -3452,8 +4782,8 @@ function firstNonEmptyString2(...values) {
3452
4782
  return void 0;
3453
4783
  }
3454
4784
  function resolveStructuredErrorPayload2(raw) {
3455
- if (!isRecord7(raw)) return null;
3456
- return isRecord7(raw.error) ? raw.error : raw;
4785
+ if (!isRecord8(raw)) return null;
4786
+ return isRecord8(raw.error) ? raw.error : raw;
3457
4787
  }
3458
4788
  function resolveStructuredErrorDetails(payload, message) {
3459
4789
  if (!payload || !("details" in payload)) {
@@ -3469,7 +4799,7 @@ function resolveStructuredErrorDetails(payload, message) {
3469
4799
  return details;
3470
4800
  }
3471
4801
  function createResultError(response, result, normalized) {
3472
- const rawRecord = isRecord7(response.raw) ? response.raw : null;
4802
+ const rawRecord = isRecord8(response.raw) ? response.raw : null;
3473
4803
  const payload = resolveStructuredErrorPayload2(response.raw);
3474
4804
  const message = firstNonEmptyString2(
3475
4805
  response.error,
@@ -4932,7 +6262,7 @@ function createClientFromConfig(config) {
4932
6262
  };
4933
6263
  const query = createQueryBuilder(gateway, formatGatewayResult, config.experimental, queryTracer);
4934
6264
  const db = createDbModule({ from, rpc, query });
4935
- return {
6265
+ const sdkClient = {
4936
6266
  from,
4937
6267
  db,
4938
6268
  rpc,
@@ -4940,6 +6270,14 @@ function createClientFromConfig(config) {
4940
6270
  verifyConnection: gateway.verifyConnection,
4941
6271
  auth: auth.auth
4942
6272
  };
6273
+ if (config.experimental?.athenaStorageBackend) {
6274
+ const storageClient = {
6275
+ ...sdkClient,
6276
+ storage: createStorageModule(gateway, config.experimental.storage)
6277
+ };
6278
+ return storageClient;
6279
+ }
6280
+ return sdkClient;
4943
6281
  }
4944
6282
  var DEFAULT_BACKEND = { type: "athena" };
4945
6283
  function toBackendConfig(b) {
@@ -4970,6 +6308,12 @@ function mergeExperimentalOptions(current, next) {
4970
6308
  ...next.traceQueries
4971
6309
  };
4972
6310
  }
6311
+ if (current?.storage || next.storage) {
6312
+ merged.storage = {
6313
+ ...current?.storage ?? {},
6314
+ ...next.storage ?? {}
6315
+ };
6316
+ }
4973
6317
  return merged;
4974
6318
  }
4975
6319
  var AthenaClientBuilderImpl = class {
@@ -5006,7 +6350,7 @@ var AthenaClientBuilderImpl = class {
5006
6350
  }
5007
6351
  experimental(options) {
5008
6352
  this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options);
5009
- return this;
6353
+ return options.athenaStorageBackend ? this : this;
5010
6354
  }
5011
6355
  options(options) {
5012
6356
  if (options.client !== void 0) {
@@ -5027,7 +6371,7 @@ var AthenaClientBuilderImpl = class {
5027
6371
  if (options.experimental !== void 0) {
5028
6372
  this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options.experimental);
5029
6373
  }
5030
- return this;
6374
+ return options.experimental?.athenaStorageBackend ? this : this;
5031
6375
  }
5032
6376
  build() {
5033
6377
  if (!this.baseUrl || !this.apiKey) {
@@ -5223,7 +6567,7 @@ function resolveNullishValue(mode) {
5223
6567
  if (mode === "null") return null;
5224
6568
  return "";
5225
6569
  }
5226
- function isRecord8(value) {
6570
+ function isRecord9(value) {
5227
6571
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5228
6572
  }
5229
6573
  function isNullableColumn(model, key) {
@@ -5232,7 +6576,7 @@ function isNullableColumn(model, key) {
5232
6576
  }
5233
6577
  function toModelFormDefaults(model, values, options) {
5234
6578
  const source = values;
5235
- if (!isRecord8(source)) {
6579
+ if (!isRecord9(source)) {
5236
6580
  return {};
5237
6581
  }
5238
6582
  const mode = options?.nullishMode ?? "empty-string";
@@ -5307,6 +6651,90 @@ function resolveProviderSchemas(providerConfig) {
5307
6651
  return [...DEFAULT_POSTGRES_SCHEMAS];
5308
6652
  }
5309
6653
 
6654
+ // src/generator/env.ts
6655
+ function readEnvStringValue(key) {
6656
+ if (typeof process === "undefined" || !process.env) {
6657
+ return void 0;
6658
+ }
6659
+ const value = process.env[key];
6660
+ if (typeof value !== "string") {
6661
+ return void 0;
6662
+ }
6663
+ const trimmed = value.trim();
6664
+ return trimmed.length > 0 ? trimmed : void 0;
6665
+ }
6666
+ function throwMissingEnvVar(key) {
6667
+ throw new Error(
6668
+ `Generator config env var ${key} is missing or empty. Set ${key} or provide a default value.`
6669
+ );
6670
+ }
6671
+ function resolveEnvValue(key, options, resolver) {
6672
+ const rawValue = readEnvStringValue(key);
6673
+ if (rawValue === void 0) {
6674
+ if (options?.default !== void 0) {
6675
+ return options.default;
6676
+ }
6677
+ if (options?.optional) {
6678
+ return void 0;
6679
+ }
6680
+ return throwMissingEnvVar(key);
6681
+ }
6682
+ return resolver(rawValue);
6683
+ }
6684
+ function resolveStringEnv(key, options) {
6685
+ return resolveEnvValue(key, options, (value) => value);
6686
+ }
6687
+ function resolveBooleanEnv(key, options) {
6688
+ return resolveEnvValue(key, options, (value) => parseBooleanFlag2(value, false));
6689
+ }
6690
+ function resolveListEnv(key, options) {
6691
+ return resolveEnvValue(key, options, (value) => {
6692
+ const separator = options?.separator ?? ",";
6693
+ return value.split(separator).map((entry) => entry.trim()).filter((entry, index, entries) => entry.length > 0 && entries.indexOf(entry) === index);
6694
+ })?.slice();
6695
+ }
6696
+ function resolveJsonEnv(key, options) {
6697
+ return resolveEnvValue(key, options, (value) => {
6698
+ try {
6699
+ return JSON.parse(value);
6700
+ } catch (error) {
6701
+ const message = error instanceof Error ? error.message : String(error);
6702
+ throw new Error(`Generator config env var ${key} must contain valid JSON. ${message}`);
6703
+ }
6704
+ });
6705
+ }
6706
+ function resolveOneOfEnv(key, allowedValues, options) {
6707
+ return resolveEnvValue(key, options, (value) => {
6708
+ if (allowedValues.includes(value)) {
6709
+ return value;
6710
+ }
6711
+ throw new Error(
6712
+ `Generator config env var ${key} must be one of: ${allowedValues.join(", ")}. Received: ${value}.`
6713
+ );
6714
+ });
6715
+ }
6716
+ function generatorEnvString(key, options) {
6717
+ return resolveStringEnv(key, options);
6718
+ }
6719
+ function generatorEnvBoolean(key, options) {
6720
+ return resolveBooleanEnv(key, options);
6721
+ }
6722
+ function generatorEnvList(key, options) {
6723
+ return resolveListEnv(key, options);
6724
+ }
6725
+ function generatorEnvJson(key, options) {
6726
+ return resolveJsonEnv(key, options);
6727
+ }
6728
+ function generatorEnvOneOf(key, allowedValues, options) {
6729
+ return resolveOneOfEnv(key, allowedValues, options);
6730
+ }
6731
+ var generatorEnv = Object.assign(generatorEnvString, {
6732
+ boolean: generatorEnvBoolean,
6733
+ list: generatorEnvList,
6734
+ json: generatorEnvJson,
6735
+ oneOf: generatorEnvOneOf
6736
+ });
6737
+
5310
6738
  // src/generator/postgres-type-mapping.ts
5311
6739
  var NUMBER_TYPES = /* @__PURE__ */ new Set([
5312
6740
  "int2",
@@ -5423,6 +6851,433 @@ function resolvePostgresColumnType(column) {
5423
6851
  return wrapArrayType(baseType, column.arrayDimensions);
5424
6852
  }
5425
6853
 
6854
+ // src/auth/server.ts
6855
+ var DEFAULT_AUTH_BASE_PATH = "/api/auth";
6856
+ var ATHENA_AUTH_BASE_ERROR_CODES = {
6857
+ HANDLER_NOT_CONFIGURED: "HANDLER_NOT_CONFIGURED",
6858
+ INVALID_BASE_URL: "INVALID_BASE_URL",
6859
+ UNTRUSTED_HOST: "UNTRUSTED_HOST"
6860
+ };
6861
+ function capitalize(value) {
6862
+ return value.length > 0 ? `${value[0]?.toUpperCase()}${value.slice(1)}` : value;
6863
+ }
6864
+ function serializeSetCookieValue(name, value, attributes) {
6865
+ const parts = [`${name}=${encodeURIComponent(value)}`];
6866
+ const knownKeys = /* @__PURE__ */ new Set([
6867
+ "maxAge",
6868
+ "expires",
6869
+ "domain",
6870
+ "path",
6871
+ "secure",
6872
+ "httpOnly",
6873
+ "partitioned",
6874
+ "sameSite"
6875
+ ]);
6876
+ if (attributes.maxAge !== void 0) {
6877
+ parts.push(`Max-Age=${Math.trunc(attributes.maxAge)}`);
6878
+ }
6879
+ if (attributes.expires instanceof Date) {
6880
+ parts.push(`Expires=${attributes.expires.toUTCString()}`);
6881
+ }
6882
+ if (attributes.domain) {
6883
+ parts.push(`Domain=${attributes.domain}`);
6884
+ }
6885
+ if (attributes.path) {
6886
+ parts.push(`Path=${attributes.path}`);
6887
+ }
6888
+ if (attributes.secure) {
6889
+ parts.push("Secure");
6890
+ }
6891
+ if (attributes.httpOnly) {
6892
+ parts.push("HttpOnly");
6893
+ }
6894
+ if (attributes.partitioned) {
6895
+ parts.push("Partitioned");
6896
+ }
6897
+ if (attributes.sameSite) {
6898
+ parts.push(`SameSite=${capitalize(attributes.sameSite)}`);
6899
+ }
6900
+ for (const [key, rawValue] of Object.entries(attributes)) {
6901
+ if (knownKeys.has(key) || rawValue === void 0 || rawValue === null || rawValue === false) {
6902
+ continue;
6903
+ }
6904
+ if (rawValue === true) {
6905
+ parts.push(key);
6906
+ continue;
6907
+ }
6908
+ parts.push(`${key}=${String(rawValue)}`);
6909
+ }
6910
+ return parts.join("; ");
6911
+ }
6912
+ function readCookieFromHeaders(headers, name) {
6913
+ const cookieHeader = headers?.get("cookie");
6914
+ if (!cookieHeader) {
6915
+ return void 0;
6916
+ }
6917
+ return parseCookies(cookieHeader).get(name);
6918
+ }
6919
+ function isRecord10(value) {
6920
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6921
+ }
6922
+ function resolveSessionCandidate(value) {
6923
+ if (!isRecord10(value)) {
6924
+ return null;
6925
+ }
6926
+ const session = isRecord10(value.session) ? value.session : void 0;
6927
+ const user = isRecord10(value.user) ? value.user : void 0;
6928
+ if (session && typeof session.token === "string" && session.token.length > 0 && user) {
6929
+ return {
6930
+ session,
6931
+ user
6932
+ };
6933
+ }
6934
+ return null;
6935
+ }
6936
+ function inferSessionPair(returned) {
6937
+ return resolveSessionCandidate(returned) ?? (isRecord10(returned) ? resolveSessionCandidate(returned.data) : null) ?? (isRecord10(returned) ? resolveSessionCandidate(returned.session) : null);
6938
+ }
6939
+ function resolveResponseHeaders(ctx) {
6940
+ if (ctx.context.responseHeaders instanceof Headers) {
6941
+ return ctx.context.responseHeaders;
6942
+ }
6943
+ const headers = new Headers();
6944
+ ctx.context.responseHeaders = headers;
6945
+ return headers;
6946
+ }
6947
+ function normalizeBaseURL(baseURL) {
6948
+ return baseURL.replace(/\/$/, "");
6949
+ }
6950
+ function normalizeBasePath(basePath) {
6951
+ if (!basePath || basePath === "/") {
6952
+ return DEFAULT_AUTH_BASE_PATH;
6953
+ }
6954
+ const normalized = basePath.startsWith("/") ? basePath : `/${basePath}`;
6955
+ return normalized.endsWith("/") && normalized.length > 1 ? normalized.slice(0, -1) : normalized;
6956
+ }
6957
+ function isDynamicBaseURLConfig2(baseURL) {
6958
+ return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
6959
+ }
6960
+ function getRequestUrl(request) {
6961
+ try {
6962
+ return new URL(request.url);
6963
+ } catch {
6964
+ return new URL("http://localhost");
6965
+ }
6966
+ }
6967
+ function getRequestHost(request, url) {
6968
+ const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
6969
+ const host = forwardedHost || request.headers.get("host") || url.host;
6970
+ return host || null;
6971
+ }
6972
+ function getRequestProtocol(request, configuredProtocol, url) {
6973
+ if (configuredProtocol === "http" || configuredProtocol === "https") {
6974
+ return configuredProtocol;
6975
+ }
6976
+ const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
6977
+ if (forwardedProto === "http" || forwardedProto === "https") {
6978
+ return forwardedProto;
6979
+ }
6980
+ if (url.protocol === "http:" || url.protocol === "https:") {
6981
+ return url.protocol.slice(0, -1);
6982
+ }
6983
+ return "http";
6984
+ }
6985
+ function resolveRequestBaseURL(baseURL, request) {
6986
+ if (typeof baseURL === "string") {
6987
+ return normalizeBaseURL(baseURL);
6988
+ }
6989
+ const requestUrl = getRequestUrl(request);
6990
+ const host = getRequestHost(request, requestUrl);
6991
+ if (!host) {
6992
+ return null;
6993
+ }
6994
+ if (isDynamicBaseURLConfig2(baseURL)) {
6995
+ const allowedHosts = baseURL.allowedHosts ?? [];
6996
+ if (allowedHosts.length > 0 && !allowedHosts.includes(host)) {
6997
+ return null;
6998
+ }
6999
+ }
7000
+ const protocol = typeof baseURL === "object" && baseURL !== null ? getRequestProtocol(request, baseURL.protocol, requestUrl) : getRequestProtocol(request, void 0, requestUrl);
7001
+ return `${protocol}://${host}`;
7002
+ }
7003
+ function getOrigin(baseURL) {
7004
+ if (!baseURL) {
7005
+ return void 0;
7006
+ }
7007
+ try {
7008
+ return new URL(baseURL).origin;
7009
+ } catch {
7010
+ return void 0;
7011
+ }
7012
+ }
7013
+ async function resolveTrustedOrigins(config, baseURL, request) {
7014
+ const resolved = typeof config.trustedOrigins === "function" ? await config.trustedOrigins(request) : config.trustedOrigins ?? [];
7015
+ const values = [
7016
+ getOrigin(baseURL),
7017
+ ...resolved
7018
+ ];
7019
+ return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
7020
+ }
7021
+ async function resolveTrustedProviders(config, request) {
7022
+ const configured = typeof config.trustedProviders === "function" ? await config.trustedProviders(request) : config.trustedProviders ?? [];
7023
+ const values = [
7024
+ ...Object.keys(config.socialProviders ?? {}),
7025
+ ...configured
7026
+ ];
7027
+ return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
7028
+ }
7029
+ function createJsonResponse(payload, init) {
7030
+ const headers = new Headers(init?.headers);
7031
+ if (!headers.has("content-type")) {
7032
+ headers.set("content-type", "application/json; charset=utf-8");
7033
+ }
7034
+ return new Response(JSON.stringify(payload), {
7035
+ ...init,
7036
+ headers
7037
+ });
7038
+ }
7039
+ function mergeResponseHeaders(response, headers) {
7040
+ return new Response(response.body, {
7041
+ status: response.status,
7042
+ statusText: response.statusText,
7043
+ headers
7044
+ });
7045
+ }
7046
+ function defineAthenaAuthConfig(config) {
7047
+ return config;
7048
+ }
7049
+ function athenaAuth(config) {
7050
+ const normalizedBasePath = normalizeBasePath(config.basePath);
7051
+ const staticBaseURL = typeof config.baseURL === "string" ? normalizeBaseURL(config.baseURL) : void 0;
7052
+ const runtime = {
7053
+ baseURL: staticBaseURL,
7054
+ basePath: normalizedBasePath,
7055
+ secret: config.secret,
7056
+ cookies: {
7057
+ session: config.session,
7058
+ advanced: config.advanced
7059
+ }
7060
+ };
7061
+ const resolvedDatabase = typeof config.database === "function" ? config.database(runtime) : config.database;
7062
+ const cookies = getCookies({
7063
+ baseURL: staticBaseURL ?? config.baseURL,
7064
+ session: config.session,
7065
+ advanced: config.advanced
7066
+ });
7067
+ const auth = {};
7068
+ const createCookieContext = (input = {}) => {
7069
+ const responseHeaders = input.responseHeaders ?? new Headers();
7070
+ const runtimeHeaders = input.headers;
7071
+ const authCookies = input.cookies ?? auth.cookies;
7072
+ const setCookie = input.setCookie ?? ((name, value, attributes) => {
7073
+ responseHeaders.append(
7074
+ "set-cookie",
7075
+ serializeSetCookieValue(name, value, attributes)
7076
+ );
7077
+ });
7078
+ return {
7079
+ headers: runtimeHeaders,
7080
+ getCookie: input.getCookie ?? ((name) => readCookieFromHeaders(runtimeHeaders, name)),
7081
+ setCookie,
7082
+ logger: input.logger,
7083
+ setSignedCookie: input.setSignedCookie,
7084
+ getSignedCookie: input.getSignedCookie,
7085
+ context: {
7086
+ secret: runtime.secret,
7087
+ authCookies,
7088
+ sessionConfig: {
7089
+ expiresIn: config.session?.expiresIn
7090
+ },
7091
+ options: {
7092
+ session: {
7093
+ cookieCache: config.session?.cookieCache
7094
+ },
7095
+ account: {
7096
+ storeAccountCookie: true
7097
+ }
7098
+ },
7099
+ setNewSession: input.setNewSession
7100
+ }
7101
+ };
7102
+ };
7103
+ const setSession = async (input, session, dontRememberMe, overrides) => {
7104
+ const cookieContext = createCookieContext(input);
7105
+ await setSessionCookie(cookieContext, session, dontRememberMe, overrides);
7106
+ };
7107
+ const clearSession = (input, skipDontRememberMe) => {
7108
+ const cookieContext = createCookieContext(input);
7109
+ deleteSessionCookie(cookieContext, skipDontRememberMe);
7110
+ };
7111
+ const applyResponseCookies = async (ctx) => {
7112
+ const responseHeaders = resolveResponseHeaders(ctx);
7113
+ const session = ctx.context.setSession ?? inferSessionPair(ctx.context.returned);
7114
+ if (ctx.context.clearSession) {
7115
+ clearSession({
7116
+ headers: ctx.headers,
7117
+ responseHeaders
7118
+ });
7119
+ }
7120
+ if (session) {
7121
+ await setSession(
7122
+ {
7123
+ headers: ctx.headers,
7124
+ responseHeaders
7125
+ },
7126
+ session,
7127
+ ctx.context.dontRememberMe,
7128
+ ctx.context.cookieOverrides
7129
+ );
7130
+ }
7131
+ return responseHeaders;
7132
+ };
7133
+ const runAfterHooks = async (ctx) => {
7134
+ for (const plugin of auth.plugins) {
7135
+ for (const hook of plugin.hooks?.after ?? []) {
7136
+ if (!hook.matcher(ctx)) {
7137
+ continue;
7138
+ }
7139
+ await hook.handler({
7140
+ ...ctx,
7141
+ auth
7142
+ });
7143
+ }
7144
+ }
7145
+ return ctx;
7146
+ };
7147
+ const resolveRequestContext = async (request) => {
7148
+ const requestUrl = getRequestUrl(request);
7149
+ const resolvedBaseURL = resolveRequestBaseURL(config.baseURL, request);
7150
+ if (!resolvedBaseURL) {
7151
+ throw new Error(
7152
+ isDynamicBaseURLConfig2(config.baseURL) ? "Could not resolve base URL from request. Check allowedHosts/baseURL." : "Could not resolve base URL from request."
7153
+ );
7154
+ }
7155
+ const requestCookies = getCookies({
7156
+ baseURL: resolvedBaseURL,
7157
+ session: config.session,
7158
+ advanced: config.advanced
7159
+ });
7160
+ const trustedOrigins = await resolveTrustedOrigins(config, resolvedBaseURL, request);
7161
+ const trustedProviders = await resolveTrustedProviders(config, request);
7162
+ return {
7163
+ auth,
7164
+ request,
7165
+ url: requestUrl,
7166
+ path: requestUrl.pathname,
7167
+ basePath: normalizedBasePath,
7168
+ baseURL: resolvedBaseURL,
7169
+ origin: getOrigin(resolvedBaseURL) ?? resolvedBaseURL,
7170
+ headers: request.headers,
7171
+ cookies: requestCookies,
7172
+ trustedOrigins,
7173
+ trustedProviders,
7174
+ options: config,
7175
+ runtime: {
7176
+ ...runtime,
7177
+ baseURL: resolvedBaseURL
7178
+ },
7179
+ database: auth.database,
7180
+ socialProviders: auth.socialProviders
7181
+ };
7182
+ };
7183
+ const handler = async (request) => {
7184
+ const requestContext = await resolveRequestContext(request);
7185
+ if (typeof config.handler !== "function") {
7186
+ return createJsonResponse(
7187
+ {
7188
+ ok: false,
7189
+ code: ATHENA_AUTH_BASE_ERROR_CODES.HANDLER_NOT_CONFIGURED,
7190
+ error: "No native auth handler was configured for this Athena auth instance.",
7191
+ path: requestContext.path,
7192
+ basePath: requestContext.basePath
7193
+ },
7194
+ { status: 501 }
7195
+ );
7196
+ }
7197
+ const result = await config.handler(requestContext);
7198
+ if (result instanceof Response) {
7199
+ return result;
7200
+ }
7201
+ const response = result.response ?? (result.returned !== void 0 ? createJsonResponse(result.returned) : new Response(null, { status: 204 }));
7202
+ const responseHeaders = new Headers(response.headers);
7203
+ await runAfterHooks({
7204
+ path: requestContext.path,
7205
+ headers: request.headers,
7206
+ context: {
7207
+ responseHeaders,
7208
+ returned: result.returned,
7209
+ setSession: result.setSession,
7210
+ clearSession: result.clearSession,
7211
+ dontRememberMe: result.dontRememberMe,
7212
+ cookieOverrides: result.cookieOverrides
7213
+ }
7214
+ });
7215
+ return mergeResponseHeaders(response, responseHeaders);
7216
+ };
7217
+ const api = Object.assign(
7218
+ {
7219
+ applyResponseCookies,
7220
+ clearSession,
7221
+ createCookieContext,
7222
+ getCookieCache,
7223
+ getSessionCookie,
7224
+ resolveRequestContext,
7225
+ runAfterHooks,
7226
+ setSession
7227
+ },
7228
+ config.api ?? {}
7229
+ );
7230
+ const $ERROR_CODES = {
7231
+ ...auth.plugins?.reduce((acc, plugin) => {
7232
+ if (plugin.$ERROR_CODES) {
7233
+ return {
7234
+ ...acc,
7235
+ ...plugin.$ERROR_CODES
7236
+ };
7237
+ }
7238
+ return acc;
7239
+ }, {}),
7240
+ ...config.errorCodes ?? {},
7241
+ ...ATHENA_AUTH_BASE_ERROR_CODES
7242
+ };
7243
+ Object.assign(auth, {
7244
+ config,
7245
+ options: config,
7246
+ runtime,
7247
+ database: resolvedDatabase,
7248
+ socialProviders: config.socialProviders ?? {},
7249
+ plugins: [...config.plugins ?? []],
7250
+ cookies,
7251
+ api,
7252
+ $ERROR_CODES,
7253
+ createCookieContext,
7254
+ setSession,
7255
+ clearSession,
7256
+ applyResponseCookies,
7257
+ runAfterHooks,
7258
+ resolveRequestContext,
7259
+ handler
7260
+ });
7261
+ auth.$context = Promise.all([
7262
+ resolveTrustedOrigins(config, staticBaseURL),
7263
+ resolveTrustedProviders(config)
7264
+ ]).then(([trustedOrigins, trustedProviders]) => ({
7265
+ auth,
7266
+ options: config,
7267
+ runtime,
7268
+ basePath: normalizedBasePath,
7269
+ baseURL: staticBaseURL,
7270
+ origin: getOrigin(staticBaseURL),
7271
+ database: auth.database,
7272
+ socialProviders: auth.socialProviders,
7273
+ plugins: auth.plugins,
7274
+ cookies: auth.cookies,
7275
+ trustedOrigins,
7276
+ trustedProviders
7277
+ }));
7278
+ return auth;
7279
+ }
7280
+
5426
7281
  // src/browser.ts
5427
7282
  function throwBrowserUnsupported(apiName) {
5428
7283
  throw new Error(
@@ -5454,6 +7309,6 @@ async function runSchemaGenerator(options = {}) {
5454
7309
  return throwBrowserUnsupported("runSchemaGenerator");
5455
7310
  }
5456
7311
 
5457
- export { AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, coerceInt, createAuthClient, createAuthReactEmailInput, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createTypedClient, defineAuthEmailTemplate, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeAthenaGatewayBaseUrl, normalizeGeneratorConfig, normalizeSchemaSelection, parseBooleanFlag2 as parseBooleanFlag, renderAthenaReactEmail, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, toModelFormDefaults, toModelPayload, unwrap, unwrapOne, unwrapRows, verifyAthenaGatewayUrl, withRetry };
7312
+ export { ATHENA_AUTH_BASE_ERROR_CODES, AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, AthenaStorageError, AthenaStorageErrorCode, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, athenaAuth, coerceInt, createAthenaStorageError, createAuthClient, createAuthReactEmailInput, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createTypedClient, defineAthenaAuthConfig, defineAuthEmailTemplate, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, generatorEnv, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeAthenaGatewayBaseUrl, normalizeGeneratorConfig, normalizeSchemaSelection, parseBooleanFlag2 as parseBooleanFlag, renderAthenaReactEmail, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, storageSdkManifest, toModelFormDefaults, toModelPayload, unwrap, unwrapOne, unwrapRows, verifyAthenaGatewayUrl, withRetry };
5458
7313
  //# sourceMappingURL=browser.js.map
5459
7314
  //# sourceMappingURL=browser.js.map