@xylex-group/athena 2.4.0 → 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 (47) hide show
  1. package/README.md +124 -2
  2. package/bin/athena-js.js +0 -0
  3. package/dist/browser.cjs +2245 -151
  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 +2238 -152
  8. package/dist/browser.js.map +1 -1
  9. package/dist/cli/index.cjs +1073 -102
  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 +1073 -102
  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 +2246 -152
  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 +2239 -153
  24. package/dist/index.js.map +1 -1
  25. package/dist/{model-form-GzTqhEzM.d.cts → model-form-BaHWi3gm.d.cts} +9 -5
  26. package/dist/{model-form-C0FAbOaf.d.ts → model-form-Dh6gWjL0.d.ts} +9 -5
  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-CQJq92zQ.d.cts → react-email-B8O1Jeff.d.cts} +637 -30
  30. package/dist/{react-email-BuApZuyG.d.ts → react-email-CDEF0jij.d.ts} +637 -30
  31. package/dist/react.cjs +84 -4
  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 +84 -4
  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/dist/utils.cjs +131 -0
  42. package/dist/utils.cjs.map +1 -1
  43. package/dist/utils.d.cts +42 -1
  44. package/dist/utils.d.ts +42 -1
  45. package/dist/utils.js +117 -1
  46. package/dist/utils.js.map +1 -1
  47. package/package.json +193 -192
package/dist/index.cjs CHANGED
@@ -132,12 +132,685 @@ 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
+
189
+ // src/cookies/cookie-utils.ts
190
+ var SECURE_COOKIE_PREFIX = "__Secure-";
191
+ function parseCookies(cookieHeader) {
192
+ const cookies = cookieHeader.split("; ");
193
+ const cookieMap = /* @__PURE__ */ new Map();
194
+ cookies.forEach((cookie) => {
195
+ const [name, value] = cookie.split(/=(.*)/s);
196
+ cookieMap.set(name, value);
197
+ });
198
+ return cookieMap;
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
+ }
668
+ var getSessionCookie = (request, config) => {
669
+ const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
670
+ if (!cookies) {
671
+ return null;
672
+ }
673
+ const { cookieName = "session_token", cookiePrefix = "athena-auth" } = config || {};
674
+ const parsedCookie = parseCookies(cookies);
675
+ const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
676
+ const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
677
+ if (sessionToken) {
678
+ return sessionToken;
679
+ }
680
+ return null;
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
+ };
798
+
799
+ // package.json
800
+ var package_default = {
801
+ version: "2.6.0"
802
+ };
803
+
804
+ // src/sdk-version.ts
805
+ var PACKAGE_VERSION = package_default.version;
806
+ function buildSdkHeaderValue(sdkName) {
807
+ return `${sdkName} ${PACKAGE_VERSION}`;
808
+ }
809
+
135
810
  // src/gateway/client.ts
136
811
  var DEFAULT_CLIENT = "railway_direct";
137
- var FALLBACK_SDK_VERSION = "1.3.0";
138
812
  var SDK_NAME = "xylex-group/athena";
139
- var SDK_VERSION = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION;
140
- var SDK_HEADER_VALUE = `${SDK_NAME} ${SDK_VERSION}`;
813
+ var SDK_HEADER_VALUE = buildSdkHeaderValue(SDK_NAME);
141
814
  function parseResponseBody(rawText, contentType) {
142
815
  if (!rawText) {
143
816
  return { parsed: null, parseFailed: false };
@@ -156,6 +829,37 @@ function parseResponseBody(rawText, contentType) {
156
829
  function normalizeHeaderValue(value) {
157
830
  return value ? value : void 0;
158
831
  }
832
+ function resolveHeaderValue(headers, candidates) {
833
+ for (const candidate of candidates) {
834
+ const direct = normalizeHeaderValue(headers[candidate]);
835
+ if (direct) return direct;
836
+ }
837
+ const loweredCandidates = new Set(candidates.map((candidate) => candidate.toLowerCase()));
838
+ for (const [key, value] of Object.entries(headers)) {
839
+ if (!loweredCandidates.has(key.toLowerCase())) {
840
+ continue;
841
+ }
842
+ const normalized = normalizeHeaderValue(value);
843
+ if (normalized) return normalized;
844
+ }
845
+ return void 0;
846
+ }
847
+ function resolveBearerTokenFromAuthorizationHeader(headers) {
848
+ const authorization = resolveHeaderValue(headers, ["Authorization"]);
849
+ if (!authorization) {
850
+ return void 0;
851
+ }
852
+ const match = authorization.match(/^Bearer\s+(.+)$/i);
853
+ const token = match?.[1]?.trim();
854
+ return token ? token : void 0;
855
+ }
856
+ function resolveSessionTokenFromCookieHeader(headers) {
857
+ const cookie = resolveHeaderValue(headers, ["Cookie"]);
858
+ if (!cookie) {
859
+ return void 0;
860
+ }
861
+ return getSessionCookie(new Headers({ cookie })) ?? void 0;
862
+ }
159
863
  function isRecord(value) {
160
864
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
161
865
  }
@@ -273,7 +977,7 @@ function buildRpcGetEndpoint(payload) {
273
977
  status: 0
274
978
  });
275
979
  }
276
- query.set(filter.column, toRpcFilterQueryValue(filter));
980
+ query.append(filter.column, toRpcFilterQueryValue(filter));
277
981
  }
