@xylex-group/athena 2.6.0 → 2.8.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 (44) hide show
  1. package/README.md +210 -17
  2. package/dist/browser.cjs +2102 -527
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.cts +8 -7
  5. package/dist/browser.d.ts +8 -7
  6. package/dist/browser.js +2096 -528
  7. package/dist/browser.js.map +1 -1
  8. package/dist/cli/index.cjs +2116 -559
  9. package/dist/cli/index.cjs.map +1 -1
  10. package/dist/cli/index.d.cts +3 -3
  11. package/dist/cli/index.d.ts +3 -3
  12. package/dist/cli/index.js +2116 -559
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/cookies.cjs +10 -3
  15. package/dist/cookies.cjs.map +1 -1
  16. package/dist/cookies.js +10 -3
  17. package/dist/cookies.js.map +1 -1
  18. package/dist/index.cjs +2694 -748
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +8 -7
  21. package/dist/index.d.ts +8 -7
  22. package/dist/index.js +2688 -749
  23. package/dist/index.js.map +1 -1
  24. package/dist/model-form-DMed05gE.d.cts +3037 -0
  25. package/dist/model-form-DXPlOnlI.d.ts +3037 -0
  26. package/dist/{pipeline-Ce3pTw5h.d.ts → pipeline-CkMnhwPI.d.ts} +1 -1
  27. package/dist/{pipeline-D1ZYeoH7.d.cts → pipeline-D4sJRKqN.d.cts} +1 -1
  28. package/dist/react-email-DZhDDlEl.d.cts +417 -0
  29. package/dist/react-email-Lrz9A-BW.d.ts +417 -0
  30. package/dist/react.cjs +178 -71
  31. package/dist/react.cjs.map +1 -1
  32. package/dist/react.d.cts +22 -5
  33. package/dist/react.d.ts +22 -5
  34. package/dist/react.js +92 -5
  35. package/dist/react.js.map +1 -1
  36. package/dist/{types-CUuo4NDi.d.cts → types-BzY6fETM.d.ts} +47 -5
  37. package/dist/{types-DapchQY5.d.ts → types-CAtTGGoz.d.cts} +47 -5
  38. package/dist/{types-DSX6AT5B.d.cts → types-vikz9YIO.d.cts} +23 -1
  39. package/dist/{types-DSX6AT5B.d.ts → types-vikz9YIO.d.ts} +23 -1
  40. package/package.json +194 -193
  41. package/dist/model-form-BaHWi3gm.d.cts +0 -1383
  42. package/dist/model-form-Dh6gWjL0.d.ts +0 -1383
  43. package/dist/react-email-B8O1Jeff.d.cts +0 -1230
  44. package/dist/react-email-CDEF0jij.d.ts +0 -1230
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var zod = require('zod');
3
4
  var fs = require('fs');
4
5
  var path = require('path');
5
6
  var url = require('url');
