@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/index.cjs CHANGED
@@ -132,6 +132,60 @@ function buildAthenaGatewayUrl(baseUrl, path) {
132
132
  return `${baseUrl}${path}`;
133
133
  }
134
134
 
135
+ // src/cookies/base64.ts
136
+ function getAtob() {
137
+ const candidate = globalThis.atob;
138
+ return typeof candidate === "function" ? candidate : void 0;
139
+ }
140
+ function getBtoa() {
141
+ const candidate = globalThis.btoa;
142
+ return typeof candidate === "function" ? candidate : void 0;
143
+ }
144
+ function bytesToBinaryString(bytes) {
145
+ let result = "";
146
+ for (const byte of bytes) {
147
+ result += String.fromCharCode(byte);
148
+ }
149
+ return result;
150
+ }
151
+ function binaryStringToBytes(binary) {
152
+ const bytes = new Uint8Array(binary.length);
153
+ for (let i = 0; i < binary.length; i++) {
154
+ bytes[i] = binary.charCodeAt(i);
155
+ }
156
+ return bytes;
157
+ }
158
+ function encodeBase64(bytes) {
159
+ const btoaFn = getBtoa();
160
+ if (btoaFn) {
161
+ return btoaFn(bytesToBinaryString(bytes));
162
+ }
163
+ return Buffer.from(bytes).toString("base64");
164
+ }
165
+ function decodeBase64(base64) {
166
+ const atobFn = getAtob();
167
+ if (atobFn) {
168
+ return binaryStringToBytes(atobFn(base64));
169
+ }
170
+ return new Uint8Array(Buffer.from(base64, "base64"));
171
+ }
172
+ function encodeBytesToBase64Url(bytes) {
173
+ return encodeBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
174
+ }
175
+ function encodeStringToBase64Url(value) {
176
+ const bytes = new TextEncoder().encode(value);
177
+ return encodeBytesToBase64Url(bytes);
178
+ }
179
+ function decodeBase64UrlToBytes(value) {
180
+ const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
181
+ const paddingLength = normalized.length % 4;
182
+ const padded = paddingLength === 0 ? normalized : `${normalized}${"=".repeat(4 - paddingLength)}`;
183
+ return decodeBase64(padded);
184
+ }
185
+ function decodeBase64UrlToString(value) {
186
+ return new TextDecoder().decode(decodeBase64UrlToBytes(value));
187
+ }
188
+
135
189
  // src/cookies/cookie-utils.ts
136
190
  var SECURE_COOKIE_PREFIX = "__Secure-";
137
191
  function parseCookies(cookieHeader) {
@@ -143,12 +197,480 @@ function parseCookies(cookieHeader) {
143
197
  });
144
198
  return cookieMap;
145
199
  }