278
982
  }
279
983
  const endpoint = `/rpc/${encodeURIComponent(functionName)}`;
@@ -319,6 +1023,20 @@ function buildHeaders(config, options) {
319
1023
  headers["apikey"] = finalApiKey;
320
1024
  headers["x-api-key"] = headers["x-api-key"] ?? finalApiKey;
321
1025
  }
1026
+ const explicitSessionToken = resolveHeaderValue(extraHeaders, [
1027
+ "X-Athena-Auth-Session-Token"
1028
+ ]);
1029
+ const derivedSessionToken = explicitSessionToken ?? resolveSessionTokenFromCookieHeader(extraHeaders);
1030
+ if (derivedSessionToken) {
1031
+ headers["X-Athena-Auth-Session-Token"] = derivedSessionToken;
1032
+ }
1033
+ const explicitBearerToken = resolveHeaderValue(extraHeaders, [
1034
+ "X-Athena-Auth-Bearer-Token"
1035
+ ]);
1036
+ const derivedBearerToken = explicitBearerToken ?? resolveBearerTokenFromAuthorizationHeader(extraHeaders);
1037
+ if (derivedBearerToken) {
1038
+ headers["X-Athena-Auth-Bearer-Token"] = derivedBearerToken;
1039
+ }
322
1040
  const athenaClientKeys = ["x-athena-client", "X-Athena-Client"];
323
1041
  Object.entries(extraHeaders).forEach(([key, value]) => {
324
1042
  if (athenaClientKeys.includes(key)) return;
@@ -1014,10 +1732,8 @@ async function resolveReactEmailPayloadFields(input, fields, options) {
1014
1732
 
1015
1733
  // src/auth/client.ts
1016
1734
  var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
1017
- var FALLBACK_SDK_VERSION2 = "1.0.0";
1018
1735
  var SDK_NAME2 = "xylex-group/athena-auth";
1019
- var SDK_VERSION2 = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION2;
1020
- var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
1736
+ var SDK_HEADER_VALUE2 = buildSdkHeaderValue(SDK_NAME2);
1021
1737
  function normalizeBaseUrl(baseUrl) {
1022
1738
  return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
1023
1739
  }
@@ -2657,47 +3373,739 @@ function createDbModule(input) {
2657
3373
  return db;
2658
3374
  }
2659
3375
 
2660
- // src/query-ast.ts
2661
- var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
2662
- var FILTER_OPERATORS = /* @__PURE__ */ new Set([
2663
- "eq",
2664
- "neq",
2665
- "gt",
2666
- "gte",
2667
- "lt",
2668
- "lte",
2669
- "like",
2670
- "ilike",
2671
- "is",
2672
- "in",
2673
- "contains",
2674
- "containedBy"
2675
- ]);
2676
- var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
2677
- "eq",
2678
- "neq",
2679
- "gt",
2680
- "gte",
2681
- "lt",
2682
- "lte",
2683
- "like",
2684
- "ilike",
2685
- "is"
2686
- ]);
2687
- function isRecord5(value) {
2688
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2689
- }
2690
- function isUuidString(value) {
2691
- return UUID_PATTERN.test(value.trim());
2692
- }
2693
- function isUuidIdentifierColumn(column) {
2694
- return column === "id" || /(?:^|_)uuid(?:_|$)/i.test(column) || /_id$/i.test(column);
2695
- }
2696
- function shouldUseUuidTextComparison(column, value) {
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
+ );
3942
+ }
3943
+ function createStorageModule(gateway, runtimeOptions) {
3944
+ return {
3945
+ listStorageCatalogs(options) {
3946
+ return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "GET", "raw", void 0, options, runtimeOptions);
3947
+ },
3948
+ createStorageCatalog(input, options) {
3949
+ return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "POST", "raw", input, options, runtimeOptions);
3950
+ },
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
+ );
3961
+ },
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
+ );
3972
+ },
3973
+ listStorageCredentials(options) {
3974
+ return callStorageEndpoint(gateway, storagePath("/storage/credentials"), "GET", "raw", void 0, options, runtimeOptions);
3975
+ },
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
+ );
3986
+ },
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
+ );
3997
+ },
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);
4064
+ }
4065
+ };
4066
+ }
4067
+
4068
+ // src/query-ast.ts
4069
+ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
4070
+ var FILTER_OPERATORS = /* @__PURE__ */ new Set([
4071
+ "eq",
4072
+ "neq",
4073
+ "gt",
4074
+ "gte",
4075
+ "lt",
4076
+ "lte",
4077
+ "like",
4078
+ "ilike",
4079
+ "is",
4080
+ "in",
4081
+ "contains",
4082
+ "containedBy"
4083
+ ]);
4084
+ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
4085
+ "eq",
4086
+ "neq",
4087
+ "gt",
4088
+ "gte",
4089
+ "lt",
4090
+ "lte",
4091
+ "like",
4092
+ "ilike",
4093
+ "is"
4094
+ ]);
4095
+ function isRecord6(value) {
4096
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4097
+ }
4098
+ function isUuidString(value) {
4099
+ return UUID_PATTERN.test(value.trim());
4100
+ }
4101
+ function isUuidIdentifierColumn(column) {
4102
+ return column === "id" || /(?:^|_)uuid(?:_|$)/i.test(column) || /_id$/i.test(column);
4103
+ }
4104
+ function shouldUseUuidTextComparison(column, value) {
2697
4105
  return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
2698
4106
  }