@@ -673,9 +674,16 @@ var getSessionCookie = (request, config) => {
673
674
  const { cookieName = "session_token", cookiePrefix = "athena-auth" } = config || {};
674
675
  const parsedCookie = parseCookies(cookies);
675
676
  const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
676
- const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
677
- if (sessionToken) {
678
- return sessionToken;
677
+ const candidateCookieNames = Array.from(/* @__PURE__ */ new Set([
678
+ cookieName,
679
+ cookieName.replace(/_/g, "-"),
680
+ cookieName.replace(/-/g, "_")
681
+ ])).filter(Boolean);
682
+ for (const candidateName of candidateCookieNames) {
683
+ const sessionToken = getCookie(`${cookiePrefix}.${candidateName}`) || getCookie(`${cookiePrefix}-${candidateName}`);
684
+ if (sessionToken) {
685
+ return sessionToken;
686
+ }
679
687
  }
680
688
  return null;
681
689
  };
@@ -798,7 +806,7 @@ var getCookieCache = async (request, config) => {
798
806
 
799
807
  // package.json
800
808
  var package_default = {
801
- version: "2.6.0"
809
+ version: "2.8.0"
802
810
  };
803
811
 
804
812
  // src/sdk-version.ts
@@ -3115,7 +3123,7 @@ function normalizeAthenaError(resultOrError, context) {
3115
3123
  const details = resultOrError.errorDetails;
3116
3124
  const message2 = messageFromUnknownError(resultOrError.error) ?? details?.message ?? `Athena ${context?.operation ?? operationFromDetails(details) ?? "request"} failed`;
3117
3125
  const operation = context?.operation ?? operationFromDetails(details);
3118
- const table = context?.table ?? extractTable(message2);
3126
+ const table2 = context?.table ?? extractTable(message2);
3119
3127
  const constraint = extractConstraint(message2);
3120
3128
  const gatewayCode = details?.code ?? gatewayCodeFromUnknownError(resultOrError.error);
3121
3129
  const kind2 = classifyKind(resultOrError.status, gatewayCode, message2);
@@ -3128,7 +3136,7 @@ function normalizeAthenaError(resultOrError, context) {
3128
3136
  retryable: isRetryable(kind2, resultOrError.status),
3129
3137
  status: resultOrError.status,
3130
3138
  constraint,
3131
- table,
3139
+ table: table2,
3132
3140
  operation,
3133
3141
  message: message2,
3134
3142
  raw: resultOrError.raw
@@ -3137,7 +3145,7 @@ function normalizeAthenaError(resultOrError, context) {
3137
3145
  if (isAthenaGatewayError(resultOrError)) {
3138
3146
  const details = resultOrError.toDetails();
3139
3147
  const operation = context?.operation ?? operationFromDetails(details);
3140
- const table = context?.table ?? extractTable(resultOrError.message);
3148
+ const table2 = context?.table ?? extractTable(resultOrError.message);
3141
3149
  const constraint = extractConstraint(resultOrError.message);
3142
3150
  const kind2 = classifyKind(resultOrError.status, resultOrError.code, resultOrError.message);
3143
3151
  const code = toAthenaErrorCode(kind2, resultOrError.status, resultOrError.code);
@@ -3149,7 +3157,7 @@ function normalizeAthenaError(resultOrError, context) {
3149
3157
  retryable: isRetryable(kind2, resultOrError.status),
3150
3158
  status: resultOrError.status,
3151
3159
  constraint,
3152
- table,
3160
+ table: table2,
3153
3161
  operation,
3154
3162
  message: resultOrError.message,
3155
3163
  raw: resultOrError
@@ -3345,23 +3353,24 @@ async function withRetry(config, fn) {
3345
3353
  // src/db/module.ts
3346
3354
  function createDbModule(input) {
3347
3355
  const db = {
3348
- from(table, options) {
3349
- return input.from(table, options);
3350
- },
3351
- select(table, columns, options) {
3352
- return input.from(table).select(columns, options);
3356
+ from: input.from,
3357
+ select(table2, first, second) {
3358
+ if (first && typeof first === "object" && !Array.isArray(first)) {
3359
+ return input.from(table2).select(void 0, first);
3360
+ }
3361
+ return input.from(table2).select(first, second);
3353
3362
  },
3354
- insert(table, values, options) {
3355
- return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
3363
+ insert(table2, values, options) {
3364
+ return Array.isArray(values) ? input.from(table2).insert(values, options) : input.from(table2).insert(values, options);
3356
3365
  },
3357
- upsert(table, values, options) {
3358
- return Array.isArray(values) ? input.from(table).upsert(values, options) : input.from(table).upsert(values, options);
3366
+ upsert(table2, values, options) {
3367
+ return Array.isArray(values) ? input.from(table2).upsert(values, options) : input.from(table2).upsert(values, options);
3359
3368
  },
3360
- update(table, values, options) {
3361
- return input.from(table).update(values, options);
3369
+ update(table2, values, options) {
3370
+ return input.from(table2).update(values, options);
3362
3371
  },
3363
- delete(table, options) {
3364
- return input.from(table).delete(options);
3372
+ delete(table2, options) {
3373
+ return input.from(table2).delete(options);
3365
3374
  },
3366
3375
  rpc(fn, args, options) {
3367
3376
  return input.rpc(fn, args, options);
@@ -3373,6 +3382,344 @@ function createDbModule(input) {
3373
3382
  return db;
3374
3383
  }
3375
3384
 
3385
+ // src/storage/file.ts
3386
+ function createStorageFileModule(base, config = {}) {
3387
+ const upload = async (input, options) => {
3388
+ const sources = normalizeUploadSources(input);
3389
+ validateUploadConstraints(sources, input);
3390
+ const uploadRequests = sources.map((source, index) => {
3391
+ const storageKey = resolveUploadStorageKey(input, source, index, options, config);
3392
+ return {
3393
+ source,
3394
+ uploadRequest: {
3395
+ s3_id: input.s3_id,
3396
+ bucket: input.bucket,
3397
+ storage_key: storageKey,
3398
+ name: input.name ?? source.fileName,
3399
+ original_name: input.original_name ?? source.fileName,
3400
+ resource_id: input.resource_id ?? input.resourceId,
3401
+ mime_type: input.mime_type ?? source.contentType,
3402
+ content_type: input.content_type ?? source.contentType,
3403
+ size_bytes: source.sizeBytes,
3404
+ public: input.public,
3405
+ metadata: input.metadata
3406
+ }
3407
+ };
3408
+ });
3409
+ input.onProgress?.(createProgressSnapshot("preparing", sources, 0, 0, 0));
3410
+ const uploadUrls = uploadRequests.length === 1 ? [await base.createStorageUploadUrl(uploadRequests[0].uploadRequest, options)] : (await base.createStorageUploadUrls({ files: uploadRequests.map((request) => request.uploadRequest) }, options)).files;
3411
+ const aggregateLoaded = new Array(uploadRequests.length).fill(0);
3412
+ const uploaded = [];
3413
+ for (let index = 0; index < uploadRequests.length; index += 1) {
3414
+ const request = uploadRequests[index];
3415
+ const uploadUrl = uploadUrls[index];
3416
+ const response = await putUploadBody(uploadUrl.upload.url, request.source, input, options, (progress) => {
3417
+ aggregateLoaded[index] = progress.loaded;
3418
+ input.onProgress?.(createProgressSnapshot("uploading", sources, index, progress.loaded, sum(aggregateLoaded)));
3419
+ });
3420
+ uploaded.push({
3421
+ file: uploadUrl.file,
3422
+ upload: uploadUrl.upload,
3423
+ source: request.source.source,
3424
+ fileName: request.source.fileName,
3425
+ storage_key: request.uploadRequest.storage_key,
3426
+ response
3427
+ });
3428
+ aggregateLoaded[index] = request.source.sizeBytes;
3429
+ input.onProgress?.(createProgressSnapshot("complete", sources, index, request.source.sizeBytes, sum(aggregateLoaded)));
3430
+ }
3431
+ return {
3432
+ files: uploaded,
3433
+ count: uploaded.length
3434
+ };
3435
+ };
3436
+ const download = ((input, queryOrOptions, maybeOptions) => {
3437
+ const { fileIds, query, options } = normalizeDownloadArgs(input, queryOrOptions, maybeOptions);
3438
+ const downloads = fileIds.map((fileId) => base.getStorageFileProxy(fileId, query, options));
3439
+ return Array.isArray(input) || isRecord5(input) && Array.isArray(input.fileIds) ? Promise.all(downloads) : downloads[0];
3440
+ });
3441
+ const deleteFile = ((input, options) => {
3442
+ if (Array.isArray(input)) {
3443
+ return Promise.all(input.map((fileId) => base.deleteStorageFile(fileId, options)));
3444
+ }
3445
+ return base.deleteStorageFile(input, options);
3446
+ });
3447
+ return {
3448
+ upload,
3449
+ download,
3450
+ list(input, options) {
3451
+ const prefix = resolveStoragePath(input.prefix ?? "", input, options, config);
3452
+ return base.listStorageFiles(
3453
+ {
3454
+ s3_id: input.s3_id,
3455
+ prefix
3456
+ },
3457
+ options
3458
+ );
3459
+ },
3460
+ delete: deleteFile
3461
+ };
3462
+ }
3463
+ function resolveStoragePath(path, input, options, config = {}) {
3464
+ const context = createPathContext(input, options, config);
3465
+ const prefixPath = input.prefixPath ?? config.prefixPath;
3466
+ const prefix = typeof prefixPath === "function" ? prefixPath(context) : prefixPath;
3467
+ return joinStoragePath(renderStorageTemplate(prefix ?? "", context), renderStorageTemplate(path, context));
3468
+ }
3469
+ function resolveUploadStorageKey(input, source, index, options, config) {
3470
+ const explicitKey = input.storage_key ?? input.storageKey;
3471
+ const keyTemplate = input.storageKeyTemplate;
3472
+ const fallbackName = source.fileName;
3473
+ const context = createPathContext(input, options, config);
3474
+ const key = keyTemplate ? renderStorageTemplate(keyTemplate, {
3475
+ ...context,
3476
+ vars: {
3477
+ ...context.vars,
3478
+ index,
3479
+ fileName: source.fileName,
3480
+ name: source.fileName
3481
+ }
3482
+ }) : explicitKey ?? fallbackName;
3483
+ return resolveStoragePath(key, input, options, config);
3484
+ }
3485
+ function normalizeUploadSources(input) {
3486
+ const files = toArray(input.files);
3487
+ if (files.length === 0) {
3488
+ throw new Error("athena.storage.file.upload requires at least one file");
3489
+ }
3490
+ return files.map((source, index) => {
3491
+ const fileName = input.fileName ?? sourceName(source) ?? `file-${index + 1}`;
3492
+ const sizeBytes = sourceSize(source);
3493
+ const contentType = input.content_type ?? input.mime_type ?? sourceContentType(source);
3494
+ return {
3495
+ source,
3496
+ fileName,
3497
+ sizeBytes,
3498
+ contentType
3499
+ };
3500
+ });
3501
+ }
3502
+ function validateUploadConstraints(sources, input) {
3503
+ const maxFiles = input.maxFiles ?? 1;
3504
+ if (sources.length > maxFiles) {
3505
+ throw new Error(`athena.storage.file.upload accepts at most ${maxFiles} file${maxFiles === 1 ? "" : "s"} for this call`);
3506
+ }
3507
+ const maxFileSizeBytes = input.maxFileSizeBytes ?? (input.maxFileSizeMb === void 0 ? void 0 : Math.floor(input.maxFileSizeMb * 1024 * 1024));
3508
+ if (maxFileSizeBytes !== void 0) {
3509
+ const tooLarge = sources.find((source) => source.sizeBytes > maxFileSizeBytes);
3510
+ if (tooLarge) {
3511
+ throw new Error(`athena.storage.file.upload rejected ${tooLarge.fileName}: file exceeds ${maxFileSizeBytes} bytes`);
3512
+ }
3513
+ }
3514
+ const allowedExtensions = normalizeExtensions(input.allowedExtensions ?? input.extensions);
3515
+ if (allowedExtensions.size > 0) {
3516
+ const invalid = sources.find((source) => !allowedExtensions.has(fileExtension(source.fileName)));
3517
+ if (invalid) {
3518
+ throw new Error(`athena.storage.file.upload rejected ${invalid.fileName}: extension is not allowed`);
3519
+ }
3520
+ }
3521
+ }
3522
+ async function putUploadBody(url, source, input, options, onProgress) {
3523
+ const headers = new Headers(input.uploadHeaders);
3524
+ if (source.contentType && !headers.has("Content-Type")) {
3525
+ headers.set("Content-Type", source.contentType);
3526
+ }
3527
+ if (typeof XMLHttpRequest !== "undefined") {
3528
+ return putUploadBodyWithXhr(url, source, headers, options, onProgress);
3529
+ }
3530
+ onProgress({ loaded: 0 });
3531
+ const response = await fetch(url, {
3532
+ method: "PUT",
3533
+ headers,
3534
+ body: source.source,
3535
+ signal: options?.signal
3536
+ });
3537
+ if (!response.ok) {
3538
+ throw new Error(`athena.storage.file.upload failed with status ${response.status}`);
3539
+ }
3540
+ onProgress({ loaded: source.sizeBytes });
3541
+ return response;
3542
+ }
3543
+ function putUploadBodyWithXhr(url, source, headers, options, onProgress) {
3544
+ const Xhr = XMLHttpRequest;
3545
+ if (Xhr === void 0) {
3546
+ return Promise.reject(new Error("athena.storage.file.upload requires XMLHttpRequest in this runtime"));
3547
+ }
3548
+ return new Promise((resolve3, reject) => {
3549
+ const xhr = new Xhr();
3550
+ const abort = () => xhr.abort();
3551
+ xhr.open("PUT", url);
3552
+ headers.forEach((value, key) => xhr.setRequestHeader(key, value));
3553
+ xhr.upload.onprogress = (event) => {
3554
+ onProgress({ loaded: event.loaded });
3555
+ };
3556
+ xhr.onload = () => {
3557
+ if (options?.signal) {
3558
+ options.signal.removeEventListener("abort", abort);
3559
+ }
3560
+ if (xhr.status < 200 || xhr.status >= 300) {
3561
+ reject(new Error(`athena.storage.file.upload failed with status ${xhr.status}`));
3562
+ return;
3563
+ }
3564
+ onProgress({ loaded: source.sizeBytes });
3565
+ resolve3(new Response(xhr.response, {
3566
+ status: xhr.status,
3567
+ statusText: xhr.statusText,
3568
+ headers: parseXhrHeaders(xhr.getAllResponseHeaders())
3569
+ }));
3570
+ };
3571
+ xhr.onerror = () => {
3572
+ if (options?.signal) {
3573
+ options.signal.removeEventListener("abort", abort);
3574
+ }
3575
+ reject(new Error("athena.storage.file.upload failed with a network error"));
3576
+ };
3577
+ xhr.onabort = () => {
3578
+ if (options?.signal) {
3579
+ options.signal.removeEventListener("abort", abort);
3580
+ }
3581
+ reject(new DOMException("Upload aborted", "AbortError"));
3582
+ };
3583
+ if (options?.signal) {
3584
+ if (options.signal.aborted) {
3585
+ abort();
3586
+ return;
3587
+ }
3588
+ options.signal.addEventListener("abort", abort, { once: true });
3589
+ }
3590
+ xhr.send(source.source);
3591
+ });
3592
+ }
3593
+ function normalizeDownloadArgs(input, queryOrOptions, maybeOptions) {
3594
+ if (typeof input === "string") {
3595
+ return { fileIds: [input], query: queryOrOptions, options: maybeOptions };
3596
+ }
3597
+ if (Array.isArray(input)) {
3598
+ return { fileIds: [...input], query: queryOrOptions, options: maybeOptions };
3599
+ }
3600
+ const downloadInput = input;
3601
+ const { fileId, fileIds, ...query } = downloadInput;
3602
+ return {
3603
+ fileIds: fileIds ? [...fileIds] : fileId ? [fileId] : [],
3604
+ query,
3605
+ options: queryOrOptions
3606
+ };
3607
+ }
3608
+ function createPathContext(input, options, config) {
3609
+ const organizationId = input.organizationId ?? input.organization_id ?? options?.organizationId ?? void 0;
3610
+ const userId = input.userId ?? input.user_id ?? options?.userId ?? void 0;
3611
+ const resourceId = input.resourceId ?? input.resource_id ?? void 0;
3612
+ const vars = {
3613
+ ...config.vars ?? {},
3614
+ ...input.vars ?? {}
3615
+ };
3616
+ if (organizationId !== void 0) {
3617
+ vars.organizationId = organizationId;
3618
+ vars.organization_id = organizationId;
3619
+ }
3620
+ if (userId !== void 0) {
3621
+ vars.userId = userId;
3622
+ vars.user_id = userId;
3623
+ }
3624
+ if (resourceId !== void 0) {
3625
+ vars.resourceId = resourceId;
3626
+ vars.resource_id = resourceId;
3627
+ }
3628
+ return {
3629
+ vars,
3630
+ env: {
3631
+ ...readProcessEnv(),
3632
+ ...config.env ?? {},
3633
+ ...input.env ?? {}
3634
+ },
3635
+ organizationId,
3636
+ organization_id: organizationId,
3637
+ userId,
3638
+ user_id: userId,
3639
+ resourceId,
3640
+ resource_id: resourceId
3641
+ };
3642
+ }
3643
+ function renderStorageTemplate(template, context) {
3644
+ return template.replace(/\$\{([^}]+)\}|\{([^}]+)\}/g, (_match, shellToken, braceToken) => {
3645
+ const token = (shellToken ?? braceToken ?? "").trim();
3646
+ if (!token) return "";
3647
+ const value = resolveTemplateToken(token, context);
3648
+ return value === void 0 || value === null ? "" : String(value);
3649
+ });
3650
+ }
3651
+ function resolveTemplateToken(token, context) {
3652
+ if (token.startsWith("env.")) {
3653
+ return context.env[token.slice(4)];
3654
+ }
3655
+ if (token in context.vars) {
3656
+ return context.vars[token];
3657
+ }
3658
+ return context.env[token];
3659
+ }
3660
+ function joinStoragePath(...parts) {
3661
+ return parts.map((part) => part.trim().replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
3662
+ }
3663
+ function toArray(files) {
3664
+ if (isUploadSource(files)) return [files];
3665
+ return Array.from(files);
3666
+ }
3667
+ function isUploadSource(value) {
3668
+ return value instanceof Blob || value instanceof ArrayBuffer || value instanceof Uint8Array;
3669
+ }
3670
+ function sourceName(source) {
3671
+ return isRecord5(source) && typeof source.name === "string" && source.name.trim() ? source.name.trim() : void 0;
3672
+ }
3673
+ function sourceSize(source) {
3674
+ if (source instanceof Blob) return source.size;
3675
+ return source.byteLength;
3676
+ }
3677
+ function sourceContentType(source) {
3678
+ return source instanceof Blob && source.type.trim() ? source.type.trim() : void 0;
3679
+ }
3680
+ function normalizeExtensions(extensions) {
3681
+ return new Set((extensions ?? []).map((extension) => extension.replace(/^\./, "").toLowerCase()).filter(Boolean));
3682
+ }
3683
+ function fileExtension(fileName) {
3684
+ const lastDot = fileName.lastIndexOf(".");
3685
+ return lastDot === -1 ? "" : fileName.slice(lastDot + 1).toLowerCase();
3686
+ }
3687
+ function createProgressSnapshot(phase, sources, fileIndex, loaded, aggregateLoaded) {
3688
+ const total = sources[fileIndex]?.sizeBytes ?? 0;
3689
+ const aggregateTotal = sources.reduce((totalBytes, source) => totalBytes + source.sizeBytes, 0);
3690
+ return {
3691
+ phase,
3692
+ fileIndex,
3693
+ fileCount: sources.length,
3694
+ fileName: sources[fileIndex]?.fileName ?? "",
3695
+ loaded,
3696
+ total,
3697
+ percent: total > 0 ? Math.round(loaded / total * 100) : 100,
3698
+ aggregateLoaded,
3699
+ aggregateTotal,
3700
+ aggregatePercent: aggregateTotal > 0 ? Math.round(aggregateLoaded / aggregateTotal * 100) : 100
3701
+ };
3702
+ }
3703
+ function sum(values) {
3704
+ return values.reduce((total, value) => total + value, 0);
3705
+ }
3706
+ function parseXhrHeaders(raw) {
3707
+ const headers = new Headers();
3708
+ for (const line of raw.trim().split(/[\r\n]+/)) {
3709
+ const index = line.indexOf(":");
3710
+ if (index === -1) continue;
3711
+ headers.set(line.slice(0, index).trim(), line.slice(index + 1).trim());
3712
+ }
3713
+ return headers;
3714
+ }
3715
+ function readProcessEnv() {
3716
+ const processLike = globalThis.process;
3717
+ return processLike?.env ?? {};
3718
+ }
3719
+ function isRecord5(value) {
3720
+ return Boolean(value) && typeof value === "object";
3721
+ }
3722
+
3376
3723
  // src/storage/module.ts
3377
3724
  var storageSdkManifest = {
3378
3725
  namespace: "storage",
@@ -3581,7 +3928,7 @@ var AthenaStorageError = class extends Error {
3581
3928
  };
3582
3929
  }
3583
3930
  };
3584
- function isRecord5(value) {
3931
+ function isRecord6(value) {
3585
3932
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3586
3933
  }
3587
3934
  function causeToString(cause) {
@@ -3692,11 +4039,20 @@ function appendQuery(path, query) {
3692
4039
  function storagePath(path) {
3693
4040
  return path;
3694
4041
  }
4042
+ function resolveStorageEndpointPath(endpoint, runtimeOptions) {
4043
+ if (!runtimeOptions?.stripBasePath) {
4044
+ return endpoint;
4045
+ }
4046
+ const [pathname, queryText] = String(endpoint).split("?", 2);
4047
+ const trimmedPathname = pathname.startsWith("/storage/") ? pathname.slice("/storage".length) : pathname === "/storage" ? "/" : pathname;
4048
+ const resolvedPath = trimmedPathname.startsWith("/") ? trimmedPathname : `/${trimmedPathname}`;
4049
+ return storagePath(queryText ? `${resolvedPath}?${queryText}` : resolvedPath);
4050
+ }
3695
4051
  function withPathParam(path, name, value) {
3696
4052
  return path.replace(`{${name}}`, encodeURIComponent(value));
3697
4053
  }
3698
4054
  function resolveErrorMessage3(payload, fallback) {
3699
- if (isRecord5(payload)) {
4055
+ if (isRecord6(payload)) {
3700
4056
  const message = payload.message ?? payload.error ?? payload.details;
3701
4057
  if (typeof message === "string" && message.trim()) {
3702
4058
  return message.trim();
@@ -3708,12 +4064,12 @@ function resolveErrorMessage3(payload, fallback) {
3708
4064
  return fallback;
3709
4065
  }
3710
4066
  function resolveErrorHint2(payload) {
3711
- if (!isRecord5(payload)) return void 0;
4067
+ if (!isRecord6(payload)) return void 0;
3712
4068
  const hint = payload.hint ?? payload.suggestion;
3713
4069
  return typeof hint === "string" && hint.trim() ? hint.trim() : void 0;
3714
4070
  }
3715
4071
  function resolveErrorCause(payload) {
3716
- if (!isRecord5(payload)) return void 0;
4072
+ if (!isRecord6(payload)) return void 0;
3717
4073
  const cause = payload.cause ?? payload.reason;
3718
4074
  return typeof cause === "string" && cause.trim() ? cause.trim() : void 0;
3719
4075
  }
@@ -3730,8 +4086,8 @@ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload,
3730
4086
  let url;
3731
4087
  let headers;
3732
4088
  try {
3733
- const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3734
- url = buildAthenaGatewayUrl(baseUrl, endpoint);
4089
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : runtimeOptions?.baseUrl ? normalizeAthenaGatewayBaseUrl(runtimeOptions.baseUrl) : gateway.baseUrl;
4090
+ url = buildAthenaGatewayUrl(baseUrl, resolveStorageEndpointPath(endpoint, runtimeOptions));
3735
4091
  headers = gateway.buildHeaders(options);
3736
4092
  } catch (error) {
3737
4093
  return rejectStorageError(
@@ -3832,7 +4188,7 @@ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload,
3832
4188
  );
3833
4189
  }
3834
4190
  if (envelope === "athena") {
3835
- if (!isRecord5(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4191
+ if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
3836
4192
  return rejectStorageError(
3837
4193
  {
3838
4194
  code: "INVALID_ATHENA_ENVELOPE",
@@ -3855,8 +4211,8 @@ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, run
3855
4211
  let url;
3856
4212
  let headers;
3857
4213
  try {
3858
- const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3859
- url = buildAthenaGatewayUrl(baseUrl, endpoint);
4214
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : runtimeOptions?.baseUrl ? normalizeAthenaGatewayBaseUrl(runtimeOptions.baseUrl) : gateway.baseUrl;
4215
+ url = buildAthenaGatewayUrl(baseUrl, resolveStorageEndpointPath(endpoint, runtimeOptions));
3860
4216
  headers = gateway.buildHeaders(options);
3861
4217
  } catch (error) {
3862
4218
  return rejectStorageError(
@@ -3940,129 +4296,678 @@ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, run
3940
4296
  runtimeOptions
3941
4297
  );
3942
4298
  }
3943
- function createStorageModule(gateway, runtimeOptions) {
4299
+ function isBlobBody(body) {
4300
+ return typeof Blob !== "undefined" && body instanceof Blob;
4301
+ }
4302
+ function isReadableStreamBody(body) {
4303
+ return typeof ReadableStream !== "undefined" && body instanceof ReadableStream;
4304
+ }
4305
+ async function putPresignedUploadBody(uploadUrl, uploadHeaders, body, options) {
4306
+ const headers = new Headers(uploadHeaders);
4307
+ Object.entries(options?.headers ?? {}).forEach(([key, value]) => headers.set(key, value));
4308
+ if (!headers.has("Content-Type") && isBlobBody(body) && body.type) {
4309
+ headers.set("Content-Type", body.type);
4310
+ }
4311
+ const init = {
4312
+ method: "PUT",
4313
+ headers,
4314
+ body,
4315
+ signal: options?.signal
4316
+ };
4317
+ if (isReadableStreamBody(body)) {
4318
+ init.duplex = "half";
4319
+ }
4320
+ return fetch(uploadUrl, init);
4321
+ }
4322
+ function attachManagedUpload(upload) {
4323
+ const headers = {};
4324
+ return {
4325
+ ...upload,
4326
+ method: "PUT",
4327
+ headers,
4328
+ expiresAt: upload.expires_at,
4329
+ put(body, options) {
4330
+ return putPresignedUploadBody(upload.url, headers, body, options);
4331
+ }
4332
+ };
4333
+ }
4334
+ function attachUploadHelper(response) {
4335
+ return {
4336
+ ...response,
4337
+ upload: attachManagedUpload(response.upload)
4338
+ };
4339
+ }
4340
+ function attachUploadHelpers(response) {
4341
+ return {
4342
+ files: response.files.map(attachUploadHelper)
4343
+ };
4344
+ }
4345
+ function normalizeUploadUrlRequest(input) {
4346
+ const s3_id = input.s3_id ?? input.s3Id;
4347
+ const storage_key = input.storage_key ?? input.storageKey;
4348
+ if (!s3_id?.trim()) {
4349
+ throw new Error("athena.storage.file.upload requires s3_id or s3Id");
4350
+ }
4351
+ if (!storage_key?.trim()) {
4352
+ throw new Error("athena.storage.file.upload requires storage_key or storageKey");
4353
+ }
4354
+ const fileName = input.fileName?.trim();
4355
+ const originalName = input.originalName?.trim();
3944
4356
  return {
4357
+ s3_id,
4358
+ bucket: input.bucket,
4359
+ storage_key,
4360
+ name: input.name ?? fileName,
4361
+ original_name: input.original_name ?? originalName ?? fileName,
4362
+ resource_id: input.resource_id ?? input.resourceId,
4363
+ mime_type: input.mime_type ?? input.mimeType,
4364
+ content_type: input.content_type ?? input.contentType,
4365
+ size_bytes: input.size_bytes ?? input.sizeBytes,
4366
+ file_id: input.file_id ?? input.fileId,
4367
+ public: input.public,
4368
+ visibility: input.visibility,
4369
+ metadata: input.metadata
4370
+ };
4371
+ }
4372
+ async function callStorageUploadBinaryEndpoint(gateway, endpoint, body, options, runtimeOptions) {
4373
+ let url;
4374
+ let headers;
4375
+ try {
4376
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : runtimeOptions?.baseUrl ? normalizeAthenaGatewayBaseUrl(runtimeOptions.baseUrl) : gateway.baseUrl;
4377
+ url = buildAthenaGatewayUrl(baseUrl, resolveStorageEndpointPath(endpoint, runtimeOptions));
4378
+ headers = gateway.buildHeaders(options);
4379
+ } catch (error) {
4380
+ return rejectStorageError(
4381
+ {
4382
+ code: storageCodeFromUnknown(error),
4383
+ message: error instanceof Error ? error.message : `Athena storage PUT ${endpoint} failed before sending the request`,
4384
+ status: isAthenaGatewayError(error) ? error.status : 0,
4385
+ endpoint,
4386
+ method: "PUT",
4387
+ raw: error,
4388
+ requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
4389
+ hint: isAthenaGatewayError(error) ? error.hint : void 0,
4390
+ cause: error
4391
+ },
4392
+ options,
4393
+ runtimeOptions
4394
+ );
4395
+ }
4396
+ delete headers["Content-Type"];
4397
+ delete headers["content-type"];
4398
+ if (isBlobBody(body) && body.type) {
4399
+ headers["Content-Type"] = body.type;
4400
+ }
4401
+ const requestInit = {
4402
+ method: "PUT",
4403
+ headers,
4404
+ body,
4405
+ signal: options?.signal
4406
+ };
4407
+ if (isReadableStreamBody(body)) {
4408
+ requestInit.duplex = "half";
4409
+ }
4410
+ let response;
4411
+ try {
4412
+ response = await fetch(url, requestInit);
4413
+ } catch (error) {
4414
+ const message = error instanceof Error ? error.message : String(error);
4415
+ return rejectStorageError(
4416
+ {
4417
+ code: "NETWORK_ERROR",
4418
+ message: `Network error while calling Athena storage PUT ${endpoint}: ${message}`,
4419
+ status: 0,
4420
+ endpoint,
4421
+ method: "PUT",
4422
+ cause: error
4423
+ },
4424
+ options,
4425
+ runtimeOptions
4426
+ );
4427
+ }
4428
+ let rawText;
4429
+ try {
4430
+ rawText = await response.text();
4431
+ } catch (error) {
4432
+ return rejectStorageError(
4433
+ {
4434
+ code: "NETWORK_ERROR",
4435
+ message: `Athena storage PUT ${endpoint} response body could not be read`,
4436
+ status: response.status,
4437
+ endpoint,
4438
+ method: "PUT",
4439
+ requestId: headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]),
4440
+ cause: error
4441
+ },
4442
+ options,
4443
+ runtimeOptions
4444
+ );
4445
+ }
4446
+ const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
4447
+ const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
4448
+ if (parsedBody.parseFailed) {
4449
+ return rejectStorageError(
4450
+ {
4451
+ code: "INVALID_JSON",
4452
+ message: `Athena storage PUT ${endpoint} returned malformed JSON`,
4453
+ status: response.status,
4454
+ endpoint,
4455
+ method: "PUT",
4456
+ requestId,
4457
+ raw: parsedBody.parsed
4458
+ },
4459
+ options,
4460
+ runtimeOptions
4461
+ );
4462
+ }
4463
+ if (!response.ok) {
4464
+ return rejectStorageError(
4465
+ {
4466
+ code: "HTTP_ERROR",
4467
+ message: resolveErrorMessage3(
4468
+ parsedBody.parsed,
4469
+ `Athena storage PUT ${endpoint} failed with status ${response.status}`
4470
+ ),
4471
+ status: response.status,
4472
+ endpoint,
4473
+ method: "PUT",
4474
+ requestId,
4475
+ hint: resolveErrorHint2(parsedBody.parsed),
4476
+ cause: resolveErrorCause(parsedBody.parsed),
4477
+ raw: parsedBody.parsed
4478
+ },
4479
+ options,
4480
+ runtimeOptions
4481
+ );
4482
+ }
4483
+ if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4484
+ return rejectStorageError(
4485
+ {
4486
+ code: "INVALID_ATHENA_ENVELOPE",
4487
+ message: `Athena storage PUT ${endpoint} returned an invalid Athena envelope`,
4488
+ status: response.status,
4489
+ endpoint,
4490
+ method: "PUT",
4491
+ requestId,
4492
+ raw: parsedBody.parsed
4493
+ },
4494
+ options,
4495
+ runtimeOptions
4496
+ );
4497
+ }
4498
+ return parsedBody.parsed.data;
4499
+ }
4500
+ function createStorageModule(gateway, runtimeOptions) {
4501
+ const resolvedRuntimeOptions = runtimeOptions;
4502
+ const callRaw = (path, method, payload, options) => callStorageEndpoint(
4503
+ gateway,
4504
+ storagePath(path),
4505
+ method,
4506
+ "raw",
4507
+ payload,
4508
+ options,
4509
+ resolvedRuntimeOptions
4510
+ );
4511
+ const callAthena2 = (path, method, payload, options) => callStorageEndpoint(
4512
+ gateway,
4513
+ storagePath(path),
4514
+ method,
4515
+ "athena",
4516
+ payload,
4517
+ options,
4518
+ resolvedRuntimeOptions
4519
+ );
4520
+ const base = {
3945
4521
  listStorageCatalogs(options) {
3946
- return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "GET", "raw", void 0, options, runtimeOptions);
4522
+ return callRaw("/storage/catalogs", "GET", void 0, options);
3947
4523
  },
3948
4524
  createStorageCatalog(input, options) {
3949
- return callStorageEndpoint(gateway, storagePath("/storage/catalogs"), "POST", "raw", input, options, runtimeOptions);
4525
+ return callRaw("/storage/catalogs", "POST", input, options);
3950
4526
  },
3951
4527
  updateStorageCatalog(id, input, options) {
3952
- return callStorageEndpoint(
3953
- gateway,
3954
- storagePath(withPathParam("/storage/catalogs/{id}", "id", id)),
3955
- "PATCH",
3956
- "raw",
3957
- input,
3958
- options,
3959
- runtimeOptions
3960
- );
4528
+ return callRaw(withPathParam("/storage/catalogs/{id}", "id", id), "PATCH", input, options);
3961
4529
  },
3962
4530
  deleteStorageCatalog(id, options) {
3963
- return callStorageEndpoint(
3964
- gateway,
3965
- storagePath(withPathParam("/storage/catalogs/{id}", "id", id)),
3966
- "DELETE",
3967
- "raw",
3968
- void 0,
3969
- options,
3970
- runtimeOptions
3971
- );
4531
+ return callRaw(withPathParam("/storage/catalogs/{id}", "id", id), "DELETE", void 0, options);
3972
4532
  },
3973
4533
  listStorageCredentials(options) {
3974
- return callStorageEndpoint(gateway, storagePath("/storage/credentials"), "GET", "raw", void 0, options, runtimeOptions);
4534
+ return callRaw("/storage/credentials", "GET", void 0, options);
3975
4535
  },
3976
4536
  createStorageUploadUrl(input, options) {
3977
- return callStorageEndpoint(
3978
- gateway,
3979
- storagePath("/storage/files/upload-url"),
3980
- "POST",
3981
- "athena",
3982
- input,
3983
- options,
3984
- runtimeOptions
3985
- );
4537
+ return callAthena2("/storage/files/upload-url", "POST", input, options);
3986
4538
  },
3987
4539
  createStorageUploadUrls(input, options) {
3988
- return callStorageEndpoint(
3989
- gateway,
3990
- storagePath("/storage/files/upload-urls"),
3991
- "POST",
3992
- "athena",
3993
- input,
3994
- options,
3995
- runtimeOptions
3996
- );
4540
+ return callAthena2("/storage/files/upload-urls", "POST", input, options);
3997
4541
  },
3998
4542
  listStorageFiles(input, options) {
3999
- return callStorageEndpoint(gateway, storagePath("/storage/files/list"), "POST", "athena", input, options, runtimeOptions);
4543
+ return callAthena2("/storage/files/list", "POST", input, options);
4000
4544
  },
4001
4545
  getStorageFile(fileId, options) {
4002
- return callStorageEndpoint(
4003
- gateway,
4004
- storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4005
- "GET",
4006
- "athena",
4007
- void 0,
4008
- options,
4009
- runtimeOptions
4010
- );
4546
+ return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "GET", void 0, options);
4011
4547
  },
4012
4548
  getStorageFileUrl(fileId, query, options) {
4013
4549
  const path = appendQuery(
4014
4550
  withPathParam("/storage/files/{file_id}/url", "file_id", fileId),
4015
4551
  query
4016
4552
  );
4017
- return callStorageEndpoint(gateway, storagePath(path), "GET", "athena", void 0, options, runtimeOptions);
4553
+ return callAthena2(path, "GET", void 0, options);
4018
4554
  },
4019
4555
  getStorageFileProxy(fileId, query, options) {
4020
4556
  const path = appendQuery(
4021
4557
  withPathParam("/storage/files/{file_id}/proxy", "file_id", fileId),
4022
4558
  query
4023
4559
  );
4024
- return callStorageBinaryEndpoint(gateway, storagePath(path), "GET", options, runtimeOptions);
4560
+ return callStorageBinaryEndpoint(gateway, storagePath(path), "GET", options, resolvedRuntimeOptions);
4025
4561
  },
4026
4562
  updateStorageFile(fileId, input, options) {
4027
- return callStorageEndpoint(
4028
- gateway,
4029
- storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4030
- "PATCH",
4031
- "athena",
4032
- input,
4033
- options,
4034
- runtimeOptions
4035
- );
4563
+ return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "PATCH", input, options);
4036
4564
  },
4037
4565
  deleteStorageFile(fileId, options) {
4038
- return callStorageEndpoint(
4039
- gateway,
4040
- storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
4041
- "DELETE",
4042
- "athena",
4043
- void 0,
4044
- options,
4045
- runtimeOptions
4046
- );
4566
+ return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "DELETE", void 0, options);
4047
4567
  },
4048
4568
  setStorageFileVisibility(fileId, input, options) {
4049
- return callStorageEndpoint(
4569
+ return callAthena2(withPathParam("/storage/files/{file_id}/visibility", "file_id", fileId), "PATCH", input, options);
4570
+ },
4571
+ deleteStorageFolder(input, options) {
4572
+ return callAthena2("/storage/folders/delete", "POST", input, options);
4573
+ },
4574
+ moveStorageFolder(input, options) {
4575
+ return callAthena2("/storage/folders/move", "POST", input, options);
4576
+ }
4577
+ };
4578
+ const fileFacade = createStorageFileModule(base, runtimeOptions);
4579
+ const fileUpload = ((input, options) => {
4580
+ if (isRecord6(input) && "files" in input) {
4581
+ return fileFacade.upload(input, options);
4582
+ }
4583
+ return base.createStorageUploadUrl(
4584
+ normalizeUploadUrlRequest(input),
4585
+ options
4586
+ ).then(attachUploadHelper);
4587
+ });
4588
+ const fileDelete = ((input, options) => fileFacade.delete(input, options));
4589
+ const file = {
4590
+ ...fileFacade,
4591
+ upload: fileUpload,
4592
+ uploadMany(input, options) {
4593
+ return base.createStorageUploadUrls(
4594
+ { files: input.files.map(normalizeUploadUrlRequest) },
4595
+ options
4596
+ ).then(attachUploadHelpers);
4597
+ },
4598
+ confirmUpload(fileId, input, options) {
4599
+ return callAthena2(withPathParam("/storage/files/{file_id}/confirm-upload", "file_id", fileId), "POST", input ?? {}, options);
4600
+ },
4601
+ uploadBinary(fileId, body, options) {
4602
+ return callStorageUploadBinaryEndpoint(
4050
4603
  gateway,
4051
- storagePath(withPathParam("/storage/files/{file_id}/visibility", "file_id", fileId)),
4052
- "PATCH",
4053
- "athena",
4054
- input,
4604
+ storagePath(withPathParam("/storage/files/{file_id}/upload", "file_id", fileId)),
4605
+ body,
4055
4606
  options,
4056
- runtimeOptions
4607
+ resolvedRuntimeOptions
4057
4608
  );
4058
4609
  },
4059
- deleteStorageFolder(input, options) {
4060
- return callStorageEndpoint(gateway, storagePath("/storage/folders/delete"), "POST", "athena", input, options, runtimeOptions);
4610
+ search(input, options) {
4611
+ return callAthena2("/storage/files/search", "POST", input, options);
4061
4612
  },
4062
- moveStorageFolder(input, options) {
4063
- return callStorageEndpoint(gateway, storagePath("/storage/folders/move"), "POST", "athena", input, options, runtimeOptions);
4613
+ get(fileId, options) {
4614
+ return base.getStorageFile(fileId, options);
4615
+ },
4616
+ update(fileId, input, options) {
4617
+ return base.updateStorageFile(fileId, input, options);
4618
+ },
4619
+ delete: fileDelete,
4620
+ deleteMany(input, options) {
4621
+ return callAthena2("/storage/files/delete-many", "POST", input, options);
4622
+ },
4623
+ updateMany(input, options) {
4624
+ return callAthena2("/storage/files/update-many", "POST", input, options);
4625
+ },
4626
+ restore(fileId, options) {
4627
+ return callAthena2(withPathParam("/storage/files/{file_id}/restore", "file_id", fileId), "POST", {}, options);
4628
+ },
4629
+ purge(fileId, options) {
4630
+ return callAthena2(withPathParam("/storage/files/{file_id}/purge", "file_id", fileId), "DELETE", void 0, options);
4631
+ },
4632
+ copy(fileId, input, options) {
4633
+ return callAthena2(withPathParam("/storage/files/{file_id}/copy", "file_id", fileId), "POST", input, options);
4634
+ },
4635
+ url(fileId, query, options) {
4636
+ return base.getStorageFileUrl(fileId, query, options);
4637
+ },
4638
+ publicUrl(fileId, options) {
4639
+ return callAthena2(withPathParam("/storage/files/{file_id}/public-url", "file_id", fileId), "GET", void 0, options);
4640
+ },
4641
+ proxy(fileId, query, options) {
4642
+ return base.getStorageFileProxy(fileId, query, options);
4643
+ },
4644
+ visibility: {
4645
+ set(fileId, input, options) {
4646
+ return base.setStorageFileVisibility(fileId, input, options);
4647
+ },
4648
+ setMany(input, options) {
4649
+ return callAthena2("/storage/files/visibility-many", "POST", input, options);
4650
+ }
4651
+ }
4652
+ };
4653
+ const credentials = {
4654
+ list(options) {
4655
+ return base.listStorageCredentials(options);
4656
+ }
4657
+ };
4658
+ const catalog = {
4659
+ list(options) {
4660
+ return base.listStorageCatalogs(options);
4661
+ },
4662
+ create(input, options) {
4663
+ return base.createStorageCatalog(input, options);
4664
+ },
4665
+ update(id, input, options) {
4666
+ return base.updateStorageCatalog(id, input, options);
4667
+ },
4668
+ delete(id, options) {
4669
+ return base.deleteStorageCatalog(id, options);
4670
+ }
4671
+ };
4672
+ const folder = {
4673
+ list(input, options) {
4674
+ return callAthena2("/storage/folders/list", "POST", input, options);
4675
+ },
4676
+ tree(input, options) {
4677
+ return callAthena2("/storage/folders/tree", "POST", input, options);
4678
+ },
4679
+ delete(input, options) {
4680
+ return base.deleteStorageFolder(input, options);
4681
+ },
4682
+ move(input, options) {
4683
+ return base.moveStorageFolder(input, options);
4684
+ }
4685
+ };
4686
+ const permission = {
4687
+ list(input, options) {
4688
+ return callAthena2("/storage/permissions/list", "POST", input, options);
4689
+ },
4690
+ grant(input, options) {
4691
+ return callAthena2("/storage/permissions/grant", "POST", input, options);
4692
+ },
4693
+ revoke(input, options) {
4694
+ return callAthena2("/storage/permissions/revoke", "POST", input, options);
4695
+ },
4696
+ check(input, options) {
4697
+ return callAthena2("/storage/permissions/check", "POST", input, options);
4698
+ }
4699
+ };
4700
+ const objectFolder = {
4701
+ create(input, options) {
4702
+ return callAthena2("/storage/objects/folder", "POST", input, options);
4703
+ },
4704
+ delete(input, options) {
4705
+ return callAthena2("/storage/objects/folder/delete", "POST", input, options);
4706
+ },
4707
+ rename(input, options) {
4708
+ return callAthena2("/storage/objects/folder/rename", "POST", input, options);
4709
+ }
4710
+ };
4711
+ const object = {
4712
+ list(input, options) {
4713
+ return callAthena2("/storage/objects", "POST", input, options);
4714
+ },
4715
+ head(input, options) {
4716
+ return callAthena2("/storage/objects/head", "POST", input, options);
4717
+ },
4718
+ exists(input, options) {
4719
+ return callAthena2("/storage/objects/exists", "POST", input, options);
4720
+ },
4721
+ validate(input, options) {
4722
+ return callAthena2("/storage/objects/validate", "POST", input, options);
4723
+ },
4724
+ update(input, options) {
4725
+ return callAthena2("/storage/objects/update", "POST", input, options);
4726
+ },
4727
+ copy(input, options) {
4728
+ return callAthena2("/storage/objects/copy", "POST", input, options);
4729
+ },
4730
+ url(input, options) {
4731
+ return callAthena2("/storage/objects/url", "POST", input, options);
4732
+ },
4733
+ publicUrl(input, options) {
4734
+ return callAthena2("/storage/objects/public-url", "POST", input, options);
4735
+ },
4736
+ delete(input, options) {
4737
+ return callAthena2("/storage/objects/delete", "POST", input, options);
4738
+ },
4739
+ uploadUrl(input, options) {
4740
+ return callAthena2("/storage/objects/upload-url", "POST", input, options);
4741
+ },
4742
+ folder: objectFolder
4743
+ };
4744
+ const bucket = {
4745
+ list(input, options) {
4746
+ return callAthena2("/storage/buckets/list", "POST", input, options);
4747
+ },
4748
+ create(input, options) {
4749
+ return callAthena2("/storage/buckets/create", "POST", input, options);
4750
+ },
4751
+ delete(input, options) {
4752
+ return callAthena2("/storage/buckets/delete", "POST", input, options);
4753
+ },
4754
+ cors: {
4755
+ get(input, options) {
4756
+ return callAthena2("/storage/buckets/cors", "POST", input, options);
4757
+ },
4758
+ set(input, options) {
4759
+ return callAthena2("/storage/buckets/cors/set", "POST", input, options);
4760
+ },
4761
+ delete(input, options) {
4762
+ return callAthena2("/storage/buckets/cors/delete", "POST", input, options);
4763
+ }
4064
4764
  }
4065
4765
  };
4766
+ const multipart = {
4767
+ create(input, options) {
4768
+ return callAthena2("/storage/multipart/create", "POST", input, options);
4769
+ },
4770
+ signPart(input, options) {
4771
+ return callAthena2("/storage/multipart/sign-part", "POST", input, options);
4772
+ },
4773
+ complete(input, options) {
4774
+ return callAthena2("/storage/multipart/complete", "POST", input, options);
4775
+ },
4776
+ abort(input, options) {
4777
+ return callAthena2("/storage/multipart/abort", "POST", input, options);
4778
+ },
4779
+ listParts(input, options) {
4780
+ return callAthena2("/storage/multipart/list-parts", "POST", input, options);
4781
+ }
4782
+ };
4783
+ const audit = {
4784
+ list(input, options) {
4785
+ return callAthena2("/storage/audit/list", "POST", input, options);
4786
+ }
4787
+ };
4788
+ return {
4789
+ ...base,
4790
+ credentials,
4791
+ catalog,
4792
+ file,
4793
+ folder,
4794
+ permission,
4795
+ object,
4796
+ bucket,
4797
+ multipart,
4798
+ audit,
4799
+ delete: file.delete
4800
+ };
4801
+ }
4802
+
4803
+ // src/client-builder.ts
4804
+ var DEFAULT_BACKEND = { type: "athena" };
4805
+ function toBackendConfig(value) {
4806
+ if (!value) return DEFAULT_BACKEND;
4807
+ return typeof value === "string" ? { type: value } : value;
4808
+ }
4809
+ function mergeHeaders(current, next) {
4810
+ return {
4811
+ ...current ?? {},
4812
+ ...next
4813
+ };
4814
+ }
4815
+ function mergeAuthClientConfig(current, next) {
4816
+ const merged = {
4817
+ ...current ?? {},
4818
+ ...next
4819
+ };
4820
+ if (current?.headers || next.headers) {
4821
+ merged.headers = mergeHeaders(current?.headers, next.headers ?? {});
4822
+ }
4823
+ return merged;
4824
+ }
4825
+ function mergeExperimentalOptions(current, next) {
4826
+ const merged = {
4827
+ ...current ?? {},
4828
+ ...next
4829
+ };
4830
+ if (current?.traceQueries && typeof current.traceQueries === "object" && next.traceQueries && typeof next.traceQueries === "object") {
4831
+ merged.traceQueries = {
4832
+ ...current.traceQueries,
4833
+ ...next.traceQueries
4834
+ };
4835
+ }
4836
+ if (current?.storage || next.storage) {
4837
+ merged.storage = {
4838
+ ...current?.storage ?? {},
4839
+ ...next.storage ?? {}
4840
+ };
4841
+ }
4842
+ return merged;
4843
+ }
4844
+ function resolveBuilderReturn(builder, storageEnabled, strictEnabled) {
4845
+ return builder;
4846
+ }
4847
+ var AthenaClientBuilderImpl = class {
4848
+ constructor(buildClient) {
4849
+ this.buildClient = buildClient;
4850
+ }
4851
+ rootUrl;
4852
+ apiKey;
4853
+ backendConfig = DEFAULT_BACKEND;
4854
+ clientName;
4855
+ defaultHeaders;
4856
+ authConfig;
4857
+ dbUrlOverride;
4858
+ gatewayUrlOverride;
4859
+ authUrlOverride;
4860
+ storageUrlOverride;
4861
+ experimentalOptions;
4862
+ url(url) {
4863
+ this.rootUrl = url;
4864
+ return this;
4865
+ }
4866
+ key(apiKey) {
4867
+ this.apiKey = apiKey;
4868
+ return this;
4869
+ }
4870
+ backend(backend) {
4871
+ this.backendConfig = toBackendConfig(backend);
4872
+ return this;
4873
+ }
4874
+ client(clientName) {
4875
+ this.clientName = clientName;
4876
+ return this;
4877
+ }
4878
+ headers(headers) {
4879
+ this.defaultHeaders = headers;
4880
+ return this;
4881
+ }
4882
+ auth(config) {
4883
+ this.authConfig = mergeAuthClientConfig(this.authConfig, config);
4884
+ return this;
4885
+ }
4886
+ experimental(options) {
4887
+ this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options);
4888
+ if (options.athenaStorageBackend && options.typecheckColumns) {
4889
+ return resolveBuilderReturn(this);
4890
+ }
4891
+ if (options.athenaStorageBackend) {
4892
+ return resolveBuilderReturn(this);
4893
+ }
4894
+ if (options.typecheckColumns) {
4895
+ return resolveBuilderReturn(this);
4896
+ }
4897
+ return this;
4898
+ }
4899
+ options(options) {
4900
+ if (options.client !== void 0) {
4901
+ this.clientName = options.client;
4902
+ }
4903
+ if (options.backend !== void 0) {
4904
+ this.backendConfig = toBackendConfig(options.backend);
4905
+ }
4906
+ if (options.headers !== void 0) {
4907
+ this.defaultHeaders = mergeHeaders(this.defaultHeaders, options.headers);
4908
+ }
4909
+ if (options.auth !== void 0) {
4910
+ this.authConfig = mergeAuthClientConfig(this.authConfig, options.auth);
4911
+ }
4912
+ if (options.db?.url !== void 0 && options.db.url !== null) {
4913
+ this.dbUrlOverride = options.db.url;
4914
+ }
4915
+ if (options.gateway?.url !== void 0 && options.gateway.url !== null) {
4916
+ this.gatewayUrlOverride = options.gateway.url;
4917
+ }
4918
+ if (options.dbUrl !== void 0 && options.dbUrl !== null) {
4919
+ this.dbUrlOverride = options.dbUrl;
4920
+ }
4921
+ if (options.gatewayUrl !== void 0 && options.gatewayUrl !== null) {
4922
+ this.gatewayUrlOverride = options.gatewayUrl;
4923
+ }
4924
+ if (options.authUrl !== void 0 && options.authUrl !== null) {
4925
+ this.authUrlOverride = options.authUrl;
4926
+ }
4927
+ if (options.storage?.url !== void 0 && options.storage.url !== null) {
4928
+ this.storageUrlOverride = options.storage.url;
4929
+ }
4930
+ if (options.storageUrl !== void 0 && options.storageUrl !== null) {
4931
+ this.storageUrlOverride = options.storageUrl;
4932
+ }
4933
+ if (options.experimental !== void 0) {
4934
+ this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options.experimental);
4935
+ }
4936
+ if (options.experimental?.athenaStorageBackend && options.experimental.typecheckColumns) {
4937
+ return resolveBuilderReturn(this);
4938
+ }
4939
+ if (options.experimental?.athenaStorageBackend) {
4940
+ return resolveBuilderReturn(this);
4941
+ }
4942
+ if (options.experimental?.typecheckColumns) {
4943
+ return resolveBuilderReturn(this);
4944
+ }
4945
+ return this;
4946
+ }
4947
+ build() {
4948
+ if (!this.rootUrl && !this.dbUrlOverride && !this.gatewayUrlOverride || !this.apiKey) {
4949
+ throw new Error(
4950
+ "AthenaClient requires key plus either .url() or a db/gateway override before .build()"
4951
+ );
4952
+ }
4953
+ return this.buildClient({
4954
+ url: this.rootUrl,
4955
+ key: this.apiKey,
4956
+ client: this.clientName,
4957
+ backend: this.backendConfig,
4958
+ headers: this.defaultHeaders,
4959
+ db: this.dbUrlOverride ? { url: this.dbUrlOverride } : void 0,
4960
+ gateway: this.gatewayUrlOverride ? { url: this.gatewayUrlOverride } : void 0,
4961
+ auth: this.authConfig,
4962
+ authUrl: this.authUrlOverride,
4963
+ storage: this.storageUrlOverride ? { url: this.storageUrlOverride } : void 0,
4964
+ storageUrl: this.storageUrlOverride,
4965
+ experimental: this.experimentalOptions
4966
+ });
4967
+ }
4968
+ };
4969
+ function createAthenaClientBuilder(buildClient) {
4970
+ return new AthenaClientBuilderImpl(buildClient);
4066
4971
  }
4067
4972
 
4068
4973
  // src/query-ast.ts
@@ -4092,7 +4997,7 @@ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
4092
4997
  "ilike",
4093
4998
  "is"
4094
4999
  ]);
4095
- function isRecord6(value) {
5000
+ function isRecord7(value) {
4096
5001
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4097
5002
  }
4098
5003
  function isUuidString(value) {
@@ -4105,7 +5010,7 @@ function shouldUseUuidTextComparison(column, value) {
4105
5010
  return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
4106
5011
  }
4107
5012
  function isRelationSelectNode(value) {
4108
- return isRecord6(value) && isRecord6(value.select);
5013
+ return isRecord7(value) && isRecord7(value.select);
4109
5014
  }
4110
5015
  function normalizeIdentifier(value, label) {
4111
5016
  const normalized = value.trim();
@@ -4161,7 +5066,7 @@ function compileRelationToken(key, node) {
4161
5066
  return `${prefix}${relationToken}(${nested})`;
4162
5067
  }
4163
5068
  function compileSelectShape(select) {
4164
- if (!isRecord6(select)) {
5069
+ if (!isRecord7(select)) {
4165
5070
  throw new Error("findMany select must be an object");
4166
5071
  }
4167
5072
  const tokens = [];
@@ -4185,7 +5090,7 @@ function compileSelectShape(select) {
4185
5090
  return tokens.join(",");
4186
5091
  }
4187
5092
  function selectShapeUsesRelationSchema(select) {
4188
- if (!isRecord6(select)) {
5093
+ if (!isRecord7(select)) {
4189
5094
  return false;
4190
5095
  }
4191
5096
  for (const rawValue of Object.values(select)) {
@@ -4203,7 +5108,7 @@ function selectShapeUsesRelationSchema(select) {
4203
5108
  }
4204
5109
  function compileColumnWhere(column, input) {
4205
5110
  const normalizedColumn = normalizeIdentifier(column, "where column");
4206
- if (!isRecord6(input)) {
5111
+ if (!isRecord7(input)) {
4207
5112
  return [buildGatewayCondition("eq", normalizedColumn, input)];
4208
5113
  }
4209
5114
  const conditions = [];
@@ -4231,7 +5136,7 @@ function compileColumnWhere(column, input) {
4231
5136
  return conditions;
4232
5137
  }
4233
5138
  function compileBooleanExpressionTerms(clause, label) {
4234
- if (!isRecord6(clause)) {
5139
+ if (!isRecord7(clause)) {
4235
5140
  throw new Error(`findMany where.${label} clauses must be objects`);
4236
5141
  }
4237
5142
  const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
@@ -4240,7 +5145,7 @@ function compileBooleanExpressionTerms(clause, label) {
4240
5145
  }
4241
5146
  const [rawColumn, rawValue] = entries[0];
4242
5147
  const column = normalizeIdentifier(rawColumn, `where.${label} column`);
4243
- if (!isRecord6(rawValue)) {
5148
+ if (!isRecord7(rawValue)) {
4244
5149
  return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
4245
5150
  }
4246
5151
  const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
@@ -4264,7 +5169,7 @@ function compileWhere(where) {
4264
5169
  if (where === void 0) {
4265
5170
  return void 0;
4266
5171
  }
4267
- if (!isRecord6(where)) {
5172
+ if (!isRecord7(where)) {
4268
5173
  throw new Error("findMany where must be an object");
4269
5174
  }
4270
5175
  const conditions = [];
@@ -4314,7 +5219,7 @@ function compileOrderBy(orderBy) {
4314
5219
  if (orderBy === void 0) {
4315
5220
  return void 0;
4316
5221
  }
4317
- if (!isRecord6(orderBy)) {
5222
+ if (!isRecord7(orderBy)) {
4318
5223
  throw new Error("findMany orderBy must be an object");
4319
5224
  }
4320
5225
  if ("column" in orderBy) {
@@ -4489,11 +5394,11 @@ function toFindManyAstOrder(order) {
4489
5394
  ascending: order.direction !== "descending"
4490
5395
  };
4491
5396
  }
4492
- function isRecord7(value) {
5397
+ function isRecord8(value) {
4493
5398
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4494
5399
  }
4495
5400
  function normalizeFindManyAstColumnPredicate(value) {
4496
- if (!isRecord7(value)) {
5401
+ if (!isRecord8(value)) {
4497
5402
  return {
4498
5403
  eq: value
4499
5404
  };
@@ -4517,7 +5422,7 @@ function normalizeFindManyAstBooleanOperand(clause) {
4517
5422
  return normalized;
4518
5423
  }
4519
5424
  function normalizeFindManyAstWhere(where) {
4520
- if (!where || !isRecord7(where)) {
5425
+ if (!where || !isRecord8(where)) {
4521
5426
  return where;
4522
5427
  }
4523
5428
  const normalized = {};
@@ -4531,7 +5436,7 @@ function normalizeFindManyAstWhere(where) {
4531
5436
  );
4532
5437
  continue;
4533
5438
  }
4534
- if (key === "not" && isRecord7(value)) {
5439
+ if (key === "not" && isRecord8(value)) {
4535
5440
  normalized.not = normalizeFindManyAstBooleanOperand(
4536
5441
  value
4537
5442
  );
@@ -4542,7 +5447,7 @@ function normalizeFindManyAstWhere(where) {
4542
5447
  return normalized;
4543
5448
  }
4544
5449
  function predicateRequiresUuidQueryFallback(column, value) {
4545
- if (!isRecord7(value)) {
5450
+ if (!isRecord8(value)) {
4546
5451
  return shouldUseUuidTextComparison(column, value);
4547
5452
  }
4548
5453
  const eqValue = value.eq;
@@ -4560,7 +5465,7 @@ function booleanOperandRequiresUuidQueryFallback(clause) {
4560
5465
  return false;
4561
5466
  }
4562
5467
  function findManyAstWhereRequiresLegacyTransport(where) {
4563
- if (!where || !isRecord7(where)) {
5468
+ if (!where || !isRecord8(where)) {
4564
5469
  return false;
4565
5470
  }
4566
5471
  for (const [key, value] of Object.entries(where)) {
@@ -4575,7 +5480,7 @@ function findManyAstWhereRequiresLegacyTransport(where) {
4575
5480
  }
4576
5481
  continue;
4577
5482
  }
4578
- if (key === "not" && isRecord7(value)) {
5483
+ if (key === "not" && isRecord8(value)) {
4579
5484
  if (booleanOperandRequiresUuidQueryFallback(value)) {
4580
5485
  return true;
4581
5486
  }
@@ -4687,161 +5592,258 @@ function createSelectTransportPlan(input) {
4687
5592
  };
4688
5593
  }
4689
5594
 
4690
- // src/client.ts
4691
- var DEFAULT_COLUMNS = "*";
4692
- var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
4693
- var ATHENA_NORMALIZED_ERROR_KEY = "__athenaNormalizedError";
4694
- var QUERY_TRACE_STACK_SKIP_PATTERNS = [
4695
- "src\\client.ts",
4696
- "src/client.ts",
4697
- "dist\\client.",
4698
- "dist/client.",
4699
- "node_modules\\@xylex-group\\athena",
4700
- "node_modules/@xylex-group/athena",
4701
- "node:internal",
4702
- "internal/process"
4703
- ];
4704
- function formatResult(response) {
4705
- const result = {
4706
- data: response.data ?? null,
4707
- error: null,
4708
- errorDetails: response.errorDetails ?? null,
4709
- status: response.status,
4710
- statusText: response.statusText ?? null,
4711
- raw: response.raw
5595
+ // src/query-debug-ast.ts
5596
+ var ATHENA_DEBUG_AST_KEY = "__athenaDebugAst";
5597
+ function cloneConditions(conditions) {
5598
+ return conditions.map((condition) => ({ ...condition }));
5599
+ }
5600
+ function cloneTableBuilderStateAst(state) {
5601
+ return {
5602
+ conditions: cloneConditions(state.conditions),
5603
+ limit: state.limit,
5604
+ offset: state.offset,
5605
+ order: state.order ? { ...state.order } : void 0,
5606
+ currentPage: state.currentPage,
5607
+ pageSize: state.pageSize,
5608
+ totalPages: state.totalPages
4712
5609
  };
4713
- if (response.count !== void 0) {
4714
- result.count = response.count;
5610
+ }
5611
+ function cloneRpcBuilderStateAst(state) {
5612
+ return {
5613
+ filters: state.filters.map((filter) => ({ ...filter })),
5614
+ limit: state.limit,
5615
+ offset: state.offset,
5616
+ order: state.order ? { ...state.order } : void 0
5617
+ };
5618
+ }
5619
+ function toSelectTransportAst(plan) {
5620
+ if (plan.kind === "query") {
5621
+ return {
5622
+ mode: "typed-query",
5623
+ endpoint: "/gateway/query",
5624
+ payload: plan.payload
5625
+ };
4715
5626
  }
4716
- return result;
5627
+ return {
5628
+ mode: plan.payload.select !== void 0 ? "structured-fetch" : "compiled-fetch",
5629
+ endpoint: "/gateway/fetch",
5630
+ payload: plan.payload
5631
+ };
4717
5632
  }
4718
- var EXPERIMENTAL_READ_RETRY_CONFIG = {
4719
- retries: 2,
4720
- baseDelayMs: 100,
4721
- maxDelayMs: 1e3,
4722
- backoff: "exponential",
4723
- jitter: true
4724
- };
4725
- function attachNormalizedError(result, normalizedError) {
4726
- Object.defineProperty(result, ATHENA_NORMALIZED_ERROR_KEY, {
4727
- value: normalizedError,
4728
- enumerable: false,
4729
- configurable: true,
4730
- writable: false
4731
- });
5633
+ function resolveDebugTableName(tableName) {
5634
+ return tableName ?? "__unknown_table__";
4732
5635
  }
4733
- function createResultFormatter(experimental) {
4734
- return (response, context) => {
4735
- const result = formatResult(response);
4736
- if (response.error == null && response.errorDetails == null) {
4737
- return result;
5636
+ function buildSelectDebugAst(input) {
5637
+ return {
5638
+ version: 1,
5639
+ kind: "select",
5640
+ tableName: input.tableName,
5641
+ input: {
5642
+ columns: input.columns,
5643
+ state: cloneTableBuilderStateAst(input.state)
5644
+ },
5645
+ transport: toSelectTransportAst(input.plan)
5646
+ };
5647
+ }
5648
+ function buildFindManyCompiledDebugAst(input) {
5649
+ return {
5650
+ version: 1,
5651
+ kind: "findMany",
5652
+ tableName: input.tableName,
5653
+ input: {
5654
+ select: input.options.select,
5655
+ where: input.options.where,
5656
+ orderBy: input.options.orderBy,
5657
+ limit: input.options.limit
5658
+ },
5659
+ compiled: {
5660
+ columns: input.compiledColumns,
5661
+ baseState: cloneTableBuilderStateAst(input.baseState),
5662
+ executionState: cloneTableBuilderStateAst(input.executionState)
5663
+ },
5664
+ transport: planToFindManyTransport(input.plan)
5665
+ };
5666
+ }
5667
+ function buildFindManyDirectDebugAst(input) {
5668
+ return {
5669
+ version: 1,
5670
+ kind: "findMany",
5671
+ tableName: input.tableName,
5672
+ input: {
5673
+ select: input.options.select,
5674
+ where: input.options.where,
5675
+ orderBy: input.options.orderBy,
5676
+ limit: input.options.limit
5677
+ },
5678
+ compiled: {
5679
+ columns: input.compiledColumns,
5680
+ baseState: cloneTableBuilderStateAst(input.baseState),
5681
+ executionState: cloneTableBuilderStateAst(input.executionState)
5682
+ },
5683
+ transport: {
5684
+ mode: "direct-ast-fetch",
5685
+ endpoint: "/gateway/fetch",
5686
+ payload: input.payload
4738
5687
  }
4739
- const normalizedError = normalizeAthenaError(
4740
- {
4741
- ...result,
4742
- error: response.error ?? response.errorDetails?.message ?? null
4743
- },
4744
- context
4745
- );
4746
- result.error = createResultError(response, result, normalizedError);
4747
- attachNormalizedError(result, normalizedError);
4748
- return result;
4749
5688
  };
4750
5689
  }
4751
- async function executeExperimentalRead(experimental, runner) {
4752
- if (!experimental?.retryReads) {
4753
- return runner();
5690
+ function planToFindManyTransport(plan) {
5691
+ if (plan.kind === "query") {
5692
+ return {
5693
+ mode: "compiled-query",
5694
+ endpoint: "/gateway/query",
5695
+ payload: plan.payload
5696
+ };
4754
5697
  }
4755
- let lastRetryableResult;
4756
- let lastRetrySignal = null;
4757
- try {
4758
- return await withRetry(
4759
- {
4760
- ...EXPERIMENTAL_READ_RETRY_CONFIG,
4761
- shouldRetry: (error) => error === lastRetrySignal || normalizeAthenaError(error).retryable
4762
- },
4763
- async () => {
4764
- const result = await runner();
4765
- if (result.error?.retryable) {
4766
- lastRetryableResult = result;
4767
- lastRetrySignal = result.error;
4768
- throw lastRetrySignal;
4769
- }
4770
- return result;
4771
- }
4772
- );
4773
- } catch (error) {
4774
- if (lastRetryableResult && error === lastRetrySignal) {
4775
- return lastRetryableResult;
5698
+ return {
5699
+ mode: plan.payload.select !== void 0 ? "structured-fetch" : "compiled-fetch",
5700
+ endpoint: "/gateway/fetch",
5701
+ payload: plan.payload
5702
+ };
5703
+ }
5704
+ function buildInsertDebugAst(payload) {
5705
+ return {
5706
+ version: 1,
5707
+ kind: "insert",
5708
+ tableName: payload.table_name,
5709
+ input: {
5710
+ values: payload.insert_body,
5711
+ returning: payload.columns,
5712
+ count: payload.count,
5713
+ head: payload.head,
5714
+ defaultToNull: payload.default_to_null
5715
+ },
5716
+ transport: {
5717
+ mode: "insert",
5718
+ endpoint: "/gateway/insert",
5719
+ payload
4776
5720
  }
4777
- throw error;
4778
- }
5721
+ };
4779
5722
  }
4780
- function isRecord8(value) {
4781
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5723
+ function buildUpsertDebugAst(payload) {
5724
+ return {
5725
+ version: 1,
5726
+ kind: "upsert",
5727
+ tableName: payload.table_name,
5728
+ input: {
5729
+ values: payload.insert_body,
5730
+ updateBody: payload.update_body,
5731
+ onConflict: payload.on_conflict,
5732
+ returning: payload.columns,
5733
+ count: payload.count,
5734
+ head: payload.head,
5735
+ defaultToNull: payload.default_to_null
5736
+ },
5737
+ transport: {
5738
+ mode: "upsert",
5739
+ endpoint: "/gateway/insert",
5740
+ payload
5741
+ }
5742
+ };
4782
5743
  }
4783
- function firstNonEmptyString2(...values) {
4784
- for (const value of values) {
4785
- if (typeof value === "string" && value.trim().length > 0) {
4786
- return value.trim();
5744
+ function buildUpdateDebugAst(input) {
5745
+ return {
5746
+ version: 1,
5747
+ kind: "update",
5748
+ tableName: resolveDebugTableName(input.payload.table_name),
5749
+ input: {
5750
+ values: input.payload.set,
5751
+ state: cloneTableBuilderStateAst(input.state),
5752
+ returning: input.payload.columns
5753
+ },
5754
+ transport: {
5755
+ mode: "update",
5756
+ endpoint: "/gateway/update",
5757
+ payload: input.payload
4787
5758
  }
4788
- }
4789
- return void 0;
5759
+ };
4790
5760
  }
4791
- function resolveStructuredErrorPayload2(raw) {
4792
- if (!isRecord8(raw)) return null;
4793
- return isRecord8(raw.error) ? raw.error : raw;
5761
+ function buildDeleteDebugAst(input) {
5762
+ return {
5763
+ version: 1,
5764
+ kind: "delete",
5765
+ tableName: input.payload.table_name,
5766
+ input: {
5767
+ resourceId: input.payload.resource_id,
5768
+ state: cloneTableBuilderStateAst(input.state),
5769
+ returning: input.payload.columns
5770
+ },
5771
+ transport: {
5772
+ mode: "delete",
5773
+ endpoint: "/gateway/delete",
5774
+ payload: input.payload
5775
+ }
5776
+ };
4794
5777
  }
4795
- function resolveStructuredErrorDetails(payload, message) {
4796
- if (!payload || !("details" in payload)) {
4797
- return null;
5778
+ function buildRpcDebugAst(input) {
5779
+ return {
5780
+ version: 1,
5781
+ kind: "rpc",
5782
+ functionName: input.functionName,
5783
+ input: {
5784
+ args: input.args,
5785
+ select: input.selectedColumns,
5786
+ state: cloneRpcBuilderStateAst(input.state)
5787
+ },
5788
+ transport: {
5789
+ mode: input.endpoint === "/gateway/rpc" ? "rpc-post" : "rpc-get",
5790
+ endpoint: input.endpoint,
5791
+ payload: input.payload
5792
+ }
5793
+ };
5794
+ }
5795
+ function buildRawQueryDebugAst(query) {
5796
+ return {
5797
+ version: 1,
5798
+ kind: "query",
5799
+ input: {
5800
+ query
5801
+ },
5802
+ transport: {
5803
+ mode: "raw-query",
5804
+ endpoint: "/gateway/query",
5805
+ payload: {
5806
+ query
5807
+ }
5808
+ }
5809
+ };
5810
+ }
5811
+ function attachAthenaDebugAst(target, ast) {
5812
+ if (!ast) {
5813
+ return;
4798
5814
  }
4799
- const details = payload.details;
4800
- if (details == null) {
4801
- return null;
5815
+ if (!target || typeof target !== "object" && typeof target !== "function") {
5816
+ return;
4802
5817
  }
4803
- if (typeof details === "string" && details.trim() === message.trim()) {
5818
+ Object.defineProperty(target, ATHENA_DEBUG_AST_KEY, {
5819
+ value: ast,
5820
+ enumerable: false,
5821
+ configurable: true,
5822
+ writable: false
5823
+ });
5824
+ }
5825
+ function getAthenaDebugAst(value) {
5826
+ if (!value || typeof value !== "object" && typeof value !== "function") {
4804
5827
  return null;
4805
5828
  }
4806
- return details;
4807
- }
4808
- function createResultError(response, result, normalized) {
4809
- const rawRecord = isRecord8(response.raw) ? response.raw : null;
4810
- const payload = resolveStructuredErrorPayload2(response.raw);
4811
- const message = firstNonEmptyString2(
4812
- response.error,
4813
- payload?.message,
4814
- payload?.error,
4815
- payload?.details,
4816
- response.errorDetails?.message,
4817
- normalized.message
4818
- ) ?? normalized.message;
4819
- const statusText = firstNonEmptyString2(response.statusText, rawRecord?.statusText) ?? null;
4820
- const hint = firstNonEmptyString2(payload?.hint, response.errorDetails?.hint) ?? null;
4821
- const code = firstNonEmptyString2(payload?.code) ?? normalized.code;
4822
- const details = resolveStructuredErrorDetails(payload, message) ?? response.errorDetails?.cause ?? null;
4823
- return {
4824
- message,
4825
- code,
4826
- athenaCode: normalized.code,
4827
- gatewayCode: response.errorDetails?.code ?? null,
4828
- kind: normalized.kind,
4829
- category: normalized.category,
4830
- retryable: normalized.retryable,
4831
- details,
4832
- hint,
4833
- status: result.status,
4834
- statusText,
4835
- constraint: normalized.constraint,
4836
- table: normalized.table,
4837
- operation: normalized.operation,
4838
- endpoint: response.errorDetails?.endpoint,
4839
- method: response.errorDetails?.method,
4840
- requestId: response.errorDetails?.requestId,
4841
- cause: response.errorDetails?.cause,
4842
- raw: result.raw
4843
- };
5829
+ return value[ATHENA_DEBUG_AST_KEY] ?? null;
4844
5830
  }
5831
+
5832
+ // src/query-tracing.ts
5833
+ var QUERY_TRACE_STACK_SKIP_PATTERNS = [
5834
+ "src\\client.ts",
5835
+ "src/client.ts",
5836
+ "src\\query-tracing.ts",
5837
+ "src/query-tracing.ts",
5838
+ "dist\\client.",
5839
+ "dist/client.",
5840
+ "dist\\query-tracing.",
5841
+ "dist/query-tracing.",
5842
+ "node_modules\\@xylex-group\\athena",
5843
+ "node_modules/@xylex-group/athena",
5844
+ "node:internal",
5845
+ "internal/process"
5846
+ ];
4845
5847
  function parseQueryTraceCallsiteFrame(frame) {
4846
5848
  const trimmed = frame.trim();
4847
5849
  if (!trimmed) {
@@ -4946,6 +5948,7 @@ function createQueryTracer(experimental) {
4946
5948
  functionName: context.functionName,
4947
5949
  sql: context.sql,
4948
5950
  payload: context.payload,
5951
+ ast: context.ast,
4949
5952
  options: context.options,
4950
5953
  callsite,
4951
5954
  outcome: {
@@ -4968,6 +5971,7 @@ function createQueryTracer(experimental) {
4968
5971
  functionName: context.functionName,
4969
5972
  sql: context.sql,
4970
5973
  payload: context.payload,
5974
+ ast: context.ast,
4971
5975
  options: context.options,
4972
5976
  callsite,
4973
5977
  thrownError: error
@@ -4976,20 +5980,196 @@ function createQueryTracer(experimental) {
4976
5980
  };
4977
5981
  }
4978
5982
  async function executeWithQueryTrace(tracer, context, runner, callsiteOverride) {
4979
- if (!tracer) {
4980
- return runner();
4981
- }
4982
- const callsite = callsiteOverride ?? tracer.captureCallsite();
4983
- const startedAt = Date.now();
5983
+ const callsite = tracer ? callsiteOverride ?? tracer.captureCallsite() : null;
5984
+ const startedAt = tracer ? Date.now() : 0;
4984
5985
  try {
4985
5986
  const result = await runner();
4986
- tracer.publishSuccess(context, result, Date.now() - startedAt, callsite);
5987
+ attachAthenaDebugAst(result, context.ast);
5988
+ if (tracer) {
5989
+ tracer.publishSuccess(context, result, Date.now() - startedAt, callsite);
5990
+ }
5991
+ return result;
5992
+ } catch (error) {
5993
+ attachAthenaDebugAst(error, context.ast);
5994
+ if (tracer) {
5995
+ tracer.publishFailure(context, error, Date.now() - startedAt, callsite);
5996
+ }
5997
+ throw error;
5998
+ }
5999
+ }
6000
+
6001
+ // src/schema/model-target.ts
6002
+ function normalizeOptionalName(value) {
6003
+ const normalized = value?.trim();
6004
+ return normalized ? normalized : void 0;
6005
+ }
6006
+ function isAthenaModelTarget(value) {
6007
+ if (!value || typeof value !== "object") {
6008
+ return false;
6009
+ }
6010
+ const candidate = value;
6011
+ return Boolean(candidate.meta && Array.isArray(candidate.meta.primaryKey));
6012
+ }
6013
+ function resolveAthenaModelTargetTableName(target, options = {}) {
6014
+ const explicitTableName = normalizeOptionalName(target.meta.tableName);
6015
+ if (explicitTableName) {
6016
+ return explicitTableName;
6017
+ }
6018
+ const schemaName = normalizeOptionalName(target.meta.schema ?? options.fallbackSchema);
6019
+ const modelName = normalizeOptionalName(target.meta.model ?? options.fallbackModel);
6020
+ if (!modelName) {
6021
+ throw new Error(
6022
+ "Athena model target is missing meta.model or meta.tableName. Provide one of those before calling from(model)."
6023
+ );
6024
+ }
6025
+ return schemaName ? `${schemaName}.${modelName}` : modelName;
6026
+ }
6027
+
6028
+ // src/client.ts
6029
+ var DEFAULT_COLUMNS = "*";
6030
+ var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
6031
+ var ATHENA_NORMALIZED_ERROR_KEY = "__athenaNormalizedError";
6032
+ function formatResult(response) {
6033
+ const result = {
6034
+ data: response.data ?? null,
6035
+ error: null,
6036
+ errorDetails: response.errorDetails ?? null,
6037
+ status: response.status,
6038
+ statusText: response.statusText ?? null,
6039
+ raw: response.raw
6040
+ };
6041
+ if (response.count !== void 0) {
6042
+ result.count = response.count;
6043
+ }
6044
+ return result;
6045
+ }
6046
+ var EXPERIMENTAL_READ_RETRY_CONFIG = {
6047
+ retries: 2,
6048
+ baseDelayMs: 100,
6049
+ maxDelayMs: 1e3,
6050
+ backoff: "exponential",
6051
+ jitter: true
6052
+ };
6053
+ function attachNormalizedError(result, normalizedError) {
6054
+ Object.defineProperty(result, ATHENA_NORMALIZED_ERROR_KEY, {
6055
+ value: normalizedError,
6056
+ enumerable: false,
6057
+ configurable: true,
6058
+ writable: false
6059
+ });
6060
+ }
6061
+ function createResultFormatter(experimental) {
6062
+ return (response, context) => {
6063
+ const result = formatResult(response);
6064
+ if (response.error == null && response.errorDetails == null) {
6065
+ return result;
6066
+ }
6067
+ const normalizedError = normalizeAthenaError(
6068
+ {
6069
+ ...result,
6070
+ error: response.error ?? response.errorDetails?.message ?? null
6071
+ },
6072
+ context
6073
+ );
6074
+ result.error = createResultError(response, result, normalizedError);
6075
+ attachNormalizedError(result, normalizedError);
4987
6076
  return result;
6077
+ };
6078
+ }
6079
+ async function executeExperimentalRead(experimental, runner) {
6080
+ if (!experimental?.retryReads) {
6081
+ return runner();
6082
+ }
6083
+ let lastRetryableResult;
6084
+ let lastRetrySignal = null;
6085
+ try {
6086
+ return await withRetry(
6087
+ {
6088
+ ...EXPERIMENTAL_READ_RETRY_CONFIG,
6089
+ shouldRetry: (error) => error === lastRetrySignal || normalizeAthenaError(error).retryable
6090
+ },
6091
+ async () => {
6092
+ const result = await runner();
6093
+ if (result.error?.retryable) {
6094
+ lastRetryableResult = result;
6095
+ lastRetrySignal = result.error;
6096
+ throw lastRetrySignal;
6097
+ }
6098
+ return result;
6099
+ }
6100
+ );
4988
6101
  } catch (error) {
4989
- tracer.publishFailure(context, error, Date.now() - startedAt, callsite);
6102
+ if (lastRetryableResult && error === lastRetrySignal) {
6103
+ return lastRetryableResult;
6104
+ }
4990
6105
  throw error;
4991
6106
  }
4992
6107
  }
6108
+ function isRecord9(value) {
6109
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6110
+ }
6111
+ function firstNonEmptyString2(...values) {
6112
+ for (const value of values) {
6113
+ if (typeof value === "string" && value.trim().length > 0) {
6114
+ return value.trim();
6115
+ }
6116
+ }
6117
+ return void 0;
6118
+ }
6119
+ function resolveStructuredErrorPayload2(raw) {
6120
+ if (!isRecord9(raw)) return null;
6121
+ return isRecord9(raw.error) ? raw.error : raw;
6122
+ }
6123
+ function resolveStructuredErrorDetails(payload, message) {
6124
+ if (!payload || !("details" in payload)) {
6125
+ return null;
6126
+ }
6127
+ const details = payload.details;
6128
+ if (details == null) {
6129
+ return null;
6130
+ }
6131
+ if (typeof details === "string" && details.trim() === message.trim()) {
6132
+ return null;
6133
+ }
6134
+ return details;
6135
+ }
6136
+ function createResultError(response, result, normalized) {
6137
+ const rawRecord = isRecord9(response.raw) ? response.raw : null;
6138
+ const payload = resolveStructuredErrorPayload2(response.raw);
6139
+ const message = firstNonEmptyString2(
6140
+ response.error,
6141
+ payload?.message,
6142
+ payload?.error,
6143
+ payload?.details,
6144
+ response.errorDetails?.message,
6145
+ normalized.message
6146
+ ) ?? normalized.message;
6147
+ const statusText = firstNonEmptyString2(response.statusText, rawRecord?.statusText) ?? null;
6148
+ const hint = firstNonEmptyString2(payload?.hint, response.errorDetails?.hint) ?? null;
6149
+ const code = firstNonEmptyString2(payload?.code) ?? normalized.code;
6150
+ const details = resolveStructuredErrorDetails(payload, message) ?? response.errorDetails?.cause ?? null;
6151
+ return {
6152
+ message,
6153
+ code,
6154
+ athenaCode: normalized.code,
6155
+ gatewayCode: response.errorDetails?.code ?? null,
6156
+ kind: normalized.kind,
6157
+ category: normalized.category,
6158
+ retryable: normalized.retryable,
6159
+ details,
6160
+ hint,
6161
+ status: result.status,
6162
+ statusText,
6163
+ constraint: normalized.constraint,
6164
+ table: normalized.table,
6165
+ operation: normalized.operation,
6166
+ endpoint: response.errorDetails?.endpoint,
6167
+ method: response.errorDetails?.method,
6168
+ requestId: response.errorDetails?.requestId,
6169
+ cause: response.errorDetails?.cause,
6170
+ raw: result.raw
6171
+ };
6172
+ }
4993
6173
  function toSingleResult(response) {
4994
6174
  const payload = response.data;
4995
6175
  const singleData = Array.isArray(payload) ? payload.length ? payload[0] : null : payload ?? null;
@@ -5017,6 +6197,15 @@ function asAthenaJsonObject(value) {
5017
6197
  function asAthenaJsonObjectArray(values) {
5018
6198
  return values;
5019
6199
  }
6200
+ function normalizeSelectColumnsInput(columns) {
6201
+ if (columns === void 0) {
6202
+ return void 0;
6203
+ }
6204
+ if (typeof columns === "string") {
6205
+ return columns;
6206
+ }
6207
+ return [...columns];
6208
+ }
5020
6209
  function createMutationQuery(executor, defaultColumns = DEFAULT_COLUMNS, tracer, initialCallsite) {
5021
6210
  let selectedColumns = defaultColumns === null ? void 0 : defaultColumns;
5022
6211
  let selectedOptions;
@@ -5026,25 +6215,29 @@ function createMutationQuery(executor, defaultColumns = DEFAULT_COLUMNS, tracer,
5026
6215
  const payloadColumns = columns ?? selectedColumns;
5027
6216
  const payloadOptions = options ?? selectedOptions;
5028
6217
  if (!promise) {
5029
- promise = executor(payloadColumns, payloadOptions, callsiteStore.resolve(callsite));
6218
+ promise = executor(
6219
+ normalizeSelectColumnsInput(payloadColumns),
6220
+ payloadOptions,
6221
+ callsiteStore.resolve(callsite)
6222
+ );
5030
6223
  }
5031
6224
  return promise;
5032
6225
  };
5033
6226
  const mutationQuery = {
5034
- select(columns = selectedColumns, options) {
6227
+ select(columns, options) {
5035
6228
  selectedColumns = columns;
5036
6229
  selectedOptions = options ?? selectedOptions;
5037
6230
  return run(columns, options, captureTraceCallsite(tracer));
5038
6231
  },
5039
- returning(columns = selectedColumns, options) {
6232
+ returning(columns, options) {
5040
6233
  return mutationQuery.select(columns, options);
5041
6234
  },
5042
- single(columns = selectedColumns, options) {
6235
+ single(columns, options) {
5043
6236
  selectedColumns = columns;
5044
6237
  selectedOptions = options ?? selectedOptions;
5045
6238
  return run(columns, options, captureTraceCallsite(tracer)).then(toSingleResult);
5046
6239
  },
5047
- maybeSingle(columns = selectedColumns, options) {
6240
+ maybeSingle(columns, options) {
5048
6241
  return mutationQuery.single(columns, options);
5049
6242
  },
5050
6243
  then(onfulfilled, onrejected) {
@@ -5601,7 +6794,10 @@ function createFilterMethods(state, addCondition, self) {
5601
6794
  }
5602
6795
  function toRpcSelect(columns) {
5603
6796
  if (!columns) return void 0;
5604
- return Array.isArray(columns) ? columns.join(",") : columns;
6797
+ if (typeof columns === "string") {
6798
+ return columns;
6799
+ }
6800
+ return columns.join(",");
5605
6801
  }
5606
6802
  function createRpcFilterMethods(filters, self) {
5607
6803
  const addFilter = (operator, column, value) => {
@@ -5650,7 +6846,7 @@ function createRpcFilterMethods(filters, self) {
5650
6846
  }
5651
6847
  };
5652
6848
  }
5653
- function createRpcBuilder(functionName, args, baseOptions, client, formatGatewayResult, tracer, initialCallsite) {
6849
+ function createRpcBuilder(functionName, args, baseOptions, client, formatGatewayResult, tracer, initialCallsite, debugAstEnabled = false) {
5654
6850
  const state = {
5655
6851
  filters: []
5656
6852
  };
@@ -5660,6 +6856,7 @@ function createRpcBuilder(functionName, args, baseOptions, client, formatGateway
5660
6856
  const callsiteStore = createTraceCallsiteStore(tracer, initialCallsite);
5661
6857
  const executeRpc = async (columns, options, callsite) => {
5662
6858
  const mergedOptions = mergeOptions(baseOptions, options);
6859
+ const normalizedSelectedColumns = normalizeSelectColumnsInput(columns);
5663
6860
  const payload = {
5664
6861
  function: functionName,
5665
6862
  args,
@@ -5674,6 +6871,14 @@ function createRpcBuilder(functionName, args, baseOptions, client, formatGateway
5674
6871
  };
5675
6872
  const endpoint = mergedOptions?.get ? `/rpc/${functionName}` : "/gateway/rpc";
5676
6873
  const sql = buildRpcDebugSql(payload);
6874
+ const debugAst = debugAstEnabled ? buildRpcDebugAst({
6875
+ functionName,
6876
+ args,
6877
+ selectedColumns: normalizedSelectedColumns,
6878
+ state,
6879
+ payload,
6880
+ endpoint
6881
+ }) : void 0;
5677
6882
  return executeWithQueryTrace(
5678
6883
  tracer,
5679
6884
  {
@@ -5682,6 +6887,7 @@ function createRpcBuilder(functionName, args, baseOptions, client, formatGateway
5682
6887
  functionName,
5683
6888
  sql,
5684
6889
  payload,
6890
+ ast: debugAst,
5685
6891
  options: mergedOptions
5686
6892
  },
5687
6893
  async () => {
@@ -5702,7 +6908,7 @@ function createRpcBuilder(functionName, args, baseOptions, client, formatGateway
5702
6908
  const builder = {};
5703
6909
  const filterMethods = createRpcFilterMethods(state.filters, builder);
5704
6910
  Object.assign(builder, filterMethods, {
5705
- select(columns = selectedColumns, options) {
6911
+ select(columns, options) {
5706
6912
  selectedColumns = columns;
5707
6913
  selectedOptions = options ?? selectedOptions;
5708
6914
  return run(columns, options, captureTraceCallsite(tracer));
@@ -5747,6 +6953,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5747
6953
  const state = {
5748
6954
  conditions: []
5749
6955
  };
6956
+ const debugAstEnabled = Boolean(experimental?.debugAst);
5750
6957
  const addCondition = (operator, column, value, hints) => {
5751
6958
  const condition = { operator };
5752
6959
  if (column) {
@@ -5790,15 +6997,27 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5790
6997
  addCondition,
5791
6998
  builder
5792
6999
  );
5793
- const runSelect = async (columns = DEFAULT_COLUMNS, options, executionState = snapshotState(), callsite) => {
7000
+ const runSelect = async (columns = DEFAULT_COLUMNS, options, executionState = snapshotState(), callsite, debugAstFactory) => {
7001
+ const runtimeColumns = normalizeSelectColumnsInput(columns) ?? DEFAULT_COLUMNS;
5794
7002
  const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
5795
7003
  const plan = createSelectTransportPlan({
5796
7004
  tableName: resolvedTableName,
5797
- columns,
7005
+ columns: runtimeColumns,
5798
7006
  state: executionState,
5799
7007
  options,
5800
7008
  buildTypedSelectQuery
5801
7009
  });
7010
+ const debugAst = debugAstEnabled ? debugAstFactory?.({
7011
+ tableName: resolvedTableName,
7012
+ columns: runtimeColumns,
7013
+ executionState,
7014
+ plan
7015
+ }) ?? buildSelectDebugAst({
7016
+ tableName: resolvedTableName,
7017
+ columns: runtimeColumns,
7018
+ state: executionState,
7019
+ plan
7020
+ }) : void 0;
5802
7021
  if (plan.kind === "query") {
5803
7022
  return executeExperimentalRead(
5804
7023
  experimental,
@@ -5810,6 +7029,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5810
7029
  table: resolvedTableName,
5811
7030
  sql: plan.query,
5812
7031
  payload: plan.payload,
7032
+ ast: debugAst,
5813
7033
  options
5814
7034
  },
5815
7035
  async () => {
@@ -5834,6 +7054,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5834
7054
  table: resolvedTableName,
5835
7055
  sql,
5836
7056
  payload: plan.payload,
7057
+ ast: debugAst,
5837
7058
  options
5838
7059
  },
5839
7060
  async () => {
@@ -5847,7 +7068,11 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5847
7068
  const createSelectChain = (columns, options, initialCallsite) => {
5848
7069
  const chain = {};
5849
7070
  const callsiteStore = createTraceCallsiteStore(tracer, initialCallsite);
5850
- const filterMethods2 = createFilterMethods(state, addCondition, chain);
7071
+ const filterMethods2 = createFilterMethods(
7072
+ state,
7073
+ addCondition,
7074
+ chain
7075
+ );
5851
7076
  Object.assign(chain, filterMethods2, {
5852
7077
  async single(cols, opts) {
5853
7078
  const r = await runSelect(
@@ -5934,6 +7159,14 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5934
7159
  limit: executionState.limit,
5935
7160
  order: executionState.order
5936
7161
  });
7162
+ const debugAst = debugAstEnabled ? buildFindManyDirectDebugAst({
7163
+ tableName: resolvedTableName,
7164
+ options,
7165
+ compiledColumns: columns,
7166
+ baseState,
7167
+ executionState,
7168
+ payload
7169
+ }) : void 0;
5937
7170
  return executeExperimentalRead(
5938
7171
  experimental,
5939
7172
  () => executeWithQueryTrace(
@@ -5943,7 +7176,8 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5943
7176
  endpoint: "/gateway/fetch",
5944
7177
  table: resolvedTableName,
5945
7178
  sql,
5946
- payload
7179
+ payload,
7180
+ ast: debugAst
5947
7181
  },
5948
7182
  async () => {
5949
7183
  const response = await client.fetchGateway(
@@ -5959,7 +7193,15 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5959
7193
  columns,
5960
7194
  void 0,
5961
7195
  executionState,
5962
- callsite
7196
+ callsite,
7197
+ debugAstEnabled ? ({ tableName: resolvedTableName, executionState: tracedState, plan }) => buildFindManyCompiledDebugAst({
7198
+ tableName: resolvedTableName,
7199
+ options,
7200
+ compiledColumns: columns,
7201
+ baseState,
7202
+ executionState: tracedState,
7203
+ plan
7204
+ }) : void 0
5963
7205
  );
5964
7206
  },
5965
7207
  insert(values, options) {
@@ -5979,6 +7221,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5979
7221
  payload.default_to_null = mergedOptions.defaultToNull;
5980
7222
  }
5981
7223
  const sql = buildInsertDebugSql(payload);
7224
+ const debugAst = debugAstEnabled ? buildInsertDebugAst(payload) : void 0;
5982
7225
  return executeWithQueryTrace(
5983
7226
  tracer,
5984
7227
  {
@@ -5987,6 +7230,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5987
7230
  table: resolvedTableName,
5988
7231
  sql,
5989
7232
  payload,
7233
+ ast: debugAst,
5990
7234
  options: mergedOptions
5991
7235
  },
5992
7236
  async () => {
@@ -6012,6 +7256,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6012
7256
  payload.default_to_null = mergedOptions.defaultToNull;
6013
7257
  }
6014
7258
  const sql = buildInsertDebugSql(payload);
7259
+ const debugAst = debugAstEnabled ? buildInsertDebugAst(payload) : void 0;
6015
7260
  return executeWithQueryTrace(
6016
7261
  tracer,
6017
7262
  {
@@ -6020,6 +7265,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6020
7265
  table: resolvedTableName,
6021
7266
  sql,
6022
7267
  payload,
7268
+ ast: debugAst,
6023
7269
  options: mergedOptions
6024
7270
  },
6025
7271
  async () => {
@@ -6050,6 +7296,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6050
7296
  payload.default_to_null = mergedOptions.defaultToNull;
6051
7297
  }
6052
7298
  const sql = buildInsertDebugSql(payload);
7299
+ const debugAst = debugAstEnabled ? buildUpsertDebugAst(payload) : void 0;
6053
7300
  return executeWithQueryTrace(
6054
7301
  tracer,
6055
7302
  {
@@ -6058,6 +7305,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6058
7305
  table: resolvedTableName,
6059
7306
  sql,
6060
7307
  payload,
7308
+ ast: debugAst,
6061
7309
  options: mergedOptions
6062
7310
  },
6063
7311
  async () => {
@@ -6085,6 +7333,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6085
7333
  payload.default_to_null = mergedOptions.defaultToNull;
6086
7334
  }
6087
7335
  const sql = buildInsertDebugSql(payload);
7336
+ const debugAst = debugAstEnabled ? buildUpsertDebugAst(payload) : void 0;
6088
7337
  return executeWithQueryTrace(
6089
7338
  tracer,
6090
7339
  {
@@ -6093,6 +7342,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6093
7342
  table: resolvedTableName,
6094
7343
  sql,
6095
7344
  payload,
7345
+ ast: debugAst,
6096
7346
  options: mergedOptions
6097
7347
  },
6098
7348
  async () => {
@@ -6107,7 +7357,8 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6107
7357
  update(values, options) {
6108
7358
  const mutationCallsite = captureTraceCallsite(tracer);
6109
7359
  const executeUpdate = async (columns, selectOptions, callsite) => {
6110
- const filters = state.conditions.length ? [...state.conditions] : void 0;
7360
+ const executionState = snapshotState();
7361
+ const filters = executionState.conditions.length ? [...executionState.conditions] : void 0;
6111
7362
  const mergedOptions = mergeOptions(options, selectOptions);
6112
7363
  const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
6113
7364
  const payload = {
@@ -6116,12 +7367,16 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6116
7367
  conditions: filters,
6117
7368
  strip_nulls: mergedOptions?.stripNulls ?? true
6118
7369
  };
6119
- if (state.order) payload.sort_by = state.order;
6120
- if (state.currentPage !== void 0) payload.current_page = state.currentPage;
6121
- if (state.pageSize !== void 0) payload.page_size = state.pageSize;
6122
- if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
7370
+ if (executionState.order) payload.sort_by = executionState.order;
7371
+ if (executionState.currentPage !== void 0) payload.current_page = executionState.currentPage;
7372
+ if (executionState.pageSize !== void 0) payload.page_size = executionState.pageSize;
7373
+ if (executionState.totalPages !== void 0) payload.total_pages = executionState.totalPages;
6123
7374
  if (columns) payload.columns = columns;
6124
7375
  const sql = buildUpdateDebugSql(payload);
7376
+ const debugAst = debugAstEnabled ? buildUpdateDebugAst({
7377
+ state: executionState,
7378
+ payload
7379
+ }) : void 0;
6125
7380
  return executeWithQueryTrace(
6126
7381
  tracer,
6127
7382
  {
@@ -6130,6 +7385,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6130
7385
  table: resolvedTableName,
6131
7386
  sql,
6132
7387
  payload,
7388
+ ast: debugAst,
6133
7389
  options: mergedOptions
6134
7390
  },
6135
7391
  async () => {
@@ -6153,6 +7409,11 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6153
7409
  }
6154
7410
  const mutationCallsite = captureTraceCallsite(tracer);
6155
7411
  const executeDelete = async (columns, selectOptions, callsite) => {
7412
+ const executionState = snapshotState();
7413
+ const debugState = {
7414
+ ...executionState,
7415
+ conditions: filters ? filters.map((condition) => ({ ...condition })) : []
7416
+ };
6156
7417
  const mergedOptions = mergeOptions(options, selectOptions);
6157
7418
  const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
6158
7419
  const payload = {
@@ -6160,12 +7421,16 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6160
7421
  resource_id: resourceId,
6161
7422
  conditions: filters
6162
7423
  };
6163
- if (state.order) payload.sort_by = state.order;
6164
- if (state.currentPage !== void 0) payload.current_page = state.currentPage;
6165
- if (state.pageSize !== void 0) payload.page_size = state.pageSize;
6166
- if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
7424
+ if (executionState.order) payload.sort_by = executionState.order;
7425
+ if (executionState.currentPage !== void 0) payload.current_page = executionState.currentPage;
7426
+ if (executionState.pageSize !== void 0) payload.page_size = executionState.pageSize;
7427
+ if (executionState.totalPages !== void 0) payload.total_pages = executionState.totalPages;
6167
7428
  if (columns) payload.columns = columns;
6168
7429
  const sql = buildDeleteDebugSql(payload);
7430
+ const debugAst = debugAstEnabled ? buildDeleteDebugAst({
7431
+ state: debugState,
7432
+ payload
7433
+ }) : void 0;
6169
7434
  return executeWithQueryTrace(
6170
7435
  tracer,
6171
7436
  {
@@ -6174,6 +7439,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6174
7439
  table: resolvedTableName,
6175
7440
  sql,
6176
7441
  payload,
7442
+ ast: debugAst,
6177
7443
  options: mergedOptions
6178
7444
  },
6179
7445
  async () => {
@@ -6201,6 +7467,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
6201
7467
  return builder;
6202
7468
  }
6203
7469
  function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
7470
+ const debugAstEnabled = Boolean(experimental?.debugAst);
6204
7471
  return async function query(query, options) {
6205
7472
  const normalizedQuery = query.trim();
6206
7473
  if (!normalizedQuery) {
@@ -6217,6 +7484,7 @@ function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
6217
7484
  endpoint: "/gateway/query",
6218
7485
  sql: normalizedQuery,
6219
7486
  payload,
7487
+ ast: debugAstEnabled ? buildRawQueryDebugAst(normalizedQuery) : void 0,
6220
7488
  options
6221
7489
  },
6222
7490
  async () => {
@@ -6228,6 +7496,63 @@ function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
6228
7496
  );
6229
7497
  };
6230
7498
  }
7499
+ function resolveClientServiceBaseUrl(value, label) {
7500
+ if (value === void 0 || value === null) {
7501
+ return void 0;
7502
+ }
7503
+ return normalizeAthenaGatewayBaseUrl(value, { label });
7504
+ }
7505
+ function appendServicePath(baseUrl, segment) {
7506
+ const normalizedBaseUrl = normalizeAthenaGatewayBaseUrl(baseUrl, { label: "Athena public base URL" });
7507
+ return `${normalizedBaseUrl}/${segment.replace(/^\/+/, "")}`;
7508
+ }
7509
+ function resolveServiceUrlOverride(value, label) {
7510
+ return resolveClientServiceBaseUrl(value, label);
7511
+ }
7512
+ function resolveServiceUrls(config) {
7513
+ const baseUrl = resolveClientServiceBaseUrl(config.url, "Athena public base URL");
7514
+ return {
7515
+ dbUrl: resolveServiceUrlOverride(config.db?.url, "Athena DB base URL") ?? resolveServiceUrlOverride(config.gateway?.url, "Athena gateway base URL") ?? resolveServiceUrlOverride(config.dbUrl, "Athena DB base URL") ?? resolveServiceUrlOverride(config.gatewayUrl, "Athena gateway base URL") ?? (baseUrl ? appendServicePath(baseUrl, "db") : void 0),
7516
+ authUrl: resolveServiceUrlOverride(config.auth?.url, "Athena auth base URL") ?? resolveServiceUrlOverride(config.auth?.baseUrl, "Athena auth base URL") ?? resolveServiceUrlOverride(config.authUrl, "Athena auth base URL") ?? (baseUrl ? appendServicePath(baseUrl, "auth") : void 0),
7517
+ storageUrl: resolveServiceUrlOverride(config.storage?.url, "Athena storage base URL") ?? resolveServiceUrlOverride(config.storageUrl, "Athena storage base URL") ?? (baseUrl ? appendServicePath(baseUrl, "storage") : void 0)
7518
+ };
7519
+ }
7520
+ function normalizeAuthClientConfig(auth, defaultBaseUrl) {
7521
+ if (!auth && defaultBaseUrl === void 0) {
7522
+ return void 0;
7523
+ }
7524
+ const { url, ...rest } = auth ?? {};
7525
+ const normalized = {
7526
+ ...rest
7527
+ };
7528
+ const resolvedBaseUrl = resolveClientServiceBaseUrl(
7529
+ url ?? rest.baseUrl ?? defaultBaseUrl,
7530
+ "Athena auth base URL"
7531
+ );
7532
+ if (resolvedBaseUrl !== void 0) {
7533
+ normalized.baseUrl = resolvedBaseUrl;
7534
+ }
7535
+ return normalized;
7536
+ }
7537
+ function resolveCreateClientConfig(config) {
7538
+ const resolvedUrls = resolveServiceUrls(config);
7539
+ if (!resolvedUrls.dbUrl) {
7540
+ throw new Error(
7541
+ "Athena DB base URL is required. Pass createClient(url, key) for a unified root, or set db.url / gateway.url / gatewayUrl explicitly."
7542
+ );
7543
+ }
7544
+ return {
7545
+ baseUrl: resolvedUrls.dbUrl,
7546
+ apiKey: config.key,
7547
+ client: config.client,
7548
+ backend: toBackendConfig(config.backend),
7549
+ headers: config.headers,
7550
+ auth: config.auth,
7551
+ authUrl: resolvedUrls.authUrl,
7552
+ storageUrl: resolvedUrls.storageUrl,
7553
+ experimental: config.experimental
7554
+ };
7555
+ }
6231
7556
  function createClientFromConfig(config) {
6232
7557
  const gatewayHeaders = {
6233
7558
  ...config.headers ?? {}
@@ -6244,14 +7569,31 @@ function createClientFromConfig(config) {
6244
7569
  });
6245
7570
  const formatGatewayResult = createResultFormatter(config.experimental);
6246
7571
  const queryTracer = createQueryTracer(config.experimental);
6247
- const auth = createAuthClient(config.auth);
6248
- const from = (table, options) => createTableBuilder(
6249
- resolveTableNameForCall(table, options?.schema),
6250
- gateway,
6251
- formatGatewayResult,
6252
- queryTracer,
6253
- config.experimental
6254
- );
7572
+ const auth = createAuthClient(normalizeAuthClientConfig(config.auth, config.authUrl));
7573
+ function from(tableOrModel, options) {
7574
+ if (isAthenaModelTarget(tableOrModel)) {
7575
+ if (options?.schema !== void 0) {
7576
+ throw new Error(
7577
+ "from(model) does not accept a schema override because the model already defines its target."
7578
+ );
7579
+ }
7580
+ return createTableBuilder(
7581
+ resolveAthenaModelTargetTableName(tableOrModel),
7582
+ gateway,
7583
+ formatGatewayResult,
7584
+ queryTracer,
7585
+ config.experimental
7586
+ );
7587
+ }
7588
+ const resolvedTableName = resolveTableNameForCall(tableOrModel, options?.schema);
7589
+ return createTableBuilder(
7590
+ resolvedTableName,
7591
+ gateway,
7592
+ formatGatewayResult,
7593
+ queryTracer,
7594
+ config.experimental
7595
+ );
7596
+ }
6255
7597
  const rpc = (fn, args, options) => {
6256
7598
  const normalizedFn = fn.trim();
6257
7599
  if (!normalizedFn) {
@@ -6264,10 +7606,16 @@ function createClientFromConfig(config) {
6264
7606
  gateway,
6265
7607
  formatGatewayResult,
6266
7608
  queryTracer,
6267
- captureTraceCallsite(queryTracer)
7609
+ captureTraceCallsite(queryTracer),
7610
+ Boolean(config.experimental?.debugAst)
6268
7611
  );
6269
7612
  };
6270
- const query = createQueryBuilder(gateway, formatGatewayResult, config.experimental, queryTracer);
7613
+ const query = createQueryBuilder(
7614
+ gateway,
7615
+ formatGatewayResult,
7616
+ config.experimental,
7617
+ queryTracer
7618
+ );
6271
7619
  const db = createDbModule({ from, rpc, query });
6272
7620
  const sdkClient = {
6273
7621
  from,
@@ -6280,170 +7628,448 @@ function createClientFromConfig(config) {
6280
7628
  if (config.experimental?.athenaStorageBackend) {
6281
7629
  const storageClient = {
6282
7630
  ...sdkClient,
6283
- storage: createStorageModule(gateway, config.experimental.storage)
7631
+ storage: createStorageModule(gateway, {
7632
+ ...config.experimental.storage,
7633
+ ...config.storageUrl ? {
7634
+ baseUrl: config.storageUrl,
7635
+ stripBasePath: true
7636
+ } : {}
7637
+ })
6284
7638
  };
6285
7639
  return storageClient;
6286
7640
  }
6287
7641
  return sdkClient;
6288
7642
  }
6289
- var DEFAULT_BACKEND = { type: "athena" };
6290
- function toBackendConfig(b) {
6291
- if (!b) return DEFAULT_BACKEND;
6292
- return typeof b === "string" ? { type: b } : b;
6293
- }
6294
- function mergeAuthClientConfig(current, next) {
6295
- const merged = {
6296
- ...current ?? {},
6297
- ...next
6298
- };
6299
- if (current?.headers || next.headers) {
6300
- merged.headers = {
6301
- ...current?.headers ?? {},
6302
- ...next.headers ?? {}
6303
- };
7643
+ var AthenaClient = class {
7644
+ /** Create a fluent builder for a strongly-typed Athena SDK client. */
7645
+ static builder() {
7646
+ return createAthenaClientBuilder((config) => createClientFromConfig(resolveCreateClientConfig(config)));
6304
7647
  }
6305
- return merged;
6306
- }
6307
- function mergeExperimentalOptions(current, next) {
6308
- const merged = {
6309
- ...current ?? {},
6310
- ...next
6311
- };
6312
- if (current?.traceQueries && typeof current.traceQueries === "object" && next.traceQueries && typeof next.traceQueries === "object") {
6313
- merged.traceQueries = {
6314
- ...current.traceQueries,
6315
- ...next.traceQueries
6316
- };
7648
+ /** Build a client from process environment variables. */
7649
+ static fromEnvironment() {
7650
+ const url = process.env.ATHENA_URL;
7651
+ const gatewayUrl = process.env.ATHENA_DB_URL ?? process.env.ATHENA_GATEWAY_URL;
7652
+ const authUrl = process.env.ATHENA_AUTH_URL;
7653
+ const storageUrl = process.env.ATHENA_STORAGE_URL;
7654
+ const key = process.env.ATHENA_API_KEY ?? process.env.ATHENA_GATEWAY_API_KEY;
7655
+ if (!url && !gatewayUrl || !key) {
7656
+ throw new Error(
7657
+ "ATHENA_API_KEY plus ATHENA_URL or ATHENA_GATEWAY_URL (optionally ATHENA_DB_URL, ATHENA_AUTH_URL, ATHENA_STORAGE_URL) are required"
7658
+ );
7659
+ }
7660
+ return createClient({
7661
+ url,
7662
+ gatewayUrl,
7663
+ authUrl,
7664
+ storageUrl,
7665
+ key
7666
+ });
6317
7667
  }
6318
- if (current?.storage || next.storage) {
6319
- merged.storage = {
6320
- ...current?.storage ?? {},
6321
- ...next.storage ?? {}
6322
- };
7668
+ };
7669
+ function createClient(configOrUrl, apiKey, options) {
7670
+ if (typeof configOrUrl === "string") {
7671
+ return createClientFromConfig(resolveCreateClientConfig({
7672
+ url: configOrUrl,
7673
+ key: apiKey ?? "",
7674
+ ...options
7675
+ }));
6323
7676
  }
6324
- return merged;
7677
+ return createClientFromConfig(resolveCreateClientConfig(configOrUrl));
6325
7678
  }
6326
- var AthenaClientBuilderImpl = class {
6327
- baseUrl;
6328
- apiKey;
6329
- backendConfig = DEFAULT_BACKEND;
6330
- clientName;
6331
- defaultHeaders;
6332
- authConfig;
6333
- experimentalOptions;
6334
- url(url) {
6335
- this.baseUrl = url;
6336
- return this;
6337
- }
6338
- key(apiKey) {
6339
- this.apiKey = apiKey;
6340
- return this;
6341
- }
6342
- backend(backend) {
6343
- this.backendConfig = toBackendConfig(backend);
6344
- return this;
6345
- }
6346
- client(clientName) {
6347
- this.clientName = clientName;
6348
- return this;
6349
- }
6350
- headers(headers) {
6351
- this.defaultHeaders = headers;
6352
- return this;
6353
- }
6354
- auth(config) {
6355
- this.authConfig = mergeAuthClientConfig(this.authConfig, config);
6356
- return this;
7679
+
7680
+ // src/gateway/types.ts
7681
+ var Backend = {
7682
+ Athena: { type: "athena" },
7683
+ Postgrest: { type: "postgrest" },
7684
+ PostgreSQL: { type: "postgresql" },
7685
+ ScyllaDB: { type: "scylladb" }
7686
+ };
7687
+
7688
+ // src/schema/definitions.ts
7689
+ function defineModel(input) {
7690
+ return input;
7691
+ }
7692
+ function defineSchema(models) {
7693
+ return { models };
7694
+ }
7695
+ function defineDatabase(schemas) {
7696
+ return { schemas };
7697
+ }
7698
+ function defineRegistry(databases) {
7699
+ return databases;
7700
+ }
7701
+
7702
+ // src/schema/model-form.ts
7703
+ function resolveNullishValue(mode) {
7704
+ if (mode === "undefined") return void 0;
7705
+ if (mode === "null") return null;
7706
+ return "";
7707
+ }
7708
+ function isRecord10(value) {
7709
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
7710
+ }
7711
+ function isNullableColumn(model, key) {
7712
+ const nullable = model.meta.nullable;
7713
+ return nullable?.[key] === true;
7714
+ }
7715
+ function toModelFormDefaults(model, values, options) {
7716
+ const source = values;
7717
+ if (!isRecord10(source)) {
7718
+ return {};
6357
7719
  }
6358
- experimental(options) {
6359
- this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options);
6360
- return options.athenaStorageBackend ? this : this;
7720
+ const mode = options?.nullishMode ?? "empty-string";
7721
+ const nullishValue = resolveNullishValue(mode);
7722
+ const result = {};
7723
+ for (const [key, value] of Object.entries(source)) {
7724
+ if (value === null && isNullableColumn(model, key)) {
7725
+ result[key] = nullishValue;
7726
+ continue;
7727
+ }
7728
+ result[key] = value;
6361
7729
  }
6362
- options(options) {
6363
- if (options.client !== void 0) {
6364
- this.clientName = options.client;
7730
+ return result;
7731
+ }
7732
+ function toModelPayload(model, formValues, options) {
7733
+ const emptyStringAsNull = options?.emptyStringAsNull ?? true;
7734
+ const stripUndefined = options?.stripUndefined ?? true;
7735
+ const result = {};
7736
+ for (const [key, rawValue] of Object.entries(formValues)) {
7737
+ if (rawValue === void 0 && stripUndefined) {
7738
+ continue;
6365
7739
  }
6366
- if (options.backend !== void 0) {
6367
- this.backendConfig = toBackendConfig(options.backend);
7740
+ if (emptyStringAsNull && rawValue === "" && isNullableColumn(model, key)) {
7741
+ result[key] = null;
7742
+ continue;
6368
7743
  }
6369
- if (options.headers !== void 0) {
6370
- this.defaultHeaders = {
6371
- ...this.defaultHeaders ?? {},
6372
- ...options.headers
6373
- };
7744
+ result[key] = rawValue;
7745
+ }
7746
+ return result;
7747
+ }
7748
+ function createModelFormAdapter(model) {
7749
+ return {
7750
+ model,
7751
+ toDefaults(values, options) {
7752
+ return toModelFormDefaults(model, values, options);
7753
+ },
7754
+ toInsert(values, options) {
7755
+ return toModelPayload(model, values, options);
7756
+ },
7757
+ toUpdate(values, options) {
7758
+ return toModelPayload(model, values, options);
6374
7759
  }
6375
- if (options.auth !== void 0) {
6376
- this.authConfig = mergeAuthClientConfig(this.authConfig, options.auth);
7760
+ };
7761
+ }
7762
+
7763
+ // src/schema/table-columns.ts
7764
+ var COLUMN_CONFIG = /* @__PURE__ */ Symbol("athena.column.config");
7765
+ function createColumnBuilder(config) {
7766
+ return {
7767
+ [COLUMN_CONFIG]: config,
7768
+ optional() {
7769
+ return createColumnBuilder({
7770
+ ...config,
7771
+ nullable: true
7772
+ });
7773
+ },
7774
+ from(columnName) {
7775
+ return createColumnBuilder({
7776
+ ...config,
7777
+ columnName
7778
+ });
7779
+ },
7780
+ defaulted() {
7781
+ return createColumnBuilder({
7782
+ ...config,
7783
+ hasDefault: true
7784
+ });
7785
+ },
7786
+ generated() {
7787
+ return createColumnBuilder({
7788
+ ...config,
7789
+ isGenerated: true
7790
+ });
6377
7791
  }
6378
- if (options.experimental !== void 0) {
6379
- this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options.experimental);
7792
+ };
7793
+ }
7794
+ function isColumnBuilder(value) {
7795
+ return value !== null && typeof value === "object" && COLUMN_CONFIG in value;
7796
+ }
7797
+ function getColumnConfig(column) {
7798
+ return column[COLUMN_CONFIG];
7799
+ }
7800
+ function string() {
7801
+ return createColumnBuilder({
7802
+ kind: "string",
7803
+ nullable: false,
7804
+ hasDefault: false,
7805
+ isGenerated: false
7806
+ });
7807
+ }
7808
+ function number() {
7809
+ return createColumnBuilder({
7810
+ kind: "number",
7811
+ nullable: false,
7812
+ hasDefault: false,
7813
+ isGenerated: false
7814
+ });
7815
+ }
7816
+ function boolean() {
7817
+ return createColumnBuilder({
7818
+ kind: "boolean",
7819
+ nullable: false,
7820
+ hasDefault: false,
7821
+ isGenerated: false
7822
+ });
7823
+ }
7824
+ function json(schema) {
7825
+ return createColumnBuilder({
7826
+ kind: "json",
7827
+ nullable: false,
7828
+ hasDefault: false,
7829
+ isGenerated: false,
7830
+ jsonSchema: schema
7831
+ });
7832
+ }
7833
+ function enumeration(values) {
7834
+ if (values.length === 0) {
7835
+ throw new Error("enumeration() requires at least one value");
7836
+ }
7837
+ return createColumnBuilder({
7838
+ kind: "enumeration",
7839
+ nullable: false,
7840
+ hasDefault: false,
7841
+ isGenerated: false,
7842
+ enumValues: values
7843
+ });
7844
+ }
7845
+
7846
+ // src/schema/table-schemas.ts
7847
+ function isScalarFormKind(kind) {
7848
+ return kind === "string" || kind === "number" || kind === "boolean" || kind === "enumeration";
7849
+ }
7850
+ function createBaseSchema(column) {
7851
+ const config = getColumnConfig(column);
7852
+ switch (config.kind) {
7853
+ case "boolean":
7854
+ return zod.z.boolean();
7855
+ case "number":
7856
+ return zod.z.number();
7857
+ case "json":
7858
+ return config.jsonSchema ?? zod.z.unknown();
7859
+ case "enumeration":
7860
+ if (!config.enumValues || config.enumValues.length === 0) {
7861
+ return zod.z.string();
7862
+ }
7863
+ return zod.z.enum(config.enumValues);
7864
+ case "string":
7865
+ default:
7866
+ return zod.z.string();
7867
+ }
7868
+ }
7869
+ function applyNullable(schema, column) {
7870
+ const config = getColumnConfig(column);
7871
+ return config.nullable ? schema.nullable() : schema;
7872
+ }
7873
+ function applyInsertOptional(schema, column) {
7874
+ const config = getColumnConfig(column);
7875
+ return config.nullable || config.hasDefault ? schema.optional() : schema;
7876
+ }
7877
+ function createFormFieldSchema(column) {
7878
+ const config = getColumnConfig(column);
7879
+ const base = createBaseSchema(column);
7880
+ let schema;
7881
+ if (config.nullable && isScalarFormKind(config.kind)) {
7882
+ schema = zod.z.union([base, zod.z.literal("")]).transform((value) => value === "" ? null : value);
7883
+ } else {
7884
+ schema = applyNullable(base, column);
7885
+ }
7886
+ if (config.nullable || config.hasDefault) {
7887
+ schema = schema.optional();
7888
+ }
7889
+ return schema;
7890
+ }
7891
+ function buildTableSchemaBundle(model, columns) {
7892
+ const rowShape = {};
7893
+ const insertShape = {};
7894
+ const updateShape = {};
7895
+ const formShape = {};
7896
+ for (const [columnName, column] of Object.entries(columns)) {
7897
+ const config = getColumnConfig(column);
7898
+ const base = createBaseSchema(column);
7899
+ rowShape[columnName] = applyNullable(base, column);
7900
+ if (config.isGenerated) {
7901
+ continue;
6380
7902
  }
6381
- return options.experimental?.athenaStorageBackend ? this : this;
7903
+ insertShape[columnName] = applyInsertOptional(applyNullable(base, column), column);
7904
+ updateShape[columnName] = applyNullable(base, column).optional();
7905
+ formShape[columnName] = createFormFieldSchema(column);
6382
7906
  }
6383
- build() {
6384
- if (!this.baseUrl || !this.apiKey) {
6385
- throw new Error("AthenaClient requires url and key; call .url() and .key() before .build()");
7907
+ const rowSchema = zod.z.object(rowShape);
7908
+ const insertSchema = zod.z.object(insertShape);
7909
+ const updateSchema = zod.z.object(updateShape);
7910
+ const formSchema = zod.z.object(formShape).transform((value) => toModelPayload(model, value));
7911
+ return {
7912
+ row: rowSchema,
7913
+ insert: insertSchema,
7914
+ update: updateSchema,
7915
+ form: formSchema
7916
+ };
7917
+ }
7918
+
7919
+ // src/schema/table-builder.ts
7920
+ function assertColumnRecord(columns) {
7921
+ for (const [columnName, column] of Object.entries(columns)) {
7922
+ if (!isColumnBuilder(column)) {
7923
+ throw new Error(`Invalid column definition for "${columnName}"`);
6386
7924
  }
6387
- return createClientFromConfig({
6388
- baseUrl: this.baseUrl,
6389
- apiKey: this.apiKey,
6390
- client: this.clientName,
6391
- backend: this.backendConfig,
6392
- headers: this.defaultHeaders,
6393
- auth: this.authConfig,
6394
- experimental: this.experimentalOptions
6395
- });
6396
7925
  }
6397
- };
6398
- var AthenaClient = class _AthenaClient {
6399
- /** Create a fluent builder for a strongly-typed Athena SDK client. */
6400
- static builder() {
6401
- return new AthenaClientBuilderImpl();
7926
+ }
7927
+ function normalizeMappedNameInput(mappedName) {
7928
+ const normalized = mappedName.trim();
7929
+ if (!normalized) {
7930
+ throw new Error("table.from() requires a non-empty table name");
7931
+ }
7932
+ return normalized;
7933
+ }
7934
+ function normalizeSchemaNameInput(schemaName) {
7935
+ const normalized = schemaName.trim();
7936
+ if (!normalized) {
7937
+ throw new Error("table.schema() requires a non-empty schema name");
7938
+ }
7939
+ if (normalized.includes(".")) {
7940
+ throw new Error(
7941
+ 'table.schema() expects a schema name without dots. Use .schema("schema").from("table") or .from("schema.table").'
7942
+ );
7943
+ }
7944
+ return normalized;
7945
+ }
7946
+ function resolveTableTarget(logicalName, mappedName, explicitSchemaName) {
7947
+ const physicalName = (mappedName ?? logicalName).trim();
7948
+ if (!physicalName) {
7949
+ throw new Error("table() requires a non-empty name");
6402
7950
  }
6403
- /** Build a client from process environment variables. */
6404
- static fromEnvironment() {
6405
- const url = process.env.ATHENA_URL ?? process.env.ATHENA_GATEWAY_URL;
6406
- const key = process.env.ATHENA_API_KEY ?? process.env.ATHENA_GATEWAY_API_KEY;
6407
- if (!url || !key) {
7951
+ const firstDot = physicalName.indexOf(".");
7952
+ const lastDot = physicalName.lastIndexOf(".");
7953
+ if (firstDot > 0 && firstDot === lastDot) {
7954
+ const inlineSchema = physicalName.slice(0, firstDot).trim();
7955
+ const inlineModel = physicalName.slice(firstDot + 1).trim();
7956
+ if (!inlineSchema || !inlineModel) {
7957
+ throw new Error('table.from() schema-qualified names must look like "schema.table"');
7958
+ }
7959
+ if (explicitSchemaName && explicitSchemaName !== inlineSchema) {
6408
7960
  throw new Error(
6409
- "ATHENA_URL and ATHENA_API_KEY (or ATHENA_GATEWAY_URL and ATHENA_GATEWAY_API_KEY) are required"
7961
+ `table schema "${explicitSchemaName}" conflicts with mapped table "${physicalName}"`
6410
7962
  );
6411
7963
  }
6412
- return _AthenaClient.builder().url(url).key(key).build();
7964
+ return {
7965
+ schema: explicitSchemaName ?? inlineSchema,
7966
+ model: inlineModel,
7967
+ qualifiedName: `${explicitSchemaName ?? inlineSchema}.${inlineModel}`
7968
+ };
6413
7969
  }
6414
- };
6415
- function createClient(url, apiKey, options) {
6416
- return createClientFromConfig({
6417
- baseUrl: url,
6418
- apiKey,
6419
- client: options?.client,
6420
- backend: toBackendConfig(options?.backend),
6421
- headers: options?.headers,
6422
- auth: options?.auth,
6423
- experimental: options?.experimental
6424
- });
7970
+ if (explicitSchemaName) {
7971
+ return {
7972
+ schema: explicitSchemaName,
7973
+ model: physicalName,
7974
+ qualifiedName: `${explicitSchemaName}.${physicalName}`
7975
+ };
7976
+ }
7977
+ return {
7978
+ model: physicalName,
7979
+ qualifiedName: physicalName
7980
+ };
6425
7981
  }
6426
-
6427
- // src/gateway/types.ts
6428
- var Backend = {
6429
- Athena: { type: "athena" },
6430
- Postgrest: { type: "postgrest" },
6431
- PostgreSQL: { type: "postgresql" },
6432
- ScyllaDB: { type: "scylladb" }
6433
- };
6434
-
6435
- // src/schema/definitions.ts
6436
- function defineModel(input) {
6437
- return input;
7982
+ function toColumnMetadata(column) {
7983
+ const config = getColumnConfig(column);
7984
+ return {
7985
+ kind: config.kind,
7986
+ columnName: config.columnName,
7987
+ nullable: config.nullable,
7988
+ hasDefault: config.hasDefault,
7989
+ isGenerated: config.isGenerated,
7990
+ enumValues: config.enumValues
7991
+ };
6438
7992
  }
6439
- function defineSchema(models) {
6440
- return { models };
7993
+ function buildNullableMap(columns) {
7994
+ return Object.fromEntries(
7995
+ Object.entries(columns).map(([columnName, column]) => [columnName, getColumnConfig(column).nullable])
7996
+ );
6441
7997
  }
6442
- function defineDatabase(schemas) {
6443
- return { schemas };
7998
+ function buildColumnMetadataMap(columns) {
7999
+ return Object.fromEntries(
8000
+ Object.entries(columns).map(([columnName, column]) => [columnName, toColumnMetadata(column)])
8001
+ );
6444
8002
  }
6445
- function defineRegistry(databases) {
6446
- return databases;
8003
+ function finalizeTable(name, mappedName, schemaName, columns, primaryKey) {
8004
+ const target = resolveTableTarget(name, mappedName, schemaName);
8005
+ const model = defineModel({
8006
+ meta: {
8007
+ schema: target.schema,
8008
+ model: target.model,
8009
+ primaryKey: [...primaryKey],
8010
+ nullable: buildNullableMap(columns),
8011
+ columns: buildColumnMetadataMap(columns)
8012
+ }
8013
+ });
8014
+ const schemas = buildTableSchemaBundle(model, columns);
8015
+ return Object.assign(model, {
8016
+ kind: "table",
8017
+ name,
8018
+ mappedName,
8019
+ schemaName: target.schema,
8020
+ tableName: target.model,
8021
+ qualifiedName: target.qualifiedName,
8022
+ columns,
8023
+ schemas
8024
+ });
8025
+ }
8026
+ function createColumnsBuilder(name, mappedName, schemaName, columns) {
8027
+ assertColumnRecord(columns);
8028
+ return {
8029
+ name,
8030
+ mappedName,
8031
+ schemaName,
8032
+ columns,
8033
+ from(tableName) {
8034
+ const normalizedTableName = normalizeMappedNameInput(tableName);
8035
+ resolveTableTarget(name, normalizedTableName, schemaName);
8036
+ return createColumnsBuilder(name, normalizedTableName, schemaName, columns);
8037
+ },
8038
+ schema(nextSchemaName) {
8039
+ const normalizedSchemaName = normalizeSchemaNameInput(nextSchemaName);
8040
+ resolveTableTarget(name, mappedName, normalizedSchemaName);
8041
+ return createColumnsBuilder(name, mappedName, normalizedSchemaName, columns);
8042
+ },
8043
+ primaryKey(...keys) {
8044
+ return finalizeTable(name, mappedName, schemaName, columns, keys);
8045
+ }
8046
+ };
8047
+ }
8048
+ function createTableBuilder2(name, mappedName, schemaName) {
8049
+ return {
8050
+ name,
8051
+ mappedName,
8052
+ schemaName,
8053
+ from(tableName) {
8054
+ const normalizedTableName = normalizeMappedNameInput(tableName);
8055
+ resolveTableTarget(name, normalizedTableName, schemaName);
8056
+ return createTableBuilder2(name, normalizedTableName, schemaName);
8057
+ },
8058
+ schema(nextSchemaName) {
8059
+ const normalizedSchemaName = normalizeSchemaNameInput(nextSchemaName);
8060
+ resolveTableTarget(name, mappedName, normalizedSchemaName);
8061
+ return createTableBuilder2(name, mappedName, normalizedSchemaName);
8062
+ },
8063
+ columns(columns) {
8064
+ return createColumnsBuilder(name, mappedName, schemaName, columns);
8065
+ }
8066
+ };
8067
+ }
8068
+ function table(name) {
8069
+ if (!name.trim()) {
8070
+ throw new Error("table() requires a non-empty name");
8071
+ }
8072
+ return createTableBuilder2(name, void 0, void 0);
6447
8073
  }
6448
8074
 
6449
8075
  // src/schema/typed-client.ts
@@ -6485,12 +8111,10 @@ var RegistryNavigator = class {
6485
8111
  return modelDef;
6486
8112
  }
6487
8113
  resolveTableName(schema, model, modelDef) {
6488
- if (modelDef.meta.tableName) {
6489
- return modelDef.meta.tableName;
6490
- }
6491
- const schemaName = modelDef.meta.schema ?? schema;
6492
- const modelName = modelDef.meta.model ?? model;
6493
- return `${schemaName}.${modelName}`;
8114
+ return resolveAthenaModelTargetTableName(modelDef, {
8115
+ fallbackSchema: schema,
8116
+ fallbackModel: model
8117
+ });
6494
8118
  }
6495
8119
  };
6496
8120
  var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
@@ -6517,17 +8141,20 @@ var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
6517
8141
  this.clientOptions = {
6518
8142
  backend: input.options?.backend,
6519
8143
  client: input.options?.client,
6520
- headers: input.options?.headers
8144
+ headers: input.options?.headers,
8145
+ experimental: input.options?.experimental
6521
8146
  };
6522
8147
  this.baseClient = createClient(this.url, this.apiKey, {
6523
8148
  backend: this.clientOptions.backend,
6524
8149
  client: this.clientOptions.client,
6525
- headers: this.tenantHeaderMapper.apply(this.clientOptions.headers, tenantContext)
8150
+ headers: this.tenantHeaderMapper.apply(this.clientOptions.headers, tenantContext),
8151
+ experimental: this.clientOptions.experimental
6526
8152
  });
6527
8153
  this.db = this.baseClient.db;
6528
8154
  }
6529
- from(table, options) {
6530
- return this.baseClient.from(table, options);
8155
+ from(tableOrModel, options) {
8156
+ const from = this.baseClient.from;
8157
+ return from(tableOrModel, options);
6531
8158
  }
6532
8159
  rpc(fn, args, options) {
6533
8160
  return this.baseClient.rpc(fn, args, options);
@@ -6549,7 +8176,8 @@ var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
6549
8176
  tenantContext: {
6550
8177
  ...this.tenantContext,
6551
8178
  ...context ?? {}
6552
- }
8179
+ },
8180
+ experimental: this.clientOptions.experimental
6553
8181
  }
6554
8182
  });
6555
8183
  }
@@ -6655,8 +8283,8 @@ var POSTGRES_CATALOG_SQL = {
6655
8283
  ORDER BY sn.nspname, sc.relname, con.conname;
6656
8284
  `
6657
8285
  };
6658
- function tableKey(schema, table) {
6659
- return `${schema}.${table}`;
8286
+ function tableKey(schema, table2) {
8287
+ return `${schema}.${table2}`;
6660
8288
  }
6661
8289
  function relationKey(...parts) {
6662
8290
  const base = parts.join("_").replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
@@ -6767,8 +8395,8 @@ var PostgresCatalogSnapshotAssembler = class {
6767
8395
  schemas = {};
6768
8396
  addColumnRows(columnRows, enumMap) {
6769
8397
  for (const row of columnRows) {
6770
- const table = this.ensureTable(row.schema_name, row.table_name);
6771
- table.columns[row.column_name] = {
8398
+ const table2 = this.ensureTable(row.schema_name, row.table_name);
8399
+ table2.columns[row.column_name] = {
6772
8400
  name: row.column_name,
6773
8401
  dataType: row.data_type,
6774
8402
  udtName: row.udt_name,
@@ -6784,12 +8412,12 @@ var PostgresCatalogSnapshotAssembler = class {
6784
8412
  }
6785
8413
  addPrimaryKeyRows(primaryKeyRows) {
6786
8414
  for (const row of primaryKeyRows) {
6787
- const table = this.ensureTable(row.schema_name, row.table_name);
8415
+ const table2 = this.ensureTable(row.schema_name, row.table_name);
6788
8416
  const primaryKeyColumns = coerceStringArray(row.columns);
6789
8417
  row.columns = primaryKeyColumns;
6790
- table.primaryKey = primaryKeyColumns;
8418
+ table2.primaryKey = primaryKeyColumns;
6791
8419
  for (const columnName of primaryKeyColumns) {
6792
- const column = table.columns[columnName];
8420
+ const column = table2.columns[columnName];
6793
8421
  if (column) {
6794
8422
  column.isPrimaryKey = true;
6795
8423
  }
@@ -6905,14 +8533,14 @@ var PostgresCatalogSnapshotAssembler = class {
6905
8533
  }
6906
8534
  return schema.tables[tableName];
6907
8535
  }
6908
- upsertRelation(table, baseKey, relation) {
8536
+ upsertRelation(table2, baseKey, relation) {
6909
8537
  let key = baseKey;
6910
8538
  let suffix = 2;
6911
- while (table.relations[key]) {
8539
+ while (table2.relations[key]) {
6912
8540
  key = `${baseKey}_${suffix}`;
6913
8541
  suffix += 1;
6914
8542
  }
6915
- table.relations[key] = relation;
8543
+ table2.relations[key] = relation;
6916
8544
  }
6917
8545
  };
6918
8546
 
@@ -7003,67 +8631,6 @@ function createPostgresIntrospectionProvider(options) {
7003
8631
  return new PostgresIntrospectionProvider(options);
7004
8632
  }
7005
8633
 
7006
- // src/schema/model-form.ts
7007
- function resolveNullishValue(mode) {
7008
- if (mode === "undefined") return void 0;
7009
- if (mode === "null") return null;
7010
- return "";
7011
- }
7012
- function isRecord9(value) {
7013
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
7014
- }
7015
- function isNullableColumn(model, key) {
7016
- const nullable = model.meta.nullable;
7017
- return nullable?.[key] === true;
7018
- }
7019
- function toModelFormDefaults(model, values, options) {
7020
- const source = values;
7021
- if (!isRecord9(source)) {
7022
- return {};
7023
- }
7024
- const mode = options?.nullishMode ?? "empty-string";
7025
- const nullishValue = resolveNullishValue(mode);
7026
- const result = {};
7027
- for (const [key, value] of Object.entries(source)) {
7028
- if (value === null && isNullableColumn(model, key)) {
7029
- result[key] = nullishValue;
7030
- continue;
7031
- }
7032
- result[key] = value;
7033
- }
7034
- return result;
7035
- }
7036
- function toModelPayload(model, formValues, options) {
7037
- const emptyStringAsNull = options?.emptyStringAsNull ?? true;
7038
- const stripUndefined = options?.stripUndefined ?? true;
7039
- const result = {};
7040
- for (const [key, rawValue] of Object.entries(formValues)) {
7041
- if (rawValue === void 0 && stripUndefined) {
7042
- continue;
7043
- }
7044
- if (emptyStringAsNull && rawValue === "" && isNullableColumn(model, key)) {
7045
- result[key] = null;
7046
- continue;
7047
- }
7048
- result[key] = rawValue;
7049
- }
7050
- return result;
7051
- }
7052
- function createModelFormAdapter(model) {
7053
- return {
7054
- model,
7055
- toDefaults(values, options) {
7056
- return toModelFormDefaults(model, values, options);
7057
- },
7058
- toInsert(values, options) {
7059
- return toModelPayload(model, values, options);
7060
- },
7061
- toUpdate(values, options) {
7062
- return toModelPayload(model, values, options);
7063
- }
7064
- };
7065
- }
7066
-
7067
8634
  // src/generator/schema-selection.ts
7068
8635
  var DEFAULT_POSTGRES_SCHEMAS = ["public"];
7069
8636
  function collectSchemaNames(input) {
@@ -7109,6 +8676,7 @@ var DEFAULT_TARGETS = {
7109
8676
  database: "athena/relations.ts",
7110
8677
  registry: "athena/config.ts"
7111
8678
  };
8679
+ var DEFAULT_OUTPUT_FORMAT = "define-model";
7112
8680
  var DEFAULT_NAMING = {
7113
8681
  modelType: "pascal",
7114
8682
  modelConst: "camel",
@@ -7124,6 +8692,9 @@ var DEFAULT_EXPERIMENTAL_FLAGS = {
7124
8692
  postgresGatewayIntrospection: false,
7125
8693
  scyllaProviderContracts: true
7126
8694
  };
8695
+ var DEFAULT_INTERNAL_CONFIG = {
8696
+ schemaVersion: 1
8697
+ };
7127
8698
  var PROJECT_ENV_FILENAMES = [".env", ".env.local"];
7128
8699
  var DIRECT_CONNECTION_STRING_ENV_KEYS = [
7129
8700
  "ATHENA_GENERATOR_PG_URL",
@@ -7140,6 +8711,27 @@ var GATEWAY_API_KEY_ENV_KEYS = [
7140
8711
  "ATHENA_GATEWAY_API_KEY",
7141
8712
  "ATHENA_GENERATOR_API_KEY"
7142
8713
  ];
8714
+ var GENERATOR_SCHEMA_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMAS"];
8715
+ var OUTPUT_FORMAT_ENV_KEYS = ["ATHENA_GENERATOR_OUTPUT_FORMAT"];
8716
+ var MODEL_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_TARGET"];
8717
+ var SCHEMA_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMA_TARGET"];
8718
+ var DATABASE_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_DATABASE_TARGET"];
8719
+ var REGISTRY_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_REGISTRY_TARGET"];
8720
+ var PLACEHOLDER_MAP_ENV_KEYS = ["ATHENA_GENERATOR_PLACEHOLDER_MAP"];
8721
+ var MODEL_TYPE_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_TYPE", "ATHENA_GENERATOR_MODEL_STYLE"];
8722
+ var MODEL_CONST_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_CONST"];
8723
+ var SCHEMA_CONST_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMA_CONST"];
8724
+ var DATABASE_CONST_ENV_KEYS = ["ATHENA_GENERATOR_DATABASE_CONST"];
8725
+ var REGISTRY_CONST_ENV_KEYS = ["ATHENA_GENERATOR_REGISTRY_CONST"];
8726
+ var EMIT_RELATIONS_ENV_KEYS = ["ATHENA_GENERATOR_EMIT_RELATIONS"];
8727
+ var EMIT_REGISTRY_ENV_KEYS = ["ATHENA_GENERATOR_EMIT_REGISTRY"];
8728
+ var GATEWAY_BACKEND_ENV_KEYS = ["ATHENA_GENERATOR_BACKEND"];
8729
+ var GATEWAY_EXPERIMENTAL_ENV_KEYS = ["ATHENA_GENERATOR_GATEWAY_EXPERIMENTAL"];
8730
+ var SCYLLA_PROVIDER_CONTRACTS_ENV_KEYS = ["ATHENA_GENERATOR_SCYLLA_PROVIDER_CONTRACTS"];
8731
+ var ENV_ONLY_CONFIG_PATH = "[environment defaults]";
8732
+ var NAMING_STYLE_VALUES = ["preserve", "camel", "pascal", "snake", "kebab"];
8733
+ var OUTPUT_FORMAT_VALUES = ["define-model", "table-builder"];
8734
+ var BACKEND_TYPE_VALUES = ["athena", "postgrest", "postgresql", "scylladb"];
7143
8735
  function normalizeRawEnvValue(rawValue) {
7144
8736
  if (rawValue.startsWith('"') && rawValue.endsWith('"') && rawValue.length >= 2) {
7145
8737
  const inner = rawValue.slice(1, -1);
@@ -7231,6 +8823,50 @@ function resolveFallbackValue(fallbackKeys) {
7231
8823
  }
7232
8824
  return void 0;
7233
8825
  }
8826
+ function normalizeOneOfValue(rawValue, allowedValues, envKeys) {
8827
+ if (!rawValue) {
8828
+ return void 0;
8829
+ }
8830
+ if (allowedValues.includes(rawValue)) {
8831
+ return rawValue;
8832
+ }
8833
+ throw new Error(
8834
+ `Generator config env vars ${envKeys.join(", ")} must resolve to one of: ${allowedValues.join(", ")}. Received: ${rawValue}.`
8835
+ );
8836
+ }
8837
+ function resolveOptionalOneOf(envKeys, allowedValues) {
8838
+ return normalizeOneOfValue(resolveFallbackValue(envKeys), allowedValues, envKeys);
8839
+ }
8840
+ function resolveOptionalBoolean(envKeys) {
8841
+ const rawValue = resolveFallbackValue(envKeys);
8842
+ return rawValue === void 0 ? void 0 : parseBooleanFlag2(rawValue, false);
8843
+ }
8844
+ function resolveOptionalJson(envKeys) {
8845
+ const rawValue = resolveFallbackValue(envKeys);
8846
+ if (rawValue === void 0) {
8847
+ return void 0;
8848
+ }
8849
+ try {
8850
+ return JSON.parse(rawValue);
8851
+ } catch (error) {
8852
+ const message = error instanceof Error ? error.message : String(error);
8853
+ throw new Error(
8854
+ `Generator config env vars ${envKeys.join(", ")} must contain valid JSON. ${message}`
8855
+ );
8856
+ }
8857
+ }
8858
+ function deriveDatabaseNameFromConnectionString(connectionString) {
8859
+ try {
8860
+ const parsedUrl = new URL(connectionString);
8861
+ if (!POSTGRES_PROTOCOLS.has(parsedUrl.protocol)) {
8862
+ return void 0;
8863
+ }
8864
+ const pathname = parsedUrl.pathname.replace(/^\/+/, "").trim();
8865
+ return pathname.length > 0 ? decodeURIComponent(pathname) : void 0;
8866
+ } catch {
8867
+ return void 0;
8868
+ }
8869
+ }
7234
8870
  function normalizeOptionalString(value, fallbackKeys) {
7235
8871
  if (typeof value === "string") {
7236
8872
  const trimmed = value.trim();
@@ -7304,12 +8940,13 @@ function normalizeExperimentalFlags(input) {
7304
8940
  }
7305
8941
  function normalizeOutputConfig(output) {
7306
8942
  return {
8943
+ format: output?.format ?? DEFAULT_OUTPUT_FORMAT,
7307
8944
  targets: {
7308
8945
  ...DEFAULT_TARGETS,
7309
- ...output.targets ?? {}
8946
+ ...output?.targets ?? {}
7310
8947
  },
7311
8948
  placeholderMap: {
7312
- ...output.placeholderMap ?? {}
8949
+ ...output?.placeholderMap ?? {}
7313
8950
  }
7314
8951
  };
7315
8952
  }
@@ -7320,7 +8957,7 @@ function normalizeProviderConfig(provider) {
7320
8957
  "provider.connectionString",
7321
8958
  DIRECT_CONNECTION_STRING_ENV_KEYS
7322
8959
  );
7323
- const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS);
8960
+ const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS) ?? deriveDatabaseNameFromConnectionString(connectionString);
7324
8961
  return {
7325
8962
  ...provider,
7326
8963
  connectionString: applyPostgresPasswordFallback(connectionString),
@@ -7339,11 +8976,7 @@ function normalizeProviderConfig(provider) {
7339
8976
  "provider.apiKey",
7340
8977
  GATEWAY_API_KEY_ENV_KEYS
7341
8978
  );
7342
- const database = normalizeRequiredString(
7343
- provider.database,
7344
- "provider.database",
7345
- POSTGRES_DATABASE_ENV_KEYS
7346
- );
8979
+ const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS) ?? "postgres";
7347
8980
  return {
7348
8981
  ...provider,
7349
8982
  gatewayUrl,
@@ -7352,6 +8985,26 @@ function normalizeProviderConfig(provider) {
7352
8985
  schemas: normalizeSchemaSelection(provider.schemas)
7353
8986
  };
7354
8987
  }
8988
+ if (provider.kind === "scylla" && provider.mode === "direct") {
8989
+ if (!provider.contactPoints?.length) {
8990
+ throw new Error(
8991
+ "Generator config is missing provider.contactPoints for scylla direct mode."
8992
+ );
8993
+ }
8994
+ const keyspace = normalizeOptionalString(provider.keyspace, []);
8995
+ if (!keyspace) {
8996
+ throw new Error(
8997
+ "Generator config is missing provider.keyspace for scylla direct mode."
8998
+ );
8999
+ }
9000
+ return {
9001
+ kind: "scylla",
9002
+ mode: "direct",
9003
+ contactPoints: provider.contactPoints.slice(),
9004
+ keyspace,
9005
+ datacenter: normalizeOptionalString(provider.datacenter, [])
9006
+ };
9007
+ }
7355
9008
  return provider;
7356
9009
  }
7357
9010
  function isAthenaGeneratorConfig(value) {
@@ -7359,7 +9012,7 @@ function isAthenaGeneratorConfig(value) {
7359
9012
  return false;
7360
9013
  }
7361
9014
  const record = value;
7362
- return Boolean(record.provider && typeof record.provider === "object") && Boolean(record.output && typeof record.output === "object");
9015
+ return Boolean(record.provider && typeof record.provider === "object") && (record.output === void 0 || typeof record.output === "object");
7363
9016
  }
7364
9017
  function normalizeGeneratorConfig(input) {
7365
9018
  return {
@@ -7370,7 +9023,10 @@ function normalizeGeneratorConfig(input) {
7370
9023
  ...input.naming ?? {}
7371
9024
  },
7372
9025
  features: normalizeFeatureFlags(input.features),
7373
- experimental: normalizeExperimentalFlags(input.experimental)
9026
+ experimental: normalizeExperimentalFlags(input.experimental),
9027
+ internal: {
9028
+ ...DEFAULT_INTERNAL_CONFIG
9029
+ }
7374
9030
  };
7375
9031
  }
7376
9032
  function defineGeneratorConfig(config) {
@@ -7427,16 +9083,123 @@ function importConfigModule(moduleSpecifier) {
7427
9083
  );
7428
9084
  return runtimeImport(moduleSpecifier);
7429
9085
  }
9086
+ function buildEnvironmentOutputConfig() {
9087
+ const format = resolveOptionalOneOf(OUTPUT_FORMAT_ENV_KEYS, OUTPUT_FORMAT_VALUES);
9088
+ const modelTarget = resolveFallbackValue(MODEL_TARGET_ENV_KEYS);
9089
+ const schemaTarget = resolveFallbackValue(SCHEMA_TARGET_ENV_KEYS);
9090
+ const databaseTarget = resolveFallbackValue(DATABASE_TARGET_ENV_KEYS);
9091
+ const registryTarget = resolveFallbackValue(REGISTRY_TARGET_ENV_KEYS);
9092
+ const placeholderMap = resolveOptionalJson(PLACEHOLDER_MAP_ENV_KEYS);
9093
+ if (format === void 0 && modelTarget === void 0 && schemaTarget === void 0 && databaseTarget === void 0 && registryTarget === void 0 && placeholderMap === void 0) {
9094
+ return void 0;
9095
+ }
9096
+ return {
9097
+ format,
9098
+ targets: {
9099
+ ...modelTarget ? { model: modelTarget } : {},
9100
+ ...schemaTarget ? { schema: schemaTarget } : {},
9101
+ ...databaseTarget ? { database: databaseTarget } : {},
9102
+ ...registryTarget ? { registry: registryTarget } : {}
9103
+ },
9104
+ placeholderMap
9105
+ };
9106
+ }
9107
+ function buildEnvironmentNamingConfig() {
9108
+ const modelType = resolveOptionalOneOf(MODEL_TYPE_ENV_KEYS, NAMING_STYLE_VALUES);
9109
+ const modelConst = resolveOptionalOneOf(MODEL_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
9110
+ const schemaConst = resolveOptionalOneOf(SCHEMA_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
9111
+ const databaseConst = resolveOptionalOneOf(DATABASE_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
9112
+ const registryConst = resolveOptionalOneOf(REGISTRY_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
9113
+ if (modelType === void 0 && modelConst === void 0 && schemaConst === void 0 && databaseConst === void 0 && registryConst === void 0) {
9114
+ return void 0;
9115
+ }
9116
+ return {
9117
+ ...modelType ? { modelType } : {},
9118
+ ...modelConst ? { modelConst } : {},
9119
+ ...schemaConst ? { schemaConst } : {},
9120
+ ...databaseConst ? { databaseConst } : {},
9121
+ ...registryConst ? { registryConst } : {}
9122
+ };
9123
+ }
9124
+ function buildEnvironmentFeatureFlags() {
9125
+ const emitRelations = resolveOptionalBoolean(EMIT_RELATIONS_ENV_KEYS);
9126
+ const emitRegistry = resolveOptionalBoolean(EMIT_REGISTRY_ENV_KEYS);
9127
+ if (emitRelations === void 0 && emitRegistry === void 0) {
9128
+ return void 0;
9129
+ }
9130
+ return {
9131
+ ...emitRelations !== void 0 ? { emitRelations } : {},
9132
+ ...emitRegistry !== void 0 ? { emitRegistry } : {}
9133
+ };
9134
+ }
9135
+ function buildEnvironmentExperimentalFlags() {
9136
+ const postgresGatewayIntrospection = resolveOptionalBoolean(GATEWAY_EXPERIMENTAL_ENV_KEYS);
9137
+ const scyllaProviderContracts = resolveOptionalBoolean(SCYLLA_PROVIDER_CONTRACTS_ENV_KEYS);
9138
+ if (postgresGatewayIntrospection === void 0 && scyllaProviderContracts === void 0) {
9139
+ return void 0;
9140
+ }
9141
+ return {
9142
+ ...postgresGatewayIntrospection !== void 0 ? { postgresGatewayIntrospection } : {},
9143
+ ...scyllaProviderContracts !== void 0 ? { scyllaProviderContracts } : {}
9144
+ };
9145
+ }
9146
+ function buildEnvironmentProviderConfig() {
9147
+ const directConnectionString = resolveFallbackValue(DIRECT_CONNECTION_STRING_ENV_KEYS);
9148
+ if (directConnectionString) {
9149
+ return {
9150
+ kind: "postgres",
9151
+ mode: "direct",
9152
+ connectionString: directConnectionString,
9153
+ database: normalizeOptionalString(void 0, POSTGRES_DATABASE_ENV_KEYS),
9154
+ schemas: normalizeSchemaSelection(resolveFallbackValue(GENERATOR_SCHEMA_ENV_KEYS))
9155
+ };
9156
+ }
9157
+ const gatewayUrl = resolveFallbackValue(GATEWAY_URL_ENV_KEYS);
9158
+ const apiKey = resolveFallbackValue(GATEWAY_API_KEY_ENV_KEYS);
9159
+ if (gatewayUrl && apiKey) {
9160
+ const backend = resolveOptionalOneOf(GATEWAY_BACKEND_ENV_KEYS, BACKEND_TYPE_VALUES);
9161
+ return {
9162
+ kind: "postgres",
9163
+ mode: "gateway",
9164
+ gatewayUrl,
9165
+ apiKey,
9166
+ database: normalizeOptionalString(void 0, POSTGRES_DATABASE_ENV_KEYS),
9167
+ schemas: normalizeSchemaSelection(resolveFallbackValue(GENERATOR_SCHEMA_ENV_KEYS)),
9168
+ backend
9169
+ };
9170
+ }
9171
+ return void 0;
9172
+ }
9173
+ function createEnvironmentGeneratorConfig() {
9174
+ const provider = buildEnvironmentProviderConfig();
9175
+ if (!provider) {
9176
+ return void 0;
9177
+ }
9178
+ return {
9179
+ provider,
9180
+ output: buildEnvironmentOutputConfig(),
9181
+ naming: buildEnvironmentNamingConfig(),
9182
+ features: buildEnvironmentFeatureFlags(),
9183
+ experimental: buildEnvironmentExperimentalFlags()
9184
+ };
9185
+ }
7430
9186
  async function loadGeneratorConfig(options = {}) {
7431
9187
  const cwd = options.cwd ?? process.cwd();
7432
9188
  const restoreProjectEnv = applyProjectEnv(cwd);
7433
- const resolvedPath = options.configPath ? path.resolve(cwd, options.configPath) : findGeneratorConfigPath(cwd);
7434
- if (!resolvedPath) {
7435
- throw new Error(
7436
- `No generator config found in ${cwd}. Expected one of: ${DEFAULT_CONFIG_CANDIDATES.join(", ")}`
7437
- );
7438
- }
7439
9189
  try {
9190
+ const resolvedPath = options.configPath ? path.resolve(cwd, options.configPath) : findGeneratorConfigPath(cwd);
9191
+ if (!resolvedPath) {
9192
+ const environmentConfig = createEnvironmentGeneratorConfig();
9193
+ if (environmentConfig) {
9194
+ return {
9195
+ configPath: ENV_ONLY_CONFIG_PATH,
9196
+ config: normalizeGeneratorConfig(environmentConfig)
9197
+ };
9198
+ }
9199
+ throw new Error(
9200
+ `No generator config found in ${cwd}. Expected one of: ${DEFAULT_CONFIG_CANDIDATES.join(", ")}. To run without a config file, set DATABASE_URL (direct mode) or ATHENA_URL + ATHENA_API_KEY (gateway mode).`
9201
+ );
9202
+ }
7440
9203
  const moduleUrl = url.pathToFileURL(resolvedPath);
7441
9204
  const module = await importConfigModule(`${moduleUrl.href}?cacheBust=${Date.now()}`);
7442
9205
  const rawConfig = extractConfigExport(module);
@@ -7657,59 +9420,6 @@ function escapeStringLiteral(value) {
7657
9420
  return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
7658
9421
  }
7659
9422
 
7660
- // src/generator/placeholders.ts
7661
- function createStyleTokens(prefix, value) {
7662
- return {
7663
- [prefix]: value,
7664
- [`${prefix}_camel`]: applyNamingStyle(value, "camel"),
7665
- [`${prefix}_pascal`]: applyNamingStyle(value, "pascal"),
7666
- [`${prefix}_snake`]: applyNamingStyle(value, "snake"),
7667
- [`${prefix}_kebab`]: applyNamingStyle(value, "kebab")
7668
- };
7669
- }
7670
- function renderTemplate(template, tokenMap) {
7671
- return template.replace(/\{([A-Za-z0-9_]+)\}/g, (_match, token) => {
7672
- if (!(token in tokenMap)) {
7673
- throw new Error(`Unknown placeholder token "${token}" in template "${template}"`);
7674
- }
7675
- return tokenMap[token];
7676
- });
7677
- }
7678
- function resolvePlaceholderMap(baseTokens, outputConfig) {
7679
- const resolved = {
7680
- ...baseTokens
7681
- };
7682
- const reservedTokenKeys = new Set(Object.keys(baseTokens));
7683
- const entries = Object.entries(outputConfig.placeholderMap ?? {});
7684
- for (let index = 0; index < entries.length; index += 1) {
7685
- const [key, value] = entries[index];
7686
- if (reservedTokenKeys.has(key)) {
7687
- continue;
7688
- }
7689
- let current = value;
7690
- for (let depth = 0; depth < 8; depth += 1) {
7691
- const next = renderTemplate(current, resolved);
7692
- if (next === current) {
7693
- break;
7694
- }
7695
- current = next;
7696
- }
7697
- resolved[key] = current;
7698
- }
7699
- return resolved;
7700
- }
7701
- function renderOutputPath(template, context, outputConfig) {
7702
- const baseTokens = {
7703
- provider: context.provider,
7704
- kind: context.kind,
7705
- ...createStyleTokens("database", context.database),
7706
- ...createStyleTokens("schema", context.schema),
7707
- ...createStyleTokens("model", context.model)
7708
- };
7709
- const tokens = resolvePlaceholderMap(baseTokens, outputConfig);
7710
- return renderTemplate(template, tokens);
7711
- }
7712
-
7713
9423
  // src/generator/postgres-type-mapping.ts
7714
9424
  var NUMBER_TYPES = /* @__PURE__ */ new Set([
7715
9425
  "int2",
@@ -7826,7 +9536,60 @@ function resolvePostgresColumnType(column) {
7826
9536
  return wrapArrayType(baseType, column.arrayDimensions);
7827
9537
  }
7828
9538
 
7829
- // src/generator/renderer.ts
9539
+ // src/generator/placeholders.ts
9540
+ function createStyleTokens(prefix, value) {
9541
+ return {
9542
+ [prefix]: value,
9543
+ [`${prefix}_camel`]: applyNamingStyle(value, "camel"),
9544
+ [`${prefix}_pascal`]: applyNamingStyle(value, "pascal"),
9545
+ [`${prefix}_snake`]: applyNamingStyle(value, "snake"),
9546
+ [`${prefix}_kebab`]: applyNamingStyle(value, "kebab")
9547
+ };
9548
+ }
9549
+ function renderTemplate(template, tokenMap) {
9550
+ return template.replace(/\{([A-Za-z0-9_]+)\}/g, (_match, token) => {
9551
+ if (!(token in tokenMap)) {
9552
+ throw new Error(`Unknown placeholder token "${token}" in template "${template}"`);
9553
+ }
9554
+ return tokenMap[token];
9555
+ });
9556
+ }
9557
+ function resolvePlaceholderMap(baseTokens, outputConfig) {
9558
+ const resolved = {
9559
+ ...baseTokens
9560
+ };
9561
+ const reservedTokenKeys = new Set(Object.keys(baseTokens));
9562
+ const entries = Object.entries(outputConfig.placeholderMap ?? {});
9563
+ for (let index = 0; index < entries.length; index += 1) {
9564
+ const [key, value] = entries[index];
9565
+ if (reservedTokenKeys.has(key)) {
9566
+ continue;
9567
+ }
9568
+ let current = value;
9569
+ for (let depth = 0; depth < 8; depth += 1) {
9570
+ const next = renderTemplate(current, resolved);
9571
+ if (next === current) {
9572
+ break;
9573
+ }
9574
+ current = next;
9575
+ }
9576
+ resolved[key] = current;
9577
+ }
9578
+ return resolved;
9579
+ }
9580
+ function renderOutputPath(template, context, outputConfig) {
9581
+ const baseTokens = {
9582
+ provider: context.provider,
9583
+ kind: context.kind,
9584
+ ...createStyleTokens("database", context.database),
9585
+ ...createStyleTokens("schema", context.schema),
9586
+ ...createStyleTokens("model", context.model)
9587
+ };
9588
+ const tokens = resolvePlaceholderMap(baseTokens, outputConfig);
9589
+ return renderTemplate(template, tokens);
9590
+ }
9591
+
9592
+ // src/generator/render-shared.ts
7830
9593
  function normalizePath(pathValue) {
7831
9594
  return pathValue.replace(/\\/g, "/");
7832
9595
  }
@@ -7839,11 +9602,13 @@ function toModuleImportPath(fromFile, targetFile) {
7839
9602
  );
7840
9603
  return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
7841
9604
  }
9605
+ function resolveOutputPath(target, tokens, config) {
9606
+ return normalizePath(renderOutputPath(target, tokens, config.output));
9607
+ }
7842
9608
  function renderObjectKey(key) {
7843
- const escaped = escapeTypePropertyName(key);
7844
- return escaped.startsWith("'") ? escaped : escaped;
9609
+ return escapeTypePropertyName(key);
7845
9610
  }
7846
- function renderRelation(relation) {
9611
+ function renderRelationLiteral(relation) {
7847
9612
  const through = relation.through ? `,
7848
9613
  through: {
7849
9614
  schema: ${escapeStringLiteral(relation.through.schema)},
@@ -7859,54 +9624,12 @@ function renderRelation(relation) {
7859
9624
  targetColumns: [${relation.targetColumns.map((value) => escapeStringLiteral(value)).join(", ")}]${through}
7860
9625
  }`;
7861
9626
  }
7862
- function renderModelArtifact(snapshot, descriptor, config) {
7863
- const columnLines = Object.values(descriptor.table.columns).map((column) => {
7864
- const propertyName = escapeTypePropertyName(column.name);
7865
- const baseType = resolvePostgresColumnType(column);
7866
- const isOptional = column.isNullable;
7867
- const typeWithNullability = column.isNullable ? `${baseType} | null` : baseType;
7868
- return ` ${propertyName}${isOptional ? "?" : ""}: ${typeWithNullability}`;
7869
- }).join("\n");
7870
- const nullableLines = Object.values(descriptor.table.columns).map((column) => ` ${renderObjectKey(column.name)}: ${column.isNullable ? "true" : "false"}`).join(",\n");
7871
- const relationEntries = Object.entries(descriptor.table.relations);
7872
- const relationBlock = config.features.emitRelations && relationEntries.length > 0 ? `,
7873
- relations: {
7874
- ${relationEntries.map(([relationKey2, relationValue]) => ` ${renderObjectKey(relationKey2)}: ${renderRelation(relationValue)}`).join(",\n")}
7875
- }` : "";
7876
- const content = `import { defineModel } from '@xylex-group/athena'
7877
-
7878
- export interface ${descriptor.rowTypeName} {
7879
- ${columnLines}
7880
- }
7881
-
7882
- export type ${descriptor.insertTypeName} = Partial<${descriptor.rowTypeName}>
7883
- export type ${descriptor.updateTypeName} = Partial<${descriptor.insertTypeName}>
7884
-
7885
- export const ${descriptor.modelConstName} = defineModel<${descriptor.rowTypeName}, ${descriptor.insertTypeName}, ${descriptor.updateTypeName}>({
7886
- meta: {
7887
- database: ${escapeStringLiteral(snapshot.database)},
7888
- schema: ${escapeStringLiteral(descriptor.schemaName)},
7889
- model: ${escapeStringLiteral(descriptor.tableName)},
7890
- tableName: ${escapeStringLiteral(`${descriptor.schemaName}.${descriptor.tableName}`)},
7891
- primaryKey: [${descriptor.table.primaryKey.map((value) => escapeStringLiteral(value)).join(", ")}],
7892
- nullable: {
7893
- ${nullableLines}
7894
- }${relationBlock}
7895
- }
7896
- })
7897
- `;
7898
- return {
7899
- kind: "model",
7900
- path: descriptor.filePath,
7901
- content
7902
- };
7903
- }
7904
9627
  function renderSchemaArtifact(descriptor) {
7905
9628
  const importLines = descriptor.models.map((modelDescriptor) => {
7906
9629
  const importPath = toModuleImportPath(descriptor.filePath, modelDescriptor.filePath);
7907
- return `import { ${modelDescriptor.modelConstName} } from '${importPath}'`;
9630
+ return `import { ${modelDescriptor.exportConstName} } from '${importPath}'`;
7908
9631
  }).join("\n");
7909
- const modelEntries = descriptor.models.map((modelDescriptor) => ` ${renderObjectKey(modelDescriptor.tableName)}: ${modelDescriptor.modelConstName}`).join(",\n");
9632
+ const modelEntries = descriptor.models.map((modelDescriptor) => ` ${renderObjectKey(modelDescriptor.tableName)}: ${modelDescriptor.exportConstName}`).join(",\n");
7910
9633
  const content = `import { defineSchema } from '@xylex-group/athena'
7911
9634
  ${importLines ? `
7912
9635
  ${importLines}
@@ -7941,11 +9664,18 @@ ${schemaEntries}
7941
9664
  content
7942
9665
  };
7943
9666
  }
7944
- function renderRegistryArtifact(registryPath, databasePath, databaseConstName, registryConstName, databaseName) {
9667
+ function renderRegistryArtifact(registryPath, databasePath, databaseConstName, registryConstName, databaseName, generatedAt, outputFormat, schemaVersion) {
7945
9668
  const databaseImportPath = toModuleImportPath(registryPath, databasePath);
7946
9669
  const content = `import { defineRegistry } from '@xylex-group/athena'
7947
9670
  import { ${databaseConstName} } from '${databaseImportPath}'
7948
9671
 
9672
+ export const __athena_schema_meta = {
9673
+ schemaVersion: ${schemaVersion},
9674
+ generatedAt: ${escapeStringLiteral(generatedAt)},
9675
+ database: ${escapeStringLiteral(databaseName)},
9676
+ outputFormat: ${escapeStringLiteral(outputFormat)},
9677
+ } as const
9678
+
7949
9679
  export const ${registryConstName} = defineRegistry({
7950
9680
  ${renderObjectKey(databaseName)}: ${databaseConstName}
7951
9681
  })
@@ -8024,123 +9754,332 @@ function scopeDuplicateDescriptorPathsBySchema(descriptors) {
8024
9754
  }
8025
9755
  return nextDescriptors;
8026
9756
  }
8027
- var ArtifactComposer = class {
8028
- constructor(snapshot, config) {
8029
- this.snapshot = snapshot;
8030
- this.config = config;
8031
- }
8032
- compose() {
8033
- const providerName = this.snapshot.backend;
8034
- const databaseName = this.snapshot.database;
8035
- const modelDescriptors = [];
8036
- for (const schemaName of Object.keys(this.snapshot.schemas).sort()) {
8037
- const schema = this.snapshot.schemas[schemaName];
8038
- for (const tableName of Object.keys(schema.tables).sort()) {
8039
- const table = schema.tables[tableName];
8040
- const rowTypeName = `${toSafeIdentifier(`${schemaName} ${tableName}`, this.config.naming.modelType, "Model")}Row`;
8041
- const insertTypeName = `${toSafeIdentifier(`${schemaName} ${tableName}`, this.config.naming.modelType, "Model")}Insert`;
8042
- const updateTypeName = `${toSafeIdentifier(`${schemaName} ${tableName}`, this.config.naming.modelType, "Model")}Update`;
8043
- const modelConstName = `${toSafeIdentifier(`${schemaName} ${tableName} model`, this.config.naming.modelConst, "model")}`;
8044
- const modelPath = normalizePath(
8045
- renderOutputPath(this.config.output.targets.model, {
8046
- provider: providerName,
8047
- kind: "model",
8048
- database: databaseName,
8049
- schema: schemaName,
8050
- model: tableName
8051
- }, this.config.output)
8052
- );
8053
- modelDescriptors.push({
9757
+ function composeGeneratorArtifacts(input) {
9758
+ const { snapshot, config, createModelDescriptor, renderModelArtifact: renderModelArtifact3 } = input;
9759
+ const providerName = snapshot.backend;
9760
+ const databaseName = snapshot.database;
9761
+ const modelDescriptors = [];
9762
+ for (const schemaName of Object.keys(snapshot.schemas).sort()) {
9763
+ const schema = snapshot.schemas[schemaName];
9764
+ for (const tableName of Object.keys(schema.tables).sort()) {
9765
+ modelDescriptors.push(
9766
+ createModelDescriptor({
9767
+ providerName,
9768
+ databaseName,
8054
9769
  schemaName,
8055
9770
  tableName,
8056
- filePath: modelPath,
8057
- rowTypeName,
8058
- insertTypeName,
8059
- updateTypeName,
8060
- modelConstName,
8061
- table
8062
- });
8063
- }
8064
- }
8065
- const scopedModelDescriptors = scopeDuplicateDescriptorPathsBySchema(modelDescriptors);
8066
- let schemaDescriptors = Object.keys(this.snapshot.schemas).sort().map((schemaName) => {
8067
- const schemaPath = normalizePath(
8068
- renderOutputPath(this.config.output.targets.schema, {
8069
- provider: providerName,
8070
- kind: "schema",
8071
- database: databaseName,
8072
- schema: schemaName,
8073
- model: "index"
8074
- }, this.config.output)
9771
+ table: schema.tables[tableName]
9772
+ })
8075
9773
  );
8076
- return {
8077
- schemaName,
8078
- filePath: schemaPath,
8079
- schemaConstName: toSafeIdentifier(
8080
- `${schemaName} schema`,
8081
- this.config.naming.schemaConst,
8082
- "schema"
8083
- ),
8084
- models: scopedModelDescriptors.filter((model) => model.schemaName === schemaName)
8085
- };
8086
- });
8087
- schemaDescriptors = scopeDuplicateDescriptorPathsBySchema(schemaDescriptors);
8088
- const databasePath = normalizePath(
8089
- renderOutputPath(this.config.output.targets.database, {
9774
+ }
9775
+ }
9776
+ const scopedModelDescriptors = scopeDuplicateDescriptorPathsBySchema(modelDescriptors);
9777
+ let schemaDescriptors = Object.keys(snapshot.schemas).sort().map((schemaName) => ({
9778
+ schemaName,
9779
+ filePath: resolveOutputPath(
9780
+ config.output.targets.schema,
9781
+ {
9782
+ provider: providerName,
9783
+ kind: "schema",
9784
+ database: databaseName,
9785
+ schema: schemaName,
9786
+ model: "index"
9787
+ },
9788
+ config
9789
+ ),
9790
+ schemaConstName: toSafeIdentifier(
9791
+ `${schemaName} schema`,
9792
+ config.naming.schemaConst,
9793
+ "schema"
9794
+ ),
9795
+ models: scopedModelDescriptors.filter((model) => model.schemaName === schemaName)
9796
+ }));
9797
+ schemaDescriptors = scopeDuplicateDescriptorPathsBySchema(schemaDescriptors);
9798
+ const databaseDescriptor = {
9799
+ filePath: resolveOutputPath(
9800
+ config.output.targets.database,
9801
+ {
8090
9802
  provider: providerName,
8091
9803
  kind: "database",
8092
9804
  database: databaseName,
8093
9805
  schema: "index",
8094
9806
  model: "index"
8095
- }, this.config.output)
9807
+ },
9808
+ config
9809
+ ),
9810
+ databaseConstName: toSafeIdentifier(
9811
+ `${databaseName} database`,
9812
+ config.naming.databaseConst,
9813
+ "database"
9814
+ ),
9815
+ schemas: schemaDescriptors
9816
+ };
9817
+ const files = [];
9818
+ for (const modelDescriptor of scopedModelDescriptors) {
9819
+ files.push(renderModelArtifact3(modelDescriptor));
9820
+ }
9821
+ for (const schemaDescriptor of schemaDescriptors) {
9822
+ files.push(renderSchemaArtifact(schemaDescriptor));
9823
+ }
9824
+ files.push(renderDatabaseArtifact(databaseDescriptor));
9825
+ if (config.features.emitRegistry) {
9826
+ const registryPath = resolveOutputPath(
9827
+ config.output.targets.registry,
9828
+ {
9829
+ provider: providerName,
9830
+ kind: "registry",
9831
+ database: databaseName,
9832
+ schema: "index",
9833
+ model: "index"
9834
+ },
9835
+ config
9836
+ );
9837
+ files.push(
9838
+ renderRegistryArtifact(
9839
+ registryPath,
9840
+ databaseDescriptor.filePath,
9841
+ databaseDescriptor.databaseConstName,
9842
+ toSafeIdentifier("registry", config.naming.registryConst, "registry"),
9843
+ databaseName,
9844
+ snapshot.generatedAt,
9845
+ config.output.format,
9846
+ config.internal.schemaVersion
9847
+ )
8096
9848
  );
8097
- const databaseDescriptor = {
8098
- filePath: databasePath,
8099
- databaseConstName: toSafeIdentifier(
8100
- `${databaseName} database`,
8101
- this.config.naming.databaseConst,
8102
- "database"
8103
- ),
8104
- schemas: schemaDescriptors
8105
- };
8106
- const files = [];
8107
- for (const modelDescriptor of scopedModelDescriptors) {
8108
- files.push(renderModelArtifact(this.snapshot, modelDescriptor, this.config));
8109
- }
8110
- for (const schemaDescriptor of schemaDescriptors) {
8111
- files.push(renderSchemaArtifact(schemaDescriptor));
8112
- }
8113
- files.push(renderDatabaseArtifact(databaseDescriptor));
8114
- if (this.config.features.emitRegistry) {
8115
- const registryPath = normalizePath(
8116
- renderOutputPath(this.config.output.targets.registry, {
8117
- provider: providerName,
8118
- kind: "registry",
8119
- database: databaseName,
8120
- schema: "index",
8121
- model: "index"
8122
- }, this.config.output)
8123
- );
8124
- files.push(
8125
- renderRegistryArtifact(
8126
- registryPath,
8127
- databaseDescriptor.filePath,
8128
- databaseDescriptor.databaseConstName,
8129
- toSafeIdentifier("registry", this.config.naming.registryConst, "registry"),
8130
- databaseName
8131
- )
8132
- );
8133
- }
8134
- assertNoDuplicatePaths(files);
8135
- return {
8136
- snapshot: this.snapshot,
8137
- files
8138
- };
8139
9849
  }
8140
- };
9850
+ assertNoDuplicatePaths(files);
9851
+ return {
9852
+ snapshot,
9853
+ files
9854
+ };
9855
+ }
9856
+
9857
+ // src/generator/table-builder-renderer.ts
9858
+ var SAFE_NUMBER_TYPES = /* @__PURE__ */ new Set([
9859
+ "int2",
9860
+ "int4",
9861
+ "float4",
9862
+ "float8",
9863
+ "smallint",
9864
+ "integer",
9865
+ "real",
9866
+ "double precision"
9867
+ ]);
9868
+ var JSON_TYPES = /* @__PURE__ */ new Set(["json", "jsonb"]);
9869
+ var BOOLEAN_TYPES = /* @__PURE__ */ new Set(["bool", "boolean"]);
9870
+ var STRING_TYPES = /* @__PURE__ */ new Set([
9871
+ "int8",
9872
+ "bigint",
9873
+ "serial8",
9874
+ "bigserial",
9875
+ "numeric",
9876
+ "decimal",
9877
+ "money",
9878
+ "bytea"
9879
+ ]);
9880
+ function normalizeTypeLabel2(column) {
9881
+ const preferred = (column.udtName || column.dataType).toLowerCase().trim();
9882
+ if (column.arrayDimensions > 0 && preferred.startsWith("_")) {
9883
+ return preferred.slice(1);
9884
+ }
9885
+ return preferred;
9886
+ }
9887
+ function renderColumnBuilder(column) {
9888
+ const label = normalizeTypeLabel2(column);
9889
+ let helper;
9890
+ let expression;
9891
+ if (column.typeKind === "enum" && column.enumValues && column.enumValues.length > 0) {
9892
+ helper = "enumeration";
9893
+ expression = `enumeration([${column.enumValues.map((value) => escapeStringLiteral(value)).join(", ")}] as const)`;
9894
+ } else if (column.arrayDimensions > 0 || JSON_TYPES.has(label) || column.typeKind === "composite") {
9895
+ helper = "json";
9896
+ expression = `json<${resolvePostgresColumnType(column)}>()`;
9897
+ } else if (BOOLEAN_TYPES.has(label)) {
9898
+ helper = "boolean";
9899
+ expression = "boolean()";
9900
+ } else if (SAFE_NUMBER_TYPES.has(label)) {
9901
+ helper = "number";
9902
+ expression = "number()";
9903
+ } else if (STRING_TYPES.has(label)) {
9904
+ helper = "string";
9905
+ expression = "string()";
9906
+ } else {
9907
+ helper = "string";
9908
+ expression = "string()";
9909
+ }
9910
+ if (column.isNullable) {
9911
+ expression = `${expression}.optional()`;
9912
+ }
9913
+ if (column.hasDefault) {
9914
+ expression = `${expression}.defaulted()`;
9915
+ }
9916
+ if (column.isGenerated) {
9917
+ expression = `${expression}.generated()`;
9918
+ }
9919
+ return { helper, expression };
9920
+ }
9921
+ function renderModelArtifact(descriptor, config) {
9922
+ const helperImports = /* @__PURE__ */ new Set(["table"]);
9923
+ const columnLines = Object.entries(descriptor.table.columns).map(([columnName, column]) => {
9924
+ const propertyName = escapeTypePropertyName(columnName);
9925
+ const rendered = renderColumnBuilder(column);
9926
+ helperImports.add(rendered.helper);
9927
+ return ` ${propertyName}: ${rendered.expression}`;
9928
+ }).join(",\n");
9929
+ const helperImportLine = Array.from(helperImports).sort().join(", ");
9930
+ const rowSchemaConstName = `${descriptor.tableConstName}_row_schema`;
9931
+ const insertSchemaConstName = `${descriptor.tableConstName}_insert_schema`;
9932
+ const updateSchemaConstName = `${descriptor.tableConstName}_update_schema`;
9933
+ const formSchemaConstName = `${descriptor.tableConstName}_form_schema`;
9934
+ const relationEntries = Object.entries(descriptor.table.relations);
9935
+ const relationsAssignment = config.features.emitRelations && relationEntries.length > 0 ? `
9936
+ Object.assign(${descriptor.tableConstName}.meta, {
9937
+ relations: {
9938
+ ${relationEntries.map(([relationKey2, relationValue]) => ` ${renderObjectKey(relationKey2)}: ${renderRelationLiteral(relationValue)}`).join(",\n")}
9939
+ }
9940
+ })
9941
+ ` : "";
9942
+ const content = `import { ${helperImportLine} } from '@xylex-group/athena'
9943
+ import type { FormValuesOf, InsertOf, RowOf, UpdateOf } from '@xylex-group/athena'
9944
+
9945
+ export const ${descriptor.tableConstName} = table(${escapeStringLiteral(descriptor.tableName)})
9946
+ .schema(${escapeStringLiteral(descriptor.schemaName)})
9947
+ .columns({
9948
+ ${columnLines}
9949
+ })
9950
+ .primaryKey(${descriptor.table.primaryKey.map((value) => escapeStringLiteral(value)).join(", ")})
9951
+ ${relationsAssignment ? `${relationsAssignment}` : ""}
9952
+ export type ${descriptor.rowTypeName} = RowOf<typeof ${descriptor.tableConstName}>
9953
+ export type ${descriptor.insertTypeName} = InsertOf<typeof ${descriptor.tableConstName}>
9954
+ export type ${descriptor.updateTypeName} = UpdateOf<typeof ${descriptor.tableConstName}>
9955
+ export type ${descriptor.formValuesTypeName} = FormValuesOf<typeof ${descriptor.tableConstName}>
9956
+
9957
+ export const ${rowSchemaConstName} = ${descriptor.tableConstName}.schemas.row
9958
+ export const ${insertSchemaConstName} = ${descriptor.tableConstName}.schemas.insert
9959
+ export const ${updateSchemaConstName} = ${descriptor.tableConstName}.schemas.update
9960
+ export const ${formSchemaConstName} = ${descriptor.tableConstName}.schemas.form
9961
+ `;
9962
+ return {
9963
+ kind: "model",
9964
+ path: descriptor.filePath,
9965
+ content
9966
+ };
9967
+ }
9968
+ function generateTableBuilderArtifactsFromSnapshot(snapshot, config) {
9969
+ const normalizedConfig = "internal" in config ? config : normalizeGeneratorConfig(config);
9970
+ return composeGeneratorArtifacts({
9971
+ snapshot,
9972
+ config: normalizedConfig,
9973
+ createModelDescriptor({ providerName, databaseName, schemaName, tableName, table: table2 }) {
9974
+ const tableConstName = toSafeIdentifier(tableName, "preserve", "table");
9975
+ return {
9976
+ schemaName,
9977
+ tableName,
9978
+ filePath: resolveOutputPath(
9979
+ normalizedConfig.output.targets.model,
9980
+ {
9981
+ provider: providerName,
9982
+ kind: "model",
9983
+ database: databaseName,
9984
+ schema: schemaName,
9985
+ model: tableName
9986
+ },
9987
+ normalizedConfig
9988
+ ),
9989
+ rowTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Row`,
9990
+ insertTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Insert`,
9991
+ updateTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Update`,
9992
+ formValuesTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}FormValues`,
9993
+ tableConstName,
9994
+ exportConstName: tableConstName,
9995
+ table: table2
9996
+ };
9997
+ },
9998
+ renderModelArtifact: (descriptor) => renderModelArtifact(descriptor, normalizedConfig)
9999
+ });
10000
+ }
10001
+
10002
+ // src/generator/renderer.ts
10003
+ function renderModelArtifact2(databaseName, descriptor, config) {
10004
+ const columnLines = Object.values(descriptor.table.columns).map((column) => {
10005
+ const propertyName = escapeTypePropertyName(column.name);
10006
+ const baseType = resolvePostgresColumnType(column);
10007
+ const isOptional = column.isNullable;
10008
+ const typeWithNullability = column.isNullable ? `${baseType} | null` : baseType;
10009
+ return ` ${propertyName}${isOptional ? "?" : ""}: ${typeWithNullability}`;
10010
+ }).join("\n");
10011
+ const nullableLines = Object.values(descriptor.table.columns).map((column) => ` ${renderObjectKey(column.name)}: ${column.isNullable ? "true" : "false"}`).join(",\n");
10012
+ const relationEntries = Object.entries(descriptor.table.relations);
10013
+ const relationBlock = config.features.emitRelations && relationEntries.length > 0 ? `,
10014
+ relations: {
10015
+ ${relationEntries.map(([relationKey2, relationValue]) => ` ${renderObjectKey(relationKey2)}: ${renderRelationLiteral(relationValue)}`).join(",\n")}
10016
+ }` : "";
10017
+ const content = `import { defineModel } from '@xylex-group/athena'
10018
+
10019
+ export interface ${descriptor.rowTypeName} {
10020
+ ${columnLines}
10021
+ }
10022
+
10023
+ export type ${descriptor.insertTypeName} = Partial<${descriptor.rowTypeName}>
10024
+ export type ${descriptor.updateTypeName} = Partial<${descriptor.insertTypeName}>
10025
+
10026
+ export const ${descriptor.modelConstName} = defineModel<${descriptor.rowTypeName}, ${descriptor.insertTypeName}, ${descriptor.updateTypeName}>({
10027
+ meta: {
10028
+ database: ${escapeStringLiteral(databaseName)},
10029
+ schema: ${escapeStringLiteral(descriptor.schemaName)},
10030
+ model: ${escapeStringLiteral(descriptor.tableName)},
10031
+ tableName: ${escapeStringLiteral(`${descriptor.schemaName}.${descriptor.tableName}`)},
10032
+ primaryKey: [${descriptor.table.primaryKey.map((value) => escapeStringLiteral(value)).join(", ")}],
10033
+ nullable: {
10034
+ ${nullableLines}
10035
+ }${relationBlock}
10036
+ }
10037
+ })
10038
+ `;
10039
+ return {
10040
+ kind: "model",
10041
+ path: descriptor.filePath,
10042
+ content
10043
+ };
10044
+ }
8141
10045
  function generateArtifactsFromSnapshot(snapshot, config) {
8142
- const normalizedConfig = "naming" in config && "features" in config && "experimental" in config ? config : normalizeGeneratorConfig(config);
8143
- return new ArtifactComposer(snapshot, normalizedConfig).compose();
10046
+ const normalizedConfig = "internal" in config ? config : normalizeGeneratorConfig(config);
10047
+ if (normalizedConfig.output.format === "table-builder") {
10048
+ return generateTableBuilderArtifactsFromSnapshot(snapshot, normalizedConfig);
10049
+ }
10050
+ return composeGeneratorArtifacts({
10051
+ snapshot,
10052
+ config: normalizedConfig,
10053
+ createModelDescriptor({ providerName, databaseName, schemaName, tableName, table: table2 }) {
10054
+ const modelConstName = toSafeIdentifier(
10055
+ `${schemaName} ${tableName} model`,
10056
+ normalizedConfig.naming.modelConst,
10057
+ "model"
10058
+ );
10059
+ return {
10060
+ schemaName,
10061
+ tableName,
10062
+ filePath: resolveOutputPath(
10063
+ normalizedConfig.output.targets.model,
10064
+ {
10065
+ provider: providerName,
10066
+ kind: "model",
10067
+ database: databaseName,
10068
+ schema: schemaName,
10069
+ model: tableName
10070
+ },
10071
+ normalizedConfig
10072
+ ),
10073
+ rowTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Row`,
10074
+ insertTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Insert`,
10075
+ updateTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Update`,
10076
+ modelConstName,
10077
+ exportConstName: modelConstName,
10078
+ table: table2
10079
+ };
10080
+ },
10081
+ renderModelArtifact: (descriptor) => renderModelArtifact2(snapshot.database, descriptor, normalizedConfig)
10082
+ });
8144
10083
  }
8145
10084
 
8146
10085
  // src/generator/providers.ts
@@ -8355,15 +10294,15 @@ function readCookieFromHeaders(headers, name) {
8355
10294
  }
8356
10295
  return parseCookies(cookieHeader).get(name);
8357
10296
  }
8358
- function isRecord10(value) {
10297
+ function isRecord11(value) {
8359
10298
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8360
10299
  }
8361
10300
  function resolveSessionCandidate(value) {
8362
- if (!isRecord10(value)) {
10301
+ if (!isRecord11(value)) {
8363
10302
  return null;
8364
10303
  }
8365
- const session = isRecord10(value.session) ? value.session : void 0;
8366
- const user = isRecord10(value.user) ? value.user : void 0;
10304
+ const session = isRecord11(value.session) ? value.session : void 0;
10305
+ const user = isRecord11(value.user) ? value.user : void 0;
8367
10306
  if (session && typeof session.token === "string" && session.token.length > 0 && user) {
8368
10307
  return {
8369
10308
  session,
@@ -8373,7 +10312,7 @@ function resolveSessionCandidate(value) {
8373
10312
  return null;
8374
10313
  }
8375
10314
  function inferSessionPair(returned) {
8376
- return resolveSessionCandidate(returned) ?? (isRecord10(returned) ? resolveSessionCandidate(returned.data) : null) ?? (isRecord10(returned) ? resolveSessionCandidate(returned.session) : null);
10315
+ return resolveSessionCandidate(returned) ?? (isRecord11(returned) ? resolveSessionCandidate(returned.data) : null) ?? (isRecord11(returned) ? resolveSessionCandidate(returned.session) : null);
8377
10316
  }
8378
10317
  function resolveResponseHeaders(ctx) {
8379
10318
  if (ctx.context.responseHeaders instanceof Headers) {
@@ -8730,6 +10669,7 @@ exports.Backend = Backend;
8730
10669
  exports.DEFAULT_POSTGRES_SCHEMAS = DEFAULT_POSTGRES_SCHEMAS;
8731
10670
  exports.assertInt = assertInt;
8732
10671
  exports.athenaAuth = athenaAuth;
10672
+ exports.boolean = boolean;
8733
10673
  exports.coerceInt = coerceInt;
8734
10674
  exports.createAthenaStorageError = createAthenaStorageError;
8735
10675
  exports.createAuthClient = createAuthClient;
@@ -8745,17 +10685,21 @@ exports.defineGeneratorConfig = defineGeneratorConfig;
8745
10685
  exports.defineModel = defineModel;
8746
10686
  exports.defineRegistry = defineRegistry;
8747
10687
  exports.defineSchema = defineSchema;
10688
+ exports.enumeration = enumeration;
8748
10689
  exports.findGeneratorConfigPath = findGeneratorConfigPath;
8749
10690
  exports.generateArtifactsFromSnapshot = generateArtifactsFromSnapshot;
8750
10691
  exports.generatorEnv = generatorEnv;
10692
+ exports.getAthenaDebugAst = getAthenaDebugAst;
8751
10693
  exports.identifier = identifier;
8752
10694
  exports.isAthenaGatewayError = isAthenaGatewayError;
8753
10695
  exports.isOk = isOk;
10696
+ exports.json = json;
8754
10697
  exports.loadGeneratorConfig = loadGeneratorConfig;
8755
10698
  exports.normalizeAthenaError = normalizeAthenaError;
8756
10699
  exports.normalizeAthenaGatewayBaseUrl = normalizeAthenaGatewayBaseUrl;
8757
10700
  exports.normalizeGeneratorConfig = normalizeGeneratorConfig;
8758
10701
  exports.normalizeSchemaSelection = normalizeSchemaSelection;
10702
+ exports.number = number;
8759
10703
  exports.parseBooleanFlag = parseBooleanFlag2;
8760
10704
  exports.renderAthenaReactEmail = renderAthenaReactEmail;
8761
10705
  exports.requireAffected = requireAffected;
@@ -8765,6 +10709,8 @@ exports.resolvePostgresColumnType = resolvePostgresColumnType;
8765
10709
  exports.resolveProviderSchemas = resolveProviderSchemas;
8766
10710
  exports.runSchemaGenerator = runSchemaGenerator;
8767
10711
  exports.storageSdkManifest = storageSdkManifest;
10712
+ exports.string = string;
10713
+ exports.table = table;
8768
10714
  exports.toModelFormDefaults = toModelFormDefaults;
8769
10715
  exports.toModelPayload = toModelPayload;
8770
10716
  exports.unwrap = unwrap;