200
+
201
+ // src/cookies/crypto.ts
202
+ var HS256_ALG = "HS256";
203
+ async function getSubtleCrypto() {
204
+ const globalCrypto = globalThis.crypto;
205
+ if (globalCrypto?.subtle) {
206
+ return globalCrypto.subtle;
207
+ }
208
+ const { webcrypto } = await import('crypto');
209
+ const subtle = webcrypto.subtle;
210
+ if (!subtle) {
211
+ throw new Error("Web Crypto subtle API is unavailable.");
212
+ }
213
+ return subtle;
214
+ }
215
+ async function importHmacKey(secret, usage) {
216
+ const subtle = await getSubtleCrypto();
217
+ return subtle.importKey(
218
+ "raw",
219
+ new TextEncoder().encode(secret),
220
+ {
221
+ name: "HMAC",
222
+ hash: "SHA-256"
223
+ },
224
+ false,
225
+ [usage]
226
+ );
227
+ }
228
+ function bufferToBytes(buffer) {
229
+ return new Uint8Array(buffer);
230
+ }
231
+ function parseJwtPayload(payloadSegment) {
232
+ try {
233
+ const decoded = decodeBase64UrlToString(payloadSegment);
234
+ const payload = JSON.parse(decoded);
235
+ if (!payload || typeof payload !== "object") {
236
+ return null;
237
+ }
238
+ return payload;
239
+ } catch {
240
+ return null;
241
+ }
242
+ }
243
+ function isJwtExpired(payload) {
244
+ const exp = payload.exp;
245
+ if (typeof exp !== "number") {
246
+ return false;
247
+ }
248
+ return exp < Math.floor(Date.now() / 1e3);
249
+ }
250
+ async function signHmacBase64Url(secret, value) {
251
+ const subtle = await getSubtleCrypto();
252
+ const key = await importHmacKey(secret, "sign");
253
+ const signature = await subtle.sign("HMAC", key, new TextEncoder().encode(value));
254
+ return encodeBytesToBase64Url(bufferToBytes(signature));
255
+ }
256
+ async function signJwtHS256(payload, secret, expiresIn = 60 * 5) {
257
+ const now = Math.floor(Date.now() / 1e3);
258
+ const header = { alg: HS256_ALG, typ: "JWT" };
259
+ const fullPayload = {
260
+ ...payload,
261
+ iat: now,
262
+ exp: now + expiresIn
263
+ };
264
+ const headerPart = encodeStringToBase64Url(JSON.stringify(header));
265
+ const payloadPart = encodeStringToBase64Url(JSON.stringify(fullPayload));
266
+ const message = `${headerPart}.${payloadPart}`;
267
+ const signature = await signHmacBase64Url(secret, message);
268
+ return `${message}.${signature}`;
269
+ }
270
+ async function verifyJwtHS256(token, secret) {
271
+ const parts = token.split(".");
272
+ if (parts.length !== 3) {
273
+ return null;
274
+ }
275
+ const [headerPart, payloadPart, signaturePart] = parts;
276
+ if (!headerPart || !payloadPart || !signaturePart) {
277
+ return null;
278
+ }
279
+ let header = null;
280
+ try {
281
+ header = JSON.parse(decodeBase64UrlToString(headerPart));
282
+ } catch {
283
+ return null;
284
+ }
285
+ if (!header || header.alg !== HS256_ALG) {
286
+ return null;
287
+ }
288
+ const payload = parseJwtPayload(payloadPart);
289
+ if (!payload) {
290
+ return null;
291
+ }
292
+ const expectedSignature = await signHmacBase64Url(secret, `${headerPart}.${payloadPart}`);
293
+ if (expectedSignature !== signaturePart) {
294
+ return null;
295
+ }
296
+ if (isJwtExpired(payload)) {
297
+ return null;
298
+ }
299
+ return payload;
300
+ }
301
+
302
+ // src/cookies/session-store.ts
303
+ var ALLOWED_COOKIE_SIZE = 4096;
304
+ var ESTIMATED_EMPTY_COOKIE_SIZE = 200;
305
+ var CHUNK_SIZE = ALLOWED_COOKIE_SIZE - ESTIMATED_EMPTY_COOKIE_SIZE;
306
+ function getChunkIndex(cookieName) {
307
+ const parts = cookieName.split(".");
308
+ const lastPart = parts[parts.length - 1];
309
+ const index = parseInt(lastPart || "0", 10);
310
+ return Number.isNaN(index) ? 0 : index;
311
+ }
312
+ function readExistingChunks(cookieName, ctx) {
313
+ const chunks = {};
314
+ const cookies = parseCookies(ctx.headers?.get("cookie") || "");
315
+ for (const [name, value] of cookies) {
316
+ if (name.startsWith(cookieName)) {
317
+ chunks[name] = value;
318
+ }
319
+ }
320
+ return chunks;
321
+ }
322
+ function joinChunks(chunks) {
323
+ const sortedKeys = Object.keys(chunks).sort((left, right) => getChunkIndex(left) - getChunkIndex(right));
324
+ return sortedKeys.map((key) => chunks[key]).join("");
325
+ }
326
+ function chunkCookie(storeName, cookie, chunks, ctx) {
327
+ const chunkCount = Math.ceil(cookie.value.length / CHUNK_SIZE);
328
+ if (chunkCount === 1) {
329
+ chunks[cookie.name] = cookie.value;
330
+ return [cookie];
331
+ }
332
+ const cookies = [];
333
+ for (let index = 0; index < chunkCount; index++) {
334
+ const name = `${cookie.name}.${index}`;
335
+ const start = index * CHUNK_SIZE;
336
+ const value = cookie.value.substring(start, start + CHUNK_SIZE);
337
+ cookies.push({
338
+ ...cookie,
339
+ name,
340
+ value
341
+ });
342
+ chunks[name] = value;
343
+ }
344
+ ctx.logger?.debug?.(`CHUNKING_${storeName.toUpperCase()}_COOKIE`, {
345
+ message: `${storeName} cookie exceeds allowed ${ALLOWED_COOKIE_SIZE} bytes.`,
346
+ emptyCookieSize: ESTIMATED_EMPTY_COOKIE_SIZE,
347
+ valueSize: cookie.value.length,
348
+ chunkCount,
349
+ chunks: cookies.map((entry) => entry.value.length + ESTIMATED_EMPTY_COOKIE_SIZE)
350
+ });
351
+ return cookies;
352
+ }
353
+ function getCleanCookies(chunks, cookieOptions) {
354
+ const cleanedChunks = {};
355
+ for (const name in chunks) {
356
+ cleanedChunks[name] = {
357
+ name,
358
+ value: "",
359
+ attributes: {
360
+ ...cookieOptions,
361
+ maxAge: 0
362
+ }
363
+ };
364
+ }
365
+ return cleanedChunks;
366
+ }
367
+ var storeFactory = (storeName) => (cookieName, cookieOptions, ctx) => {
368
+ const chunks = readExistingChunks(cookieName, ctx);
369
+ return {
370
+ getValue() {
371
+ return joinChunks(chunks);
372
+ },
373
+ hasChunks() {
374
+ return Object.keys(chunks).length > 0;
375
+ },
376
+ chunk(value, options) {
377
+ const cleanedChunks = getCleanCookies(chunks, cookieOptions);
378
+ for (const name in chunks) {
379
+ delete chunks[name];
380
+ }
381
+ const cookies = cleanedChunks;
382
+ const chunked = chunkCookie(
383
+ storeName,
384
+ {
385
+ name: cookieName,
386
+ value,
387
+ attributes: {
388
+ ...cookieOptions,
389
+ ...options
390
+ }
391
+ },
392
+ chunks,
393
+ ctx
394
+ );
395
+ for (const chunk of chunked) {
396
+ cookies[chunk.name] = chunk;
397
+ }
398
+ return Object.values(cookies);
399
+ },
400
+ clean() {
401
+ const cleanedChunks = getCleanCookies(chunks, cookieOptions);
402
+ for (const name in chunks) {
403
+ delete chunks[name];
404
+ }
405
+ return Object.values(cleanedChunks);
406
+ },
407
+ setCookies(cookies) {
408
+ for (const cookie of cookies) {
409
+ ctx.setCookie(cookie.name, cookie.value, cookie.attributes);
410
+ }
411
+ }
412
+ };
413
+ };
414
+ var createSessionStore = storeFactory("Session");
415
+ var createAccountStore = storeFactory("Account");
416
+
417
+ // src/cookies/index.ts
418
+ var DEFAULT_COOKIE_PREFIX = "athena-auth";
419
+ var LEGACY_COOKIE_PREFIX = "better-auth";
420
+ var DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60;
421
+ var DEFAULT_CACHE_MAX_AGE = 60 * 5;
422
+ function isProductionRuntime() {
423
+ return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
424
+ }
425
+ function getEnvironmentSecret() {
426
+ if (typeof process === "undefined") {
427
+ return void 0;
428
+ }
429
+ return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET;
430
+ }
431
+ function isDynamicBaseURLConfig(baseURL) {
432
+ return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
433
+ }
434
+ function resolveCookiePrefixes(primaryPrefix) {
435
+ const prefixes = [primaryPrefix];
436
+ if (!prefixes.includes(DEFAULT_COOKIE_PREFIX)) {
437
+ prefixes.push(DEFAULT_COOKIE_PREFIX);
438
+ }
439
+ if (!prefixes.includes(LEGACY_COOKIE_PREFIX)) {
440
+ prefixes.push(LEGACY_COOKIE_PREFIX);
441
+ }
442
+ return prefixes;
443
+ }
444
+ function createError(message) {
445
+ return new Error(`@xylex-group/athena/cookies: ${message}`);
446
+ }
447
+ function getSecretOrThrow(secret) {
448
+ const resolved = secret || getEnvironmentSecret();
449
+ if (!resolved) {
450
+ throw createError(
451
+ "getCookieCache requires a secret. Pass `secret` or set ATHENA_AUTH_SECRET/BETTER_AUTH_SECRET/AUTH_SECRET."
452
+ );
453
+ }
454
+ return resolved;
455
+ }
456
+ function asObject(value) {
457
+ if (!value || typeof value !== "object") {
458
+ return null;
459
+ }
460
+ return value;
461
+ }
462
+ function getSessionTokenFromPair(session) {
463
+ const token = session.session?.token;
464
+ if (typeof token !== "string" || token.length === 0) {
465
+ throw createError("setSessionCookie requires `session.session.token` to be a non-empty string.");
466
+ }
467
+ return token;
468
+ }
469
+ async function resolveCookieVersion(versionConfig, session, user) {
470
+ if (!versionConfig) {
471
+ return "1";
472
+ }
473
+ if (typeof versionConfig === "string") {
474
+ return versionConfig;
475
+ }
476
+ return versionConfig(session, user);
477
+ }
478
+ function getSessionCookieCacheName(cookiePrefix, cookieName, isSecure) {
479
+ return isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`;
480
+ }
481
+ async function setCookieValue(ctx, name, value, attributes) {
482
+ const secret = ctx.context.secret;
483
+ if (secret && typeof ctx.setSignedCookie === "function") {
484
+ await ctx.setSignedCookie(name, value, secret, attributes);
485
+ return;
486
+ }
487
+ ctx.setCookie(name, value, attributes);
488
+ }
489
+ function parseJsonSafely(value) {
490
+ try {
491
+ return JSON.parse(value);
492
+ } catch {
493
+ return null;
494
+ }
495
+ }
496
+ function getIsSecureCookie(config) {
497
+ if (config?.isSecure !== void 0) {
498
+ return config.isSecure;
499
+ }
500
+ return isProductionRuntime();
501
+ }
502
+ function createCookieGetter(options) {
503
+ const baseURLString = typeof options.baseURL === "string" ? options.baseURL : void 0;
504
+ const dynamicProtocol = typeof options.baseURL === "object" && options.baseURL !== null ? options.baseURL.protocol : void 0;
505
+ const secure = options.advanced?.useSecureCookies !== void 0 ? options.advanced.useSecureCookies : dynamicProtocol === "https" ? true : dynamicProtocol === "http" ? false : baseURLString ? baseURLString.startsWith("https://") : isProductionRuntime();
506
+ const secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : "";
507
+ const crossSubdomainEnabled = !!options.advanced?.crossSubDomainCookies?.enabled;
508
+ const domain = crossSubdomainEnabled ? options.advanced?.crossSubDomainCookies?.domain || (baseURLString ? new URL(baseURLString).hostname : void 0) : void 0;
509
+ if (crossSubdomainEnabled && !domain && !isDynamicBaseURLConfig(options.baseURL)) {
510
+ throw createError("baseURL is required when `crossSubDomainCookies.enabled` is true.");
511
+ }
512
+ function createCookie(cookieName, overrideAttributes = {}) {
513
+ const prefix = options.advanced?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
514
+ const name = options.advanced?.cookies?.[cookieName]?.name || `${prefix}.${cookieName}`;
515
+ const attributes = options.advanced?.cookies?.[cookieName]?.attributes || {};
516
+ return {
517
+ name: `${secureCookiePrefix}${name}`,
518
+ attributes: {
519
+ secure: !!secureCookiePrefix,
520
+ sameSite: "lax",
521
+ path: "/",
522
+ httpOnly: true,
523
+ ...crossSubdomainEnabled ? { domain } : {},
524
+ ...options.advanced?.defaultCookieAttributes,
525
+ ...overrideAttributes,
526
+ ...attributes
527
+ }
528
+ };
529
+ }
530
+ return createCookie;
531
+ }
532
+ function getCookies(options) {
533
+ const createCookie = createCookieGetter(options);
534
+ const sessionToken = createCookie("session_token", { maxAge: options.session?.expiresIn || DEFAULT_SESSION_MAX_AGE });
535
+ const sessionData = createCookie("session_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
536
+ const accountData = createCookie("account_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
537
+ const dontRememberToken = createCookie("dont_remember");
538
+ return {
539
+ sessionToken: {
540
+ name: sessionToken.name,
541
+ attributes: sessionToken.attributes
542
+ },
543
+ sessionData: {
544
+ name: sessionData.name,
545
+ attributes: sessionData.attributes
546
+ },
547
+ dontRememberToken: {
548
+ name: dontRememberToken.name,
549
+ attributes: dontRememberToken.attributes
550
+ },
551
+ accountData: {
552
+ name: accountData.name,
553
+ attributes: accountData.attributes
554
+ }
555
+ };
556
+ }
557
+ async function setCookieCache(ctx, session, dontRememberMe) {
558
+ const cookieCacheConfig = ctx.context.options?.session?.cookieCache;
559
+ if (!cookieCacheConfig?.enabled) {
560
+ return;
561
+ }
562
+ const version = await resolveCookieVersion(
563
+ cookieCacheConfig.version,
564
+ session.session,
565
+ session.user
566
+ );
567
+ const sessionData = {
568
+ session: session.session,
569
+ user: session.user,
570
+ updatedAt: Date.now(),
571
+ version
572
+ };
573
+ const baseAttributes = ctx.context.authCookies.sessionData.attributes;
574
+ const maxAge = dontRememberMe ? void 0 : baseAttributes.maxAge;
575
+ const options = {
576
+ ...baseAttributes,
577
+ maxAge
578
+ };
579
+ const expiresAt = Date.now() + (options.maxAge || 60) * 1e3;
580
+ const strategy = cookieCacheConfig.strategy || "compact";
581
+ const secret = getSecretOrThrow(ctx.context.secret);
582
+ let encoded;
583
+ if (strategy === "jwt") {
584
+ encoded = await signJwtHS256(sessionData, secret, options.maxAge || DEFAULT_CACHE_MAX_AGE);
585
+ } else if (strategy === "jwe") {
586
+ throw createError("`jwe` strategy is not supported by the SDK cookie helper.");
587
+ } else {
588
+ const signature = await signHmacBase64Url(
589
+ secret,
590
+ JSON.stringify({
591
+ ...sessionData,
592
+ expiresAt
593
+ })
594
+ );
595
+ encoded = encodeStringToBase64Url(
596
+ JSON.stringify({
597
+ session: sessionData,
598
+ expiresAt,
599
+ signature
600
+ })
601
+ );
602
+ }
603
+ if (encoded.length > 4093) {
604
+ const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
605
+ const cookies = store.chunk(encoded, options);
606
+ store.setCookies(cookies);
607
+ } else {
608
+ const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
609
+ if (store.hasChunks()) {
610
+ store.setCookies(store.clean());
611
+ }
612
+ ctx.setCookie(ctx.context.authCookies.sessionData.name, encoded, options);
613
+ }
614
+ }
615
+ async function setSessionCookie(ctx, session, dontRememberMe, overrides) {
616
+ if (dontRememberMe === void 0 && typeof ctx.getSignedCookie === "function" && ctx.context.secret) {
617
+ const existingFlag = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
618
+ dontRememberMe = !!existingFlag;
619
+ }
620
+ const resolvedDontRememberMe = dontRememberMe ?? false;
621
+ const token = getSessionTokenFromPair(session);
622
+ const options = ctx.context.authCookies.sessionToken.attributes;
623
+ const maxAge = resolvedDontRememberMe ? void 0 : ctx.context.sessionConfig?.expiresIn;
624
+ await setCookieValue(ctx, ctx.context.authCookies.sessionToken.name, token, {
625
+ ...options,
626
+ maxAge,
627
+ ...overrides
628
+ });
629
+ if (resolvedDontRememberMe) {
630
+ await setCookieValue(
631
+ ctx,
632
+ ctx.context.authCookies.dontRememberToken.name,
633
+ "true",
634
+ ctx.context.authCookies.dontRememberToken.attributes
635
+ );
636
+ }
637
+ await setCookieCache(ctx, session, resolvedDontRememberMe);
638
+ ctx.context.setNewSession?.(session);
639
+ }
640
+ function expireCookie(ctx, cookie) {
641
+ ctx.setCookie(cookie.name, "", {
642
+ ...cookie.attributes,
643
+ maxAge: 0
644
+ });
645
+ }
646
+ function deleteSessionCookie(ctx, skipDontRememberMe) {
647
+ expireCookie(ctx, ctx.context.authCookies.sessionToken);
648
+ expireCookie(ctx, ctx.context.authCookies.sessionData);
649
+ if (ctx.context.options?.account?.storeAccountCookie) {
650
+ expireCookie(ctx, ctx.context.authCookies.accountData);
651
+ const accountStore = createAccountStore(
652
+ ctx.context.authCookies.accountData.name,
653
+ ctx.context.authCookies.accountData.attributes,
654
+ ctx
655
+ );
656
+ accountStore.setCookies(accountStore.clean());
657
+ }
658
+ const sessionStore = createSessionStore(
659
+ ctx.context.authCookies.sessionData.name,
660
+ ctx.context.authCookies.sessionData.attributes,
661
+ ctx
662
+ );
663
+ sessionStore.setCookies(sessionStore.clean());
664
+ if (!skipDontRememberMe) {
665
+ expireCookie(ctx, ctx.context.authCookies.dontRememberToken);
666
+ }
667
+ }
146
668
  var getSessionCookie = (request, config) => {
147
669
  const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
148
670
  if (!cookies) {
149
671
  return null;
150
672
  }
151
- const { cookieName = "session_token", cookiePrefix = "athena-auth" } = {};
673
+ const { cookieName = "session_token", cookiePrefix = "athena-auth" } = config || {};
152
674
  const parsedCookie = parseCookies(cookies);
153
675
  const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
154
676
  const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
@@ -157,10 +679,126 @@ var getSessionCookie = (request, config) => {
157
679
  }
158
680
  return null;
159
681
  };
682
+ var getCookieCache = async (request, config) => {
683
+ const headers = request instanceof Headers || !("headers" in request) ? request : request.headers;
684
+ const cookieHeader = headers.get("cookie");
685
+ if (!cookieHeader) {
686
+ return null;
687
+ }
688
+ const parsedCookie = parseCookies(cookieHeader);
689
+ const cookieName = config?.cookieName || "session_data";
690
+ const requestedPrefix = config?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
691
+ const strategy = config?.strategy || "compact";
692
+ const cookiePrefixes = resolveCookiePrefixes(requestedPrefix);
693
+ const isSecure = getIsSecureCookie(config);
694
+ const secret = getSecretOrThrow(config?.secret);
695
+ let sessionData;
696
+ for (const prefix of cookiePrefixes) {
697
+ const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
698
+ const cookieValue = parsedCookie.get(candidate);
699
+ if (cookieValue) {
700
+ sessionData = cookieValue;
701
+ break;
702
+ }
703
+ }
704
+ if (!sessionData) {
705
+ const reconstructedChunks = [];
706
+ for (const prefix of cookiePrefixes) {
707
+ const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
708
+ for (const [name, value] of parsedCookie.entries()) {
709
+ if (!name.startsWith(`${candidate}.`)) {
710
+ continue;
711
+ }
712
+ const parts = name.split(".");
713
+ const indexStr = parts[parts.length - 1];
714
+ const index = parseInt(indexStr || "0", 10);
715
+ if (!Number.isNaN(index)) {
716
+ reconstructedChunks.push({ index, value });
717
+ }
718
+ }
719
+ if (reconstructedChunks.length > 0) {
720
+ break;
721
+ }
722
+ }
723
+ if (reconstructedChunks.length > 0) {
724
+ reconstructedChunks.sort((left, right) => left.index - right.index);
725
+ sessionData = reconstructedChunks.map((chunk) => chunk.value).join("");
726
+ }
727
+ }
728
+ if (!sessionData) {
729
+ return null;
730
+ }
731
+ if (strategy === "jwe") {
732
+ throw createError(
733
+ "`jwe` strategy is not supported by the SDK cookie helper. Use compact/jwt or pass cookie data through the auth server."
734
+ );
735
+ }
736
+ if (strategy === "jwt") {
737
+ const payload = await verifyJwtHS256(sessionData, secret);
738
+ if (!payload) {
739
+ return null;
740
+ }
741
+ const sessionRecord = asObject(payload.session);
742
+ const userRecord = asObject(payload.user);
743
+ const updatedAt = payload.updatedAt;
744
+ if (!sessionRecord || !userRecord || typeof updatedAt !== "number") {
745
+ return null;
746
+ }
747
+ if (config?.version) {
748
+ const cookieVersion = typeof payload.version === "string" ? payload.version : "1";
749
+ const expectedVersion = typeof config.version === "string" ? config.version : await config.version(sessionRecord, userRecord);
750
+ if (cookieVersion !== expectedVersion) {
751
+ return null;
752
+ }
753
+ }
754
+ return {
755
+ session: sessionRecord,
756
+ user: userRecord,
757
+ updatedAt,
758
+ version: typeof payload.version === "string" ? payload.version : void 0
759
+ };
760
+ }
761
+ const compactPayload = parseJsonSafely(decodeBase64UrlToString(sessionData));
762
+ if (!compactPayload) {
763
+ return null;
764
+ }
765
+ const expectedSignature = await signHmacBase64Url(
766
+ secret,
767
+ JSON.stringify({
768
+ ...compactPayload.session,
769
+ expiresAt: compactPayload.expiresAt
770
+ })
771
+ );
772
+ if (expectedSignature !== compactPayload.signature) {
773
+ return null;
774
+ }
775
+ if (compactPayload.expiresAt <= Date.now()) {
776
+ return null;
777
+ }
778
+ const resolvedSession = compactPayload.session;
779
+ if (config?.version) {
780
+ const cookieVersion = resolvedSession.version || "1";
781
+ const expectedVersion = typeof config.version === "string" ? config.version : await config.version(resolvedSession.session, resolvedSession.user);
782
+ if (cookieVersion !== expectedVersion) {
783
+ return null;
784
+ }
785
+ }
786
+ const sessionObject = asObject(resolvedSession.session);
787
+ const userObject = asObject(resolvedSession.user);
788
+ if (!sessionObject || !userObject) {
789
+ return null;
790
+ }
791
+ return {
792
+ session: sessionObject,
793
+ user: userObject,
794
+ updatedAt: resolvedSession.updatedAt,
795
+ version: resolvedSession.version
796
+ };
797
+ };
160
798
 
161
799
  // package.json
162
800
  var package_default = {
163
- version: "2.4.1"
801
+ version: "2.6.0"
164
802
  };
165
803
 
166
804
  // src/sdk-version.ts
@@ -2701,38 +3339,730 @@ async function withRetry(config, fn) {
2701
3339
  await sleep(delay);
2702
3340
  }
2703
3341
  }
2704
- throw new Error("withRetry reached an unexpected state");
3342
+ throw new Error("withRetry reached an unexpected state");
3343
+ }
3344
+
3345
+ // src/db/module.ts
3346
+ function createDbModule(input) {
3347
+ const db = {
3348
+ from(table, options) {
3349
+ return input.from(table, options);
3350
+ },
3351
+ select(table, columns, options) {
3352
+ return input.from(table).select(columns, options);
3353
+ },
3354
+ insert(table, values, options) {
3355
+ return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
3356
+ },
3357
+ upsert(table, values, options) {
3358
+ return Array.isArray(values) ? input.from(table).upsert(values, options) : input.from(table).upsert(values, options);
3359
+ },
3360
+ update(table, values, options) {
3361
+ return input.from(table).update(values, options);
3362
+ },
3363
+ delete(table, options) {
3364
+ return input.from(table).delete(options);
3365
+ },
3366
+ rpc(fn, args, options) {
3367
+ return input.rpc(fn, args, options);
3368
+ },
3369
+ query(query, options) {
3370
+ return input.query(query, options);
3371
+ }
3372
+ };
3373
+ return db;
3374
+ }
3375
+
3376
+ // src/storage/module.ts
3377
+ var storageSdkManifest = {
3378
+ namespace: "storage",
3379
+ basePath: "/storage",
3380
+ envelopeKinds: {
3381
+ raw: "response body is the payload",
3382
+ athena: "response body is { status, message, data }"
3383
+ },
3384
+ methods: [
3385
+ {
3386
+ name: "listStorageCatalogs",
3387
+ method: "GET",
3388
+ path: "/storage/catalogs",
3389
+ responseEnvelope: "raw",
3390
+ responseType: "{ data: S3CatalogItem[] }"
3391
+ },
3392
+ {
3393
+ name: "createStorageCatalog",
3394
+ method: "POST",
3395
+ path: "/storage/catalogs",
3396
+ requestType: "CreateStorageCatalogRequest",
3397
+ responseEnvelope: "raw",
3398
+ responseType: "S3CatalogItem"
3399
+ },
3400
+ {
3401
+ name: "updateStorageCatalog",
3402
+ method: "PATCH",
3403
+ path: "/storage/catalogs/{id}",
3404
+ pathParams: ["id"],
3405
+ requestType: "UpdateStorageCatalogRequest",
3406
+ responseEnvelope: "raw",
3407
+ responseType: "S3CatalogItem"
3408
+ },
3409
+ {
3410
+ name: "deleteStorageCatalog",
3411
+ method: "DELETE",
3412
+ path: "/storage/catalogs/{id}",
3413
+ pathParams: ["id"],
3414
+ responseEnvelope: "raw",
3415
+ responseType: "{ id: string; deleted: boolean }"
3416
+ },
3417
+ {
3418
+ name: "listStorageCredentials",
3419
+ method: "GET",
3420
+ path: "/storage/credentials",
3421
+ responseEnvelope: "raw",
3422
+ responseType: "{ data: S3CredentialListItem[] }"
3423
+ },
3424
+ {
3425
+ name: "createStorageUploadUrl",
3426
+ method: "POST",
3427
+ path: "/storage/files/upload-url",
3428
+ requestType: "CreateStorageUploadUrlRequest",
3429
+ responseEnvelope: "athena",
3430
+ responseType: "StorageUploadUrlResponse"
3431
+ },
3432
+ {
3433
+ name: "createStorageUploadUrls",
3434
+ method: "POST",
3435
+ path: "/storage/files/upload-urls",
3436
+ requestType: "CreateStorageUploadUrlsRequest",
3437
+ responseEnvelope: "athena",
3438
+ responseType: "StorageBatchUploadUrlResponse"
3439
+ },
3440
+ {
3441
+ name: "listStorageFiles",
3442
+ method: "POST",
3443
+ path: "/storage/files/list",
3444
+ requestType: "ListStorageFilesRequest",
3445
+ responseEnvelope: "athena",
3446
+ responseType: "StorageListFilesResponse"
3447
+ },
3448
+ {
3449
+ name: "getStorageFile",
3450
+ method: "GET",
3451
+ path: "/storage/files/{file_id}",
3452
+ pathParams: ["file_id"],
3453
+ responseEnvelope: "athena",
3454
+ responseType: "StorageFileMutationResponse"
3455
+ },
3456
+ {
3457
+ name: "getStorageFileUrl",
3458
+ method: "GET",
3459
+ path: "/storage/files/{file_id}/url",
3460
+ pathParams: ["file_id"],
3461
+ queryParams: ["purpose"],
3462
+ responseEnvelope: "athena",
3463
+ responseType: "PresignedFileUrlResponse"
3464
+ },
3465
+ {
3466
+ name: "getStorageFileProxy",
3467
+ method: "GET",
3468
+ path: "/storage/files/{file_id}/proxy",
3469
+ pathParams: ["file_id"],
3470
+ queryParams: ["purpose"],
3471
+ responseEnvelope: "raw",
3472
+ responseType: "Response",
3473
+ binary: true
3474
+ },
3475
+ {
3476
+ name: "updateStorageFile",
3477
+ method: "PATCH",
3478
+ path: "/storage/files/{file_id}",
3479
+ pathParams: ["file_id"],
3480
+ requestType: "UpdateStorageFileRequest",
3481
+ responseEnvelope: "athena",
3482
+ responseType: "StorageFileMutationResponse"
3483
+ },
3484
+ {
3485
+ name: "deleteStorageFile",
3486
+ method: "DELETE",
3487
+ path: "/storage/files/{file_id}",
3488
+ pathParams: ["file_id"],
3489
+ responseEnvelope: "athena",
3490
+ responseType: "StorageFileMutationResponse"
3491
+ },
3492
+ {
3493
+ name: "setStorageFileVisibility",
3494
+ method: "PATCH",
3495
+ path: "/storage/files/{file_id}/visibility",
3496
+ pathParams: ["file_id"],
3497
+ requestType: "SetStorageFileVisibilityRequest",
3498
+ responseEnvelope: "athena",
3499
+ responseType: "StorageFileMutationResponse"
3500
+ },
3501
+ {
3502
+ name: "deleteStorageFolder",
3503
+ method: "POST",
3504
+ path: "/storage/folders/delete",
3505
+ requestType: "DeleteStorageFolderRequest",
3506
+ responseEnvelope: "athena",
3507
+ responseType: "StorageFolderMutationResponse"
3508
+ },
3509
+ {
3510
+ name: "moveStorageFolder",
3511
+ method: "POST",
3512
+ path: "/storage/folders/move",
3513
+ requestType: "MoveStorageFolderRequest",
3514
+ responseEnvelope: "athena",
3515
+ responseType: "StorageFolderMutationResponse"
3516
+ }
3517
+ ]
3518
+ };
3519
+ var AthenaStorageErrorCode = {
3520
+ InvalidUrl: "INVALID_URL",
3521
+ NetworkError: "NETWORK_ERROR",
3522
+ HttpError: "HTTP_ERROR",
3523
+ InvalidJson: "INVALID_JSON",
3524
+ InvalidAthenaEnvelope: "INVALID_ATHENA_ENVELOPE",
3525
+ UnknownError: "UNKNOWN_ERROR"
3526
+ };
3527
+ var AthenaStorageError = class extends Error {
3528
+ code;
3529
+ athenaCode;
3530
+ kind;
3531
+ category;
3532
+ retryable;
3533
+ status;
3534
+ endpoint;
3535
+ method;
3536
+ requestId;
3537
+ hint;
3538
+ causeDetail;
3539
+ raw;
3540
+ normalized;
3541
+ __athenaNormalizedError;
3542
+ constructor(input) {
3543
+ super(input.message, { cause: input.cause });
3544
+ this.name = "AthenaStorageError";
3545
+ this.code = input.code;
3546
+ this.status = input.status;
3547
+ this.endpoint = input.endpoint;
3548
+ this.method = input.method;
3549
+ this.requestId = input.requestId;
3550
+ this.hint = input.hint;
3551
+ this.causeDetail = causeToString(input.cause);
3552
+ this.raw = input.raw ?? null;
3553
+ this.normalized = normalizeStorageErrorInput(input);
3554
+ this.__athenaNormalizedError = this.normalized;
3555
+ this.athenaCode = this.normalized.code;
3556
+ this.kind = this.normalized.kind;
3557
+ this.category = this.normalized.category;
3558
+ this.retryable = this.normalized.retryable;
3559
+ Object.defineProperty(this, "__athenaNormalizedError", {
3560
+ value: this.normalized,
3561
+ enumerable: false,
3562
+ configurable: false,
3563
+ writable: false
3564
+ });
3565
+ }
3566
+ toDetails() {
3567
+ return {
3568
+ code: this.code,
3569
+ athenaCode: this.athenaCode,
3570
+ kind: this.kind,
3571
+ category: this.category,
3572
+ retryable: this.retryable,
3573
+ message: this.message,
3574
+ status: this.status,
3575
+ endpoint: this.endpoint,
3576
+ method: this.method,
3577
+ requestId: this.requestId,
3578
+ hint: this.hint,
3579
+ cause: this.causeDetail,
3580
+ raw: this.raw
3581
+ };
3582
+ }
3583
+ };
3584
+ function isRecord5(value) {
3585
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3586
+ }
3587
+ function causeToString(cause) {
3588
+ if (cause === void 0 || cause === null) return void 0;
3589
+ if (typeof cause === "string") return cause;
3590
+ if (cause instanceof Error && cause.message.trim()) return cause.message.trim();
3591
+ try {
3592
+ return JSON.stringify(cause);
3593
+ } catch {
3594
+ return String(cause);
3595
+ }
3596
+ }
3597
+ function storageGatewayCode(code) {
3598
+ if (code === "INVALID_URL") return "INVALID_URL";
3599
+ if (code === "NETWORK_ERROR") return "NETWORK_ERROR";
3600
+ if (code === "INVALID_JSON" || code === "INVALID_ATHENA_ENVELOPE") return "INVALID_JSON";
3601
+ if (code === "HTTP_ERROR") return "HTTP_ERROR";
3602
+ return "UNKNOWN_ERROR";
3603
+ }
3604
+ function headerValue(headers, names) {
3605
+ for (const name of names) {
3606
+ const value = headers.get(name);
3607
+ if (value?.trim()) return value.trim();
3608
+ }
3609
+ return void 0;
3610
+ }
3611
+ function storageOperationFromEndpoint(endpoint, method) {
3612
+ const endpointPath = String(endpoint).split("?")[0];
3613
+ for (const candidate of storageSdkManifest.methods) {
3614
+ if (candidate.method !== method) continue;
3615
+ const pattern = `^${candidate.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\\\{[^/]+\\\}/g, "[^/]+")}$`;
3616
+ if (new RegExp(pattern).test(endpointPath)) {
3617
+ return candidate.name;
3618
+ }
3619
+ }
3620
+ return `storage:${method.toLowerCase()}`;
3621
+ }
3622
+ function normalizeStorageErrorInput(input) {
3623
+ return normalizeAthenaError(
3624
+ {
3625
+ data: null,
3626
+ error: {
3627
+ message: input.message,
3628
+ gatewayCode: storageGatewayCode(input.code),
3629
+ status: input.status,
3630
+ raw: input.raw ?? input.cause ?? null
3631
+ },
3632
+ errorDetails: {
3633
+ code: storageGatewayCode(input.code),
3634
+ message: input.message,
3635
+ status: input.status,
3636
+ endpoint: input.endpoint,
3637
+ method: input.method,
3638
+ requestId: input.requestId,
3639
+ hint: input.hint,
3640
+ cause: causeToString(input.cause)
3641
+ },
3642
+ raw: input.raw ?? input.cause ?? null,
3643
+ status: input.status
3644
+ },
3645
+ { operation: storageOperationFromEndpoint(input.endpoint, input.method) }
3646
+ );
3647
+ }
3648
+ function createAthenaStorageError(input) {
3649
+ return new AthenaStorageError(input);
3650
+ }
3651
+ async function notifyStorageError(error, options, runtimeOptions) {
3652
+ const handlers = [runtimeOptions?.onError, options?.onError].filter(
3653
+ (handler) => typeof handler === "function"
3654
+ );
3655
+ for (const handler of handlers) {
3656
+ try {
3657
+ await handler(error);
3658
+ } catch {
3659
+ }
3660
+ }
3661
+ }
3662
+ async function rejectStorageError(input, options, runtimeOptions) {
3663
+ const error = createAthenaStorageError(input);
3664
+ await notifyStorageError(error, options, runtimeOptions);
3665
+ throw error;
3666
+ }
3667
+ function parseResponseBody3(rawText, contentType) {
3668
+ if (!rawText) {
3669
+ return { parsed: null, parseFailed: false };
3670
+ }
3671
+ const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
3672
+ const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
3673
+ if (!looksJson) {
3674
+ return { parsed: rawText, parseFailed: false };
3675
+ }
3676
+ try {
3677
+ return { parsed: JSON.parse(rawText), parseFailed: false };
3678
+ } catch {
3679
+ return { parsed: rawText, parseFailed: true };
3680
+ }
3681
+ }
3682
+ function appendQuery(path, query) {
3683
+ if (!query) return path;
3684
+ const params = new URLSearchParams();
3685
+ for (const [key, value] of Object.entries(query)) {
3686
+ if (value === void 0 || value === null) continue;
3687
+ params.set(key, String(value));
3688
+ }
3689
+ const queryText = params.toString();
3690
+ return queryText ? `${path}?${queryText}` : path;
3691
+ }
3692
+ function storagePath(path) {
3693
+ return path;
3694
+ }
3695
+ function withPathParam(path, name, value) {
3696
+ return path.replace(`{${name}}`, encodeURIComponent(value));
3697
+ }
3698
+ function resolveErrorMessage3(payload, fallback) {
3699
+ if (isRecord5(payload)) {
3700
+ const message = payload.message ?? payload.error ?? payload.details;
3701
+ if (typeof message === "string" && message.trim()) {
3702
+ return message.trim();
3703
+ }
3704
+ }
3705
+ if (typeof payload === "string" && payload.trim()) {
3706
+ return payload.trim();
3707
+ }
3708
+ return fallback;
3709
+ }
3710
+ function resolveErrorHint2(payload) {
3711
+ if (!isRecord5(payload)) return void 0;
3712
+ const hint = payload.hint ?? payload.suggestion;
3713
+ return typeof hint === "string" && hint.trim() ? hint.trim() : void 0;
3714
+ }
3715
+ function resolveErrorCause(payload) {
3716
+ if (!isRecord5(payload)) return void 0;
3717
+ const cause = payload.cause ?? payload.reason;
3718
+ return typeof cause === "string" && cause.trim() ? cause.trim() : void 0;
3719
+ }
3720
+ function storageCodeFromUnknown(error) {
3721
+ if (isAthenaGatewayError(error)) {
3722
+ if (error.code === "INVALID_URL") return "INVALID_URL";
3723
+ if (error.code === "NETWORK_ERROR") return "NETWORK_ERROR";
3724
+ if (error.code === "INVALID_JSON") return "INVALID_JSON";
3725
+ if (error.code === "HTTP_ERROR") return "HTTP_ERROR";
3726
+ }
3727
+ return "UNKNOWN_ERROR";
3728
+ }
3729
+ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload, options, runtimeOptions) {
3730
+ let url;
3731
+ let headers;
3732
+ try {
3733
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3734
+ url = buildAthenaGatewayUrl(baseUrl, endpoint);
3735
+ headers = gateway.buildHeaders(options);
3736
+ } catch (error) {
3737
+ return rejectStorageError(
3738
+ {
3739
+ code: storageCodeFromUnknown(error),
3740
+ message: error instanceof Error ? error.message : `Athena storage ${method} ${endpoint} failed before sending the request`,
3741
+ status: isAthenaGatewayError(error) ? error.status : 0,
3742
+ endpoint,
3743
+ method,
3744
+ raw: error,
3745
+ requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
3746
+ hint: isAthenaGatewayError(error) ? error.hint : void 0,
3747
+ cause: error
3748
+ },
3749
+ options,
3750
+ runtimeOptions
3751
+ );
3752
+ }
3753
+ const requestInit = {
3754
+ method,
3755
+ headers,
3756
+ signal: options?.signal
3757
+ };
3758
+ if (payload !== void 0 && method !== "GET") {
3759
+ requestInit.body = JSON.stringify(payload);
3760
+ }
3761
+ let response;
3762
+ try {
3763
+ response = await fetch(url, requestInit);
3764
+ } catch (error) {
3765
+ const message = error instanceof Error ? error.message : String(error);
3766
+ return rejectStorageError(
3767
+ {
3768
+ code: "NETWORK_ERROR",
3769
+ message: `Network error while calling Athena storage ${method} ${endpoint}: ${message}`,
3770
+ status: 0,
3771
+ endpoint,
3772
+ method,
3773
+ cause: error
3774
+ },
3775
+ options,
3776
+ runtimeOptions
3777
+ );
3778
+ }
3779
+ let rawText;
3780
+ try {
3781
+ rawText = await response.text();
3782
+ } catch (error) {
3783
+ return rejectStorageError(
3784
+ {
3785
+ code: "NETWORK_ERROR",
3786
+ message: `Athena storage ${method} ${endpoint} response body could not be read`,
3787
+ status: response.status,
3788
+ endpoint,
3789
+ method,
3790
+ requestId: headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]),
3791
+ cause: error
3792
+ },
3793
+ options,
3794
+ runtimeOptions
3795
+ );
3796
+ }
3797
+ const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
3798
+ const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
3799
+ if (parsedBody.parseFailed) {
3800
+ return rejectStorageError(
3801
+ {
3802
+ code: "INVALID_JSON",
3803
+ message: `Athena storage ${method} ${endpoint} returned malformed JSON`,
3804
+ status: response.status,
3805
+ endpoint,
3806
+ method,
3807
+ requestId,
3808
+ raw: parsedBody.parsed
3809
+ },
3810
+ options,
3811
+ runtimeOptions
3812
+ );
3813
+ }
3814
+ if (!response.ok) {
3815
+ return rejectStorageError(
3816
+ {
3817
+ code: "HTTP_ERROR",
3818
+ message: resolveErrorMessage3(
3819
+ parsedBody.parsed,
3820
+ `Athena storage ${method} ${endpoint} failed with status ${response.status}`
3821
+ ),
3822
+ status: response.status,
3823
+ endpoint,
3824
+ method,
3825
+ requestId,
3826
+ hint: resolveErrorHint2(parsedBody.parsed),
3827
+ cause: resolveErrorCause(parsedBody.parsed),
3828
+ raw: parsedBody.parsed
3829
+ },
3830
+ options,
3831
+ runtimeOptions
3832
+ );
3833
+ }
3834
+ if (envelope === "athena") {
3835
+ if (!isRecord5(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
3836
+ return rejectStorageError(
3837
+ {
3838
+ code: "INVALID_ATHENA_ENVELOPE",
3839
+ message: `Athena storage ${method} ${endpoint} returned an invalid Athena envelope`,
3840
+ status: response.status,
3841
+ endpoint,
3842
+ method,
3843
+ requestId,
3844
+ raw: parsedBody.parsed
3845
+ },
3846
+ options,
3847
+ runtimeOptions
3848
+ );
3849
+ }
3850
+ return parsedBody.parsed.data;
3851
+ }
3852
+ return parsedBody.parsed;
3853
+ }
3854
+ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, runtimeOptions) {
3855
+ let url;
3856
+ let headers;
3857
+ try {
3858
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3859
+ url = buildAthenaGatewayUrl(baseUrl, endpoint);
3860
+ headers = gateway.buildHeaders(options);
3861
+ } catch (error) {
3862
+ return rejectStorageError(
3863
+ {
3864
+ code: storageCodeFromUnknown(error),
3865
+ message: error instanceof Error ? error.message : `Athena storage ${method} ${endpoint} failed before sending the request`,
3866
+ status: isAthenaGatewayError(error) ? error.status : 0,
3867
+ endpoint,
3868
+ method,
3869
+ raw: error,
3870
+ requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
3871
+ hint: isAthenaGatewayError(error) ? error.hint : void 0,
3872
+ cause: error
3873
+ },
3874
+ options,
3875
+ runtimeOptions
3876
+ );
3877
+ }
3878
+ let response;
3879
+ try {
3880
+ response = await fetch(url, {
3881
+ method,
3882
+ headers,
3883
+ signal: options?.signal
3884
+ });
3885
+ } catch (error) {
3886
+ const message = error instanceof Error ? error.message : String(error);
3887
+ return rejectStorageError(
3888
+ {
3889
+ code: "NETWORK_ERROR",
3890
+ message: `Network error while calling Athena storage ${method} ${endpoint}: ${message}`,
3891
+ status: 0,
3892
+ endpoint,
3893
+ method,
3894
+ cause: error
3895
+ },
3896
+ options,
3897
+ runtimeOptions
3898
+ );
3899
+ }
3900
+ if (response.ok) {
3901
+ return response;
3902
+ }
3903
+ const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
3904
+ let rawErrorBody = null;
3905
+ try {
3906
+ const rawText = await response.text();
3907
+ const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
3908
+ rawErrorBody = parsedBody.parsed;
3909
+ } catch (error) {
3910
+ return rejectStorageError(
3911
+ {
3912
+ code: "NETWORK_ERROR",
3913
+ message: `Athena storage ${method} ${endpoint} error response body could not be read`,
3914
+ status: response.status,
3915
+ endpoint,
3916
+ method,
3917
+ requestId,
3918
+ cause: error
3919
+ },
3920
+ options,
3921
+ runtimeOptions
3922
+ );
3923
+ }
3924
+ return rejectStorageError(
3925
+ {
3926
+ code: "HTTP_ERROR",
3927
+ message: resolveErrorMessage3(
3928
+ rawErrorBody,
3929
+ `Athena storage ${method} ${endpoint} failed with status ${response.status}`
3930
+ ),
3931
+ status: response.status,
3932
+ endpoint,
3933
+ method,
3934
+ requestId,
3935
+ hint: resolveErrorHint2(rawErrorBody),
3936
+ cause: resolveErrorCause(rawErrorBody),
3937
+ raw: rawErrorBody
3938
+ },
3939
+ options,
3940
+ runtimeOptions
3941
+ );
2705
3942
  }
2706
-
2707
- // src/db/module.ts
2708
- function createDbModule(input) {
2709
- const db = {
2710
- from(table, options) {
2711
- return input.from(table, options);
3943
+ function createStorageModule(gateway, runtimeOptions) {
3944
+ return {
3945
+ listStorageCatalogs(options) {
3946
+ return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "GET", "raw", void 0, options, runtimeOptions);
2712
3947
  },
2713
- select(table, columns, options) {
2714
- return input.from(table).select(columns, options);
3948
+ createStorageCatalog(input, options) {
3949
+ return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "POST", "raw", input, options, runtimeOptions);
2715
3950
  },
2716
- insert(table, values, options) {
2717
- return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
3951
+ updateStorageCatalog(id, input, options) {
3952
+ return callStorageEndpoint(
3953
+ gateway,
3954
+ storagePath(withPathParam("/storage/catalogs/{id}", "id", id)),
3955
+ "PATCH",
3956
+ "raw",
3957
+ input,
3958
+ options,
3959
+ runtimeOptions
3960
+ );
2718
3961
  },
2719
- upsert(table, values, options) {
2720
- return Array.isArray(values) ? input.from(table).upsert(values, options) : input.from(table).upsert(values, options);
3962
+ deleteStorageCatalog(id, options) {
3963
+ return callStorageEndpoint(
3964
+ gateway,
3965
+ storagePath(withPathParam("/storage/catalogs/{id}", "id", id)),
3966
+ "DELETE",
3967
+ "raw",
3968
+ void 0,
3969
+ options,
3970
+ runtimeOptions
3971
+ );
2721
3972
  },
2722
- update(table, values, options) {
2723
- return input.from(table).update(values, options);
3973
+ listStorageCredentials(options) {
3974
+ return callStorageEndpoint(gateway, storagePath("/storage/credentials"), "GET", "raw", void 0, options, runtimeOptions);
2724
3975
  },
2725
- delete(table, options) {
2726
- return input.from(table).delete(options);
3976
+ createStorageUploadUrl(input, options) {
3977
+ return callStorageEndpoint(
3978
+ gateway,
3979
+ storagePath("/storage/files/upload-url"),
3980
+ "POST",
3981
+ "athena",
3982
+ input,
3983
+ options,
3984
+ runtimeOptions
3985
+ );
2727
3986
  },
2728
- rpc(fn, args, options) {
2729
- return input.rpc(fn, args, options);
3987
+ createStorageUploadUrls(input, options) {
3988
+ return callStorageEndpoint(
3989
+ gateway,
3990
+ storagePath("/storage/files/upload-urls"),
3991
+ "POST",
3992
+ "athena",
3993
+ input,
3994
+ options,
3995
+ runtimeOptions
3996
+ );
2730
3997
  },
2731
- query(query, options) {
2732
- return input.query(query, options);
3998
+ listStorageFiles(input, options) {
3999
+ return callStorageEndpoint(gateway, storagePath("/storage/files/list"), "POST", "athena", input, options, runtimeOptions);
4000
+ },
4001
+ getStorageFile(fileId, options) {
4002
+ return callStorageEndpoint(
4003
+ gateway,
4004
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4005
+ "GET",
4006
+ "athena",
4007
+ void 0,
4008
+ options,
4009
+ runtimeOptions
4010
+ );
4011
+ },
4012
+ getStorageFileUrl(fileId, query, options) {
4013
+ const path = appendQuery(
4014
+ withPathParam("/storage/files/{file_id}/url", "file_id", fileId),
4015
+ query
4016
+ );
4017
+ return callStorageEndpoint(gateway, storagePath(path), "GET", "athena", void 0, options, runtimeOptions);
4018
+ },
4019
+ getStorageFileProxy(fileId, query, options) {
4020
+ const path = appendQuery(
4021
+ withPathParam("/storage/files/{file_id}/proxy", "file_id", fileId),
4022
+ query
4023
+ );
4024
+ return callStorageBinaryEndpoint(gateway, storagePath(path), "GET", options, runtimeOptions);
4025
+ },
4026
+ updateStorageFile(fileId, input, options) {
4027
+ return callStorageEndpoint(
4028
+ gateway,
4029
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4030
+ "PATCH",
4031
+ "athena",
4032
+ input,
4033
+ options,
4034
+ runtimeOptions
4035
+ );
4036
+ },
4037
+ deleteStorageFile(fileId, options) {
4038
+ return callStorageEndpoint(
4039
+ gateway,
4040
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4041
+ "DELETE",
4042
+ "athena",
4043
+ void 0,
4044
+ options,
4045
+ runtimeOptions
4046
+ );
4047
+ },
4048
+ setStorageFileVisibility(fileId, input, options) {
4049
+ return callStorageEndpoint(
4050
+ gateway,
4051
+ storagePath(withPathParam("/storage/files/{file_id}/visibility", "file_id", fileId)),
4052
+ "PATCH",
4053
+ "athena",
4054
+ input,
4055
+ options,
4056
+ runtimeOptions
4057
+ );
4058
+ },
4059
+ deleteStorageFolder(input, options) {
4060
+ return callStorageEndpoint(gateway, storagePath("/storage/folders/delete"), "POST", "athena", input, options, runtimeOptions);
4061
+ },
4062
+ moveStorageFolder(input, options) {
4063
+ return callStorageEndpoint(gateway, storagePath("/storage/folders/move"), "POST", "athena", input, options, runtimeOptions);
2733
4064
  }
2734
4065
  };
2735
- return db;
2736
4066
  }
2737
4067
 
2738
4068
  // src/query-ast.ts
@@ -2762,7 +4092,7 @@ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
2762
4092
  "ilike",
2763
4093
  "is"
2764
4094
  ]);
2765
- function isRecord5(value) {
4095
+ function isRecord6(value) {
2766
4096
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2767
4097
  }
2768
4098
  function isUuidString(value) {
@@ -2775,7 +4105,7 @@ function shouldUseUuidTextComparison(column, value) {
2775
4105
  return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
2776
4106
  }
2777
4107
  function isRelationSelectNode(value) {
2778
- return isRecord5(value) && isRecord5(value.select);
4108
+ return isRecord6(value) && isRecord6(value.select);
2779
4109
  }
2780
4110
  function normalizeIdentifier(value, label) {
2781
4111
  const normalized = value.trim();
@@ -2831,7 +4161,7 @@ function compileRelationToken(key, node) {
2831
4161
  return `${prefix}${relationToken}(${nested})`;
2832
4162
  }
2833
4163
  function compileSelectShape(select) {
2834
- if (!isRecord5(select)) {
4164
+ if (!isRecord6(select)) {
2835
4165
  throw new Error("findMany select must be an object");
2836
4166
  }
2837
4167
  const tokens = [];
@@ -2855,7 +4185,7 @@ function compileSelectShape(select) {
2855
4185
  return tokens.join(",");
2856
4186
  }
2857
4187
  function selectShapeUsesRelationSchema(select) {
2858
- if (!isRecord5(select)) {
4188
+ if (!isRecord6(select)) {
2859
4189
  return false;
2860
4190
  }
2861
4191
  for (const rawValue of Object.values(select)) {
@@ -2873,7 +4203,7 @@ function selectShapeUsesRelationSchema(select) {
2873
4203
  }
2874
4204
  function compileColumnWhere(column, input) {
2875
4205
  const normalizedColumn = normalizeIdentifier(column, "where column");
2876
- if (!isRecord5(input)) {
4206
+ if (!isRecord6(input)) {
2877
4207
  return [buildGatewayCondition("eq", normalizedColumn, input)];
2878
4208
  }
2879
4209
  const conditions = [];
@@ -2901,7 +4231,7 @@ function compileColumnWhere(column, input) {
2901
4231
  return conditions;
2902
4232
  }
2903
4233
  function compileBooleanExpressionTerms(clause, label) {
2904
- if (!isRecord5(clause)) {
4234
+ if (!isRecord6(clause)) {
2905
4235
  throw new Error(`findMany where.${label} clauses must be objects`);
2906
4236
  }
2907
4237
  const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
@@ -2910,7 +4240,7 @@ function compileBooleanExpressionTerms(clause, label) {
2910
4240
  }
2911
4241
  const [rawColumn, rawValue] = entries[0];
2912
4242
  const column = normalizeIdentifier(rawColumn, `where.${label} column`);
2913
- if (!isRecord5(rawValue)) {
4243
+ if (!isRecord6(rawValue)) {
2914
4244
  return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
2915
4245
  }
2916
4246
  const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
@@ -2934,7 +4264,7 @@ function compileWhere(where) {
2934
4264
  if (where === void 0) {
2935
4265
  return void 0;
2936
4266
  }
2937
- if (!isRecord5(where)) {
4267
+ if (!isRecord6(where)) {
2938
4268
  throw new Error("findMany where must be an object");
2939
4269
  }
2940
4270
  const conditions = [];
@@ -2984,7 +4314,7 @@ function compileOrderBy(orderBy) {
2984
4314
  if (orderBy === void 0) {
2985
4315
  return void 0;
2986
4316
  }
2987
- if (!isRecord5(orderBy)) {
4317
+ if (!isRecord6(orderBy)) {
2988
4318
  throw new Error("findMany orderBy must be an object");
2989
4319
  }
2990
4320
  if ("column" in orderBy) {
@@ -3159,11 +4489,11 @@ function toFindManyAstOrder(order) {
3159
4489
  ascending: order.direction !== "descending"
3160
4490
  };
3161
4491
  }
3162
- function isRecord6(value) {
4492
+ function isRecord7(value) {
3163
4493
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3164
4494
  }
3165
4495
  function normalizeFindManyAstColumnPredicate(value) {
3166
- if (!isRecord6(value)) {
4496
+ if (!isRecord7(value)) {
3167
4497
  return {
3168
4498
  eq: value
3169
4499
  };
@@ -3187,7 +4517,7 @@ function normalizeFindManyAstBooleanOperand(clause) {
3187
4517
  return normalized;
3188
4518
  }
3189
4519
  function normalizeFindManyAstWhere(where) {
3190
- if (!where || !isRecord6(where)) {
4520
+ if (!where || !isRecord7(where)) {
3191
4521
  return where;
3192
4522
  }
3193
4523
  const normalized = {};
@@ -3201,7 +4531,7 @@ function normalizeFindManyAstWhere(where) {
3201
4531
  );
3202
4532
  continue;
3203
4533
  }
3204
- if (key === "not" && isRecord6(value)) {
4534
+ if (key === "not" && isRecord7(value)) {
3205
4535
  normalized.not = normalizeFindManyAstBooleanOperand(
3206
4536
  value
3207
4537
  );
@@ -3212,7 +4542,7 @@ function normalizeFindManyAstWhere(where) {
3212
4542
  return normalized;
3213
4543
  }
3214
4544
  function predicateRequiresUuidQueryFallback(column, value) {
3215
- if (!isRecord6(value)) {
4545
+ if (!isRecord7(value)) {
3216
4546
  return shouldUseUuidTextComparison(column, value);
3217
4547
  }
3218
4548
  const eqValue = value.eq;
@@ -3230,7 +4560,7 @@ function booleanOperandRequiresUuidQueryFallback(clause) {
3230
4560
  return false;
3231
4561
  }
3232
4562
  function findManyAstWhereRequiresLegacyTransport(where) {
3233
- if (!where || !isRecord6(where)) {
4563
+ if (!where || !isRecord7(where)) {
3234
4564
  return false;
3235
4565
  }
3236
4566
  for (const [key, value] of Object.entries(where)) {
@@ -3245,7 +4575,7 @@ function findManyAstWhereRequiresLegacyTransport(where) {
3245
4575
  }
3246
4576
  continue;
3247
4577
  }
3248
- if (key === "not" && isRecord6(value)) {
4578
+ if (key === "not" && isRecord7(value)) {
3249
4579
  if (booleanOperandRequiresUuidQueryFallback(value)) {
3250
4580
  return true;
3251
4581
  }
@@ -3447,7 +4777,7 @@ async function executeExperimentalRead(experimental, runner) {
3447
4777
  throw error;
3448
4778
  }
3449
4779
  }
3450
- function isRecord7(value) {
4780
+ function isRecord8(value) {
3451
4781
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3452
4782
  }
3453
4783
  function firstNonEmptyString2(...values) {
@@ -3459,8 +4789,8 @@ function firstNonEmptyString2(...values) {
3459
4789
  return void 0;
3460
4790
  }
3461
4791
  function resolveStructuredErrorPayload2(raw) {
3462
- if (!isRecord7(raw)) return null;
3463
- return isRecord7(raw.error) ? raw.error : raw;
4792
+ if (!isRecord8(raw)) return null;
4793
+ return isRecord8(raw.error) ? raw.error : raw;
3464
4794
  }
3465
4795
  function resolveStructuredErrorDetails(payload, message) {
3466
4796
  if (!payload || !("details" in payload)) {
@@ -3476,7 +4806,7 @@ function resolveStructuredErrorDetails(payload, message) {
3476
4806
  return details;
3477
4807
  }
3478
4808
  function createResultError(response, result, normalized) {
3479
- const rawRecord = isRecord7(response.raw) ? response.raw : null;
4809
+ const rawRecord = isRecord8(response.raw) ? response.raw : null;
3480
4810
  const payload = resolveStructuredErrorPayload2(response.raw);
3481
4811
  const message = firstNonEmptyString2(
3482
4812
  response.error,
@@ -4939,7 +6269,7 @@ function createClientFromConfig(config) {
4939
6269
  };
4940
6270
  const query = createQueryBuilder(gateway, formatGatewayResult, config.experimental, queryTracer);
4941
6271
  const db = createDbModule({ from, rpc, query });
4942
- return {
6272
+ const sdkClient = {
4943
6273
  from,
4944
6274
  db,
4945
6275
  rpc,
@@ -4947,6 +6277,14 @@ function createClientFromConfig(config) {
4947
6277
  verifyConnection: gateway.verifyConnection,
4948
6278
  auth: auth.auth
4949
6279
  };
6280
+ if (config.experimental?.athenaStorageBackend) {
6281
+ const storageClient = {
6282
+ ...sdkClient,
6283
+ storage: createStorageModule(gateway, config.experimental.storage)
6284
+ };
6285
+ return storageClient;
6286
+ }
6287
+ return sdkClient;
4950
6288
  }
4951
6289
  var DEFAULT_BACKEND = { type: "athena" };
4952
6290
  function toBackendConfig(b) {
@@ -4977,6 +6315,12 @@ function mergeExperimentalOptions(current, next) {
4977
6315
  ...next.traceQueries
4978
6316
  };
4979
6317
  }
6318
+ if (current?.storage || next.storage) {
6319
+ merged.storage = {
6320
+ ...current?.storage ?? {},
6321
+ ...next.storage ?? {}
6322
+ };
6323
+ }
4980
6324
  return merged;
4981
6325
  }
4982
6326
  var AthenaClientBuilderImpl = class {
@@ -5013,7 +6357,7 @@ var AthenaClientBuilderImpl = class {
5013
6357
  }
5014
6358
  experimental(options) {
5015
6359
  this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options);
5016
- return this;
6360
+ return options.athenaStorageBackend ? this : this;
5017
6361
  }
5018
6362
  options(options) {
5019
6363
  if (options.client !== void 0) {
@@ -5034,7 +6378,7 @@ var AthenaClientBuilderImpl = class {
5034
6378
  if (options.experimental !== void 0) {
5035
6379
  this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options.experimental);
5036
6380
  }
5037
- return this;
6381
+ return options.experimental?.athenaStorageBackend ? this : this;
5038
6382
  }
5039
6383
  build() {
5040
6384
  if (!this.baseUrl || !this.apiKey) {
@@ -5665,7 +7009,7 @@ function resolveNullishValue(mode) {
5665
7009
  if (mode === "null") return null;
5666
7010
  return "";
5667
7011
  }
5668
- function isRecord8(value) {
7012
+ function isRecord9(value) {
5669
7013
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5670
7014
  }
5671
7015
  function isNullableColumn(model, key) {
@@ -5674,7 +7018,7 @@ function isNullableColumn(model, key) {
5674
7018
  }
5675
7019
  function toModelFormDefaults(model, values, options) {
5676
7020
  const source = values;
5677
- if (!isRecord8(source)) {
7021
+ if (!isRecord9(source)) {
5678
7022
  return {};
5679
7023
  }
5680
7024
  const mode = options?.nullishMode ?? "empty-string";
@@ -6105,6 +7449,90 @@ async function loadGeneratorConfig(options = {}) {
6105
7449
  }
6106
7450
  }
6107
7451
 
7452
+ // src/generator/env.ts
7453
+ function readEnvStringValue2(key) {
7454
+ if (typeof process === "undefined" || !process.env) {
7455
+ return void 0;
7456
+ }
7457
+ const value = process.env[key];
7458
+ if (typeof value !== "string") {
7459
+ return void 0;
7460
+ }
7461
+ const trimmed = value.trim();
7462
+ return trimmed.length > 0 ? trimmed : void 0;
7463
+ }
7464
+ function throwMissingEnvVar(key) {
7465
+ throw new Error(
7466
+ `Generator config env var ${key} is missing or empty. Set ${key} or provide a default value.`
7467
+ );
7468
+ }
7469
+ function resolveEnvValue(key, options, resolver) {
7470
+ const rawValue = readEnvStringValue2(key);
7471
+ if (rawValue === void 0) {
7472
+ if (options?.default !== void 0) {
7473
+ return options.default;
7474
+ }
7475
+ if (options?.optional) {
7476
+ return void 0;
7477
+ }
7478
+ return throwMissingEnvVar(key);
7479
+ }
7480
+ return resolver(rawValue);
7481
+ }
7482
+ function resolveStringEnv(key, options) {
7483
+ return resolveEnvValue(key, options, (value) => value);
7484
+ }
7485
+ function resolveBooleanEnv(key, options) {
7486
+ return resolveEnvValue(key, options, (value) => parseBooleanFlag2(value, false));
7487
+ }
7488
+ function resolveListEnv(key, options) {
7489
+ return resolveEnvValue(key, options, (value) => {
7490
+ const separator = options?.separator ?? ",";
7491
+ return value.split(separator).map((entry) => entry.trim()).filter((entry, index, entries) => entry.length > 0 && entries.indexOf(entry) === index);
7492
+ })?.slice();
7493
+ }
7494
+ function resolveJsonEnv(key, options) {
7495
+ return resolveEnvValue(key, options, (value) => {
7496
+ try {
7497
+ return JSON.parse(value);
7498
+ } catch (error) {
7499
+ const message = error instanceof Error ? error.message : String(error);
7500
+ throw new Error(`Generator config env var ${key} must contain valid JSON. ${message}`);
7501
+ }
7502
+ });
7503
+ }
7504
+ function resolveOneOfEnv(key, allowedValues, options) {
7505
+ return resolveEnvValue(key, options, (value) => {
7506
+ if (allowedValues.includes(value)) {
7507
+ return value;
7508
+ }
7509
+ throw new Error(
7510
+ `Generator config env var ${key} must be one of: ${allowedValues.join(", ")}. Received: ${value}.`
7511
+ );
7512
+ });
7513
+ }
7514
+ function generatorEnvString(key, options) {
7515
+ return resolveStringEnv(key, options);
7516
+ }
7517
+ function generatorEnvBoolean(key, options) {
7518
+ return resolveBooleanEnv(key, options);
7519
+ }
7520
+ function generatorEnvList(key, options) {
7521
+ return resolveListEnv(key, options);
7522
+ }
7523
+ function generatorEnvJson(key, options) {
7524
+ return resolveJsonEnv(key, options);
7525
+ }
7526
+ function generatorEnvOneOf(key, allowedValues, options) {
7527
+ return resolveOneOfEnv(key, allowedValues, options);
7528
+ }
7529
+ var generatorEnv = Object.assign(generatorEnvString, {
7530
+ boolean: generatorEnvBoolean,
7531
+ list: generatorEnvList,
7532
+ json: generatorEnvJson,
7533
+ oneOf: generatorEnvOneOf
7534
+ });
7535
+
6108
7536
  // src/utils/slugify.ts
6109
7537
  function slugify(input) {
6110
7538
  return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
@@ -6862,22 +8290,455 @@ async function runSchemaGenerator(options = {}) {
6862
8290
  };
6863
8291
  }
6864
8292
 
8293
+ // src/auth/server.ts
8294
+ var DEFAULT_AUTH_BASE_PATH = "/api/auth";
8295
+ var ATHENA_AUTH_BASE_ERROR_CODES = {
8296
+ HANDLER_NOT_CONFIGURED: "HANDLER_NOT_CONFIGURED",
8297
+ INVALID_BASE_URL: "INVALID_BASE_URL",
8298
+ UNTRUSTED_HOST: "UNTRUSTED_HOST"
8299
+ };
8300
+ function capitalize2(value) {
8301
+ return value.length > 0 ? `${value[0]?.toUpperCase()}${value.slice(1)}` : value;
8302
+ }
8303
+ function serializeSetCookieValue(name, value, attributes) {
8304
+ const parts = [`${name}=${encodeURIComponent(value)}`];
8305
+ const knownKeys = /* @__PURE__ */ new Set([
8306
+ "maxAge",
8307
+ "expires",
8308
+ "domain",
8309
+ "path",
8310
+ "secure",
8311
+ "httpOnly",
8312
+ "partitioned",
8313
+ "sameSite"
8314
+ ]);
8315
+ if (attributes.maxAge !== void 0) {
8316
+ parts.push(`Max-Age=${Math.trunc(attributes.maxAge)}`);
8317
+ }
8318
+ if (attributes.expires instanceof Date) {
8319
+ parts.push(`Expires=${attributes.expires.toUTCString()}`);
8320
+ }
8321
+ if (attributes.domain) {
8322
+ parts.push(`Domain=${attributes.domain}`);
8323
+ }
8324
+ if (attributes.path) {
8325
+ parts.push(`Path=${attributes.path}`);
8326
+ }
8327
+ if (attributes.secure) {
8328
+ parts.push("Secure");
8329
+ }
8330
+ if (attributes.httpOnly) {
8331
+ parts.push("HttpOnly");
8332
+ }
8333
+ if (attributes.partitioned) {
8334
+ parts.push("Partitioned");
8335
+ }
8336
+ if (attributes.sameSite) {
8337
+ parts.push(`SameSite=${capitalize2(attributes.sameSite)}`);
8338
+ }
8339
+ for (const [key, rawValue] of Object.entries(attributes)) {
8340
+ if (knownKeys.has(key) || rawValue === void 0 || rawValue === null || rawValue === false) {
8341
+ continue;
8342
+ }
8343
+ if (rawValue === true) {
8344
+ parts.push(key);
8345
+ continue;
8346
+ }
8347
+ parts.push(`${key}=${String(rawValue)}`);
8348
+ }
8349
+ return parts.join("; ");
8350
+ }
8351
+ function readCookieFromHeaders(headers, name) {
8352
+ const cookieHeader = headers?.get("cookie");
8353
+ if (!cookieHeader) {
8354
+ return void 0;
8355
+ }
8356
+ return parseCookies(cookieHeader).get(name);
8357
+ }
8358
+ function isRecord10(value) {
8359
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8360
+ }
8361
+ function resolveSessionCandidate(value) {
8362
+ if (!isRecord10(value)) {
8363
+ return null;
8364
+ }
8365
+ const session = isRecord10(value.session) ? value.session : void 0;
8366
+ const user = isRecord10(value.user) ? value.user : void 0;
8367
+ if (session && typeof session.token === "string" && session.token.length > 0 && user) {
8368
+ return {
8369
+ session,
8370
+ user
8371
+ };
8372
+ }
8373
+ return null;
8374
+ }
8375
+ function inferSessionPair(returned) {
8376
+ return resolveSessionCandidate(returned) ?? (isRecord10(returned) ? resolveSessionCandidate(returned.data) : null) ?? (isRecord10(returned) ? resolveSessionCandidate(returned.session) : null);
8377
+ }
8378
+ function resolveResponseHeaders(ctx) {
8379
+ if (ctx.context.responseHeaders instanceof Headers) {
8380
+ return ctx.context.responseHeaders;
8381
+ }
8382
+ const headers = new Headers();
8383
+ ctx.context.responseHeaders = headers;
8384
+ return headers;
8385
+ }
8386
+ function normalizeBaseURL(baseURL) {
8387
+ return baseURL.replace(/\/$/, "");
8388
+ }
8389
+ function normalizeBasePath(basePath) {
8390
+ if (!basePath || basePath === "/") {
8391
+ return DEFAULT_AUTH_BASE_PATH;
8392
+ }
8393
+ const normalized = basePath.startsWith("/") ? basePath : `/${basePath}`;
8394
+ return normalized.endsWith("/") && normalized.length > 1 ? normalized.slice(0, -1) : normalized;
8395
+ }
8396
+ function isDynamicBaseURLConfig2(baseURL) {
8397
+ return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
8398
+ }
8399
+ function getRequestUrl(request) {
8400
+ try {
8401
+ return new URL(request.url);
8402
+ } catch {
8403
+ return new URL("http://localhost");
8404
+ }
8405
+ }
8406
+ function getRequestHost(request, url) {
8407
+ const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
8408
+ const host = forwardedHost || request.headers.get("host") || url.host;
8409
+ return host || null;
8410
+ }
8411
+ function getRequestProtocol(request, configuredProtocol, url) {
8412
+ if (configuredProtocol === "http" || configuredProtocol === "https") {
8413
+ return configuredProtocol;
8414
+ }
8415
+ const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
8416
+ if (forwardedProto === "http" || forwardedProto === "https") {
8417
+ return forwardedProto;
8418
+ }
8419
+ if (url.protocol === "http:" || url.protocol === "https:") {
8420
+ return url.protocol.slice(0, -1);
8421
+ }
8422
+ return "http";
8423
+ }
8424
+ function resolveRequestBaseURL(baseURL, request) {
8425
+ if (typeof baseURL === "string") {
8426
+ return normalizeBaseURL(baseURL);
8427
+ }
8428
+ const requestUrl = getRequestUrl(request);
8429
+ const host = getRequestHost(request, requestUrl);
8430
+ if (!host) {
8431
+ return null;
8432
+ }
8433
+ if (isDynamicBaseURLConfig2(baseURL)) {
8434
+ const allowedHosts = baseURL.allowedHosts ?? [];
8435
+ if (allowedHosts.length > 0 && !allowedHosts.includes(host)) {
8436
+ return null;
8437
+ }
8438
+ }
8439
+ const protocol = typeof baseURL === "object" && baseURL !== null ? getRequestProtocol(request, baseURL.protocol, requestUrl) : getRequestProtocol(request, void 0, requestUrl);
8440
+ return `${protocol}://${host}`;
8441
+ }
8442
+ function getOrigin(baseURL) {
8443
+ if (!baseURL) {
8444
+ return void 0;
8445
+ }
8446
+ try {
8447
+ return new URL(baseURL).origin;
8448
+ } catch {
8449
+ return void 0;
8450
+ }
8451
+ }
8452
+ async function resolveTrustedOrigins(config, baseURL, request) {
8453
+ const resolved = typeof config.trustedOrigins === "function" ? await config.trustedOrigins(request) : config.trustedOrigins ?? [];
8454
+ const values = [
8455
+ getOrigin(baseURL),
8456
+ ...resolved
8457
+ ];
8458
+ return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
8459
+ }
8460
+ async function resolveTrustedProviders(config, request) {
8461
+ const configured = typeof config.trustedProviders === "function" ? await config.trustedProviders(request) : config.trustedProviders ?? [];
8462
+ const values = [
8463
+ ...Object.keys(config.socialProviders ?? {}),
8464
+ ...configured
8465
+ ];
8466
+ return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
8467
+ }
8468
+ function createJsonResponse(payload, init) {
8469
+ const headers = new Headers(init?.headers);
8470
+ if (!headers.has("content-type")) {
8471
+ headers.set("content-type", "application/json; charset=utf-8");
8472
+ }
8473
+ return new Response(JSON.stringify(payload), {
8474
+ ...init,
8475
+ headers
8476
+ });
8477
+ }
8478
+ function mergeResponseHeaders(response, headers) {
8479
+ return new Response(response.body, {
8480
+ status: response.status,
8481
+ statusText: response.statusText,
8482
+ headers
8483
+ });
8484
+ }
8485
+ function defineAthenaAuthConfig(config) {
8486
+ return config;
8487
+ }
8488
+ function athenaAuth(config) {
8489
+ const normalizedBasePath = normalizeBasePath(config.basePath);
8490
+ const staticBaseURL = typeof config.baseURL === "string" ? normalizeBaseURL(config.baseURL) : void 0;
8491
+ const runtime = {
8492
+ baseURL: staticBaseURL,
8493
+ basePath: normalizedBasePath,
8494
+ secret: config.secret,
8495
+ cookies: {
8496
+ session: config.session,
8497
+ advanced: config.advanced
8498
+ }
8499
+ };
8500
+ const resolvedDatabase = typeof config.database === "function" ? config.database(runtime) : config.database;
8501
+ const cookies = getCookies({
8502
+ baseURL: staticBaseURL ?? config.baseURL,
8503
+ session: config.session,
8504
+ advanced: config.advanced
8505
+ });
8506
+ const auth = {};
8507
+ const createCookieContext = (input = {}) => {
8508
+ const responseHeaders = input.responseHeaders ?? new Headers();
8509
+ const runtimeHeaders = input.headers;
8510
+ const authCookies = input.cookies ?? auth.cookies;
8511
+ const setCookie = input.setCookie ?? ((name, value, attributes) => {
8512
+ responseHeaders.append(
8513
+ "set-cookie",
8514
+ serializeSetCookieValue(name, value, attributes)
8515
+ );
8516
+ });
8517
+ return {
8518
+ headers: runtimeHeaders,
8519
+ getCookie: input.getCookie ?? ((name) => readCookieFromHeaders(runtimeHeaders, name)),
8520
+ setCookie,
8521
+ logger: input.logger,
8522
+ setSignedCookie: input.setSignedCookie,
8523
+ getSignedCookie: input.getSignedCookie,
8524
+ context: {
8525
+ secret: runtime.secret,
8526
+ authCookies,
8527
+ sessionConfig: {
8528
+ expiresIn: config.session?.expiresIn
8529
+ },
8530
+ options: {
8531
+ session: {
8532
+ cookieCache: config.session?.cookieCache
8533
+ },
8534
+ account: {
8535
+ storeAccountCookie: true
8536
+ }
8537
+ },
8538
+ setNewSession: input.setNewSession
8539
+ }
8540
+ };
8541
+ };
8542
+ const setSession = async (input, session, dontRememberMe, overrides) => {
8543
+ const cookieContext = createCookieContext(input);
8544
+ await setSessionCookie(cookieContext, session, dontRememberMe, overrides);
8545
+ };
8546
+ const clearSession = (input, skipDontRememberMe) => {
8547
+ const cookieContext = createCookieContext(input);
8548
+ deleteSessionCookie(cookieContext, skipDontRememberMe);
8549
+ };
8550
+ const applyResponseCookies = async (ctx) => {
8551
+ const responseHeaders = resolveResponseHeaders(ctx);
8552
+ const session = ctx.context.setSession ?? inferSessionPair(ctx.context.returned);
8553
+ if (ctx.context.clearSession) {
8554
+ clearSession({
8555
+ headers: ctx.headers,
8556
+ responseHeaders
8557
+ });
8558
+ }
8559
+ if (session) {
8560
+ await setSession(
8561
+ {
8562
+ headers: ctx.headers,
8563
+ responseHeaders
8564
+ },
8565
+ session,
8566
+ ctx.context.dontRememberMe,
8567
+ ctx.context.cookieOverrides
8568
+ );
8569
+ }
8570
+ return responseHeaders;
8571
+ };
8572
+ const runAfterHooks = async (ctx) => {
8573
+ for (const plugin of auth.plugins) {
8574
+ for (const hook of plugin.hooks?.after ?? []) {
8575
+ if (!hook.matcher(ctx)) {
8576
+ continue;
8577
+ }
8578
+ await hook.handler({
8579
+ ...ctx,
8580
+ auth
8581
+ });
8582
+ }
8583
+ }
8584
+ return ctx;
8585
+ };
8586
+ const resolveRequestContext = async (request) => {
8587
+ const requestUrl = getRequestUrl(request);
8588
+ const resolvedBaseURL = resolveRequestBaseURL(config.baseURL, request);
8589
+ if (!resolvedBaseURL) {
8590
+ throw new Error(
8591
+ isDynamicBaseURLConfig2(config.baseURL) ? "Could not resolve base URL from request. Check allowedHosts/baseURL." : "Could not resolve base URL from request."
8592
+ );
8593
+ }
8594
+ const requestCookies = getCookies({
8595
+ baseURL: resolvedBaseURL,
8596
+ session: config.session,
8597
+ advanced: config.advanced
8598
+ });
8599
+ const trustedOrigins = await resolveTrustedOrigins(config, resolvedBaseURL, request);
8600
+ const trustedProviders = await resolveTrustedProviders(config, request);
8601
+ return {
8602
+ auth,
8603
+ request,
8604
+ url: requestUrl,
8605
+ path: requestUrl.pathname,
8606
+ basePath: normalizedBasePath,
8607
+ baseURL: resolvedBaseURL,
8608
+ origin: getOrigin(resolvedBaseURL) ?? resolvedBaseURL,
8609
+ headers: request.headers,
8610
+ cookies: requestCookies,
8611
+ trustedOrigins,
8612
+ trustedProviders,
8613
+ options: config,
8614
+ runtime: {
8615
+ ...runtime,
8616
+ baseURL: resolvedBaseURL
8617
+ },
8618
+ database: auth.database,
8619
+ socialProviders: auth.socialProviders
8620
+ };
8621
+ };
8622
+ const handler = async (request) => {
8623
+ const requestContext = await resolveRequestContext(request);
8624
+ if (typeof config.handler !== "function") {
8625
+ return createJsonResponse(
8626
+ {
8627
+ ok: false,
8628
+ code: ATHENA_AUTH_BASE_ERROR_CODES.HANDLER_NOT_CONFIGURED,
8629
+ error: "No native auth handler was configured for this Athena auth instance.",
8630
+ path: requestContext.path,
8631
+ basePath: requestContext.basePath
8632
+ },
8633
+ { status: 501 }
8634
+ );
8635
+ }
8636
+ const result = await config.handler(requestContext);
8637
+ if (result instanceof Response) {
8638
+ return result;
8639
+ }
8640
+ const response = result.response ?? (result.returned !== void 0 ? createJsonResponse(result.returned) : new Response(null, { status: 204 }));
8641
+ const responseHeaders = new Headers(response.headers);
8642
+ await runAfterHooks({
8643
+ path: requestContext.path,
8644
+ headers: request.headers,
8645
+ context: {
8646
+ responseHeaders,
8647
+ returned: result.returned,
8648
+ setSession: result.setSession,
8649
+ clearSession: result.clearSession,
8650
+ dontRememberMe: result.dontRememberMe,
8651
+ cookieOverrides: result.cookieOverrides
8652
+ }
8653
+ });
8654
+ return mergeResponseHeaders(response, responseHeaders);
8655
+ };
8656
+ const api = Object.assign(
8657
+ {
8658
+ applyResponseCookies,
8659
+ clearSession,
8660
+ createCookieContext,
8661
+ getCookieCache,
8662
+ getSessionCookie,
8663
+ resolveRequestContext,
8664
+ runAfterHooks,
8665
+ setSession
8666
+ },
8667
+ config.api ?? {}
8668
+ );
8669
+ const $ERROR_CODES = {
8670
+ ...auth.plugins?.reduce((acc, plugin) => {
8671
+ if (plugin.$ERROR_CODES) {
8672
+ return {
8673
+ ...acc,
8674
+ ...plugin.$ERROR_CODES
8675
+ };
8676
+ }
8677
+ return acc;
8678
+ }, {}),
8679
+ ...config.errorCodes ?? {},
8680
+ ...ATHENA_AUTH_BASE_ERROR_CODES
8681
+ };
8682
+ Object.assign(auth, {
8683
+ config,
8684
+ options: config,
8685
+ runtime,
8686
+ database: resolvedDatabase,
8687
+ socialProviders: config.socialProviders ?? {},
8688
+ plugins: [...config.plugins ?? []],
8689
+ cookies,
8690
+ api,
8691
+ $ERROR_CODES,
8692
+ createCookieContext,
8693
+ setSession,
8694
+ clearSession,
8695
+ applyResponseCookies,
8696
+ runAfterHooks,
8697
+ resolveRequestContext,
8698
+ handler
8699
+ });
8700
+ auth.$context = Promise.all([
8701
+ resolveTrustedOrigins(config, staticBaseURL),
8702
+ resolveTrustedProviders(config)
8703
+ ]).then(([trustedOrigins, trustedProviders]) => ({
8704
+ auth,
8705
+ options: config,
8706
+ runtime,
8707
+ basePath: normalizedBasePath,
8708
+ baseURL: staticBaseURL,
8709
+ origin: getOrigin(staticBaseURL),
8710
+ database: auth.database,
8711
+ socialProviders: auth.socialProviders,
8712
+ plugins: auth.plugins,
8713
+ cookies: auth.cookies,
8714
+ trustedOrigins,
8715
+ trustedProviders
8716
+ }));
8717
+ return auth;
8718
+ }
8719
+
8720
+ exports.ATHENA_AUTH_BASE_ERROR_CODES = ATHENA_AUTH_BASE_ERROR_CODES;
6865
8721
  exports.AthenaClient = AthenaClient;
