@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.js CHANGED
@@ -130,12 +130,685 @@ function buildAthenaGatewayUrl(baseUrl, path) {
130
130
  return `${baseUrl}${path}`;
131
131
  }
132
132
 
133
+ // src/cookies/base64.ts
134
+ function getAtob() {
135
+ const candidate = globalThis.atob;
136
+ return typeof candidate === "function" ? candidate : void 0;
137
+ }
138
+ function getBtoa() {
139
+ const candidate = globalThis.btoa;
140
+ return typeof candidate === "function" ? candidate : void 0;
141
+ }
142
+ function bytesToBinaryString(bytes) {
143
+ let result = "";
144
+ for (const byte of bytes) {
145
+ result += String.fromCharCode(byte);
146
+ }
147
+ return result;
148
+ }
149
+ function binaryStringToBytes(binary) {
150
+ const bytes = new Uint8Array(binary.length);
151
+ for (let i = 0; i < binary.length; i++) {
152
+ bytes[i] = binary.charCodeAt(i);
153
+ }
154
+ return bytes;
155
+ }
156
+ function encodeBase64(bytes) {
157
+ const btoaFn = getBtoa();
158
+ if (btoaFn) {
159
+ return btoaFn(bytesToBinaryString(bytes));
160
+ }
161
+ return Buffer.from(bytes).toString("base64");
162
+ }
163
+ function decodeBase64(base64) {
164
+ const atobFn = getAtob();
165
+ if (atobFn) {
166
+ return binaryStringToBytes(atobFn(base64));
167
+ }
168
+ return new Uint8Array(Buffer.from(base64, "base64"));
169
+ }
170
+ function encodeBytesToBase64Url(bytes) {
171
+ return encodeBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
172
+ }
173
+ function encodeStringToBase64Url(value) {
174
+ const bytes = new TextEncoder().encode(value);
175
+ return encodeBytesToBase64Url(bytes);
176
+ }
177
+ function decodeBase64UrlToBytes(value) {
178
+ const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
179
+ const paddingLength = normalized.length % 4;
180
+ const padded = paddingLength === 0 ? normalized : `${normalized}${"=".repeat(4 - paddingLength)}`;
181
+ return decodeBase64(padded);
182
+ }
183
+ function decodeBase64UrlToString(value) {
184
+ return new TextDecoder().decode(decodeBase64UrlToBytes(value));
185
+ }
186
+
187
+ // src/cookies/cookie-utils.ts
188
+ var SECURE_COOKIE_PREFIX = "__Secure-";
189
+ function parseCookies(cookieHeader) {
190
+ const cookies = cookieHeader.split("; ");
191
+ const cookieMap = /* @__PURE__ */ new Map();
192
+ cookies.forEach((cookie) => {
193
+ const [name, value] = cookie.split(/=(.*)/s);
194
+ cookieMap.set(name, value);
195
+ });
196
+ return cookieMap;
197
+ }
198
+
199
+ // src/cookies/crypto.ts
200
+ var HS256_ALG = "HS256";
201
+ async function getSubtleCrypto() {
202
+ const globalCrypto = globalThis.crypto;
203
+ if (globalCrypto?.subtle) {
204
+ return globalCrypto.subtle;
205
+ }
206
+ const { webcrypto } = await import('crypto');
207
+ const subtle = webcrypto.subtle;
208
+ if (!subtle) {
209
+ throw new Error("Web Crypto subtle API is unavailable.");
210
+ }
211
+ return subtle;
212
+ }
213
+ async function importHmacKey(secret, usage) {
214
+ const subtle = await getSubtleCrypto();
215
+ return subtle.importKey(
216
+ "raw",
217
+ new TextEncoder().encode(secret),
218
+ {
219
+ name: "HMAC",
220
+ hash: "SHA-256"
221
+ },
222
+ false,
223
+ [usage]
224
+ );
225
+ }
226
+ function bufferToBytes(buffer) {
227
+ return new Uint8Array(buffer);
228
+ }
229
+ function parseJwtPayload(payloadSegment) {
230
+ try {
231
+ const decoded = decodeBase64UrlToString(payloadSegment);
232
+ const payload = JSON.parse(decoded);
233
+ if (!payload || typeof payload !== "object") {
234
+ return null;
235
+ }
236
+ return payload;
237
+ } catch {
238
+ return null;
239
+ }
240
+ }
241
+ function isJwtExpired(payload) {
242
+ const exp = payload.exp;
243
+ if (typeof exp !== "number") {
244
+ return false;
245
+ }
246
+ return exp < Math.floor(Date.now() / 1e3);
247
+ }
248
+ async function signHmacBase64Url(secret, value) {
249
+ const subtle = await getSubtleCrypto();
250
+ const key = await importHmacKey(secret, "sign");
251
+ const signature = await subtle.sign("HMAC", key, new TextEncoder().encode(value));
252
+ return encodeBytesToBase64Url(bufferToBytes(signature));
253
+ }
254
+ async function signJwtHS256(payload, secret, expiresIn = 60 * 5) {
255
+ const now = Math.floor(Date.now() / 1e3);
256
+ const header = { alg: HS256_ALG, typ: "JWT" };
257
+ const fullPayload = {
258
+ ...payload,
259
+ iat: now,
260
+ exp: now + expiresIn
261
+ };
262
+ const headerPart = encodeStringToBase64Url(JSON.stringify(header));
263
+ const payloadPart = encodeStringToBase64Url(JSON.stringify(fullPayload));
264
+ const message = `${headerPart}.${payloadPart}`;
265
+ const signature = await signHmacBase64Url(secret, message);
266
+ return `${message}.${signature}`;
267
+ }
268
+ async function verifyJwtHS256(token, secret) {
269
+ const parts = token.split(".");
270
+ if (parts.length !== 3) {
271
+ return null;
272
+ }
273
+ const [headerPart, payloadPart, signaturePart] = parts;
274
+ if (!headerPart || !payloadPart || !signaturePart) {
275
+ return null;
276
+ }
277
+ let header = null;
278
+ try {
279
+ header = JSON.parse(decodeBase64UrlToString(headerPart));
280
+ } catch {
281
+ return null;
282
+ }
283
+ if (!header || header.alg !== HS256_ALG) {
284
+ return null;
285
+ }
286
+ const payload = parseJwtPayload(payloadPart);
287
+ if (!payload) {
288
+ return null;
289
+ }
290
+ const expectedSignature = await signHmacBase64Url(secret, `${headerPart}.${payloadPart}`);
291
+ if (expectedSignature !== signaturePart) {
292
+ return null;
293
+ }
294
+ if (isJwtExpired(payload)) {
295
+ return null;
296
+ }
297
+ return payload;
298
+ }
299
+
300
+ // src/cookies/session-store.ts
301
+ var ALLOWED_COOKIE_SIZE = 4096;
302
+ var ESTIMATED_EMPTY_COOKIE_SIZE = 200;
303
+ var CHUNK_SIZE = ALLOWED_COOKIE_SIZE - ESTIMATED_EMPTY_COOKIE_SIZE;
304
+ function getChunkIndex(cookieName) {
305
+ const parts = cookieName.split(".");
306
+ const lastPart = parts[parts.length - 1];
307
+ const index = parseInt(lastPart || "0", 10);
308
+ return Number.isNaN(index) ? 0 : index;
309
+ }
310
+ function readExistingChunks(cookieName, ctx) {
311
+ const chunks = {};
312
+ const cookies = parseCookies(ctx.headers?.get("cookie") || "");
313
+ for (const [name, value] of cookies) {
314
+ if (name.startsWith(cookieName)) {
315
+ chunks[name] = value;
316
+ }
317
+ }
318
+ return chunks;
319
+ }
320
+ function joinChunks(chunks) {
321
+ const sortedKeys = Object.keys(chunks).sort((left, right) => getChunkIndex(left) - getChunkIndex(right));
322
+ return sortedKeys.map((key) => chunks[key]).join("");
323
+ }
324
+ function chunkCookie(storeName, cookie, chunks, ctx) {
325
+ const chunkCount = Math.ceil(cookie.value.length / CHUNK_SIZE);
326
+ if (chunkCount === 1) {
327
+ chunks[cookie.name] = cookie.value;
328
+ return [cookie];
329
+ }
330
+ const cookies = [];
331
+ for (let index = 0; index < chunkCount; index++) {
332
+ const name = `${cookie.name}.${index}`;
333
+ const start = index * CHUNK_SIZE;
334
+ const value = cookie.value.substring(start, start + CHUNK_SIZE);
335
+ cookies.push({
336
+ ...cookie,
337
+ name,
338
+ value
339
+ });
340
+ chunks[name] = value;
341
+ }
342
+ ctx.logger?.debug?.(`CHUNKING_${storeName.toUpperCase()}_COOKIE`, {
343
+ message: `${storeName} cookie exceeds allowed ${ALLOWED_COOKIE_SIZE} bytes.`,
344
+ emptyCookieSize: ESTIMATED_EMPTY_COOKIE_SIZE,
345
+ valueSize: cookie.value.length,
346
+ chunkCount,
347
+ chunks: cookies.map((entry) => entry.value.length + ESTIMATED_EMPTY_COOKIE_SIZE)
348
+ });
349
+ return cookies;
350
+ }
351
+ function getCleanCookies(chunks, cookieOptions) {
352
+ const cleanedChunks = {};
353
+ for (const name in chunks) {
354
+ cleanedChunks[name] = {
355
+ name,
356
+ value: "",
357
+ attributes: {
358
+ ...cookieOptions,
359
+ maxAge: 0
360
+ }
361
+ };
362
+ }
363
+ return cleanedChunks;
364
+ }
365
+ var storeFactory = (storeName) => (cookieName, cookieOptions, ctx) => {
366
+ const chunks = readExistingChunks(cookieName, ctx);
367
+ return {
368
+ getValue() {
369
+ return joinChunks(chunks);
370
+ },
371
+ hasChunks() {
372
+ return Object.keys(chunks).length > 0;
373
+ },
374
+ chunk(value, options) {
375
+ const cleanedChunks = getCleanCookies(chunks, cookieOptions);
376
+ for (const name in chunks) {
377
+ delete chunks[name];
378
+ }
379
+ const cookies = cleanedChunks;
380
+ const chunked = chunkCookie(
381
+ storeName,
382
+ {
383
+ name: cookieName,
384
+ value,
385
+ attributes: {
386
+ ...cookieOptions,
387
+ ...options
388
+ }
389
+ },
390
+ chunks,
391
+ ctx
392
+ );
393
+ for (const chunk of chunked) {
394
+ cookies[chunk.name] = chunk;
395
+ }
396
+ return Object.values(cookies);
397
+ },
398
+ clean() {
399
+ const cleanedChunks = getCleanCookies(chunks, cookieOptions);
400
+ for (const name in chunks) {
401
+ delete chunks[name];
402
+ }
403
+ return Object.values(cleanedChunks);
404
+ },
405
+ setCookies(cookies) {
406
+ for (const cookie of cookies) {
407
+ ctx.setCookie(cookie.name, cookie.value, cookie.attributes);
408
+ }
409
+ }
410
+ };
411
+ };
412
+ var createSessionStore = storeFactory("Session");
413
+ var createAccountStore = storeFactory("Account");
414
+
415
+ // src/cookies/index.ts
416
+ var DEFAULT_COOKIE_PREFIX = "athena-auth";
417
+ var LEGACY_COOKIE_PREFIX = "better-auth";
418
+ var DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60;
419
+ var DEFAULT_CACHE_MAX_AGE = 60 * 5;
420
+ function isProductionRuntime() {
421
+ return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
422
+ }
423
+ function getEnvironmentSecret() {
424
+ if (typeof process === "undefined") {
425
+ return void 0;
426
+ }
427
+ return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET;
428
+ }
429
+ function isDynamicBaseURLConfig(baseURL) {
430
+ return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
431
+ }
432
+ function resolveCookiePrefixes(primaryPrefix) {
433
+ const prefixes = [primaryPrefix];
434
+ if (!prefixes.includes(DEFAULT_COOKIE_PREFIX)) {
435
+ prefixes.push(DEFAULT_COOKIE_PREFIX);
436
+ }
437
+ if (!prefixes.includes(LEGACY_COOKIE_PREFIX)) {
438
+ prefixes.push(LEGACY_COOKIE_PREFIX);
439
+ }
440
+ return prefixes;
441
+ }
442
+ function createError(message) {
443
+ return new Error(`@xylex-group/athena/cookies: ${message}`);
444
+ }
445
+ function getSecretOrThrow(secret) {
446
+ const resolved = secret || getEnvironmentSecret();
447
+ if (!resolved) {
448
+ throw createError(
449
+ "getCookieCache requires a secret. Pass `secret` or set ATHENA_AUTH_SECRET/BETTER_AUTH_SECRET/AUTH_SECRET."
450
+ );
451
+ }
452
+ return resolved;
453
+ }
454
+ function asObject(value) {
455
+ if (!value || typeof value !== "object") {
456
+ return null;
457
+ }
458
+ return value;
459
+ }
460
+ function getSessionTokenFromPair(session) {
461
+ const token = session.session?.token;
462
+ if (typeof token !== "string" || token.length === 0) {
463
+ throw createError("setSessionCookie requires `session.session.token` to be a non-empty string.");
464
+ }
465
+ return token;
466
+ }
467
+ async function resolveCookieVersion(versionConfig, session, user) {
468
+ if (!versionConfig) {
469
+ return "1";
470
+ }
471
+ if (typeof versionConfig === "string") {
472
+ return versionConfig;
473
+ }
474
+ return versionConfig(session, user);
475
+ }
476
+ function getSessionCookieCacheName(cookiePrefix, cookieName, isSecure) {
477
+ return isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`;
478
+ }
479
+ async function setCookieValue(ctx, name, value, attributes) {
480
+ const secret = ctx.context.secret;
481
+ if (secret && typeof ctx.setSignedCookie === "function") {
482
+ await ctx.setSignedCookie(name, value, secret, attributes);
483
+ return;
484
+ }
485
+ ctx.setCookie(name, value, attributes);
486
+ }
487
+ function parseJsonSafely(value) {
488
+ try {
489
+ return JSON.parse(value);
490
+ } catch {
491
+ return null;
492
+ }
493
+ }
494
+ function getIsSecureCookie(config) {
495
+ if (config?.isSecure !== void 0) {
496
+ return config.isSecure;
497
+ }
498
+ return isProductionRuntime();
499
+ }
500
+ function createCookieGetter(options) {
501
+ const baseURLString = typeof options.baseURL === "string" ? options.baseURL : void 0;
502
+ const dynamicProtocol = typeof options.baseURL === "object" && options.baseURL !== null ? options.baseURL.protocol : void 0;
503
+ const secure = options.advanced?.useSecureCookies !== void 0 ? options.advanced.useSecureCookies : dynamicProtocol === "https" ? true : dynamicProtocol === "http" ? false : baseURLString ? baseURLString.startsWith("https://") : isProductionRuntime();
504
+ const secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : "";
505
+ const crossSubdomainEnabled = !!options.advanced?.crossSubDomainCookies?.enabled;
506
+ const domain = crossSubdomainEnabled ? options.advanced?.crossSubDomainCookies?.domain || (baseURLString ? new URL(baseURLString).hostname : void 0) : void 0;
507
+ if (crossSubdomainEnabled && !domain && !isDynamicBaseURLConfig(options.baseURL)) {
508
+ throw createError("baseURL is required when `crossSubDomainCookies.enabled` is true.");
509
+ }
510
+ function createCookie(cookieName, overrideAttributes = {}) {
511
+ const prefix = options.advanced?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
512
+ const name = options.advanced?.cookies?.[cookieName]?.name || `${prefix}.${cookieName}`;
513
+ const attributes = options.advanced?.cookies?.[cookieName]?.attributes || {};
514
+ return {
515
+ name: `${secureCookiePrefix}${name}`,
516
+ attributes: {
517
+ secure: !!secureCookiePrefix,
518
+ sameSite: "lax",
519
+ path: "/",
520
+ httpOnly: true,
521
+ ...crossSubdomainEnabled ? { domain } : {},
522
+ ...options.advanced?.defaultCookieAttributes,
523
+ ...overrideAttributes,
524
+ ...attributes
525
+ }
526
+ };
527
+ }
528
+ return createCookie;
529
+ }
530
+ function getCookies(options) {
531
+ const createCookie = createCookieGetter(options);
532
+ const sessionToken = createCookie("session_token", { maxAge: options.session?.expiresIn || DEFAULT_SESSION_MAX_AGE });
533
+ const sessionData = createCookie("session_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
534
+ const accountData = createCookie("account_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
535
+ const dontRememberToken = createCookie("dont_remember");
536
+ return {
537
+ sessionToken: {
538
+ name: sessionToken.name,
539
+ attributes: sessionToken.attributes
540
+ },
541
+ sessionData: {
542
+ name: sessionData.name,
543
+ attributes: sessionData.attributes
544
+ },
545
+ dontRememberToken: {
546
+ name: dontRememberToken.name,
547
+ attributes: dontRememberToken.attributes
548
+ },
549
+ accountData: {
550
+ name: accountData.name,
551
+ attributes: accountData.attributes
552
+ }
553
+ };
554
+ }
555
+ async function setCookieCache(ctx, session, dontRememberMe) {
556
+ const cookieCacheConfig = ctx.context.options?.session?.cookieCache;
557
+ if (!cookieCacheConfig?.enabled) {
558
+ return;
559
+ }
560
+ const version = await resolveCookieVersion(
561
+ cookieCacheConfig.version,
562
+ session.session,
563
+ session.user
564
+ );
565
+ const sessionData = {
566
+ session: session.session,
567
+ user: session.user,
568
+ updatedAt: Date.now(),
569
+ version
570
+ };
571
+ const baseAttributes = ctx.context.authCookies.sessionData.attributes;
572
+ const maxAge = dontRememberMe ? void 0 : baseAttributes.maxAge;
573
+ const options = {
574
+ ...baseAttributes,
575
+ maxAge
576
+ };
577
+ const expiresAt = Date.now() + (options.maxAge || 60) * 1e3;
578
+ const strategy = cookieCacheConfig.strategy || "compact";
579
+ const secret = getSecretOrThrow(ctx.context.secret);
580
+ let encoded;
581
+ if (strategy === "jwt") {
582
+ encoded = await signJwtHS256(sessionData, secret, options.maxAge || DEFAULT_CACHE_MAX_AGE);
583
+ } else if (strategy === "jwe") {
584
+ throw createError("`jwe` strategy is not supported by the SDK cookie helper.");
585
+ } else {
586
+ const signature = await signHmacBase64Url(
587
+ secret,
588
+ JSON.stringify({
589
+ ...sessionData,
590
+ expiresAt
591
+ })
592
+ );
593
+ encoded = encodeStringToBase64Url(
594
+ JSON.stringify({
595
+ session: sessionData,
596
+ expiresAt,
597
+ signature
598
+ })
599
+ );
600
+ }
601
+ if (encoded.length > 4093) {
602
+ const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
603
+ const cookies = store.chunk(encoded, options);
604
+ store.setCookies(cookies);
605
+ } else {
606
+ const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
607
+ if (store.hasChunks()) {
608
+ store.setCookies(store.clean());
609
+ }
610
+ ctx.setCookie(ctx.context.authCookies.sessionData.name, encoded, options);
611
+ }
612
+ }
613
+ async function setSessionCookie(ctx, session, dontRememberMe, overrides) {
614
+ if (dontRememberMe === void 0 && typeof ctx.getSignedCookie === "function" && ctx.context.secret) {
615
+ const existingFlag = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
616
+ dontRememberMe = !!existingFlag;
617
+ }
618
+ const resolvedDontRememberMe = dontRememberMe ?? false;
619
+ const token = getSessionTokenFromPair(session);
620
+ const options = ctx.context.authCookies.sessionToken.attributes;
621
+ const maxAge = resolvedDontRememberMe ? void 0 : ctx.context.sessionConfig?.expiresIn;
622
+ await setCookieValue(ctx, ctx.context.authCookies.sessionToken.name, token, {
623
+ ...options,
624
+ maxAge,
625
+ ...overrides
626
+ });
627
+ if (resolvedDontRememberMe) {
628
+ await setCookieValue(
629
+ ctx,
630
+ ctx.context.authCookies.dontRememberToken.name,
631
+ "true",
632
+ ctx.context.authCookies.dontRememberToken.attributes
633
+ );
634
+ }
635
+ await setCookieCache(ctx, session, resolvedDontRememberMe);
636
+ ctx.context.setNewSession?.(session);
637
+ }
638
+ function expireCookie(ctx, cookie) {
639
+ ctx.setCookie(cookie.name, "", {
640
+ ...cookie.attributes,
641
+ maxAge: 0
642
+ });
643
+ }
644
+ function deleteSessionCookie(ctx, skipDontRememberMe) {
645
+ expireCookie(ctx, ctx.context.authCookies.sessionToken);
646
+ expireCookie(ctx, ctx.context.authCookies.sessionData);
647
+ if (ctx.context.options?.account?.storeAccountCookie) {
648
+ expireCookie(ctx, ctx.context.authCookies.accountData);
649
+ const accountStore = createAccountStore(
650
+ ctx.context.authCookies.accountData.name,
651
+ ctx.context.authCookies.accountData.attributes,
652
+ ctx
653
+ );
654
+ accountStore.setCookies(accountStore.clean());
655
+ }
656
+ const sessionStore = createSessionStore(
657
+ ctx.context.authCookies.sessionData.name,
658
+ ctx.context.authCookies.sessionData.attributes,
659
+ ctx
660
+ );
661
+ sessionStore.setCookies(sessionStore.clean());
662
+ if (!skipDontRememberMe) {
663
+ expireCookie(ctx, ctx.context.authCookies.dontRememberToken);
664
+ }
665
+ }
666
+ var getSessionCookie = (request, config) => {
667
+ const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
668
+ if (!cookies) {
669
+ return null;
670
+ }
671
+ const { cookieName = "session_token", cookiePrefix = "athena-auth" } = config || {};
672
+ const parsedCookie = parseCookies(cookies);
673
+ const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
674
+ const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
675
+ if (sessionToken) {
676
+ return sessionToken;
677
+ }
678
+ return null;
679
+ };
680
+ var getCookieCache = async (request, config) => {
681
+ const headers = request instanceof Headers || !("headers" in request) ? request : request.headers;
682
+ const cookieHeader = headers.get("cookie");
683
+ if (!cookieHeader) {
684
+ return null;
685
+ }
686
+ const parsedCookie = parseCookies(cookieHeader);
687
+ const cookieName = config?.cookieName || "session_data";
688
+ const requestedPrefix = config?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
689
+ const strategy = config?.strategy || "compact";
690
+ const cookiePrefixes = resolveCookiePrefixes(requestedPrefix);
691
+ const isSecure = getIsSecureCookie(config);
692
+ const secret = getSecretOrThrow(config?.secret);
693
+ let sessionData;
694
+ for (const prefix of cookiePrefixes) {
695
+ const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
696
+ const cookieValue = parsedCookie.get(candidate);
697
+ if (cookieValue) {
698
+ sessionData = cookieValue;
699
+ break;
700
+ }
701
+ }
702
+ if (!sessionData) {
703
+ const reconstructedChunks = [];
704
+ for (const prefix of cookiePrefixes) {
705
+ const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
706
+ for (const [name, value] of parsedCookie.entries()) {
707
+ if (!name.startsWith(`${candidate}.`)) {
708
+ continue;
709
+ }
710
+ const parts = name.split(".");
711
+ const indexStr = parts[parts.length - 1];
712
+ const index = parseInt(indexStr || "0", 10);
713
+ if (!Number.isNaN(index)) {
714
+ reconstructedChunks.push({ index, value });
715
+ }
716
+ }
717
+ if (reconstructedChunks.length > 0) {
718
+ break;
719
+ }
720
+ }
721
+ if (reconstructedChunks.length > 0) {
722
+ reconstructedChunks.sort((left, right) => left.index - right.index);
723
+ sessionData = reconstructedChunks.map((chunk) => chunk.value).join("");
724
+ }
725
+ }
726
+ if (!sessionData) {
727
+ return null;
728
+ }
729
+ if (strategy === "jwe") {
730
+ throw createError(
731
+ "`jwe` strategy is not supported by the SDK cookie helper. Use compact/jwt or pass cookie data through the auth server."
732
+ );
733
+ }
734
+ if (strategy === "jwt") {
735
+ const payload = await verifyJwtHS256(sessionData, secret);
736
+ if (!payload) {
737
+ return null;
738
+ }
739
+ const sessionRecord = asObject(payload.session);
740
+ const userRecord = asObject(payload.user);
741
+ const updatedAt = payload.updatedAt;
742
+ if (!sessionRecord || !userRecord || typeof updatedAt !== "number") {
743
+ return null;
744
+ }
745
+ if (config?.version) {
746
+ const cookieVersion = typeof payload.version === "string" ? payload.version : "1";
747
+ const expectedVersion = typeof config.version === "string" ? config.version : await config.version(sessionRecord, userRecord);
748
+ if (cookieVersion !== expectedVersion) {
749
+ return null;
750
+ }
751
+ }
752
+ return {
753
+ session: sessionRecord,
754
+ user: userRecord,
755
+ updatedAt,
756
+ version: typeof payload.version === "string" ? payload.version : void 0
757
+ };
758
+ }
759
+ const compactPayload = parseJsonSafely(decodeBase64UrlToString(sessionData));
760
+ if (!compactPayload) {
761
+ return null;
762
+ }
763
+ const expectedSignature = await signHmacBase64Url(
764
+ secret,
765
+ JSON.stringify({
766
+ ...compactPayload.session,
767
+ expiresAt: compactPayload.expiresAt
768
+ })
769
+ );
770
+ if (expectedSignature !== compactPayload.signature) {
771
+ return null;
772
+ }
773
+ if (compactPayload.expiresAt <= Date.now()) {
774
+ return null;
775
+ }
776
+ const resolvedSession = compactPayload.session;
777
+ if (config?.version) {
778
+ const cookieVersion = resolvedSession.version || "1";
779
+ const expectedVersion = typeof config.version === "string" ? config.version : await config.version(resolvedSession.session, resolvedSession.user);
780
+ if (cookieVersion !== expectedVersion) {
781
+ return null;
782
+ }
783
+ }
784
+ const sessionObject = asObject(resolvedSession.session);
785
+ const userObject = asObject(resolvedSession.user);
786
+ if (!sessionObject || !userObject) {
787
+ return null;
788
+ }
789
+ return {
790
+ session: sessionObject,
791
+ user: userObject,
792
+ updatedAt: resolvedSession.updatedAt,
793
+ version: resolvedSession.version
794
+ };
795
+ };
796
+
797
+ // package.json
798
+ var package_default = {
799
+ version: "2.6.0"
800
+ };
801
+
802
+ // src/sdk-version.ts
803
+ var PACKAGE_VERSION = package_default.version;
804
+ function buildSdkHeaderValue(sdkName) {
805
+ return `${sdkName} ${PACKAGE_VERSION}`;
806
+ }
807
+
133
808
  // src/gateway/client.ts
134
809
  var DEFAULT_CLIENT = "railway_direct";
135
- var FALLBACK_SDK_VERSION = "1.3.0";
136
810
  var SDK_NAME = "xylex-group/athena";
137
- var SDK_VERSION = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION;
138
- var SDK_HEADER_VALUE = `${SDK_NAME} ${SDK_VERSION}`;
811
+ var SDK_HEADER_VALUE = buildSdkHeaderValue(SDK_NAME);
139
812
  function parseResponseBody(rawText, contentType) {
140
813
  if (!rawText) {
141
814
  return { parsed: null, parseFailed: false };
@@ -154,6 +827,37 @@ function parseResponseBody(rawText, contentType) {
154
827
  function normalizeHeaderValue(value) {
155
828
  return value ? value : void 0;
156
829
  }
830
+ function resolveHeaderValue(headers, candidates) {
831
+ for (const candidate of candidates) {
832
+ const direct = normalizeHeaderValue(headers[candidate]);
833
+ if (direct) return direct;
834
+ }
835
+ const loweredCandidates = new Set(candidates.map((candidate) => candidate.toLowerCase()));
836
+ for (const [key, value] of Object.entries(headers)) {
837
+ if (!loweredCandidates.has(key.toLowerCase())) {
838
+ continue;
839
+ }
840
+ const normalized = normalizeHeaderValue(value);
841
+ if (normalized) return normalized;
842
+ }
843
+ return void 0;
844
+ }
845
+ function resolveBearerTokenFromAuthorizationHeader(headers) {
846
+ const authorization = resolveHeaderValue(headers, ["Authorization"]);
847
+ if (!authorization) {
848
+ return void 0;
849
+ }
850
+ const match = authorization.match(/^Bearer\s+(.+)$/i);
851
+ const token = match?.[1]?.trim();
852
+ return token ? token : void 0;
853
+ }
854
+ function resolveSessionTokenFromCookieHeader(headers) {
855
+ const cookie = resolveHeaderValue(headers, ["Cookie"]);
856
+ if (!cookie) {
857
+ return void 0;
858
+ }
859
+ return getSessionCookie(new Headers({ cookie })) ?? void 0;
860
+ }
157
861
  function isRecord(value) {
158
862
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
159
863
  }
@@ -271,7 +975,7 @@ function buildRpcGetEndpoint(payload) {
271
975
  status: 0
272
976
  });
273
977
  }
274
- query.set(filter.column, toRpcFilterQueryValue(filter));
978
+ query.append(filter.column, toRpcFilterQueryValue(filter));
275
979
  }
276
980
  }
277
981
  const endpoint = `/rpc/${encodeURIComponent(functionName)}`;
@@ -317,6 +1021,20 @@ function buildHeaders(config, options) {
317
1021
  headers["apikey"] = finalApiKey;
318
1022
  headers["x-api-key"] = headers["x-api-key"] ?? finalApiKey;
319
1023
  }
1024
+ const explicitSessionToken = resolveHeaderValue(extraHeaders, [
1025
+ "X-Athena-Auth-Session-Token"
1026
+ ]);
1027
+ const derivedSessionToken = explicitSessionToken ?? resolveSessionTokenFromCookieHeader(extraHeaders);
1028
+ if (derivedSessionToken) {
1029
+ headers["X-Athena-Auth-Session-Token"] = derivedSessionToken;
1030
+ }
1031
+ const explicitBearerToken = resolveHeaderValue(extraHeaders, [
1032
+ "X-Athena-Auth-Bearer-Token"
1033
+ ]);
1034
+ const derivedBearerToken = explicitBearerToken ?? resolveBearerTokenFromAuthorizationHeader(extraHeaders);
1035
+ if (derivedBearerToken) {
1036
+ headers["X-Athena-Auth-Bearer-Token"] = derivedBearerToken;
1037
+ }
320
1038
  const athenaClientKeys = ["x-athena-client", "X-Athena-Client"];
321
1039
  Object.entries(extraHeaders).forEach(([key, value]) => {
322
1040
  if (athenaClientKeys.includes(key)) return;
@@ -1012,10 +1730,8 @@ async function resolveReactEmailPayloadFields(input, fields, options) {
1012
1730
 
1013
1731
  // src/auth/client.ts
1014
1732
  var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
1015
- var FALLBACK_SDK_VERSION2 = "1.0.0";
1016
1733
  var SDK_NAME2 = "xylex-group/athena-auth";
1017
- var SDK_VERSION2 = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION2;
1018
- var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
1734
+ var SDK_HEADER_VALUE2 = buildSdkHeaderValue(SDK_NAME2);
1019
1735
  function normalizeBaseUrl(baseUrl) {
1020
1736
  return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
1021
1737
  }
@@ -2655,47 +3371,739 @@ function createDbModule(input) {
2655
3371
  return db;
2656
3372
  }
2657
3373
 
2658
- // src/query-ast.ts
2659
- 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;
2660
- var FILTER_OPERATORS = /* @__PURE__ */ new Set([
2661
- "eq",
2662
- "neq",
2663
- "gt",
2664
- "gte",
2665
- "lt",
2666
- "lte",
2667
- "like",
2668
- "ilike",
2669
- "is",
2670
- "in",
2671
- "contains",
2672
- "containedBy"
2673
- ]);
2674
- var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
2675
- "eq",
2676
- "neq",
2677
- "gt",
2678
- "gte",
2679
- "lt",
2680
- "lte",
2681
- "like",
2682
- "ilike",
2683
- "is"
2684
- ]);
2685
- function isRecord5(value) {
2686
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2687
- }
2688
- function isUuidString(value) {
2689
- return UUID_PATTERN.test(value.trim());
2690
- }
2691
- function isUuidIdentifierColumn(column) {
2692
- return column === "id" || /(?:^|_)uuid(?:_|$)/i.test(column) || /_id$/i.test(column);
2693
- }
2694
- function shouldUseUuidTextComparison(column, value) {
3374
+ // src/storage/module.ts
3375
+ var storageSdkManifest = {
3376
+ namespace: "storage",
3377
+ basePath: "/storage",
3378
+ envelopeKinds: {
3379
+ raw: "response body is the payload",
3380
+ athena: "response body is { status, message, data }"
3381
+ },
3382
+ methods: [
3383
+ {
3384
+ name: "listStorageCatalogs",
3385
+ method: "GET",
3386
+ path: "/storage/catalogs",
3387
+ responseEnvelope: "raw",
3388
+ responseType: "{ data: S3CatalogItem[] }"
3389
+ },
3390
+ {
3391
+ name: "createStorageCatalog",
3392
+ method: "POST",
3393
+ path: "/storage/catalogs",
3394
+ requestType: "CreateStorageCatalogRequest",
3395
+ responseEnvelope: "raw",
3396
+ responseType: "S3CatalogItem"
3397
+ },
3398
+ {
3399
+ name: "updateStorageCatalog",
3400
+ method: "PATCH",
3401
+ path: "/storage/catalogs/{id}",
3402
+ pathParams: ["id"],
3403
+ requestType: "UpdateStorageCatalogRequest",
3404
+ responseEnvelope: "raw",
3405
+ responseType: "S3CatalogItem"
3406
+ },
3407
+ {
3408
+ name: "deleteStorageCatalog",
3409
+ method: "DELETE",
3410
+ path: "/storage/catalogs/{id}",
3411
+ pathParams: ["id"],
3412
+ responseEnvelope: "raw",
3413
+ responseType: "{ id: string; deleted: boolean }"
3414
+ },
3415
+ {
3416
+ name: "listStorageCredentials",
3417
+ method: "GET",
3418
+ path: "/storage/credentials",
3419
+ responseEnvelope: "raw",
3420
+ responseType: "{ data: S3CredentialListItem[] }"
3421
+ },
3422
+ {
3423
+ name: "createStorageUploadUrl",
3424
+ method: "POST",
3425
+ path: "/storage/files/upload-url",
3426
+ requestType: "CreateStorageUploadUrlRequest",
3427
+ responseEnvelope: "athena",
3428
+ responseType: "StorageUploadUrlResponse"
3429
+ },
3430
+ {
3431
+ name: "createStorageUploadUrls",
3432
+ method: "POST",
3433
+ path: "/storage/files/upload-urls",
3434
+ requestType: "CreateStorageUploadUrlsRequest",
3435
+ responseEnvelope: "athena",
3436
+ responseType: "StorageBatchUploadUrlResponse"
3437
+ },
3438
+ {
3439
+ name: "listStorageFiles",
3440
+ method: "POST",
3441
+ path: "/storage/files/list",
3442
+ requestType: "ListStorageFilesRequest",
3443
+ responseEnvelope: "athena",
3444
+ responseType: "StorageListFilesResponse"
3445
+ },
3446
+ {
3447
+ name: "getStorageFile",
3448
+ method: "GET",
3449
+ path: "/storage/files/{file_id}",
3450
+ pathParams: ["file_id"],
3451
+ responseEnvelope: "athena",
3452
+ responseType: "StorageFileMutationResponse"
3453
+ },
3454
+ {
3455
+ name: "getStorageFileUrl",
3456
+ method: "GET",
3457
+ path: "/storage/files/{file_id}/url",
3458
+ pathParams: ["file_id"],
3459
+ queryParams: ["purpose"],
3460
+ responseEnvelope: "athena",
3461
+ responseType: "PresignedFileUrlResponse"
3462
+ },
3463
+ {
3464
+ name: "getStorageFileProxy",
3465
+ method: "GET",
3466
+ path: "/storage/files/{file_id}/proxy",
3467
+ pathParams: ["file_id"],
3468
+ queryParams: ["purpose"],
3469
+ responseEnvelope: "raw",
3470
+ responseType: "Response",
3471
+ binary: true
3472
+ },
3473
+ {
3474
+ name: "updateStorageFile",
3475
+ method: "PATCH",
3476
+ path: "/storage/files/{file_id}",
3477
+ pathParams: ["file_id"],
3478
+ requestType: "UpdateStorageFileRequest",
3479
+ responseEnvelope: "athena",
3480
+ responseType: "StorageFileMutationResponse"
3481
+ },
3482
+ {
3483
+ name: "deleteStorageFile",
3484
+ method: "DELETE",
3485
+ path: "/storage/files/{file_id}",
3486
+ pathParams: ["file_id"],
3487
+ responseEnvelope: "athena",
3488
+ responseType: "StorageFileMutationResponse"
3489
+ },
3490
+ {
3491
+ name: "setStorageFileVisibility",
3492
+ method: "PATCH",
3493
+ path: "/storage/files/{file_id}/visibility",
3494
+ pathParams: ["file_id"],
3495
+ requestType: "SetStorageFileVisibilityRequest",
3496
+ responseEnvelope: "athena",
3497
+ responseType: "StorageFileMutationResponse"
3498
+ },
3499
+ {
3500
+ name: "deleteStorageFolder",
3501
+ method: "POST",
3502
+ path: "/storage/folders/delete",
3503
+ requestType: "DeleteStorageFolderRequest",
3504
+ responseEnvelope: "athena",
3505
+ responseType: "StorageFolderMutationResponse"
3506
+ },
3507
+ {
3508
+ name: "moveStorageFolder",
3509
+ method: "POST",
3510
+ path: "/storage/folders/move",
3511
+ requestType: "MoveStorageFolderRequest",
3512
+ responseEnvelope: "athena",
3513
+ responseType: "StorageFolderMutationResponse"
3514
+ }
3515
+ ]
3516
+ };
3517
+ var AthenaStorageErrorCode = {
3518
+ InvalidUrl: "INVALID_URL",
3519
+ NetworkError: "NETWORK_ERROR",
3520
+ HttpError: "HTTP_ERROR",
3521
+ InvalidJson: "INVALID_JSON",
3522
+ InvalidAthenaEnvelope: "INVALID_ATHENA_ENVELOPE",
3523
+ UnknownError: "UNKNOWN_ERROR"
3524
+ };
3525
+ var AthenaStorageError = class extends Error {
3526
+ code;
3527
+ athenaCode;
3528
+ kind;
3529
+ category;
3530
+ retryable;
3531
+ status;
3532
+ endpoint;
3533
+ method;
3534
+ requestId;
3535
+ hint;
3536
+ causeDetail;
3537
+ raw;
3538
+ normalized;
3539
+ __athenaNormalizedError;
3540
+ constructor(input) {
3541
+ super(input.message, { cause: input.cause });
3542
+ this.name = "AthenaStorageError";
3543
+ this.code = input.code;
3544
+ this.status = input.status;
3545
+ this.endpoint = input.endpoint;
3546
+ this.method = input.method;
3547
+ this.requestId = input.requestId;
3548
+ this.hint = input.hint;
3549
+ this.causeDetail = causeToString(input.cause);
3550
+ this.raw = input.raw ?? null;
3551
+ this.normalized = normalizeStorageErrorInput(input);
3552
+ this.__athenaNormalizedError = this.normalized;
3553
+ this.athenaCode = this.normalized.code;
3554
+ this.kind = this.normalized.kind;
3555
+ this.category = this.normalized.category;
3556
+ this.retryable = this.normalized.retryable;
3557
+ Object.defineProperty(this, "__athenaNormalizedError", {
3558
+ value: this.normalized,
3559
+ enumerable: false,
3560
+ configurable: false,
3561
+ writable: false
3562
+ });
3563
+ }
3564
+ toDetails() {
3565
+ return {
3566
+ code: this.code,
3567
+ athenaCode: this.athenaCode,
3568
+ kind: this.kind,
3569
+ category: this.category,
3570
+ retryable: this.retryable,
3571
+ message: this.message,
3572
+ status: this.status,
3573
+ endpoint: this.endpoint,
3574
+ method: this.method,
3575
+ requestId: this.requestId,
3576
+ hint: this.hint,
3577
+ cause: this.causeDetail,
3578
+ raw: this.raw
3579
+ };
3580
+ }
3581
+ };
3582
+ function isRecord5(value) {
3583
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3584
+ }
3585
+ function causeToString(cause) {
3586
+ if (cause === void 0 || cause === null) return void 0;
3587
+ if (typeof cause === "string") return cause;
3588
+ if (cause instanceof Error && cause.message.trim()) return cause.message.trim();
3589
+ try {
3590
+ return JSON.stringify(cause);
3591
+ } catch {
3592
+ return String(cause);
3593
+ }
3594
+ }
3595
+ function storageGatewayCode(code) {
3596
+ if (code === "INVALID_URL") return "INVALID_URL";
3597
+ if (code === "NETWORK_ERROR") return "NETWORK_ERROR";
3598
+ if (code === "INVALID_JSON" || code === "INVALID_ATHENA_ENVELOPE") return "INVALID_JSON";
3599
+ if (code === "HTTP_ERROR") return "HTTP_ERROR";
3600
+ return "UNKNOWN_ERROR";
3601
+ }
3602
+ function headerValue(headers, names) {
3603
+ for (const name of names) {
3604
+ const value = headers.get(name);
3605
+ if (value?.trim()) return value.trim();
3606
+ }
3607
+ return void 0;
3608
+ }
3609
+ function storageOperationFromEndpoint(endpoint, method) {
3610
+ const endpointPath = String(endpoint).split("?")[0];
3611
+ for (const candidate of storageSdkManifest.methods) {
3612
+ if (candidate.method !== method) continue;
3613
+ const pattern = `^${candidate.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\\\{[^/]+\\\}/g, "[^/]+")}$`;
3614
+ if (new RegExp(pattern).test(endpointPath)) {
3615
+ return candidate.name;
3616
+ }
3617
+ }
3618
+ return `storage:${method.toLowerCase()}`;
3619
+ }
3620
+ function normalizeStorageErrorInput(input) {
3621
+ return normalizeAthenaError(
3622
+ {
3623
+ data: null,
3624
+ error: {
3625
+ message: input.message,
3626
+ gatewayCode: storageGatewayCode(input.code),
3627
+ status: input.status,
3628
+ raw: input.raw ?? input.cause ?? null
3629
+ },
3630
+ errorDetails: {
3631
+ code: storageGatewayCode(input.code),
3632
+ message: input.message,
3633
+ status: input.status,
3634
+ endpoint: input.endpoint,
3635
+ method: input.method,
3636
+ requestId: input.requestId,
3637
+ hint: input.hint,
3638
+ cause: causeToString(input.cause)
3639
+ },
3640
+ raw: input.raw ?? input.cause ?? null,
3641
+ status: input.status
3642
+ },
3643
+ { operation: storageOperationFromEndpoint(input.endpoint, input.method) }
3644
+ );
3645
+ }
3646
+ function createAthenaStorageError(input) {
3647
+ return new AthenaStorageError(input);
3648
+ }
3649
+ async function notifyStorageError(error, options, runtimeOptions) {
3650
+ const handlers = [runtimeOptions?.onError, options?.onError].filter(
3651
+ (handler) => typeof handler === "function"
3652
+ );
3653
+ for (const handler of handlers) {
3654
+ try {
3655
+ await handler(error);
3656
+ } catch {
3657
+ }
3658
+ }
3659
+ }
3660
+ async function rejectStorageError(input, options, runtimeOptions) {
3661
+ const error = createAthenaStorageError(input);
3662
+ await notifyStorageError(error, options, runtimeOptions);
3663
+ throw error;
3664
+ }
3665
+ function parseResponseBody3(rawText, contentType) {
3666
+ if (!rawText) {
3667
+ return { parsed: null, parseFailed: false };
3668
+ }
3669
+ const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
3670
+ const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
3671
+ if (!looksJson) {
3672
+ return { parsed: rawText, parseFailed: false };
3673
+ }
3674
+ try {
3675
+ return { parsed: JSON.parse(rawText), parseFailed: false };
3676
+ } catch {
3677
+ return { parsed: rawText, parseFailed: true };
3678
+ }
3679
+ }
3680
+ function appendQuery(path, query) {
3681
+ if (!query) return path;
3682
+ const params = new URLSearchParams();
3683
+ for (const [key, value] of Object.entries(query)) {
3684
+ if (value === void 0 || value === null) continue;
3685
+ params.set(key, String(value));
3686
+ }
3687
+ const queryText = params.toString();
3688
+ return queryText ? `${path}?${queryText}` : path;
3689
+ }
3690
+ function storagePath(path) {
3691
+ return path;
3692
+ }
3693
+ function withPathParam(path, name, value) {
3694
+ return path.replace(`{${name}}`, encodeURIComponent(value));
3695
+ }
3696
+ function resolveErrorMessage3(payload, fallback) {
3697
+ if (isRecord5(payload)) {
3698
+ const message = payload.message ?? payload.error ?? payload.details;
3699
+ if (typeof message === "string" && message.trim()) {
3700
+ return message.trim();
3701
+ }
3702
+ }
3703
+ if (typeof payload === "string" && payload.trim()) {
3704
+ return payload.trim();
3705
+ }
3706
+ return fallback;
3707
+ }
3708
+ function resolveErrorHint2(payload) {
3709
+ if (!isRecord5(payload)) return void 0;
3710
+ const hint = payload.hint ?? payload.suggestion;
3711
+ return typeof hint === "string" && hint.trim() ? hint.trim() : void 0;
3712
+ }
3713
+ function resolveErrorCause(payload) {
3714
+ if (!isRecord5(payload)) return void 0;
3715
+ const cause = payload.cause ?? payload.reason;
3716
+ return typeof cause === "string" && cause.trim() ? cause.trim() : void 0;
3717
+ }
3718
+ function storageCodeFromUnknown(error) {
3719
+ if (isAthenaGatewayError(error)) {
3720
+ if (error.code === "INVALID_URL") return "INVALID_URL";
3721
+ if (error.code === "NETWORK_ERROR") return "NETWORK_ERROR";
3722
+ if (error.code === "INVALID_JSON") return "INVALID_JSON";
3723
+ if (error.code === "HTTP_ERROR") return "HTTP_ERROR";
3724
+ }
3725
+ return "UNKNOWN_ERROR";
3726
+ }
3727
+ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload, options, runtimeOptions) {
3728
+ let url;
3729
+ let headers;
3730
+ try {
3731
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3732
+ url = buildAthenaGatewayUrl(baseUrl, endpoint);
3733
+ headers = gateway.buildHeaders(options);
3734
+ } catch (error) {
3735
+ return rejectStorageError(
3736
+ {
3737
+ code: storageCodeFromUnknown(error),
3738
+ message: error instanceof Error ? error.message : `Athena storage ${method} ${endpoint} failed before sending the request`,
3739
+ status: isAthenaGatewayError(error) ? error.status : 0,
3740
+ endpoint,
3741
+ method,
3742
+ raw: error,
3743
+ requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
3744
+ hint: isAthenaGatewayError(error) ? error.hint : void 0,
3745
+ cause: error
3746
+ },
3747
+ options,
3748
+ runtimeOptions
3749
+ );
3750
+ }
3751
+ const requestInit = {
3752
+ method,
3753
+ headers,
3754
+ signal: options?.signal
3755
+ };
3756
+ if (payload !== void 0 && method !== "GET") {
3757
+ requestInit.body = JSON.stringify(payload);
3758
+ }
3759
+ let response;
3760
+ try {
3761
+ response = await fetch(url, requestInit);
3762
+ } catch (error) {
3763
+ const message = error instanceof Error ? error.message : String(error);
3764
+ return rejectStorageError(
3765
+ {
3766
+ code: "NETWORK_ERROR",
3767
+ message: `Network error while calling Athena storage ${method} ${endpoint}: ${message}`,
3768
+ status: 0,
3769
+ endpoint,
3770
+ method,
3771
+ cause: error
3772
+ },
3773
+ options,
3774
+ runtimeOptions
3775
+ );
3776
+ }
3777
+ let rawText;
3778
+ try {
3779
+ rawText = await response.text();
3780
+ } catch (error) {
3781
+ return rejectStorageError(
3782
+ {
3783
+ code: "NETWORK_ERROR",
3784
+ message: `Athena storage ${method} ${endpoint} response body could not be read`,
3785
+ status: response.status,
3786
+ endpoint,
3787
+ method,
3788
+ requestId: headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]),
3789
+ cause: error
3790
+ },
3791
+ options,
3792
+ runtimeOptions
3793
+ );
3794
+ }
3795
+ const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
3796
+ const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
3797
+ if (parsedBody.parseFailed) {
3798
+ return rejectStorageError(
3799
+ {
3800
+ code: "INVALID_JSON",
3801
+ message: `Athena storage ${method} ${endpoint} returned malformed JSON`,
3802
+ status: response.status,
3803
+ endpoint,
3804
+ method,
3805
+ requestId,
3806
+ raw: parsedBody.parsed
3807
+ },
3808
+ options,
3809
+ runtimeOptions
3810
+ );
3811
+ }
3812
+ if (!response.ok) {
3813
+ return rejectStorageError(
3814
+ {
3815
+ code: "HTTP_ERROR",
3816
+ message: resolveErrorMessage3(
3817
+ parsedBody.parsed,
3818
+ `Athena storage ${method} ${endpoint} failed with status ${response.status}`
3819
+ ),
3820
+ status: response.status,
3821
+ endpoint,
3822
+ method,
3823
+ requestId,
3824
+ hint: resolveErrorHint2(parsedBody.parsed),
3825
+ cause: resolveErrorCause(parsedBody.parsed),
3826
+ raw: parsedBody.parsed
3827
+ },
3828
+ options,
3829
+ runtimeOptions
3830
+ );
3831
+ }
3832
+ if (envelope === "athena") {
3833
+ if (!isRecord5(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
3834
+ return rejectStorageError(
3835
+ {
3836
+ code: "INVALID_ATHENA_ENVELOPE",
3837
+ message: `Athena storage ${method} ${endpoint} returned an invalid Athena envelope`,
3838
+ status: response.status,
3839
+ endpoint,
3840
+ method,
3841
+ requestId,
3842
+ raw: parsedBody.parsed
3843
+ },
3844
+ options,
3845
+ runtimeOptions
3846
+ );
3847
+ }
3848
+ return parsedBody.parsed.data;
3849
+ }
3850
+ return parsedBody.parsed;
3851
+ }
3852
+ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, runtimeOptions) {
3853
+ let url;
3854
+ let headers;
3855
+ try {
3856
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3857
+ url = buildAthenaGatewayUrl(baseUrl, endpoint);
3858
+ headers = gateway.buildHeaders(options);
3859
+ } catch (error) {
3860
+ return rejectStorageError(
3861
+ {
3862
+ code: storageCodeFromUnknown(error),
3863
+ message: error instanceof Error ? error.message : `Athena storage ${method} ${endpoint} failed before sending the request`,
3864
+ status: isAthenaGatewayError(error) ? error.status : 0,
3865
+ endpoint,
3866
+ method,
3867
+ raw: error,
3868
+ requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
3869
+ hint: isAthenaGatewayError(error) ? error.hint : void 0,
3870
+ cause: error
3871
+ },
3872
+ options,
3873
+ runtimeOptions
3874
+ );
3875
+ }
3876
+ let response;
3877
+ try {
3878
+ response = await fetch(url, {
3879
+ method,
3880
+ headers,
3881
+ signal: options?.signal
3882
+ });
3883
+ } catch (error) {
3884
+ const message = error instanceof Error ? error.message : String(error);
3885
+ return rejectStorageError(
3886
+ {
3887
+ code: "NETWORK_ERROR",
3888
+ message: `Network error while calling Athena storage ${method} ${endpoint}: ${message}`,
3889
+ status: 0,
3890
+ endpoint,
3891
+ method,
3892
+ cause: error
3893
+ },
3894
+ options,
3895
+ runtimeOptions
3896
+ );
3897
+ }
3898
+ if (response.ok) {
3899
+ return response;
3900
+ }
3901
+ const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
3902
+ let rawErrorBody = null;
3903
+ try {
3904
+ const rawText = await response.text();
3905
+ const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
3906
+ rawErrorBody = parsedBody.parsed;
3907
+ } catch (error) {
3908
+ return rejectStorageError(
3909
+ {
3910
+ code: "NETWORK_ERROR",
3911
+ message: `Athena storage ${method} ${endpoint} error response body could not be read`,
3912
+ status: response.status,
3913
+ endpoint,
3914
+ method,
3915
+ requestId,
3916
+ cause: error
3917
+ },
3918
+ options,
3919
+ runtimeOptions
3920
+ );
3921
+ }
3922
+ return rejectStorageError(
3923
+ {
3924
+ code: "HTTP_ERROR",
3925
+ message: resolveErrorMessage3(
3926
+ rawErrorBody,
3927
+ `Athena storage ${method} ${endpoint} failed with status ${response.status}`
3928
+ ),
3929
+ status: response.status,
3930
+ endpoint,
3931
+ method,
3932
+ requestId,
3933
+ hint: resolveErrorHint2(rawErrorBody),
3934
+ cause: resolveErrorCause(rawErrorBody),
3935
+ raw: rawErrorBody
3936
+ },
3937
+ options,
3938
+ runtimeOptions
3939
+ );
3940
+ }
3941
+ function createStorageModule(gateway, runtimeOptions) {
3942
+ return {
3943
+ listStorageCatalogs(options) {
3944
+ return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "GET", "raw", void 0, options, runtimeOptions);
3945
+ },
3946
+ createStorageCatalog(input, options) {
3947
+ return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "POST", "raw", input, options, runtimeOptions);
3948
+ },
3949
+ updateStorageCatalog(id, input, options) {
3950
+ return callStorageEndpoint(
3951
+ gateway,
3952
+ storagePath(withPathParam("/storage/catalogs/{id}", "id", id)),
3953
+ "PATCH",
3954
+ "raw",
3955
+ input,
3956
+ options,
3957
+ runtimeOptions
3958
+ );
3959
+ },
3960
+ deleteStorageCatalog(id, options) {
3961
+ return callStorageEndpoint(
3962
+ gateway,
3963
+ storagePath(withPathParam("/storage/catalogs/{id}", "id", id)),
3964
+ "DELETE",
3965
+ "raw",
3966
+ void 0,
3967
+ options,
3968
+ runtimeOptions
3969
+ );
3970
+ },
3971
+ listStorageCredentials(options) {
3972
+ return callStorageEndpoint(gateway, storagePath("/storage/credentials"), "GET", "raw", void 0, options, runtimeOptions);
3973
+ },
3974
+ createStorageUploadUrl(input, options) {
3975
+ return callStorageEndpoint(
3976
+ gateway,
3977
+ storagePath("/storage/files/upload-url"),
3978
+ "POST",
3979
+ "athena",
3980
+ input,
3981
+ options,
3982
+ runtimeOptions
3983
+ );
3984
+ },
3985
+ createStorageUploadUrls(input, options) {
3986
+ return callStorageEndpoint(
3987
+ gateway,
3988
+ storagePath("/storage/files/upload-urls"),
3989
+ "POST",
3990
+ "athena",
3991
+ input,
3992
+ options,
3993
+ runtimeOptions
3994
+ );
3995
+ },
3996
+ listStorageFiles(input, options) {
3997
+ return callStorageEndpoint(gateway, storagePath("/storage/files/list"), "POST", "athena", input, options, runtimeOptions);
3998
+ },
3999
+ getStorageFile(fileId, options) {
4000
+ return callStorageEndpoint(
4001
+ gateway,
4002
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4003
+ "GET",
4004
+ "athena",
4005
+ void 0,
4006
+ options,
4007
+ runtimeOptions
4008
+ );
4009
+ },
4010
+ getStorageFileUrl(fileId, query, options) {
4011
+ const path = appendQuery(
4012
+ withPathParam("/storage/files/{file_id}/url", "file_id", fileId),
4013
+ query
4014
+ );
4015
+ return callStorageEndpoint(gateway, storagePath(path), "GET", "athena", void 0, options, runtimeOptions);
4016
+ },
4017
+ getStorageFileProxy(fileId, query, options) {
4018
+ const path = appendQuery(
4019
+ withPathParam("/storage/files/{file_id}/proxy", "file_id", fileId),
4020
+ query
4021
+ );
4022
+ return callStorageBinaryEndpoint(gateway, storagePath(path), "GET", options, runtimeOptions);
4023
+ },
4024
+ updateStorageFile(fileId, input, options) {
4025
+ return callStorageEndpoint(
4026
+ gateway,
4027
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4028
+ "PATCH",
4029
+ "athena",
4030
+ input,
4031
+ options,
4032
+ runtimeOptions
4033
+ );
4034
+ },
4035
+ deleteStorageFile(fileId, options) {
4036
+ return callStorageEndpoint(
4037
+ gateway,
4038
+ storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4039
+ "DELETE",
4040
+ "athena",
4041
+ void 0,
4042
+ options,
4043
+ runtimeOptions
4044
+ );
4045
+ },
4046
+ setStorageFileVisibility(fileId, input, options) {
4047
+ return callStorageEndpoint(
4048
+ gateway,
4049
+ storagePath(withPathParam("/storage/files/{file_id}/visibility", "file_id", fileId)),
4050
+ "PATCH",
4051
+ "athena",
4052
+ input,
4053
+ options,
4054
+ runtimeOptions
4055
+ );
4056
+ },
4057
+ deleteStorageFolder(input, options) {
4058
+ return callStorageEndpoint(gateway, storagePath("/storage/folders/delete"), "POST", "athena", input, options, runtimeOptions);
4059
+ },
4060
+ moveStorageFolder(input, options) {
4061
+ return callStorageEndpoint(gateway, storagePath("/storage/folders/move"), "POST", "athena", input, options, runtimeOptions);
4062
+ }
4063
+ };
4064
+ }
4065
+
4066
+ // src/query-ast.ts
4067
+ 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;
4068
+ var FILTER_OPERATORS = /* @__PURE__ */ new Set([
4069
+ "eq",
4070
+ "neq",
4071
+ "gt",
4072
+ "gte",
4073
+ "lt",
4074
+ "lte",
4075
+ "like",
4076
+ "ilike",
4077
+ "is",
4078
+ "in",
4079
+ "contains",
4080
+ "containedBy"
4081
+ ]);
4082
+ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
4083
+ "eq",
4084
+ "neq",
4085
+ "gt",
4086
+ "gte",
4087
+ "lt",
4088
+ "lte",
4089
+ "like",
4090
+ "ilike",
4091
+ "is"
4092
+ ]);
4093
+ function isRecord6(value) {
4094
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4095
+ }
4096
+ function isUuidString(value) {
4097
+ return UUID_PATTERN.test(value.trim());
4098
+ }
4099
+ function isUuidIdentifierColumn(column) {
4100
+ return column === "id" || /(?:^|_)uuid(?:_|$)/i.test(column) || /_id$/i.test(column);
4101
+ }
4102
+ function shouldUseUuidTextComparison(column, value) {
2695
4103
  return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
2696
4104
  }
2697
4105
  function isRelationSelectNode(value) {
2698
- return isRecord5(value) && isRecord5(value.select);
4106
+ return isRecord6(value) && isRecord6(value.select);
2699
4107
  }
2700
4108
  function normalizeIdentifier(value, label) {
2701
4109
  const normalized = value.trim();
@@ -2751,7 +4159,7 @@ function compileRelationToken(key, node) {
2751
4159
  return `${prefix}${relationToken}(${nested})`;
2752
4160
  }
2753
4161
  function compileSelectShape(select) {
2754
- if (!isRecord5(select)) {
4162
+ if (!isRecord6(select)) {
2755
4163
  throw new Error("findMany select must be an object");
2756
4164
  }
2757
4165
  const tokens = [];
@@ -2775,7 +4183,7 @@ function compileSelectShape(select) {
2775
4183
  return tokens.join(",");
2776
4184
  }
2777
4185
  function selectShapeUsesRelationSchema(select) {
2778
- if (!isRecord5(select)) {
4186
+ if (!isRecord6(select)) {
2779
4187
  return false;
2780
4188
  }
2781
4189
  for (const rawValue of Object.values(select)) {
@@ -2793,7 +4201,7 @@ function selectShapeUsesRelationSchema(select) {
2793
4201
  }
2794
4202
  function compileColumnWhere(column, input) {
2795
4203
  const normalizedColumn = normalizeIdentifier(column, "where column");
2796
- if (!isRecord5(input)) {
4204
+ if (!isRecord6(input)) {
2797
4205
  return [buildGatewayCondition("eq", normalizedColumn, input)];
2798
4206
  }
2799
4207
  const conditions = [];
@@ -2821,7 +4229,7 @@ function compileColumnWhere(column, input) {
2821
4229
  return conditions;
2822
4230
  }
2823
4231
  function compileBooleanExpressionTerms(clause, label) {
2824
- if (!isRecord5(clause)) {
4232
+ if (!isRecord6(clause)) {
2825
4233
  throw new Error(`findMany where.${label} clauses must be objects`);
2826
4234
  }
2827
4235
  const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
@@ -2830,7 +4238,7 @@ function compileBooleanExpressionTerms(clause, label) {
2830
4238
  }
2831
4239
  const [rawColumn, rawValue] = entries[0];
2832
4240
  const column = normalizeIdentifier(rawColumn, `where.${label} column`);
2833
- if (!isRecord5(rawValue)) {
4241
+ if (!isRecord6(rawValue)) {
2834
4242
  return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
2835
4243
  }
2836
4244
  const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
@@ -2854,7 +4262,7 @@ function compileWhere(where) {
2854
4262
  if (where === void 0) {
2855
4263
  return void 0;
2856
4264
  }
2857
- if (!isRecord5(where)) {
4265
+ if (!isRecord6(where)) {
2858
4266
  throw new Error("findMany where must be an object");
2859
4267
  }
2860
4268
  const conditions = [];
@@ -2904,7 +4312,7 @@ function compileOrderBy(orderBy) {
2904
4312
  if (orderBy === void 0) {
2905
4313
  return void 0;
2906
4314
  }
2907
- if (!isRecord5(orderBy)) {
4315
+ if (!isRecord6(orderBy)) {
2908
4316
  throw new Error("findMany orderBy must be an object");
2909
4317
  }
2910
4318
  if ("column" in orderBy) {
@@ -3000,7 +4408,7 @@ function buildStructuredWhere(conditions) {
3000
4408
  if (!condition.column) {
3001
4409
  return null;
3002
4410
  }
3003
- if (condition.column_cast !== void 0 || condition.value_cast !== void 0) {
4411
+ if (condition.value_cast !== void 0) {
3004
4412
  return null;
3005
4413
  }
3006
4414
  const operand = condition.value;
@@ -3079,6 +4487,104 @@ function toFindManyAstOrder(order) {
3079
4487
  ascending: order.direction !== "descending"
3080
4488
  };
3081
4489
  }
4490
+ function isRecord7(value) {
4491
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4492
+ }
4493
+ function normalizeFindManyAstColumnPredicate(value) {
4494
+ if (!isRecord7(value)) {
4495
+ return {
4496
+ eq: value
4497
+ };
4498
+ }
4499
+ const normalized = {};
4500
+ for (const [key, operand] of Object.entries(value)) {
4501
+ if (operand !== void 0) {
4502
+ normalized[key] = operand;
4503
+ }
4504
+ }
4505
+ return normalized;
4506
+ }
4507
+ function normalizeFindManyAstBooleanOperand(clause) {
4508
+ const normalized = {};
4509
+ for (const [column, value] of Object.entries(clause)) {
4510
+ if (value === void 0) {
4511
+ continue;
4512
+ }
4513
+ normalized[column] = normalizeFindManyAstColumnPredicate(value);
4514
+ }
4515
+ return normalized;
4516
+ }
4517
+ function normalizeFindManyAstWhere(where) {
4518
+ if (!where || !isRecord7(where)) {
4519
+ return where;
4520
+ }
4521
+ const normalized = {};
4522
+ for (const [key, value] of Object.entries(where)) {
4523
+ if (value === void 0) {
4524
+ continue;
4525
+ }
4526
+ if (key === "or" && Array.isArray(value)) {
4527
+ normalized.or = value.map(
4528
+ (clause) => normalizeFindManyAstBooleanOperand(clause)
4529
+ );
4530
+ continue;
4531
+ }
4532
+ if (key === "not" && isRecord7(value)) {
4533
+ normalized.not = normalizeFindManyAstBooleanOperand(
4534
+ value
4535
+ );
4536
+ continue;
4537
+ }
4538
+ normalized[key] = normalizeFindManyAstColumnPredicate(value);
4539
+ }
4540
+ return normalized;
4541
+ }
4542
+ function predicateRequiresUuidQueryFallback(column, value) {
4543
+ if (!isRecord7(value)) {
4544
+ return shouldUseUuidTextComparison(column, value);
4545
+ }
4546
+ const eqValue = value.eq;
4547
+ return eqValue !== void 0 && shouldUseUuidTextComparison(column, eqValue);
4548
+ }
4549
+ function booleanOperandRequiresUuidQueryFallback(clause) {
4550
+ for (const [column, value] of Object.entries(clause)) {
4551
+ if (value === void 0) {
4552
+ continue;
4553
+ }
4554
+ if (predicateRequiresUuidQueryFallback(column, value)) {
4555
+ return true;
4556
+ }
4557
+ }
4558
+ return false;
4559
+ }
4560
+ function findManyAstWhereRequiresLegacyTransport(where) {
4561
+ if (!where || !isRecord7(where)) {
4562
+ return false;
4563
+ }
4564
+ for (const [key, value] of Object.entries(where)) {
4565
+ if (value === void 0) {
4566
+ continue;
4567
+ }
4568
+ if (key === "or" && Array.isArray(value)) {
4569
+ if (value.some(
4570
+ (clause) => booleanOperandRequiresUuidQueryFallback(clause)
4571
+ )) {
4572
+ return true;
4573
+ }
4574
+ continue;
4575
+ }
4576
+ if (key === "not" && isRecord7(value)) {
4577
+ if (booleanOperandRequiresUuidQueryFallback(value)) {
4578
+ return true;
4579
+ }
4580
+ continue;
4581
+ }
4582
+ if (predicateRequiresUuidQueryFallback(key, value)) {
4583
+ return true;
4584
+ }
4585
+ }
4586
+ return false;
4587
+ }
3082
4588
  function resolvePagination(input) {
3083
4589
  let limit = input.limit;
3084
4590
  let offset = input.offset;
@@ -3097,25 +4603,6 @@ function hasTypedEqualityComparison(conditions) {
3097
4603
  }
3098
4604
  function createSelectTransportPlan(input) {
3099
4605
  const conditions = input.state.conditions.length ? input.state.conditions.map((condition) => ({ ...condition })) : void 0;
3100
- if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
3101
- const query = input.buildTypedSelectQuery({
3102
- tableName: input.tableName,
3103
- columns: input.columns,
3104
- conditions,
3105
- limit: input.state.limit,
3106
- offset: input.state.offset,
3107
- currentPage: input.state.currentPage,
3108
- pageSize: input.state.pageSize,
3109
- order: input.state.order
3110
- });
3111
- if (query) {
3112
- return {
3113
- kind: "query",
3114
- query,
3115
- payload: { query }
3116
- };
3117
- }
3118
- }
3119
4606
  const pagination = resolvePagination({
3120
4607
  limit: input.state.limit,
3121
4608
  offset: input.state.offset,
@@ -3151,6 +4638,25 @@ function createSelectTransportPlan(input) {
3151
4638
  }
3152
4639
  };
3153
4640
  }
4641
+ if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
4642
+ const query = input.buildTypedSelectQuery({
4643
+ tableName: input.tableName,
4644
+ columns: input.columns,
4645
+ conditions,
4646
+ limit: input.state.limit,
4647
+ offset: input.state.offset,
4648
+ currentPage: input.state.currentPage,
4649
+ pageSize: input.state.pageSize,
4650
+ order: input.state.order
4651
+ });
4652
+ if (query) {
4653
+ return {
4654
+ kind: "query",
4655
+ query,
4656
+ payload: { query }
4657
+ };
4658
+ }
4659
+ }
3154
4660
  return {
3155
4661
  kind: "fetch",
3156
4662
  payload: {
@@ -3207,6 +4713,13 @@ function formatResult(response) {
3207
4713
  }
3208
4714
  return result;
3209
4715
  }
4716
+ var EXPERIMENTAL_READ_RETRY_CONFIG = {
4717
+ retries: 2,
4718
+ baseDelayMs: 100,
4719
+ maxDelayMs: 1e3,
4720
+ backoff: "exponential",
4721
+ jitter: true
4722
+ };
3210
4723
  function attachNormalizedError(result, normalizedError) {
3211
4724
  Object.defineProperty(result, ATHENA_NORMALIZED_ERROR_KEY, {
3212
4725
  value: normalizedError,
@@ -3228,12 +4741,41 @@ function createResultFormatter(experimental) {
3228
4741
  },
3229
4742
  context
3230
4743
  );
3231
- result.error = createResultError(response, result, normalizedError);
3232
- attachNormalizedError(result, normalizedError);
3233
- return result;
3234
- };
4744
+ result.error = createResultError(response, result, normalizedError);
4745
+ attachNormalizedError(result, normalizedError);
4746
+ return result;
4747
+ };
4748
+ }
4749
+ async function executeExperimentalRead(experimental, runner) {
4750
+ if (!experimental?.retryReads) {
4751
+ return runner();
4752
+ }
4753
+ let lastRetryableResult;
4754
+ let lastRetrySignal = null;
4755
+ try {
4756
+ return await withRetry(
4757
+ {
4758
+ ...EXPERIMENTAL_READ_RETRY_CONFIG,
4759
+ shouldRetry: (error) => error === lastRetrySignal || normalizeAthenaError(error).retryable
4760
+ },
4761
+ async () => {
4762
+ const result = await runner();
4763
+ if (result.error?.retryable) {
4764
+ lastRetryableResult = result;
4765
+ lastRetrySignal = result.error;
4766
+ throw lastRetrySignal;
4767
+ }
4768
+ return result;
4769
+ }
4770
+ );
4771
+ } catch (error) {
4772
+ if (lastRetryableResult && error === lastRetrySignal) {
4773
+ return lastRetryableResult;
4774
+ }
4775
+ throw error;
4776
+ }
3235
4777
  }
3236
- function isRecord6(value) {
4778
+ function isRecord8(value) {
3237
4779
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3238
4780
  }
3239
4781
  function firstNonEmptyString2(...values) {
@@ -3245,8 +4787,8 @@ function firstNonEmptyString2(...values) {
3245
4787
  return void 0;
3246
4788
  }
3247
4789
  function resolveStructuredErrorPayload2(raw) {
3248
- if (!isRecord6(raw)) return null;
3249
- return isRecord6(raw.error) ? raw.error : raw;
4790
+ if (!isRecord8(raw)) return null;
4791
+ return isRecord8(raw.error) ? raw.error : raw;
3250
4792
  }
3251
4793
  function resolveStructuredErrorDetails(payload, message) {
3252
4794
  if (!payload || !("details" in payload)) {
@@ -3262,7 +4804,7 @@ function resolveStructuredErrorDetails(payload, message) {
3262
4804
  return details;
3263
4805
  }
3264
4806
  function createResultError(response, result, normalized) {
3265
- const rawRecord = isRecord6(response.raw) ? response.raw : null;
4807
+ const rawRecord = isRecord8(response.raw) ? response.raw : null;
3266
4808
  const payload = resolveStructuredErrorPayload2(response.raw);
3267
4809
  const message = firstNonEmptyString2(
3268
4810
  response.error,
@@ -3457,7 +4999,14 @@ function toSingleResult(response) {
3457
4999
  function mergeOptions(...options) {
3458
5000
  return options.reduce((acc, next) => {
3459
5001
  if (!next) return acc;
3460
- return { ...acc, ...next };
5002
+ const merged = { ...acc ?? {}, ...next };
5003
+ if (acc?.headers || next.headers) {
5004
+ merged.headers = {
5005
+ ...acc?.headers ?? {},
5006
+ ...next.headers ?? {}
5007
+ };
5008
+ }
5009
+ return merged;
3461
5010
  }, void 0);
3462
5011
  }
3463
5012
  function asAthenaJsonObject(value) {
@@ -4249,42 +5798,48 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4249
5798
  buildTypedSelectQuery
4250
5799
  });
4251
5800
  if (plan.kind === "query") {
4252
- return executeWithQueryTrace(
5801
+ return executeExperimentalRead(
5802
+ experimental,
5803
+ () => executeWithQueryTrace(
5804
+ tracer,
5805
+ {
5806
+ operation: "select",
5807
+ endpoint: "/gateway/query",
5808
+ table: resolvedTableName,
5809
+ sql: plan.query,
5810
+ payload: plan.payload,
5811
+ options
5812
+ },
5813
+ async () => {
5814
+ const queryResponse = await client.queryGateway(plan.payload, options);
5815
+ return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
5816
+ },
5817
+ callsite
5818
+ )
5819
+ );
5820
+ }
5821
+ const sql = buildDebugSelectQuery({
5822
+ tableName: resolvedTableName,
5823
+ ...plan.debug
5824
+ });
5825
+ return executeExperimentalRead(
5826
+ experimental,
5827
+ () => executeWithQueryTrace(
4253
5828
  tracer,
4254
5829
  {
4255
5830
  operation: "select",
4256
- endpoint: "/gateway/query",
5831
+ endpoint: "/gateway/fetch",
4257
5832
  table: resolvedTableName,
4258
- sql: plan.query,
5833
+ sql,
4259
5834
  payload: plan.payload,
4260
5835
  options
4261
5836
  },
4262
5837
  async () => {
4263
- const queryResponse = await client.queryGateway(plan.payload, options);
4264
- return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
5838
+ const response = await client.fetchGateway(plan.payload, options);
5839
+ return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
4265
5840
  },
4266
5841
  callsite
4267
- );
4268
- }
4269
- const sql = buildDebugSelectQuery({
4270
- tableName: resolvedTableName,
4271
- ...plan.debug
4272
- });
4273
- return executeWithQueryTrace(
4274
- tracer,
4275
- {
4276
- operation: "select",
4277
- endpoint: "/gateway/fetch",
4278
- table: resolvedTableName,
4279
- sql,
4280
- payload: plan.payload,
4281
- options
4282
- },
4283
- async () => {
4284
- const response = await client.fetchGateway(plan.payload, options);
4285
- return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
4286
- },
4287
- callsite
5842
+ )
4288
5843
  );
4289
5844
  };
4290
5845
  const createSelectChain = (columns, options, initialCallsite) => {
@@ -4354,14 +5909,14 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4354
5909
  if (options.limit !== void 0) {
4355
5910
  executionState.limit = options.limit;
4356
5911
  }
4357
- if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select)) {
5912
+ if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select) && !findManyAstWhereRequiresLegacyTransport(options.where)) {
4358
5913
  const resolvedTableName = resolveTableNameForCall(tableName, void 0);
4359
5914
  const payload = {
4360
5915
  table_name: resolvedTableName,
4361
5916
  select: options.select
4362
5917
  };
4363
5918
  if (options.where !== void 0) {
4364
- payload.where = options.where;
5919
+ payload.where = normalizeFindManyAstWhere(options.where);
4365
5920
  }
4366
5921
  const astOrder = toFindManyAstOrder(executionState.order);
4367
5922
  if (astOrder !== void 0) {
@@ -4377,22 +5932,25 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4377
5932
  limit: executionState.limit,
4378
5933
  order: executionState.order
4379
5934
  });
4380
- return executeWithQueryTrace(
4381
- tracer,
4382
- {
4383
- operation: "select",
4384
- endpoint: "/gateway/fetch",
4385
- table: resolvedTableName,
4386
- sql,
4387
- payload
4388
- },
4389
- async () => {
4390
- const response = await client.fetchGateway(
5935
+ return executeExperimentalRead(
5936
+ experimental,
5937
+ () => executeWithQueryTrace(
5938
+ tracer,
5939
+ {
5940
+ operation: "select",
5941
+ endpoint: "/gateway/fetch",
5942
+ table: resolvedTableName,
5943
+ sql,
4391
5944
  payload
4392
- );
4393
- return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
4394
- },
4395
- callsite
5945
+ },
5946
+ async () => {
5947
+ const response = await client.fetchGateway(
5948
+ payload
5949
+ );
5950
+ return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
5951
+ },
5952
+ callsite
5953
+ )
4396
5954
  );
4397
5955
  }
4398
5956
  return runSelect(
@@ -4640,7 +6198,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4640
6198
  });
4641
6199
  return builder;
4642
6200
  }
4643
- function createQueryBuilder(client, formatGatewayResult, tracer) {
6201
+ function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
4644
6202
  return async function query(query, options) {
4645
6203
  const normalizedQuery = query.trim();
4646
6204
  if (!normalizedQuery) {
@@ -4648,30 +6206,39 @@ function createQueryBuilder(client, formatGatewayResult, tracer) {
4648
6206
  }
4649
6207
  const payload = { query: normalizedQuery };
4650
6208
  const callsite = captureTraceCallsite(tracer);
4651
- return executeWithQueryTrace(
4652
- tracer,
4653
- {
4654
- operation: "query",
4655
- endpoint: "/gateway/query",
4656
- sql: normalizedQuery,
4657
- payload,
4658
- options
4659
- },
4660
- async () => {
4661
- const response = await client.queryGateway(payload, options);
4662
- return formatGatewayResult(response, { operation: "query" });
4663
- },
4664
- callsite
6209
+ return executeExperimentalRead(
6210
+ experimental,
6211
+ () => executeWithQueryTrace(
6212
+ tracer,
6213
+ {
6214
+ operation: "query",
6215
+ endpoint: "/gateway/query",
6216
+ sql: normalizedQuery,
6217
+ payload,
6218
+ options
6219
+ },
6220
+ async () => {
6221
+ const response = await client.queryGateway(payload, options);
6222
+ return formatGatewayResult(response, { operation: "query" });
6223
+ },
6224
+ callsite
6225
+ )
4665
6226
  );
4666
6227
  };
4667
6228
  }
4668
6229
  function createClientFromConfig(config) {
6230
+ const gatewayHeaders = {
6231
+ ...config.headers ?? {}
6232
+ };
6233
+ if (config.auth?.bearerToken && gatewayHeaders["X-Athena-Auth-Bearer-Token"] === void 0 && gatewayHeaders["x-athena-auth-bearer-token"] === void 0) {
6234
+ gatewayHeaders["X-Athena-Auth-Bearer-Token"] = config.auth.bearerToken;
6235
+ }
4669
6236
  const gateway = createAthenaGatewayClient({
4670
6237
  baseUrl: config.baseUrl,
4671
6238
  apiKey: config.apiKey,
4672
6239
  client: config.client,
4673
6240
  backend: config.backend,
4674
- headers: config.headers
6241
+ headers: gatewayHeaders
4675
6242
  });
4676
6243
  const formatGatewayResult = createResultFormatter(config.experimental);
4677
6244
  const queryTracer = createQueryTracer(config.experimental);
@@ -4698,9 +6265,9 @@ function createClientFromConfig(config) {
4698
6265
  captureTraceCallsite(queryTracer)
4699
6266
  );
4700
6267
  };
4701
- const query = createQueryBuilder(gateway, formatGatewayResult, queryTracer);
6268
+ const query = createQueryBuilder(gateway, formatGatewayResult, config.experimental, queryTracer);
4702
6269
  const db = createDbModule({ from, rpc, query });
4703
- return {
6270
+ const sdkClient = {
4704
6271
  from,
4705
6272
  db,
4706
6273
  rpc,
@@ -4708,6 +6275,14 @@ function createClientFromConfig(config) {
4708
6275
  verifyConnection: gateway.verifyConnection,
4709
6276
  auth: auth.auth
4710
6277
  };
6278
+ if (config.experimental?.athenaStorageBackend) {
6279
+ const storageClient = {
6280
+ ...sdkClient,
6281
+ storage: createStorageModule(gateway, config.experimental.storage)
6282
+ };
6283
+ return storageClient;
6284
+ }
6285
+ return sdkClient;
4711
6286
  }
4712
6287
  var DEFAULT_BACKEND = { type: "athena" };
4713
6288
  function toBackendConfig(b) {
@@ -4738,6 +6313,12 @@ function mergeExperimentalOptions(current, next) {
4738
6313
  ...next.traceQueries
4739
6314
  };
4740
6315
  }
6316
+ if (current?.storage || next.storage) {
6317
+ merged.storage = {
6318
+ ...current?.storage ?? {},
6319
+ ...next.storage ?? {}
6320
+ };
6321
+ }
4741
6322
  return merged;
4742
6323
  }
4743
6324
  var AthenaClientBuilderImpl = class {
@@ -4748,7 +6329,6 @@ var AthenaClientBuilderImpl = class {
4748
6329
  defaultHeaders;
4749
6330
  authConfig;
4750
6331
  experimentalOptions;
4751
- isHealthTrackingEnabled = false;
4752
6332
  url(url) {
4753
6333
  this.baseUrl = url;
4754
6334
  return this;
@@ -4775,7 +6355,7 @@ var AthenaClientBuilderImpl = class {
4775
6355
  }
4776
6356
  experimental(options) {
4777
6357
  this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options);
4778
- return this;
6358
+ return options.athenaStorageBackend ? this : this;
4779
6359
  }
4780
6360
  options(options) {
4781
6361
  if (options.client !== void 0) {
@@ -4796,11 +6376,7 @@ var AthenaClientBuilderImpl = class {
4796
6376
  if (options.experimental !== void 0) {
4797
6377
  this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options.experimental);
4798
6378
  }
4799
- return this;
4800
- }
4801
- healthTracking(enabled) {
4802
- this.isHealthTrackingEnabled = enabled;
4803
- return this;
6379
+ return options.experimental?.athenaStorageBackend ? this : this;
4804
6380
  }
4805
6381
  build() {
4806
6382
  if (!this.baseUrl || !this.apiKey) {
@@ -4812,7 +6388,6 @@ var AthenaClientBuilderImpl = class {
4812
6388
  client: this.clientName,
4813
6389
  backend: this.backendConfig,
4814
6390
  headers: this.defaultHeaders,
4815
- healthTracking: this.isHealthTrackingEnabled,
4816
6391
  auth: this.authConfig,
4817
6392
  experimental: this.experimentalOptions
4818
6393
  });
@@ -5432,7 +7007,7 @@ function resolveNullishValue(mode) {
5432
7007
  if (mode === "null") return null;
5433
7008
  return "";
5434
7009
  }
5435
- function isRecord7(value) {
7010
+ function isRecord9(value) {
5436
7011
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5437
7012
  }
5438
7013
  function isNullableColumn(model, key) {
@@ -5441,7 +7016,7 @@ function isNullableColumn(model, key) {
5441
7016
  }
5442
7017
  function toModelFormDefaults(model, values, options) {
5443
7018
  const source = values;
5444
- if (!isRecord7(source)) {
7019
+ if (!isRecord9(source)) {
5445
7020
  return {};
5446
7021
  }
5447
7022
  const mode = options?.nullishMode ?? "empty-string";
@@ -5872,6 +7447,90 @@ async function loadGeneratorConfig(options = {}) {
5872
7447
  }
5873
7448
  }
5874
7449
 
7450
+ // src/generator/env.ts
7451
+ function readEnvStringValue2(key) {
7452
+ if (typeof process === "undefined" || !process.env) {
7453
+ return void 0;
7454
+ }
7455
+ const value = process.env[key];
7456
+ if (typeof value !== "string") {
7457
+ return void 0;
7458
+ }
7459
+ const trimmed = value.trim();
7460
+ return trimmed.length > 0 ? trimmed : void 0;
7461
+ }
7462
+ function throwMissingEnvVar(key) {
7463
+ throw new Error(
7464
+ `Generator config env var ${key} is missing or empty. Set ${key} or provide a default value.`
7465
+ );
7466
+ }
7467
+ function resolveEnvValue(key, options, resolver) {
7468
+ const rawValue = readEnvStringValue2(key);
7469
+ if (rawValue === void 0) {
7470
+ if (options?.default !== void 0) {
7471
+ return options.default;
7472
+ }
7473
+ if (options?.optional) {
7474
+ return void 0;
7475
+ }
7476
+ return throwMissingEnvVar(key);
7477
+ }
7478
+ return resolver(rawValue);
7479
+ }
7480
+ function resolveStringEnv(key, options) {
7481
+ return resolveEnvValue(key, options, (value) => value);
7482
+ }
7483
+ function resolveBooleanEnv(key, options) {
7484
+ return resolveEnvValue(key, options, (value) => parseBooleanFlag2(value, false));
7485
+ }
7486
+ function resolveListEnv(key, options) {
7487
+ return resolveEnvValue(key, options, (value) => {
7488
+ const separator = options?.separator ?? ",";
7489
+ return value.split(separator).map((entry) => entry.trim()).filter((entry, index, entries) => entry.length > 0 && entries.indexOf(entry) === index);
7490
+ })?.slice();
7491
+ }
7492
+ function resolveJsonEnv(key, options) {
7493
+ return resolveEnvValue(key, options, (value) => {
7494
+ try {
7495
+ return JSON.parse(value);
7496
+ } catch (error) {
7497
+ const message = error instanceof Error ? error.message : String(error);
7498
+ throw new Error(`Generator config env var ${key} must contain valid JSON. ${message}`);
7499
+ }
7500
+ });
7501
+ }
7502
+ function resolveOneOfEnv(key, allowedValues, options) {
7503
+ return resolveEnvValue(key, options, (value) => {
7504
+ if (allowedValues.includes(value)) {
7505
+ return value;
7506
+ }
7507
+ throw new Error(
7508
+ `Generator config env var ${key} must be one of: ${allowedValues.join(", ")}. Received: ${value}.`
7509
+ );
7510
+ });
7511
+ }
7512
+ function generatorEnvString(key, options) {
7513
+ return resolveStringEnv(key, options);
7514
+ }
7515
+ function generatorEnvBoolean(key, options) {
7516
+ return resolveBooleanEnv(key, options);
7517
+ }
7518
+ function generatorEnvList(key, options) {
7519
+ return resolveListEnv(key, options);
7520
+ }
7521
+ function generatorEnvJson(key, options) {
7522
+ return resolveJsonEnv(key, options);
7523
+ }
7524
+ function generatorEnvOneOf(key, allowedValues, options) {
7525
+ return resolveOneOfEnv(key, allowedValues, options);
7526
+ }
7527
+ var generatorEnv = Object.assign(generatorEnvString, {
7528
+ boolean: generatorEnvBoolean,
7529
+ list: generatorEnvList,
7530
+ json: generatorEnvJson,
7531
+ oneOf: generatorEnvOneOf
7532
+ });
7533
+
5875
7534
  // src/utils/slugify.ts
5876
7535
  function slugify(input) {
5877
7536
  return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
@@ -6629,6 +8288,433 @@ async function runSchemaGenerator(options = {}) {
6629
8288
  };
6630
8289
  }
6631
8290
 
6632
- export { AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, coerceInt, createAuthClient, createAuthReactEmailInput, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createTypedClient, defineAuthEmailTemplate, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeAthenaGatewayBaseUrl, normalizeGeneratorConfig, normalizeSchemaSelection, parseBooleanFlag2 as parseBooleanFlag, renderAthenaReactEmail, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, toModelFormDefaults, toModelPayload, unwrap, unwrapOne, unwrapRows, verifyAthenaGatewayUrl, withRetry };
8291
+ // src/auth/server.ts
8292
+ var DEFAULT_AUTH_BASE_PATH = "/api/auth";
8293
+ var ATHENA_AUTH_BASE_ERROR_CODES = {
8294
+ HANDLER_NOT_CONFIGURED: "HANDLER_NOT_CONFIGURED",
8295
+ INVALID_BASE_URL: "INVALID_BASE_URL",
8296
+ UNTRUSTED_HOST: "UNTRUSTED_HOST"
8297
+ };
8298
+ function capitalize2(value) {
8299
+ return value.length > 0 ? `${value[0]?.toUpperCase()}${value.slice(1)}` : value;
8300
+ }
8301
+ function serializeSetCookieValue(name, value, attributes) {
8302
+ const parts = [`${name}=${encodeURIComponent(value)}`];
8303
+ const knownKeys = /* @__PURE__ */ new Set([
8304
+ "maxAge",
8305
+ "expires",
8306
+ "domain",
8307
+ "path",
8308
+ "secure",
8309
+ "httpOnly",
8310
+ "partitioned",
8311
+ "sameSite"
8312
+ ]);
8313
+ if (attributes.maxAge !== void 0) {
8314
+ parts.push(`Max-Age=${Math.trunc(attributes.maxAge)}`);
8315
+ }
8316
+ if (attributes.expires instanceof Date) {
8317
+ parts.push(`Expires=${attributes.expires.toUTCString()}`);
8318
+ }
8319
+ if (attributes.domain) {
8320
+ parts.push(`Domain=${attributes.domain}`);
8321
+ }
8322
+ if (attributes.path) {
8323
+ parts.push(`Path=${attributes.path}`);
8324
+ }
8325
+ if (attributes.secure) {
8326
+ parts.push("Secure");
8327
+ }
8328
+ if (attributes.httpOnly) {
8329
+ parts.push("HttpOnly");
8330
+ }
8331
+ if (attributes.partitioned) {
8332
+ parts.push("Partitioned");
8333
+ }
8334
+ if (attributes.sameSite) {
8335
+ parts.push(`SameSite=${capitalize2(attributes.sameSite)}`);
8336
+ }
8337
+ for (const [key, rawValue] of Object.entries(attributes)) {
8338
+ if (knownKeys.has(key) || rawValue === void 0 || rawValue === null || rawValue === false) {
8339
+ continue;
8340
+ }
8341
+ if (rawValue === true) {
8342
+ parts.push(key);
8343
+ continue;
8344
+ }
8345
+ parts.push(`${key}=${String(rawValue)}`);
8346
+ }
8347
+ return parts.join("; ");
8348
+ }
8349
+ function readCookieFromHeaders(headers, name) {
8350
+ const cookieHeader = headers?.get("cookie");
8351
+ if (!cookieHeader) {
8352
+ return void 0;
8353
+ }
8354
+ return parseCookies(cookieHeader).get(name);
8355
+ }
8356
+ function isRecord10(value) {
8357
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8358
+ }
8359
+ function resolveSessionCandidate(value) {
8360
+ if (!isRecord10(value)) {
8361
+ return null;
8362
+ }
8363
+ const session = isRecord10(value.session) ? value.session : void 0;
8364
+ const user = isRecord10(value.user) ? value.user : void 0;
8365
+ if (session && typeof session.token === "string" && session.token.length > 0 && user) {
8366
+ return {
8367
+ session,
8368
+ user
8369
+ };
8370
+ }
8371
+ return null;
8372
+ }
8373
+ function inferSessionPair(returned) {
8374
+ return resolveSessionCandidate(returned) ?? (isRecord10(returned) ? resolveSessionCandidate(returned.data) : null) ?? (isRecord10(returned) ? resolveSessionCandidate(returned.session) : null);
8375
+ }
8376
+ function resolveResponseHeaders(ctx) {
8377
+ if (ctx.context.responseHeaders instanceof Headers) {
8378
+ return ctx.context.responseHeaders;
8379
+ }
8380
+ const headers = new Headers();
8381
+ ctx.context.responseHeaders = headers;
8382
+ return headers;
8383
+ }
8384
+ function normalizeBaseURL(baseURL) {
8385
+ return baseURL.replace(/\/$/, "");
8386
+ }
8387
+ function normalizeBasePath(basePath) {
8388
+ if (!basePath || basePath === "/") {
8389
+ return DEFAULT_AUTH_BASE_PATH;
8390
+ }
8391
+ const normalized = basePath.startsWith("/") ? basePath : `/${basePath}`;
8392
+ return normalized.endsWith("/") && normalized.length > 1 ? normalized.slice(0, -1) : normalized;
8393
+ }
8394
+ function isDynamicBaseURLConfig2(baseURL) {
8395
+ return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
8396
+ }
8397
+ function getRequestUrl(request) {
8398
+ try {
8399
+ return new URL(request.url);
8400
+ } catch {
8401
+ return new URL("http://localhost");
8402
+ }
8403
+ }
8404
+ function getRequestHost(request, url) {
8405
+ const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
8406
+ const host = forwardedHost || request.headers.get("host") || url.host;
8407
+ return host || null;
8408
+ }
8409
+ function getRequestProtocol(request, configuredProtocol, url) {
8410
+ if (configuredProtocol === "http" || configuredProtocol === "https") {
8411
+ return configuredProtocol;
8412
+ }
8413
+ const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
8414
+ if (forwardedProto === "http" || forwardedProto === "https") {
8415
+ return forwardedProto;
8416
+ }
8417
+ if (url.protocol === "http:" || url.protocol === "https:") {
8418
+ return url.protocol.slice(0, -1);
8419
+ }
8420
+ return "http";
8421
+ }
8422
+ function resolveRequestBaseURL(baseURL, request) {
8423
+ if (typeof baseURL === "string") {
8424
+ return normalizeBaseURL(baseURL);
8425
+ }
8426
+ const requestUrl = getRequestUrl(request);
8427
+ const host = getRequestHost(request, requestUrl);
8428
+ if (!host) {
8429
+ return null;
8430
+ }
8431
+ if (isDynamicBaseURLConfig2(baseURL)) {
8432
+ const allowedHosts = baseURL.allowedHosts ?? [];
8433
+ if (allowedHosts.length > 0 && !allowedHosts.includes(host)) {
8434
+ return null;
8435
+ }
8436
+ }
8437
+ const protocol = typeof baseURL === "object" && baseURL !== null ? getRequestProtocol(request, baseURL.protocol, requestUrl) : getRequestProtocol(request, void 0, requestUrl);
8438
+ return `${protocol}://${host}`;
8439
+ }
8440
+ function getOrigin(baseURL) {
8441
+ if (!baseURL) {
8442
+ return void 0;
8443
+ }
8444
+ try {
8445
+ return new URL(baseURL).origin;
8446
+ } catch {
8447
+ return void 0;
8448
+ }
8449
+ }
8450
+ async function resolveTrustedOrigins(config, baseURL, request) {
8451
+ const resolved = typeof config.trustedOrigins === "function" ? await config.trustedOrigins(request) : config.trustedOrigins ?? [];
8452
+ const values = [
8453
+ getOrigin(baseURL),
8454
+ ...resolved
8455
+ ];
8456
+ return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
8457
+ }
8458
+ async function resolveTrustedProviders(config, request) {
8459
+ const configured = typeof config.trustedProviders === "function" ? await config.trustedProviders(request) : config.trustedProviders ?? [];
8460
+ const values = [
8461
+ ...Object.keys(config.socialProviders ?? {}),
8462
+ ...configured
8463
+ ];
8464
+ return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
8465
+ }
8466
+ function createJsonResponse(payload, init) {
8467
+ const headers = new Headers(init?.headers);
8468
+ if (!headers.has("content-type")) {
8469
+ headers.set("content-type", "application/json; charset=utf-8");
8470
+ }
8471
+ return new Response(JSON.stringify(payload), {
8472
+ ...init,
8473
+ headers
8474
+ });
8475
+ }
8476
+ function mergeResponseHeaders(response, headers) {
8477
+ return new Response(response.body, {
8478
+ status: response.status,
8479
+ statusText: response.statusText,
8480
+ headers
8481
+ });
8482
+ }
8483
+ function defineAthenaAuthConfig(config) {
8484
+ return config;
8485
+ }
8486
+ function athenaAuth(config) {
8487
+ const normalizedBasePath = normalizeBasePath(config.basePath);
8488
+ const staticBaseURL = typeof config.baseURL === "string" ? normalizeBaseURL(config.baseURL) : void 0;
8489
+ const runtime = {
8490
+ baseURL: staticBaseURL,
8491
+ basePath: normalizedBasePath,
8492
+ secret: config.secret,
8493
+ cookies: {
8494
+ session: config.session,
8495
+ advanced: config.advanced
8496
+ }
8497
+ };
8498
+ const resolvedDatabase = typeof config.database === "function" ? config.database(runtime) : config.database;
8499
+ const cookies = getCookies({
8500
+ baseURL: staticBaseURL ?? config.baseURL,
8501
+ session: config.session,
8502
+ advanced: config.advanced
8503
+ });
8504
+ const auth = {};
8505
+ const createCookieContext = (input = {}) => {
8506
+ const responseHeaders = input.responseHeaders ?? new Headers();
8507
+ const runtimeHeaders = input.headers;
8508
+ const authCookies = input.cookies ?? auth.cookies;
8509
+ const setCookie = input.setCookie ?? ((name, value, attributes) => {
8510
+ responseHeaders.append(
8511
+ "set-cookie",
8512
+ serializeSetCookieValue(name, value, attributes)
8513
+ );
8514
+ });
8515
+ return {
8516
+ headers: runtimeHeaders,
8517
+ getCookie: input.getCookie ?? ((name) => readCookieFromHeaders(runtimeHeaders, name)),
8518
+ setCookie,
8519
+ logger: input.logger,
8520
+ setSignedCookie: input.setSignedCookie,
8521
+ getSignedCookie: input.getSignedCookie,
8522
+ context: {
8523
+ secret: runtime.secret,
8524
+ authCookies,
8525
+ sessionConfig: {
8526
+ expiresIn: config.session?.expiresIn
8527
+ },
8528
+ options: {
8529
+ session: {
8530
+ cookieCache: config.session?.cookieCache
8531
+ },
8532
+ account: {
8533
+ storeAccountCookie: true
8534
+ }
8535
+ },
8536
+ setNewSession: input.setNewSession
8537
+ }
8538
+ };
8539
+ };
8540
+ const setSession = async (input, session, dontRememberMe, overrides) => {
8541
+ const cookieContext = createCookieContext(input);
8542
+ await setSessionCookie(cookieContext, session, dontRememberMe, overrides);
8543
+ };
8544
+ const clearSession = (input, skipDontRememberMe) => {
8545
+ const cookieContext = createCookieContext(input);
8546
+ deleteSessionCookie(cookieContext, skipDontRememberMe);
8547
+ };
8548
+ const applyResponseCookies = async (ctx) => {
8549
+ const responseHeaders = resolveResponseHeaders(ctx);
8550
+ const session = ctx.context.setSession ?? inferSessionPair(ctx.context.returned);
8551
+ if (ctx.context.clearSession) {
8552
+ clearSession({
8553
+ headers: ctx.headers,
8554
+ responseHeaders
8555
+ });
8556
+ }
8557
+ if (session) {
8558
+ await setSession(
8559
+ {
8560
+ headers: ctx.headers,
8561
+ responseHeaders
8562
+ },
8563
+ session,
8564
+ ctx.context.dontRememberMe,
8565
+ ctx.context.cookieOverrides
8566
+ );
8567
+ }
8568
+ return responseHeaders;
8569
+ };
8570
+ const runAfterHooks = async (ctx) => {
8571
+ for (const plugin of auth.plugins) {
8572
+ for (const hook of plugin.hooks?.after ?? []) {
8573
+ if (!hook.matcher(ctx)) {
8574
+ continue;
8575
+ }
8576
+ await hook.handler({
8577
+ ...ctx,
8578
+ auth
8579
+ });
8580
+ }
8581
+ }
8582
+ return ctx;
8583
+ };
8584
+ const resolveRequestContext = async (request) => {
8585
+ const requestUrl = getRequestUrl(request);
8586
+ const resolvedBaseURL = resolveRequestBaseURL(config.baseURL, request);
8587
+ if (!resolvedBaseURL) {
8588
+ throw new Error(
8589
+ isDynamicBaseURLConfig2(config.baseURL) ? "Could not resolve base URL from request. Check allowedHosts/baseURL." : "Could not resolve base URL from request."
8590
+ );
8591
+ }
8592
+ const requestCookies = getCookies({
8593
+ baseURL: resolvedBaseURL,
8594
+ session: config.session,
8595
+ advanced: config.advanced
8596
+ });
8597
+ const trustedOrigins = await resolveTrustedOrigins(config, resolvedBaseURL, request);
8598
+ const trustedProviders = await resolveTrustedProviders(config, request);
8599
+ return {
8600
+ auth,
8601
+ request,
8602
+ url: requestUrl,
8603
+ path: requestUrl.pathname,
8604
+ basePath: normalizedBasePath,
8605
+ baseURL: resolvedBaseURL,
8606
+ origin: getOrigin(resolvedBaseURL) ?? resolvedBaseURL,
8607
+ headers: request.headers,
8608
+ cookies: requestCookies,
8609
+ trustedOrigins,
8610
+ trustedProviders,
8611
+ options: config,
8612
+ runtime: {
8613
+ ...runtime,
8614
+ baseURL: resolvedBaseURL
8615
+ },
8616
+ database: auth.database,
8617
+ socialProviders: auth.socialProviders
8618
+ };
8619
+ };
8620
+ const handler = async (request) => {
8621
+ const requestContext = await resolveRequestContext(request);
8622
+ if (typeof config.handler !== "function") {
8623
+ return createJsonResponse(
8624
+ {
8625
+ ok: false,
8626
+ code: ATHENA_AUTH_BASE_ERROR_CODES.HANDLER_NOT_CONFIGURED,
8627
+ error: "No native auth handler was configured for this Athena auth instance.",
8628
+ path: requestContext.path,
8629
+ basePath: requestContext.basePath
8630
+ },
8631
+ { status: 501 }
8632
+ );
8633
+ }
8634
+ const result = await config.handler(requestContext);
8635
+ if (result instanceof Response) {
8636
+ return result;
8637
+ }
8638
+ const response = result.response ?? (result.returned !== void 0 ? createJsonResponse(result.returned) : new Response(null, { status: 204 }));
8639
+ const responseHeaders = new Headers(response.headers);
8640
+ await runAfterHooks({
8641
+ path: requestContext.path,
8642
+ headers: request.headers,
8643
+ context: {
8644
+ responseHeaders,
8645
+ returned: result.returned,
8646
+ setSession: result.setSession,
8647
+ clearSession: result.clearSession,
8648
+ dontRememberMe: result.dontRememberMe,
8649
+ cookieOverrides: result.cookieOverrides
8650
+ }
8651
+ });
8652
+ return mergeResponseHeaders(response, responseHeaders);
8653
+ };
8654
+ const api = Object.assign(
8655
+ {
8656
+ applyResponseCookies,
8657
+ clearSession,
8658
+ createCookieContext,
8659
+ getCookieCache,
8660
+ getSessionCookie,
8661
+ resolveRequestContext,
8662
+ runAfterHooks,
8663
+ setSession
8664
+ },
8665
+ config.api ?? {}
8666
+ );
8667
+ const $ERROR_CODES = {
8668
+ ...auth.plugins?.reduce((acc, plugin) => {
8669
+ if (plugin.$ERROR_CODES) {
8670
+ return {
8671
+ ...acc,
8672
+ ...plugin.$ERROR_CODES
8673
+ };
8674
+ }
8675
+ return acc;
8676
+ }, {}),
8677
+ ...config.errorCodes ?? {},
8678
+ ...ATHENA_AUTH_BASE_ERROR_CODES
8679
+ };
8680
+ Object.assign(auth, {
8681
+ config,
8682
+ options: config,
8683
+ runtime,
8684
+ database: resolvedDatabase,
8685
+ socialProviders: config.socialProviders ?? {},
8686
+ plugins: [...config.plugins ?? []],
8687
+ cookies,
8688
+ api,
8689
+ $ERROR_CODES,
8690
+ createCookieContext,
8691
+ setSession,
8692
+ clearSession,
8693
+ applyResponseCookies,
8694
+ runAfterHooks,
8695
+ resolveRequestContext,
8696
+ handler
8697
+ });
8698
+ auth.$context = Promise.all([
8699
+ resolveTrustedOrigins(config, staticBaseURL),
8700
+ resolveTrustedProviders(config)
8701
+ ]).then(([trustedOrigins, trustedProviders]) => ({
8702
+ auth,
8703
+ options: config,
8704
+ runtime,
8705
+ basePath: normalizedBasePath,
8706
+ baseURL: staticBaseURL,
8707
+ origin: getOrigin(staticBaseURL),
8708
+ database: auth.database,
8709
+ socialProviders: auth.socialProviders,
8710
+ plugins: auth.plugins,
8711
+ cookies: auth.cookies,
8712
+ trustedOrigins,
8713
+ trustedProviders
8714
+ }));
8715
+ return auth;
8716
+ }
8717
+
8718
+ export { ATHENA_AUTH_BASE_ERROR_CODES, AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, AthenaStorageError, AthenaStorageErrorCode, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, athenaAuth, coerceInt, createAthenaStorageError, createAuthClient, createAuthReactEmailInput, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createTypedClient, defineAthenaAuthConfig, defineAuthEmailTemplate, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, generatorEnv, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeAthenaGatewayBaseUrl, normalizeGeneratorConfig, normalizeSchemaSelection, parseBooleanFlag2 as parseBooleanFlag, renderAthenaReactEmail, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, storageSdkManifest, toModelFormDefaults, toModelPayload, unwrap, unwrapOne, unwrapRows, verifyAthenaGatewayUrl, withRetry };
6633
8719
  //# sourceMappingURL=index.js.map
6634
8720
  //# sourceMappingURL=index.js.map