2699
4107
  function isRelationSelectNode(value) {
2700
- return isRecord5(value) && isRecord5(value.select);
4108
+ return isRecord6(value) && isRecord6(value.select);
2701
4109
  }
2702
4110
  function normalizeIdentifier(value, label) {
2703
4111
  const normalized = value.trim();
@@ -2753,7 +4161,7 @@ function compileRelationToken(key, node) {
2753
4161
  return `${prefix}${relationToken}(${nested})`;
2754
4162
  }
2755
4163
  function compileSelectShape(select) {
2756
- if (!isRecord5(select)) {
4164
+ if (!isRecord6(select)) {
2757
4165
  throw new Error("findMany select must be an object");
2758
4166
  }
2759
4167
  const tokens = [];
@@ -2777,7 +4185,7 @@ function compileSelectShape(select) {
2777
4185
  return tokens.join(",");
2778
4186
  }
2779
4187
  function selectShapeUsesRelationSchema(select) {
2780
- if (!isRecord5(select)) {
4188
+ if (!isRecord6(select)) {
2781
4189
  return false;
2782
4190
  }
2783
4191
  for (const rawValue of Object.values(select)) {
@@ -2795,7 +4203,7 @@ function selectShapeUsesRelationSchema(select) {
2795
4203
  }
2796
4204
  function compileColumnWhere(column, input) {
2797
4205
  const normalizedColumn = normalizeIdentifier(column, "where column");
2798
- if (!isRecord5(input)) {
4206
+ if (!isRecord6(input)) {
2799
4207
  return [buildGatewayCondition("eq", normalizedColumn, input)];
2800
4208
  }
2801
4209
  const conditions = [];
@@ -2823,7 +4231,7 @@ function compileColumnWhere(column, input) {
2823
4231
  return conditions;
2824
4232
  }
2825
4233
  function compileBooleanExpressionTerms(clause, label) {
2826
- if (!isRecord5(clause)) {
4234
+ if (!isRecord6(clause)) {
2827
4235
  throw new Error(`findMany where.${label} clauses must be objects`);
2828
4236
  }
2829
4237
  const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
@@ -2832,7 +4240,7 @@ function compileBooleanExpressionTerms(clause, label) {
2832
4240
  }
2833
4241
  const [rawColumn, rawValue] = entries[0];
2834
4242
  const column = normalizeIdentifier(rawColumn, `where.${label} column`);
2835
- if (!isRecord5(rawValue)) {
4243
+ if (!isRecord6(rawValue)) {
2836
4244
  return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
2837
4245
  }
2838
4246
  const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
@@ -2856,7 +4264,7 @@ function compileWhere(where) {
2856
4264
  if (where === void 0) {
2857
4265
  return void 0;
2858
4266
  }
2859
- if (!isRecord5(where)) {
4267
+ if (!isRecord6(where)) {
2860
4268
  throw new Error("findMany where must be an object");
2861
4269
  }
2862
4270
  const conditions = [];
@@ -2906,7 +4314,7 @@ function compileOrderBy(orderBy) {
2906
4314
  if (orderBy === void 0) {
2907
4315
  return void 0;
2908
4316
  }
2909
- if (!isRecord5(orderBy)) {
4317
+ if (!isRecord6(orderBy)) {
2910
4318
  throw new Error("findMany orderBy must be an object");
2911
4319
  }
2912
4320
  if ("column" in orderBy) {
@@ -3002,7 +4410,7 @@ function buildStructuredWhere(conditions) {
3002
4410
  if (!condition.column) {
3003
4411
  return null;
3004
4412
  }
3005
- if (condition.column_cast !== void 0 || condition.value_cast !== void 0) {
4413
+ if (condition.value_cast !== void 0) {
3006
4414
  return null;
3007
4415
  }
3008
4416
  const operand = condition.value;
@@ -3081,6 +4489,104 @@ function toFindManyAstOrder(order) {
3081
4489
  ascending: order.direction !== "descending"
3082
4490
  };
3083
4491
  }
4492
+ function isRecord7(value) {
4493
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4494
+ }
4495
+ function normalizeFindManyAstColumnPredicate(value) {
4496
+ if (!isRecord7(value)) {
4497
+ return {
4498
+ eq: value
4499
+ };
4500
+ }
4501
+ const normalized = {};
4502
+ for (const [key, operand] of Object.entries(value)) {
4503
+ if (operand !== void 0) {
4504
+ normalized[key] = operand;
4505
+ }
4506
+ }
4507
+ return normalized;
4508
+ }
4509
+ function normalizeFindManyAstBooleanOperand(clause) {
4510
+ const normalized = {};
4511
+ for (const [column, value] of Object.entries(clause)) {
4512
+ if (value === void 0) {
4513
+ continue;
4514
+ }
4515
+ normalized[column] = normalizeFindManyAstColumnPredicate(value);
4516
+ }
4517
+ return normalized;
4518
+ }
4519
+ function normalizeFindManyAstWhere(where) {
4520
+ if (!where || !isRecord7(where)) {
4521
+ return where;
4522
+ }
4523
+ const normalized = {};
4524
+ for (const [key, value] of Object.entries(where)) {
4525
+ if (value === void 0) {
4526
+ continue;
4527
+ }
4528
+ if (key === "or" && Array.isArray(value)) {
4529
+ normalized.or = value.map(
4530
+ (clause) => normalizeFindManyAstBooleanOperand(clause)
4531
+ );
4532
+ continue;
4533
+ }
4534
+ if (key === "not" && isRecord7(value)) {
4535
+ normalized.not = normalizeFindManyAstBooleanOperand(
4536
+ value
4537
+ );
4538
+ continue;
4539
+ }
4540
+ normalized[key] = normalizeFindManyAstColumnPredicate(value);
4541
+ }
4542
+ return normalized;
4543
+ }
4544
+ function predicateRequiresUuidQueryFallback(column, value) {
4545
+ if (!isRecord7(value)) {
4546
+ return shouldUseUuidTextComparison(column, value);
4547
+ }
4548
+ const eqValue = value.eq;
4549
+ return eqValue !== void 0 && shouldUseUuidTextComparison(column, eqValue);
4550
+ }
4551
+ function booleanOperandRequiresUuidQueryFallback(clause) {
4552
+ for (const [column, value] of Object.entries(clause)) {
4553
+ if (value === void 0) {
4554
+ continue;
4555
+ }
4556
+ if (predicateRequiresUuidQueryFallback(column, value)) {
4557
+ return true;
4558
+ }
4559
+ }
4560
+ return false;
4561
+ }
4562
+ function findManyAstWhereRequiresLegacyTransport(where) {
4563
+ if (!where || !isRecord7(where)) {
4564
+ return false;
4565
+ }
4566
+ for (const [key, value] of Object.entries(where)) {
4567
+ if (value === void 0) {
4568
+ continue;
4569
+ }
4570
+ if (key === "or" && Array.isArray(value)) {
4571
+ if (value.some(
4572
+ (clause) => booleanOperandRequiresUuidQueryFallback(clause)
4573
+ )) {
4574
+ return true;
4575
+ }
4576
+ continue;
4577
+ }
4578
+ if (key === "not" && isRecord7(value)) {
4579
+ if (booleanOperandRequiresUuidQueryFallback(value)) {
4580
+ return true;
4581
+ }
4582
+ continue;
4583
+ }
4584
+ if (predicateRequiresUuidQueryFallback(key, value)) {
4585
+ return true;
4586
+ }
4587
+ }
4588
+ return false;
4589
+ }
3084
4590
  function resolvePagination(input) {
3085
4591
  let limit = input.limit;
3086
4592
  let offset = input.offset;
@@ -3099,25 +4605,6 @@ function hasTypedEqualityComparison(conditions) {
3099
4605
  }
3100
4606
  function createSelectTransportPlan(input) {
3101
4607
  const conditions = input.state.conditions.length ? input.state.conditions.map((condition) => ({ ...condition })) : void 0;
3102
- if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
3103
- const query = input.buildTypedSelectQuery({
3104
- tableName: input.tableName,
3105
- columns: input.columns,
3106
- conditions,
3107
- limit: input.state.limit,
3108
- offset: input.state.offset,
3109
- currentPage: input.state.currentPage,
3110
- pageSize: input.state.pageSize,
3111
- order: input.state.order
3112
- });
3113
- if (query) {
3114
- return {
3115
- kind: "query",
3116
- query,
3117
- payload: { query }
3118
- };
3119
- }
3120
- }
3121
4608
  const pagination = resolvePagination({
3122
4609
  limit: input.state.limit,
3123
4610
  offset: input.state.offset,
@@ -3153,6 +4640,25 @@ function createSelectTransportPlan(input) {
3153
4640
  }
3154
4641
  };
3155
4642
  }
4643
+ if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
4644
+ const query = input.buildTypedSelectQuery({
4645
+ tableName: input.tableName,
4646
+ columns: input.columns,
4647
+ conditions,
4648
+ limit: input.state.limit,
4649
+ offset: input.state.offset,
4650
+ currentPage: input.state.currentPage,
4651
+ pageSize: input.state.pageSize,
4652
+ order: input.state.order
4653
+ });
4654
+ if (query) {
4655
+ return {
4656
+ kind: "query",
4657
+ query,
4658
+ payload: { query }
4659
+ };
4660
+ }
4661
+ }
3156
4662
  return {
3157
4663
  kind: "fetch",
3158
4664
  payload: {
@@ -3209,6 +4715,13 @@ function formatResult(response) {
3209
4715
  }
3210
4716
  return result;
3211
4717
  }
4718
+ var EXPERIMENTAL_READ_RETRY_CONFIG = {
4719
+ retries: 2,
4720
+ baseDelayMs: 100,
4721
+ maxDelayMs: 1e3,
4722
+ backoff: "exponential",
4723
+ jitter: true
4724
+ };
3212
4725
  function attachNormalizedError(result, normalizedError) {
3213
4726
  Object.defineProperty(result, ATHENA_NORMALIZED_ERROR_KEY, {
3214
4727
  value: normalizedError,
@@ -3230,12 +4743,41 @@ function createResultFormatter(experimental) {
3230
4743
  },
3231
4744
  context
3232
4745
  );
3233
- result.error = createResultError(response, result, normalizedError);
3234
- attachNormalizedError(result, normalizedError);
3235
- return result;
3236
- };
4746
+ result.error = createResultError(response, result, normalizedError);
4747
+ attachNormalizedError(result, normalizedError);
4748
+ return result;
4749
+ };
4750
+ }
4751
+ async function executeExperimentalRead(experimental, runner) {
4752
+ if (!experimental?.retryReads) {
4753
+ return runner();
4754
+ }
4755
+ let lastRetryableResult;
4756
+ let lastRetrySignal = null;
4757
+ try {
4758
+ return await withRetry(
4759
+ {
4760
+ ...EXPERIMENTAL_READ_RETRY_CONFIG,
4761
+ shouldRetry: (error) => error === lastRetrySignal || normalizeAthenaError(error).retryable
4762
+ },
4763
+ async () => {
4764
+ const result = await runner();
4765
+ if (result.error?.retryable) {
4766
+ lastRetryableResult = result;
4767
+ lastRetrySignal = result.error;
4768
+ throw lastRetrySignal;
4769
+ }
4770
+ return result;
4771
+ }
4772
+ );
4773
+ } catch (error) {
4774
+ if (lastRetryableResult && error === lastRetrySignal) {
4775
+ return lastRetryableResult;
4776
+ }
4777
+ throw error;
4778
+ }
3237
4779
  }
3238
- function isRecord6(value) {
4780
+ function isRecord8(value) {
3239
4781
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3240
4782
  }
3241
4783
  function firstNonEmptyString2(...values) {
@@ -3247,8 +4789,8 @@ function firstNonEmptyString2(...values) {
3247
4789
  return void 0;
3248
4790
  }
3249
4791
  function resolveStructuredErrorPayload2(raw) {
3250
- if (!isRecord6(raw)) return null;
3251
- return isRecord6(raw.error) ? raw.error : raw;
4792
+ if (!isRecord8(raw)) return null;
4793
+ return isRecord8(raw.error) ? raw.error : raw;
3252
4794
  }
3253
4795
  function resolveStructuredErrorDetails(payload, message) {
3254
4796
  if (!payload || !("details" in payload)) {
@@ -3264,7 +4806,7 @@ function resolveStructuredErrorDetails(payload, message) {
3264
4806
  return details;
3265
4807
  }
3266
4808
  function createResultError(response, result, normalized) {
3267
- const rawRecord = isRecord6(response.raw) ? response.raw : null;
4809
+ const rawRecord = isRecord8(response.raw) ? response.raw : null;
3268
4810
  const payload = resolveStructuredErrorPayload2(response.raw);
3269
4811
  const message = firstNonEmptyString2(
3270
4812
  response.error,
@@ -3459,7 +5001,14 @@ function toSingleResult(response) {
3459
5001
  function mergeOptions(...options) {
3460
5002
  return options.reduce((acc, next) => {
3461
5003
  if (!next) return acc;
3462
- return { ...acc, ...next };
5004
+ const merged = { ...acc ?? {}, ...next };
5005
+ if (acc?.headers || next.headers) {
5006
+ merged.headers = {
5007
+ ...acc?.headers ?? {},
5008
+ ...next.headers ?? {}
5009
+ };
5010
+ }
5011
+ return merged;
3463
5012
  }, void 0);
3464
5013
  }
3465
5014
  function asAthenaJsonObject(value) {
@@ -4251,42 +5800,48 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4251
5800
  buildTypedSelectQuery
4252
5801
  });
4253
5802
  if (plan.kind === "query") {
4254
- return executeWithQueryTrace(
5803
+ return executeExperimentalRead(
5804
+ experimental,
5805
+ () => executeWithQueryTrace(
5806
+ tracer,
5807
+ {
5808
+ operation: "select",
5809
+ endpoint: "/gateway/query",
5810
+ table: resolvedTableName,
5811
+ sql: plan.query,
5812
+ payload: plan.payload,
5813
+ options
5814
+ },
5815
+ async () => {
5816
+ const queryResponse = await client.queryGateway(plan.payload, options);
5817
+ return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
5818
+ },
5819
+ callsite
5820
+ )
5821
+ );
5822
+ }
5823
+ const sql = buildDebugSelectQuery({
5824
+ tableName: resolvedTableName,
5825
+ ...plan.debug
5826
+ });
5827
+ return executeExperimentalRead(
5828
+ experimental,
5829
+ () => executeWithQueryTrace(
4255
5830
  tracer,
4256
5831
  {
4257
5832
  operation: "select",
4258
- endpoint: "/gateway/query",
5833
+ endpoint: "/gateway/fetch",
4259
5834
  table: resolvedTableName,
4260
- sql: plan.query,
5835
+ sql,
4261
5836
  payload: plan.payload,
4262
5837
  options
4263
5838
  },
4264
5839
  async () => {
4265
- const queryResponse = await client.queryGateway(plan.payload, options);
4266
- return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
5840
+ const response = await client.fetchGateway(plan.payload, options);
5841
+ return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
4267
5842
  },
4268
5843
  callsite
4269
- );
4270
- }
4271
- const sql = buildDebugSelectQuery({
4272
- tableName: resolvedTableName,
4273
- ...plan.debug
4274
- });
4275
- return executeWithQueryTrace(
4276
- tracer,
4277
- {
4278
- operation: "select",
4279
- endpoint: "/gateway/fetch",
4280
- table: resolvedTableName,
4281
- sql,
4282
- payload: plan.payload,
4283
- options
4284
- },
4285
- async () => {
4286
- const response = await client.fetchGateway(plan.payload, options);
4287
- return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
4288
- },
4289
- callsite
5844
+ )
4290
5845
  );
4291
5846
  };
4292
5847
  const createSelectChain = (columns, options, initialCallsite) => {
@@ -4356,14 +5911,14 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4356
5911
  if (options.limit !== void 0) {
4357
5912
  executionState.limit = options.limit;
4358
5913
  }
4359
- if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select)) {
5914
+ if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select) && !findManyAstWhereRequiresLegacyTransport(options.where)) {
4360
5915
  const resolvedTableName = resolveTableNameForCall(tableName, void 0);
4361
5916
  const payload = {
4362
5917
  table_name: resolvedTableName,
4363
5918
  select: options.select
4364
5919
  };
4365
5920
  if (options.where !== void 0) {
4366
- payload.where = options.where;
5921
+ payload.where = normalizeFindManyAstWhere(options.where);
4367
5922
  }
4368
5923
  const astOrder = toFindManyAstOrder(executionState.order);
4369
5924
  if (astOrder !== void 0) {
@@ -4379,22 +5934,25 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4379
5934
  limit: executionState.limit,
4380
5935
  order: executionState.order
4381
5936
  });
4382
- return executeWithQueryTrace(
4383
- tracer,
4384
- {
4385
- operation: "select",
4386
- endpoint: "/gateway/fetch",
4387
- table: resolvedTableName,
4388
- sql,
4389
- payload
4390
- },
4391
- async () => {
4392
- const response = await client.fetchGateway(
5937
+ return executeExperimentalRead(
5938
+ experimental,
5939
+ () => executeWithQueryTrace(
5940
+ tracer,
5941
+ {
5942
+ operation: "select",
5943
+ endpoint: "/gateway/fetch",
5944
+ table: resolvedTableName,
5945
+ sql,
4393
5946
  payload
4394
- );
4395
- return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
4396
- },
4397
- callsite
5947
+ },
5948
+ async () => {
5949
+ const response = await client.fetchGateway(
5950
+ payload
5951
+ );
5952
+ return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
5953
+ },
5954
+ callsite
5955
+ )
4398
5956
  );
4399
5957
  }
4400
5958
  return runSelect(
@@ -4642,7 +6200,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4642
6200
  });
4643
6201
  return builder;
4644
6202
  }
4645
- function createQueryBuilder(client, formatGatewayResult, tracer) {
6203
+ function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
4646
6204
  return async function query(query, options) {
4647
6205
  const normalizedQuery = query.trim();
4648
6206
  if (!normalizedQuery) {
@@ -4650,30 +6208,39 @@ function createQueryBuilder(client, formatGatewayResult, tracer) {
4650
6208
  }
4651
6209
  const payload = { query: normalizedQuery };
4652
6210
  const callsite = captureTraceCallsite(tracer);
4653
- return executeWithQueryTrace(
4654
- tracer,
4655
- {
4656
- operation: "query",
4657
- endpoint: "/gateway/query",
4658
- sql: normalizedQuery,
4659
- payload,
4660
- options
4661
- },
4662
- async () => {
4663
- const response = await client.queryGateway(payload, options);
4664
- return formatGatewayResult(response, { operation: "query" });
4665
- },
4666
- callsite
6211
+ return executeExperimentalRead(
6212
+ experimental,
6213
+ () => executeWithQueryTrace(
6214
+ tracer,
6215
+ {
6216
+ operation: "query",
6217
+ endpoint: "/gateway/query",
6218
+ sql: normalizedQuery,
6219
+ payload,
6220
+ options
6221
+ },
6222
+ async () => {
6223
+ const response = await client.queryGateway(payload, options);
6224
+ return formatGatewayResult(response, { operation: "query" });
6225
+ },
6226
+ callsite
6227
+ )
4667
6228
  );
4668
6229
  };
4669
6230
  }
4670
6231
  function createClientFromConfig(config) {
6232
+ const gatewayHeaders = {
6233
+ ...config.headers ?? {}
6234
+ };
6235
+ if (config.auth?.bearerToken && gatewayHeaders["X-Athena-Auth-Bearer-Token"] === void 0 && gatewayHeaders["x-athena-auth-bearer-token"] === void 0) {
6236
+ gatewayHeaders["X-Athena-Auth-Bearer-Token"] = config.auth.bearerToken;
6237
+ }
4671
6238
  const gateway = createAthenaGatewayClient({
4672
6239
  baseUrl: config.baseUrl,
4673
6240
  apiKey: config.apiKey,
4674
6241
  client: config.client,
4675
6242
  backend: config.backend,
4676
- headers: config.headers
6243
+ headers: gatewayHeaders
4677
6244
  });
4678
6245
  const formatGatewayResult = createResultFormatter(config.experimental);
4679
6246
  const queryTracer = createQueryTracer(config.experimental);
@@ -4700,9 +6267,9 @@ function createClientFromConfig(config) {
4700
6267
  captureTraceCallsite(queryTracer)
4701
6268
  );
4702
6269
  };
4703
- const query = createQueryBuilder(gateway, formatGatewayResult, queryTracer);
6270
+ const query = createQueryBuilder(gateway, formatGatewayResult, config.experimental, queryTracer);
4704
6271
  const db = createDbModule({ from, rpc, query });
4705
- return {
6272
+ const sdkClient = {
4706
6273
  from,
4707
6274
  db,
4708
6275
  rpc,
@@ -4710,6 +6277,14 @@ function createClientFromConfig(config) {
4710
6277
  verifyConnection: gateway.verifyConnection,
4711
6278
  auth: auth.auth
4712
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;
4713
6288
  }
4714
6289
  var DEFAULT_BACKEND = { type: "athena" };
4715
6290
  function toBackendConfig(b) {
@@ -4740,6 +6315,12 @@ function mergeExperimentalOptions(current, next) {
4740
6315
  ...next.traceQueries
4741
6316
  };
4742
6317
  }
6318
+ if (current?.storage || next.storage) {
6319
+ merged.storage = {
6320
+ ...current?.storage ?? {},
6321
+ ...next.storage ?? {}
6322
+ };
6323
+ }
4743
6324
  return merged;
4744
6325
  }
4745
6326
  var AthenaClientBuilderImpl = class {
@@ -4750,7 +6331,6 @@ var AthenaClientBuilderImpl = class {
4750
6331
  defaultHeaders;
4751
6332
  authConfig;
4752
6333
  experimentalOptions;
4753
- isHealthTrackingEnabled = false;
4754
6334
  url(url) {
4755
6335
  this.baseUrl = url;
4756
6336
  return this;
@@ -4777,7 +6357,7 @@ var AthenaClientBuilderImpl = class {
4777
6357
  }
4778
6358
  experimental(options) {
4779
6359
  this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options);
4780
- return this;
6360
+ return options.athenaStorageBackend ? this : this;
4781
6361
  }
4782
6362
  options(options) {
4783
6363
  if (options.client !== void 0) {
@@ -4798,11 +6378,7 @@ var AthenaClientBuilderImpl = class {
4798
6378
  if (options.experimental !== void 0) {
4799
6379
  this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options.experimental);
4800
6380
  }
4801
- return this;
4802
- }
4803
- healthTracking(enabled) {
4804
- this.isHealthTrackingEnabled = enabled;
4805
- return this;
6381
+ return options.experimental?.athenaStorageBackend ? this : this;
4806
6382
  }
4807
6383
  build() {
4808
6384
  if (!this.baseUrl || !this.apiKey) {
@@ -4814,7 +6390,6 @@ var AthenaClientBuilderImpl = class {
4814
6390
  client: this.clientName,
4815
6391
  backend: this.backendConfig,
4816
6392
  headers: this.defaultHeaders,
4817
- healthTracking: this.isHealthTrackingEnabled,
4818
6393
  auth: this.authConfig,
4819
6394
  experimental: this.experimentalOptions
4820
6395
  });
@@ -5434,7 +7009,7 @@ function resolveNullishValue(mode) {
5434
7009
  if (mode === "null") return null;
5435
7010
  return "";
5436
7011
  }
5437
- function isRecord7(value) {
7012
+ function isRecord9(value) {
5438
7013
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5439
7014
  }
5440
7015
  function isNullableColumn(model, key) {
@@ -5443,7 +7018,7 @@ function isNullableColumn(model, key) {
5443
7018
  }
5444
7019
  function toModelFormDefaults(model, values, options) {
5445
7020
  const source = values;
5446
- if (!isRecord7(source)) {
7021
+ if (!isRecord9(source)) {
5447
7022
  return {};
5448
7023
  }
5449
7024
  const mode = options?.nullishMode ?? "empty-string";
@@ -5874,6 +7449,90 @@ async function loadGeneratorConfig(options = {}) {
5874
7449
  }
5875
7450
  }
5876
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
+
5877
7536
  // src/utils/slugify.ts
5878
7537
  function slugify(input) {
5879
7538
  return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
@@ -6631,22 +8290,455 @@ async function runSchemaGenerator(options = {}) {
6631
8290
  };
6632
8291
  }
6633
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;
6634
8721
  exports.AthenaClient = AthenaClient;
6635
8722
  exports.AthenaError = AthenaError;
6636
8723
  exports.AthenaErrorCategory = AthenaErrorCategory;
6637
8724
  exports.AthenaErrorCode = AthenaErrorCode;
6638
8725
  exports.AthenaErrorKind = AthenaErrorKind;
6639
8726
  exports.AthenaGatewayError = AthenaGatewayError;
8727
+ exports.AthenaStorageError = AthenaStorageError;
8728
+ exports.AthenaStorageErrorCode = AthenaStorageErrorCode;
6640
8729
  exports.Backend = Backend;
6641
8730
  exports.DEFAULT_POSTGRES_SCHEMAS = DEFAULT_POSTGRES_SCHEMAS;
6642
8731
  exports.assertInt = assertInt;
8732
+ exports.athenaAuth = athenaAuth;
6643
8733
  exports.coerceInt = coerceInt;
8734
+ exports.createAthenaStorageError = createAthenaStorageError;
6644
8735
  exports.createAuthClient = createAuthClient;
6645
8736
  exports.createAuthReactEmailInput = createAuthReactEmailInput;
6646
8737
  exports.createClient = createClient;
6647
8738
  exports.createModelFormAdapter = createModelFormAdapter;
6648
8739
  exports.createPostgresIntrospectionProvider = createPostgresIntrospectionProvider;
6649
8740
  exports.createTypedClient = createTypedClient;
8741
+ exports.defineAthenaAuthConfig = defineAthenaAuthConfig;
6650
8742
  exports.defineAuthEmailTemplate = defineAuthEmailTemplate;
6651
8743
  exports.defineDatabase = defineDatabase;
6652
8744
  exports.defineGeneratorConfig = defineGeneratorConfig;
@@ -6655,6 +8747,7 @@ exports.defineRegistry = defineRegistry;
6655
8747
  exports.defineSchema = defineSchema;
6656
8748
  exports.findGeneratorConfigPath = findGeneratorConfigPath;
6657
8749
  exports.generateArtifactsFromSnapshot = generateArtifactsFromSnapshot;
8750
+ exports.generatorEnv = generatorEnv;
6658
8751
  exports.identifier = identifier;
6659
8752
  exports.isAthenaGatewayError = isAthenaGatewayError;
6660
8753
  exports.isOk = isOk;
@@ -6671,6 +8764,7 @@ exports.resolveGeneratorProvider = resolveGeneratorProvider;
6671
8764
  exports.resolvePostgresColumnType = resolvePostgresColumnType;
6672
8765
  exports.resolveProviderSchemas = resolveProviderSchemas;
6673
8766
  exports.runSchemaGenerator = runSchemaGenerator;
8767
+ exports.storageSdkManifest = storageSdkManifest;
6674
8768
  exports.toModelFormDefaults = toModelFormDefaults;
6675
8769
  exports.toModelPayload = toModelPayload;
6676
8770
  exports.unwrap = unwrap;