6866
8722
  exports.AthenaError = AthenaError;
6867
8723
  exports.AthenaErrorCategory = AthenaErrorCategory;
6868
8724
  exports.AthenaErrorCode = AthenaErrorCode;
6869
8725
  exports.AthenaErrorKind = AthenaErrorKind;
6870
8726
  exports.AthenaGatewayError = AthenaGatewayError;
8727
+ exports.AthenaStorageError = AthenaStorageError;
8728
+ exports.AthenaStorageErrorCode = AthenaStorageErrorCode;
6871
8729
  exports.Backend = Backend;
6872
8730
  exports.DEFAULT_POSTGRES_SCHEMAS = DEFAULT_POSTGRES_SCHEMAS;
6873
8731
  exports.assertInt = assertInt;
8732
+ exports.athenaAuth = athenaAuth;
6874
8733
  exports.coerceInt = coerceInt;
8734
+ exports.createAthenaStorageError = createAthenaStorageError;
6875
8735
  exports.createAuthClient = createAuthClient;
6876
8736
  exports.createAuthReactEmailInput = createAuthReactEmailInput;
6877
8737
  exports.createClient = createClient;
6878
8738
  exports.createModelFormAdapter = createModelFormAdapter;
6879
8739
  exports.createPostgresIntrospectionProvider = createPostgresIntrospectionProvider;
6880
8740
  exports.createTypedClient = createTypedClient;
8741
+ exports.defineAthenaAuthConfig = defineAthenaAuthConfig;
6881
8742
  exports.defineAuthEmailTemplate = defineAuthEmailTemplate;
6882
8743
  exports.defineDatabase = defineDatabase;
6883
8744
  exports.defineGeneratorConfig = defineGeneratorConfig;
@@ -6886,6 +8747,7 @@ exports.defineRegistry = defineRegistry;
6886
8747
  exports.defineSchema = defineSchema;
6887
8748
  exports.findGeneratorConfigPath = findGeneratorConfigPath;
6888
8749
  exports.generateArtifactsFromSnapshot = generateArtifactsFromSnapshot;
8750
+ exports.generatorEnv = generatorEnv;
6889
8751
  exports.identifier = identifier;
6890
8752
  exports.isAthenaGatewayError = isAthenaGatewayError;
6891
8753
  exports.isOk = isOk;
@@ -6902,6 +8764,7 @@ exports.resolveGeneratorProvider = resolveGeneratorProvider;
6902
8764
  exports.resolvePostgresColumnType = resolvePostgresColumnType;
6903
8765
  exports.resolveProviderSchemas = resolveProviderSchemas;
6904
8766
  exports.runSchemaGenerator = runSchemaGenerator;
8767
+ exports.storageSdkManifest = storageSdkManifest;
6905
8768
  exports.toModelFormDefaults = toModelFormDefaults;
6906
8769
  exports.toModelPayload = toModelPayload;
6907
8770
  exports.unwrap = unwrap;