@xylex-group/athena 3.1.0 → 3.5.1

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 (100) hide show
  1. package/README.md +17 -1
  2. package/dist/admin.cjs +55 -1
  3. package/dist/admin.cjs.map +1 -1
  4. package/dist/admin.d.cts +32 -8
  5. package/dist/admin.d.ts +32 -8
  6. package/dist/admin.js +54 -2
  7. package/dist/admin.js.map +1 -1
  8. package/dist/athena-auth-url-C1FbVmN6.d.cts +200 -0
  9. package/dist/athena-auth-url-C1FbVmN6.d.ts +200 -0
  10. package/dist/{athena-request-headers-C7Jy-c_D.d.ts → athena-request-headers-BnFN2mbd.d.cts} +49 -201
  11. package/dist/{athena-request-headers-DujFFyMU.d.cts → athena-request-headers-Dwdkq2WR.d.ts} +49 -201
  12. package/dist/billing.cjs +1 -1
  13. package/dist/billing.cjs.map +1 -1
  14. package/dist/billing.js +1 -1
  15. package/dist/billing.js.map +1 -1
  16. package/dist/browser.cjs +3735 -248
  17. package/dist/browser.cjs.map +1 -1
  18. package/dist/browser.d.cts +11 -10
  19. package/dist/browser.d.ts +11 -10
  20. package/dist/browser.js +3726 -249
  21. package/dist/browser.js.map +1 -1
  22. package/dist/cli/index.cjs +3232 -190
  23. package/dist/cli/index.cjs.map +1 -1
  24. package/dist/cli/index.d.cts +4 -4
  25. package/dist/cli/index.d.ts +4 -4
  26. package/dist/cli/index.js +3232 -190
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/cloudflare.cjs +12914 -0
  29. package/dist/cloudflare.cjs.map +1 -0
  30. package/dist/cloudflare.d.cts +368 -0
  31. package/dist/cloudflare.d.ts +368 -0
  32. package/dist/cloudflare.js +12885 -0
  33. package/dist/cloudflare.js.map +1 -0
  34. package/dist/cookies.cjs +4 -3
  35. package/dist/cookies.cjs.map +1 -1
  36. package/dist/cookies.js +4 -3
  37. package/dist/cookies.js.map +1 -1
  38. package/dist/env.cjs +130 -0
  39. package/dist/env.cjs.map +1 -0
  40. package/dist/env.d.cts +70 -0
  41. package/dist/env.d.ts +70 -0
  42. package/dist/env.js +122 -0
  43. package/dist/env.js.map +1 -0
  44. package/dist/index.cjs +3749 -241
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +11 -10
  47. package/dist/index.d.ts +11 -10
  48. package/dist/index.js +3739 -242
  49. package/dist/index.js.map +1 -1
  50. package/dist/{model-form-BhWWsA-7.d.cts → model-form-D0ykVVOs.d.cts} +26 -4
  51. package/dist/{model-form-BbdzJ9Uh.d.ts → model-form-U8NVtfSA.d.ts} +26 -4
  52. package/dist/{module-xFd7_Igv.d.cts → module-CMWlJ1z3.d.cts} +5 -5
  53. package/dist/{module-DKkJKOuJ.d.ts → module-CZ-wPcf2.d.ts} +5 -5
  54. package/dist/next/client.cjs +3212 -196
  55. package/dist/next/client.cjs.map +1 -1
  56. package/dist/next/client.d.cts +6 -5
  57. package/dist/next/client.d.ts +6 -5
  58. package/dist/next/client.js +3212 -196
  59. package/dist/next/client.js.map +1 -1
  60. package/dist/next/server.cjs +4461 -781
  61. package/dist/next/server.cjs.map +1 -1
  62. package/dist/next/server.d.cts +139 -13
  63. package/dist/next/server.d.ts +139 -13
  64. package/dist/next/server.js +4451 -782
  65. package/dist/next/server.js.map +1 -1
  66. package/dist/{pipeline-DuKzYGia.d.cts → pipeline-BCpb4BX1.d.cts} +1 -1
  67. package/dist/{pipeline-wer2G9xW.d.ts → pipeline-CgmXwMeX.d.ts} +1 -1
  68. package/dist/{proxy-request-headers-m4D2Tduy.d.ts → proxy-request-headers-CttlcuRb.d.ts} +1 -1
  69. package/dist/{proxy-request-headers-DGxdoyA0.d.cts → proxy-request-headers-pIBSn1Fw.d.cts} +1 -1
  70. package/dist/react.cjs +290 -31
  71. package/dist/react.cjs.map +1 -1
  72. package/dist/react.d.cts +62 -12
  73. package/dist/react.d.ts +62 -12
  74. package/dist/react.js +290 -32
  75. package/dist/react.js.map +1 -1
  76. package/dist/schema-handlers-CvWqF-dW.d.ts +138 -0
  77. package/dist/schema-handlers-Dr8h9Jg-.d.cts +138 -0
  78. package/dist/social-providers.cjs +1 -1
  79. package/dist/social-providers.cjs.map +1 -1
  80. package/dist/social-providers.d.cts +1 -1
  81. package/dist/social-providers.d.ts +1 -1
  82. package/dist/social-providers.js +1 -1
  83. package/dist/social-providers.js.map +1 -1
  84. package/dist/{types-Bltx6iL6.d.ts → types-B2RZPivM.d.cts} +8 -1
  85. package/dist/{types-Bltx6iL6.d.cts → types-B2RZPivM.d.ts} +8 -1
  86. package/dist/{types-1ztXDgPa.d.cts → types-BKklrX4J.d.ts} +14 -2
  87. package/dist/{types-AOY-GLu8.d.cts → types-BVKpQmfY.d.cts} +11 -0
  88. package/dist/{types-AOY-GLu8.d.ts → types-BVKpQmfY.d.ts} +11 -0
  89. package/dist/{types-CgCv5o6R.d.cts → types-D5dj1v5Z.d.cts} +1 -1
  90. package/dist/{types-CccOiXPo.d.ts → types-DqBFwfhn.d.cts} +14 -2
  91. package/dist/{types-B75PdABb.d.ts → types-S-bTMPiM.d.ts} +1 -1
  92. package/dist/utils.cjs +30 -0
  93. package/dist/utils.cjs.map +1 -1
  94. package/dist/utils.d.cts +4 -3
  95. package/dist/utils.d.ts +4 -3
  96. package/dist/utils.js +30 -1
  97. package/dist/utils.js.map +1 -1
  98. package/dist/{v3-client-CWfZHcKL.d.cts → v3-client-DP-qg82X.d.cts} +323 -5
  99. package/dist/{v3-client-DZp2NEhK.d.ts → v3-client-OAai_JNs.d.ts} +323 -5
  100. package/package.json +25 -4
package/dist/index.js CHANGED
@@ -1842,6 +1842,8 @@ function buildUpdateDebugSql(payload) {
1842
1842
  sqlParts.push(`WHERE ${whereClauses.join(" AND ")}`);
1843
1843
  }
1844
1844
  const pagination = resolvePagination({
1845
+ limit: payload.limit,
1846
+ offset: payload.offset,
1845
1847
  currentPage: payload.current_page,
1846
1848
  pageSize: payload.page_size
1847
1849
  });
@@ -1864,6 +1866,8 @@ function buildDeleteDebugSql(payload) {
1864
1866
  sqlParts.push(`WHERE ${whereClauses.join(" AND ")}`);
1865
1867
  }
1866
1868
  const pagination = resolvePagination({
1869
+ limit: payload.limit,
1870
+ offset: payload.offset,
1867
1871
  currentPage: payload.current_page,
1868
1872
  pageSize: payload.page_size
1869
1873
  });
@@ -2007,7 +2011,7 @@ function buildAthenaGatewayUrl(baseUrl, path) {
2007
2011
 
2008
2012
  // package.json
2009
2013
  var package_default = {
2010
- version: "3.1.0"
2014
+ version: "3.5.1"
2011
2015
  };
2012
2016
 
2013
2017
  // src/sdk-version.ts
@@ -2304,13 +2308,14 @@ var LEGACY_COOKIE_PREFIX = "better-auth";
2304
2308
  var DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60;
2305
2309
  var DEFAULT_CACHE_MAX_AGE = 60 * 5;
2306
2310
  function isProductionRuntime() {
2307
- return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
2311
+ return globalThis.process?.env?.NODE_ENV === "production";
2308
2312
  }
2309
2313
  function getEnvironmentSecret() {
2310
- if (typeof process === "undefined") {
2314
+ const env = globalThis.process?.env;
2315
+ if (!env) {
2311
2316
  return void 0;
2312
2317
  }
2313
- return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET;
2318
+ return env.ATHENA_AUTH_SECRET || env.BETTER_AUTH_SECRET || env.AUTH_SECRET;
2314
2319
  }
2315
2320
  function isDynamicBaseURLConfig(baseURL) {
2316
2321
  return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
@@ -4767,6 +4772,14 @@ function createAuthModule(config = {}, runtimeOptions = {}) {
4767
4772
  changeEmailVerify: (input, options) => getWithQuery("/change-email/verify", input, options),
4768
4773
  deleteUserVerify: (input, options) => getWithQuery("/delete-user/verify", input, options),
4769
4774
  changePassword: (input, options) => postGeneric("/change-password", input, options),
4775
+ // Better Auth UI flat method aliases (also nested under session/account/social/user).
4776
+ listSessions: (input, options) => getGeneric("/list-sessions", input, options),
4777
+ revokeSession: sessionRevokeBinding,
4778
+ revokeOtherSessions,
4779
+ listAccounts: (input, options) => getGeneric("/list-accounts", input, options),
4780
+ unlinkAccount: (input, options) => postGeneric("/unlink-account", input, options),
4781
+ linkSocial: (input, options) => postGeneric("/link-social", input, options),
4782
+ updateUser: (input, options) => postGeneric("/update-user", input, options),
4770
4783
  user: {
4771
4784
  update: (input, options) => postGeneric("/update-user", input, options),
4772
4785
  delete: (input, options) => postGeneric("/delete-user", input, options),
@@ -5872,9 +5885,9 @@ function readHeadersField(value) {
5872
5885
  const headers = value.headers;
5873
5886
  if (!isRecord8(headers)) return {};
5874
5887
  const result = {};
5875
- for (const [key, headerValue2] of Object.entries(headers)) {
5876
- if (typeof headerValue2 === "string") {
5877
- result[key] = headerValue2;
5888
+ for (const [key, headerValue3] of Object.entries(headers)) {
5889
+ if (typeof headerValue3 === "string") {
5890
+ result[key] = headerValue3;
5878
5891
  }
5879
5892
  }
5880
5893
  return result;
@@ -9552,6 +9565,8 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, beha
9552
9565
  strip_nulls: mergedOptions?.stripNulls ?? true
9553
9566
  };
9554
9567
  if (executionState.order) payload.sort_by = executionState.order;
9568
+ if (executionState.limit !== void 0) payload.limit = executionState.limit;
9569
+ if (executionState.offset !== void 0) payload.offset = executionState.offset;
9555
9570
  if (executionState.currentPage !== void 0) payload.current_page = executionState.currentPage;
9556
9571
  if (executionState.pageSize !== void 0) payload.page_size = executionState.pageSize;
9557
9572
  if (executionState.totalPages !== void 0) payload.total_pages = executionState.totalPages;
@@ -9606,6 +9621,8 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, beha
9606
9621
  conditions: filters
9607
9622
  };
9608
9623
  if (executionState.order) payload.sort_by = executionState.order;
9624
+ if (executionState.limit !== void 0) payload.limit = executionState.limit;
9625
+ if (executionState.offset !== void 0) payload.offset = executionState.offset;
9609
9626
  if (executionState.currentPage !== void 0) payload.current_page = executionState.currentPage;
9610
9627
  if (executionState.pageSize !== void 0) payload.page_size = executionState.pageSize;
9611
9628
  if (executionState.totalPages !== void 0) payload.total_pages = executionState.totalPages;
@@ -9657,7 +9674,11 @@ function createQueryBuilder(client, formatGatewayResult, behavior, tracer) {
9657
9674
  if (!normalizedQuery) {
9658
9675
  throw new Error("query requires a non-empty string");
9659
9676
  }
9660
- const payload = { query: normalizedQuery };
9677
+ const params = options?.params;
9678
+ const payload = {
9679
+ query: normalizedQuery,
9680
+ ...Array.isArray(params) ? { params } : {}
9681
+ };
9661
9682
  const callsite = captureTraceCallsite(tracer);
9662
9683
  return executeRead(
9663
9684
  behavior,
@@ -9706,7 +9727,7 @@ function normalizeAuthClientConfig(auth, defaultBaseUrl) {
9706
9727
  }
9707
9728
  function createInternalClientCore(config) {
9708
9729
  const normalizedAuthConfig = normalizeAuthClientConfig(config.auth, config.authUrl);
9709
- const gatewayTransport = createAthenaGatewayClient({
9730
+ const gatewayTransport = config.gatewayTransport ?? createAthenaGatewayClient({
9710
9731
  baseUrl: config.baseUrl,
9711
9732
  apiKey: config.apiKey,
9712
9733
  client: config.client ?? void 0,
@@ -9861,205 +9882,2843 @@ function createInternalClientView(core, resolveContext) {
9861
9882
  };
9862
9883
  }
9863
9884
 
9864
- // src/billing/module.ts
9865
- var SDK_NAME5 = "xylex-group/athena-billing";
9866
- var SDK_HEADER_VALUE4 = buildSdkHeaderValue(SDK_NAME5);
9867
- var AthenaBillingError = class extends Error {
9868
- status;
9869
- endpoint;
9870
- method;
9871
- body;
9872
- constructor(input) {
9873
- super(input.message);
9874
- this.name = "AthenaBillingError";
9875
- this.status = input.status;
9876
- this.endpoint = input.endpoint;
9877
- this.method = input.method;
9878
- this.body = input.body;
9879
- }
9880
- };
9881
- var billingSdkManifest = {
9882
- namespace: "billing",
9883
- envelopeKind: "athena",
9884
- methods: [
9885
- { name: "getCapabilities", method: "GET", path: "/billing/v1/capabilities" },
9886
- { name: "createCheckout", method: "POST", path: "/billing/v1/checkouts" },
9887
- { name: "listProducts", method: "GET", path: "/billing/v1/products" },
9888
- { name: "listPrices", method: "GET", path: "/billing/v1/prices" },
9889
- { name: "listCustomers", method: "GET", path: "/billing/v1/customers" },
9890
- { name: "createCustomer", method: "POST", path: "/billing/v1/customers" },
9891
- { name: "getCustomer", method: "GET", path: "/billing/v1/customers/{id}" },
9892
- { name: "updateCustomer", method: "PATCH", path: "/billing/v1/customers/{id}" },
9893
- { name: "deleteCustomer", method: "DELETE", path: "/billing/v1/customers/{id}" },
9894
- { name: "listPayments", method: "GET", path: "/billing/v1/payments" },
9895
- { name: "createPayment", method: "POST", path: "/billing/v1/payments" },
9896
- { name: "getPayment", method: "GET", path: "/billing/v1/payments/{id}" },
9897
- { name: "cancelPayment", method: "POST", path: "/billing/v1/payments/{id}/cancel" },
9898
- { name: "listPaymentLinks", method: "GET", path: "/billing/v1/payment-links" },
9899
- { name: "createPaymentLink", method: "POST", path: "/billing/v1/payment-links" },
9900
- { name: "getPaymentLink", method: "GET", path: "/billing/v1/payment-links/{id}" },
9901
- { name: "updatePaymentLink", method: "PATCH", path: "/billing/v1/payment-links/{id}" },
9902
- { name: "deletePaymentLink", method: "DELETE", path: "/billing/v1/payment-links/{id}" },
9903
- { name: "listRefunds", method: "GET", path: "/billing/v1/refunds" },
9904
- { name: "createRefund", method: "POST", path: "/billing/v1/refunds" },
9905
- { name: "getRefund", method: "GET", path: "/billing/v1/refunds/{id}" },
9906
- { name: "cancelRefund", method: "POST", path: "/billing/v1/refunds/{id}/cancel" },
9907
- { name: "listSubscriptions", method: "GET", path: "/billing/v1/subscriptions" },
9908
- { name: "createSubscription", method: "POST", path: "/billing/v1/subscriptions" },
9909
- { name: "getSubscription", method: "GET", path: "/billing/v1/subscriptions/{id}" },
9910
- { name: "updateSubscription", method: "PATCH", path: "/billing/v1/subscriptions/{id}" },
9911
- { name: "cancelSubscription", method: "POST", path: "/billing/v1/subscriptions/{id}/cancel" },
9912
- { name: "listInvoices", method: "GET", path: "/billing/v1/invoices" },
9913
- { name: "getInvoice", method: "GET", path: "/billing/v1/invoices/{id}" },
9914
- { name: "listWebhooks", method: "GET", path: "/billing/v1/webhooks" },
9915
- { name: "createWebhook", method: "POST", path: "/billing/v1/webhooks" },
9916
- { name: "getWebhook", method: "GET", path: "/billing/v1/webhooks/{id}" },
9917
- { name: "updateWebhook", method: "PATCH", path: "/billing/v1/webhooks/{id}" },
9918
- { name: "deleteWebhook", method: "DELETE", path: "/billing/v1/webhooks/{id}" },
9919
- { name: "testWebhook", method: "POST", path: "/billing/v1/webhooks/{id}/test" },
9920
- {
9921
- name: "listConnections",
9922
- method: "GET",
9923
- path: "/admin/billing/clients/{client_name}/connections"
9924
- },
9925
- {
9926
- name: "createConnection",
9927
- method: "POST",
9928
- path: "/admin/billing/clients/{client_name}/connections"
9929
- },
9930
- {
9931
- name: "getConnection",
9932
- method: "GET",
9933
- path: "/admin/billing/clients/{client_name}/connections/{connection_id}"
9934
- },
9935
- {
9936
- name: "updateConnection",
9937
- method: "PATCH",
9938
- path: "/admin/billing/clients/{client_name}/connections/{connection_id}"
9939
- },
9940
- {
9941
- name: "deleteConnection",
9942
- method: "DELETE",
9943
- path: "/admin/billing/clients/{client_name}/connections/{connection_id}"
9944
- },
9945
- {
9946
- name: "reconcileDocument",
9947
- method: "POST",
9948
- path: "/admin/billing/clients/{client_name}/connections/{connection_id}/reconcile"
9949
- },
9950
- {
9951
- name: "listWebhookEvents",
9952
- method: "GET",
9953
- path: "/admin/billing/clients/{client_name}/webhook-events"
9885
+ // src/cloudflare/types.ts
9886
+ var CLOUDFLARE_EDGE_BASE_URL = "https://athena.local/cloudflare-edge";
9887
+ var CLOUDFLARE_EDGE_API_KEY = "cloudflare-edge-local";
9888
+
9889
+ // src/cloudflare/capabilities.ts
9890
+ function createGatewayCapabilities(options) {
9891
+ const storageConfigured = options?.storageConfigured ?? true;
9892
+ return {
9893
+ mode: "gateway",
9894
+ db: {
9895
+ engine: options?.engine ?? "postgresql",
9896
+ local: false,
9897
+ layers: {
9898
+ query: true,
9899
+ flatCrud: true,
9900
+ findManyAst: true,
9901
+ rpc: true,
9902
+ relations: true
9903
+ }
9954
9904
  },
9955
- {
9956
- name: "provisionWebhookSinks",
9957
- method: "POST",
9958
- path: "/admin/billing/clients/{client_name}/webhook-sinks/provision"
9905
+ storage: {
9906
+ local: false,
9907
+ objects: storageConfigured,
9908
+ catalogs: storageConfigured ? options?.storageCatalogs ?? true : false,
9909
+ backups: storageConfigured ? options?.storageBackups ?? true : false
9959
9910
  },
9960
- { name: "listGrants", method: "GET", path: "/admin/billing/grants" },
9961
- { name: "listProviders", method: "GET", path: "/admin/billing/providers" },
9962
- {
9963
- name: "listSinkHelpers",
9964
- method: "GET",
9965
- path: "/admin/webhook-sinks/helpers/billing"
9911
+ auth: {
9912
+ remote: options?.authRemote ?? true
9913
+ }
9914
+ };
9915
+ }
9916
+ function createCloudflareEdgeCapabilities(options) {
9917
+ const hasObjects = options.hasR2 || Boolean(options.hasRemoteStorage);
9918
+ return {
9919
+ mode: "cloudflare-edge",
9920
+ db: {
9921
+ engine: "cloudflare-d1",
9922
+ local: true,
9923
+ layers: {
9924
+ query: true,
9925
+ flatCrud: true,
9926
+ findManyAst: options.findManyAst ?? false,
9927
+ rpc: false,
9928
+ relations: false
9929
+ }
9966
9930
  },
9967
- {
9968
- name: "ingestProviderWebhook",
9969
- method: "POST",
9970
- path: "/billing/providers/{provider}/clients/{client_name}/connections/{connection_id}/webhook"
9931
+ storage: {
9932
+ // Local objects only when an R2 binding is present.
9933
+ local: options.hasR2,
9934
+ // Remote hybrid root can still expose storage.objects via the HTTP API.
9935
+ objects: hasObjects,
9936
+ catalogs: false,
9937
+ backups: false
9971
9938
  },
9972
- { name: "getDebugBilling", method: "GET", path: "/debug/billing" }
9973
- ]
9974
- };
9975
- function withPathParam2(path, name, value) {
9976
- return path.replace(`{${name}}`, encodeURIComponent(value));
9939
+ auth: {
9940
+ remote: options.authRemote
9941
+ }
9942
+ };
9977
9943
  }
9978
- function appendQuery3(path, query) {
9979
- if (!query) return path;
9980
- const params = new URLSearchParams();
9981
- for (const [key, value] of Object.entries(query)) {
9982
- if (value === void 0 || value === null) continue;
9983
- params.set(key, String(value));
9984
- }
9985
- const serialized = params.toString();
9986
- return serialized ? `${path}?${serialized}` : path;
9944
+
9945
+ // src/cloudflare/d1/runner.ts
9946
+ function resultColumns(rows) {
9947
+ const first = rows.find((value) => value && typeof value === "object" && !Array.isArray(value));
9948
+ if (!first) return [];
9949
+ return Object.keys(first);
9987
9950
  }
9988
- function connectionQuery(input) {
9989
- const query = {
9990
- connectionId: input.connectionId
9991
- };
9992
- if (input.clientName) query.clientName = input.clientName;
9993
- if ("cursor" in input && input.cursor) query.cursor = input.cursor;
9994
- if ("source" in input && input.source) query.source = input.source;
9995
- if ("limit" in input && input.limit !== void 0) query.limit = String(input.limit);
9996
- if ("offset" in input && input.offset !== void 0) query.offset = String(input.offset);
9997
- return query;
9951
+ function isIdentChar(ch) {
9952
+ if (!ch) return false;
9953
+ return /[A-Za-z0-9_]/.test(ch);
9998
9954
  }
9999
- function parseEnvelopeData(body) {
10000
- if (body && typeof body === "object" && "data" in body) {
10001
- return body.data;
9955
+ function scanSqlKeywordsOutsideLiterals(sql, onKeyword) {
9956
+ let inSingle = false;
9957
+ let inDouble = false;
9958
+ let inBacktick = false;
9959
+ let inBracket = false;
9960
+ let inLineComment = false;
9961
+ let inBlockComment = false;
9962
+ for (let i = 0; i < sql.length; i += 1) {
9963
+ const ch = sql[i];
9964
+ const next = sql[i + 1];
9965
+ if (inLineComment) {
9966
+ if (ch === "\n" || ch === "\r") inLineComment = false;
9967
+ continue;
9968
+ }
9969
+ if (inBlockComment) {
9970
+ if (ch === "*" && next === "/") {
9971
+ i += 1;
9972
+ inBlockComment = false;
9973
+ }
9974
+ continue;
9975
+ }
9976
+ if (inSingle) {
9977
+ if (ch === "'" && next === "'") {
9978
+ i += 1;
9979
+ continue;
9980
+ }
9981
+ if (ch === "'") inSingle = false;
9982
+ continue;
9983
+ }
9984
+ if (inDouble) {
9985
+ if (ch === '"' && next === '"') {
9986
+ i += 1;
9987
+ continue;
9988
+ }
9989
+ if (ch === '"') inDouble = false;
9990
+ continue;
9991
+ }
9992
+ if (inBacktick) {
9993
+ if (ch === "`" && next === "`") {
9994
+ i += 1;
9995
+ continue;
9996
+ }
9997
+ if (ch === "`") inBacktick = false;
9998
+ continue;
9999
+ }
10000
+ if (inBracket) {
10001
+ if (ch === "]") inBracket = false;
10002
+ continue;
10003
+ }
10004
+ if (ch === "-" && next === "-") {
10005
+ inLineComment = true;
10006
+ i += 1;
10007
+ continue;
10008
+ }
10009
+ if (ch === "/" && next === "*") {
10010
+ inBlockComment = true;
10011
+ i += 1;
10012
+ continue;
10013
+ }
10014
+ if (ch === "'") {
10015
+ inSingle = true;
10016
+ continue;
10017
+ }
10018
+ if (ch === '"') {
10019
+ inDouble = true;
10020
+ continue;
10021
+ }
10022
+ if (ch === "`") {
10023
+ inBacktick = true;
10024
+ continue;
10025
+ }
10026
+ if (ch === "[") {
10027
+ inBracket = true;
10028
+ continue;
10029
+ }
10030
+ if (!isIdentChar(ch) || isIdentChar(sql[i - 1])) {
10031
+ continue;
10032
+ }
10033
+ let end = i + 1;
10034
+ while (end < sql.length && isIdentChar(sql[end])) {
10035
+ end += 1;
10036
+ }
10037
+ const keyword = sql.slice(i, end);
10038
+ if (onKeyword(keyword, i)) {
10039
+ return;
10040
+ }
10041
+ i = end - 1;
10002
10042
  }
10003
- return body;
10004
10043
  }
10005
- function createBillingModule(config) {
10006
- const baseUrl = normalizeAthenaGatewayBaseUrl(config.baseUrl, {
10007
- label: "Athena billing base URL"
10044
+ function sqlContainsKeywordOutsideLiterals(sql, keyword) {
10045
+ const target = keyword.toUpperCase();
10046
+ let found = false;
10047
+ scanSqlKeywordsOutsideLiterals(sql, (token) => {
10048
+ if (token.toUpperCase() === target) {
10049
+ found = true;
10050
+ return true;
10051
+ }
10052
+ return false;
10008
10053
  });
10009
- const fetchImpl = config.fetchImpl ?? globalThis.fetch.bind(globalThis);
10010
- async function call(method, path, body, options, responseType = "json") {
10011
- const headers = buildAthenaRequestHeaders({
10012
- profile: "gateway",
10013
- sdkHeaderValue: SDK_HEADER_VALUE4,
10014
- apiKey: options?.apiKey ?? config.apiKey,
10015
- client: config.client,
10016
- configHeaders: {
10017
- ...config.headers ?? {}
10018
- },
10019
- callHeaders: options?.headers,
10020
- contentType: "application/json"
10021
- });
10022
- let requestBody;
10023
- if (body !== void 0 && body !== null) {
10024
- if (typeof body === "string" || body instanceof Blob || body instanceof ArrayBuffer || ArrayBuffer.isView(body) || body instanceof FormData || body instanceof URLSearchParams) {
10025
- requestBody = body;
10026
- } else {
10027
- requestBody = JSON.stringify(body);
10028
- if (!hasHeaderIgnoreCase(headers, "Content-Type")) {
10029
- headers["Content-Type"] = "application/json";
10030
- }
10054
+ return found;
10055
+ }
10056
+ function sqlFirstKeywordOutsideLiterals(sql) {
10057
+ let first = null;
10058
+ scanSqlKeywordsOutsideLiterals(sql, (token) => {
10059
+ first = token;
10060
+ return true;
10061
+ });
10062
+ return first;
10063
+ }
10064
+ var ROW_PRODUCING_LEAD_KEYWORDS = /* @__PURE__ */ new Set(["SELECT", "PRAGMA", "EXPLAIN", "VALUES"]);
10065
+ var MUTATION_LEAD_KEYWORDS = /* @__PURE__ */ new Set(["INSERT", "UPDATE", "DELETE", "REPLACE"]);
10066
+ var WITH_TERMINAL_KEYWORDS = /* @__PURE__ */ new Set([
10067
+ "SELECT",
10068
+ "INSERT",
10069
+ "UPDATE",
10070
+ "DELETE",
10071
+ "REPLACE",
10072
+ "VALUES",
10073
+ "PRAGMA",
10074
+ "EXPLAIN"
10075
+ ]);
10076
+ function sqlTerminalKeywordAfterWith(sql) {
10077
+ let inSingle = false;
10078
+ let inDouble = false;
10079
+ let inBacktick = false;
10080
+ let inBracket = false;
10081
+ let inLineComment = false;
10082
+ let inBlockComment = false;
10083
+ let depth = 0;
10084
+ let sawWith = false;
10085
+ for (let i = 0; i < sql.length; i += 1) {
10086
+ const ch = sql[i];
10087
+ const next = sql[i + 1];
10088
+ if (inLineComment) {
10089
+ if (ch === "\n" || ch === "\r") inLineComment = false;
10090
+ continue;
10091
+ }
10092
+ if (inBlockComment) {
10093
+ if (ch === "*" && next === "/") {
10094
+ i += 1;
10095
+ inBlockComment = false;
10031
10096
  }
10097
+ continue;
10032
10098
  }
10033
- const targetUrl = `${baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
10034
- const response = await fetchImpl(targetUrl, {
10035
- method,
10036
- headers,
10037
- body: requestBody,
10038
- signal: options?.signal
10039
- });
10040
- if (responseType === "text") {
10041
- const text = await response.text();
10042
- if (!response.ok) {
10043
- throw new AthenaBillingError({
10044
- message: `Billing request failed (${response.status})`,
10045
- status: response.status,
10046
- endpoint: path,
10047
- method,
10048
- body: text
10049
- });
10099
+ if (inSingle) {
10100
+ if (ch === "'" && next === "'") {
10101
+ i += 1;
10102
+ continue;
10050
10103
  }
10051
- return text;
10104
+ if (ch === "'") inSingle = false;
10105
+ continue;
10052
10106
  }
10053
- const rawText = await response.text();
10054
- let parsed = rawText;
10055
- if (rawText) {
10056
- try {
10057
- parsed = JSON.parse(rawText);
10058
- } catch {
10059
- parsed = rawText;
10107
+ if (inDouble) {
10108
+ if (ch === '"' && next === '"') {
10109
+ i += 1;
10110
+ continue;
10060
10111
  }
10061
- } else {
10062
- parsed = null;
10112
+ if (ch === '"') inDouble = false;
10113
+ continue;
10114
+ }
10115
+ if (inBacktick) {
10116
+ if (ch === "`" && next === "`") {
10117
+ i += 1;
10118
+ continue;
10119
+ }
10120
+ if (ch === "`") inBacktick = false;
10121
+ continue;
10122
+ }
10123
+ if (inBracket) {
10124
+ if (ch === "]") inBracket = false;
10125
+ continue;
10126
+ }
10127
+ if (ch === "-" && next === "-") {
10128
+ inLineComment = true;
10129
+ i += 1;
10130
+ continue;
10131
+ }
10132
+ if (ch === "/" && next === "*") {
10133
+ inBlockComment = true;
10134
+ i += 1;
10135
+ continue;
10136
+ }
10137
+ if (ch === "'") {
10138
+ inSingle = true;
10139
+ continue;
10140
+ }
10141
+ if (ch === '"') {
10142
+ inDouble = true;
10143
+ continue;
10144
+ }
10145
+ if (ch === "`") {
10146
+ inBacktick = true;
10147
+ continue;
10148
+ }
10149
+ if (ch === "[") {
10150
+ inBracket = true;
10151
+ continue;
10152
+ }
10153
+ if (ch === "(") {
10154
+ depth += 1;
10155
+ continue;
10156
+ }
10157
+ if (ch === ")") {
10158
+ if (depth > 0) depth -= 1;
10159
+ continue;
10160
+ }
10161
+ if (depth !== 0 || !isIdentChar(ch) || isIdentChar(sql[i - 1])) {
10162
+ continue;
10163
+ }
10164
+ let end = i + 1;
10165
+ while (end < sql.length && isIdentChar(sql[end])) {
10166
+ end += 1;
10167
+ }
10168
+ const keyword = sql.slice(i, end);
10169
+ const upper = keyword.toUpperCase();
10170
+ if (!sawWith) {
10171
+ if (upper === "WITH") {
10172
+ sawWith = true;
10173
+ }
10174
+ i = end - 1;
10175
+ continue;
10176
+ }
10177
+ if (WITH_TERMINAL_KEYWORDS.has(upper)) {
10178
+ return keyword;
10179
+ }
10180
+ i = end - 1;
10181
+ }
10182
+ return null;
10183
+ }
10184
+ function sqlLeadStatementKeyword(sql) {
10185
+ const first = sqlFirstKeywordOutsideLiterals(sql);
10186
+ if (!first) return null;
10187
+ if (first.toUpperCase() !== "WITH") return first;
10188
+ return sqlTerminalKeywordAfterWith(sql) ?? first;
10189
+ }
10190
+ function statementExpectsResultRows(sql) {
10191
+ const lead = sqlLeadStatementKeyword(sql);
10192
+ if (lead) {
10193
+ const upper = lead.toUpperCase();
10194
+ if (ROW_PRODUCING_LEAD_KEYWORDS.has(upper)) {
10195
+ return true;
10196
+ }
10197
+ if (MUTATION_LEAD_KEYWORDS.has(upper)) {
10198
+ return sqlContainsKeywordOutsideLiterals(sql, "RETURNING");
10199
+ }
10200
+ }
10201
+ return sqlContainsKeywordOutsideLiterals(sql, "RETURNING");
10202
+ }
10203
+ function collectRowsFromBatchResults(results) {
10204
+ const rows = [];
10205
+ for (const item of results) {
10206
+ if (Array.isArray(item.results) && item.results.length > 0) {
10207
+ rows.push(...item.results);
10208
+ }
10209
+ }
10210
+ return rows;
10211
+ }
10212
+ function sumBatchAffectedRows(results, statementCount) {
10213
+ let sum2 = 0;
10214
+ let sawChanges = false;
10215
+ for (const item of results) {
10216
+ const changes = item.meta?.changes;
10217
+ if (typeof changes === "number") {
10218
+ sum2 += changes;
10219
+ sawChanges = true;
10220
+ }
10221
+ }
10222
+ return sawChanges ? sum2 : statementCount;
10223
+ }
10224
+ function matchSqlKeywordAt(query, index, keyword) {
10225
+ const len = keyword.length;
10226
+ if (index + len > query.length) {
10227
+ return null;
10228
+ }
10229
+ const slice = query.slice(index, index + len);
10230
+ if (slice.toLowerCase() !== keyword.toLowerCase()) {
10231
+ return null;
10232
+ }
10233
+ const before = index === 0 ? "" : query[index - 1];
10234
+ const after = index + len >= query.length ? "" : query[index + len];
10235
+ const isIdent = (c) => /[A-Za-z0-9_]/.test(c);
10236
+ if (before && isIdent(before)) {
10237
+ return null;
10238
+ }
10239
+ if (after && isIdent(after)) {
10240
+ return null;
10241
+ }
10242
+ return len;
10243
+ }
10244
+ function splitSqlStatements(query) {
10245
+ const statements = [];
10246
+ let inSingle = false;
10247
+ let inDouble = false;
10248
+ let inBacktick = false;
10249
+ let inBracket = false;
10250
+ let inLineComment = false;
10251
+ let inBlockComment = false;
10252
+ let segmentStart = 0;
10253
+ let segmentHasContent = false;
10254
+ let awaitTriggerBegin = false;
10255
+ let triggerBodyDepth = 0;
10256
+ let caseDepth = 0;
10257
+ const flushSegment = (end) => {
10258
+ if (!segmentHasContent) {
10259
+ segmentStart = end + 1;
10260
+ return;
10261
+ }
10262
+ const sql = query.slice(segmentStart, end).trim();
10263
+ if (sql) {
10264
+ statements.push(sql);
10265
+ }
10266
+ segmentHasContent = false;
10267
+ segmentStart = end + 1;
10268
+ awaitTriggerBegin = false;
10269
+ triggerBodyDepth = 0;
10270
+ caseDepth = 0;
10271
+ };
10272
+ for (let i = 0; i < query.length; i += 1) {
10273
+ const ch = query[i];
10274
+ const next = query[i + 1];
10275
+ if (inLineComment) {
10276
+ if (ch === "\n" || ch === "\r") {
10277
+ inLineComment = false;
10278
+ }
10279
+ continue;
10280
+ }
10281
+ if (inBlockComment) {
10282
+ if (ch === "*" && next === "/") {
10283
+ inBlockComment = false;
10284
+ i += 1;
10285
+ }
10286
+ continue;
10287
+ }
10288
+ if (inSingle) {
10289
+ if (ch === "'" && next === "'") {
10290
+ i += 1;
10291
+ continue;
10292
+ }
10293
+ if (ch === "'") {
10294
+ inSingle = false;
10295
+ }
10296
+ continue;
10297
+ }
10298
+ if (inDouble) {
10299
+ if (ch === '"' && next === '"') {
10300
+ i += 1;
10301
+ continue;
10302
+ }
10303
+ if (ch === '"') {
10304
+ inDouble = false;
10305
+ }
10306
+ continue;
10307
+ }
10308
+ if (inBacktick) {
10309
+ if (ch === "`" && next === "`") {
10310
+ i += 1;
10311
+ continue;
10312
+ }
10313
+ if (ch === "`") {
10314
+ inBacktick = false;
10315
+ }
10316
+ continue;
10317
+ }
10318
+ if (inBracket) {
10319
+ if (ch === "]") {
10320
+ inBracket = false;
10321
+ }
10322
+ continue;
10323
+ }
10324
+ if (ch === "-" && next === "-") {
10325
+ inLineComment = true;
10326
+ i += 1;
10327
+ continue;
10328
+ }
10329
+ if (ch === "/" && next === "*") {
10330
+ inBlockComment = true;
10331
+ i += 1;
10332
+ continue;
10333
+ }
10334
+ if (ch === "'") {
10335
+ inSingle = true;
10336
+ segmentHasContent = true;
10337
+ continue;
10338
+ }
10339
+ if (ch === '"') {
10340
+ inDouble = true;
10341
+ segmentHasContent = true;
10342
+ continue;
10343
+ }
10344
+ if (ch === "`") {
10345
+ inBacktick = true;
10346
+ segmentHasContent = true;
10347
+ continue;
10348
+ }
10349
+ if (ch === "[") {
10350
+ inBracket = true;
10351
+ segmentHasContent = true;
10352
+ continue;
10353
+ }
10354
+ if (/[A-Za-z_]/.test(ch)) {
10355
+ const createLen = matchSqlKeywordAt(query, i, "CREATE");
10356
+ if (createLen != null) {
10357
+ let j2 = i + createLen;
10358
+ const skipWsAndComments = () => {
10359
+ while (j2 < query.length) {
10360
+ const c = query[j2];
10361
+ const n = query[j2 + 1];
10362
+ if (/\s/.test(c)) {
10363
+ j2 += 1;
10364
+ continue;
10365
+ }
10366
+ if (c === "-" && n === "-") {
10367
+ j2 += 2;
10368
+ while (j2 < query.length && query[j2] !== "\n" && query[j2] !== "\r") {
10369
+ j2 += 1;
10370
+ }
10371
+ continue;
10372
+ }
10373
+ if (c === "/" && n === "*") {
10374
+ j2 += 2;
10375
+ while (j2 < query.length) {
10376
+ if (query[j2] === "*" && query[j2 + 1] === "/") {
10377
+ j2 += 2;
10378
+ break;
10379
+ }
10380
+ j2 += 1;
10381
+ }
10382
+ continue;
10383
+ }
10384
+ break;
10385
+ }
10386
+ };
10387
+ skipWsAndComments();
10388
+ const tempLen = matchSqlKeywordAt(query, j2, "TEMPORARY") ?? matchSqlKeywordAt(query, j2, "TEMP");
10389
+ if (tempLen != null) {
10390
+ j2 += tempLen;
10391
+ skipWsAndComments();
10392
+ }
10393
+ const triggerLen = matchSqlKeywordAt(query, j2, "TRIGGER");
10394
+ if (triggerLen != null) {
10395
+ awaitTriggerBegin = true;
10396
+ segmentHasContent = true;
10397
+ i += createLen - 1;
10398
+ continue;
10399
+ }
10400
+ segmentHasContent = true;
10401
+ i += createLen - 1;
10402
+ continue;
10403
+ }
10404
+ const caseLen = matchSqlKeywordAt(query, i, "CASE");
10405
+ if (caseLen != null) {
10406
+ caseDepth += 1;
10407
+ segmentHasContent = true;
10408
+ i += caseLen - 1;
10409
+ continue;
10410
+ }
10411
+ const beginLen = matchSqlKeywordAt(query, i, "BEGIN");
10412
+ if (beginLen != null) {
10413
+ if (awaitTriggerBegin) {
10414
+ triggerBodyDepth += 1;
10415
+ awaitTriggerBegin = false;
10416
+ }
10417
+ segmentHasContent = true;
10418
+ i += beginLen - 1;
10419
+ continue;
10420
+ }
10421
+ const endLen = matchSqlKeywordAt(query, i, "END");
10422
+ if (endLen != null) {
10423
+ if (caseDepth > 0) {
10424
+ caseDepth -= 1;
10425
+ } else if (triggerBodyDepth > 0) {
10426
+ triggerBodyDepth -= 1;
10427
+ }
10428
+ segmentHasContent = true;
10429
+ i += endLen - 1;
10430
+ continue;
10431
+ }
10432
+ let j = i + 1;
10433
+ while (j < query.length && /[A-Za-z0-9_]/.test(query[j])) {
10434
+ j += 1;
10435
+ }
10436
+ segmentHasContent = true;
10437
+ i = j - 1;
10438
+ continue;
10439
+ }
10440
+ if (ch === ";") {
10441
+ if (triggerBodyDepth > 0 || caseDepth > 0) {
10442
+ segmentHasContent = true;
10443
+ continue;
10444
+ }
10445
+ flushSegment(i);
10446
+ continue;
10447
+ }
10448
+ if (!/\s/.test(ch)) {
10449
+ segmentHasContent = true;
10450
+ }
10451
+ }
10452
+ flushSegment(query.length);
10453
+ return statements;
10454
+ }
10455
+ function isMultiStatement(query) {
10456
+ return splitSqlStatements(query).length > 1;
10457
+ }
10458
+ function resolveSessionTarget(db, input) {
10459
+ const sessionValue = input.bookmark?.trim() || input.sessionMode?.trim();
10460
+ if (!sessionValue) {
10461
+ return { target: db, session: null };
10462
+ }
10463
+ if (typeof db.withSession !== "function") {
10464
+ throw new Error("D1 session mode/bookmark requested but withSession is not available");
10465
+ }
10466
+ const session = db.withSession(sessionValue);
10467
+ return { target: session, session };
10468
+ }
10469
+ function normalizeD1BindParams(params) {
10470
+ return params.map((value) => {
10471
+ if (typeof value === "boolean") {
10472
+ return value ? 1 : 0;
10473
+ }
10474
+ return value;
10475
+ });
10476
+ }
10477
+ async function executeD1Query(db, input) {
10478
+ const query = input.query?.trim();
10479
+ if (!query) {
10480
+ return { ok: false, error: "invalid_query", message: "query is required" };
10481
+ }
10482
+ const params = normalizeD1BindParams(Array.isArray(input.params) ? input.params : []);
10483
+ const { target, session } = resolveSessionTarget(db, input);
10484
+ if (isMultiStatement(query)) {
10485
+ if (params.length > 0) {
10486
+ return {
10487
+ ok: false,
10488
+ error: "invalid_query",
10489
+ message: "params are only supported for single prepared statements"
10490
+ };
10491
+ }
10492
+ const resolveBookmark = () => session?.getBookmark() ?? null;
10493
+ const parts = splitSqlStatements(query);
10494
+ if (typeof target.batch === "function") {
10495
+ const prepared = parts.map((part) => target.prepare(part));
10496
+ const results = await target.batch(prepared);
10497
+ const rows2 = collectRowsFromBatchResults(results);
10498
+ return {
10499
+ ok: true,
10500
+ rows: rows2,
10501
+ columns: resultColumns(rows2),
10502
+ // Prefer returned rows; otherwise sum mutation meta.changes (not statement count).
10503
+ count: rows2.length > 0 ? rows2.length : sumBatchAffectedRows(results, parts.length),
10504
+ bookmark: resolveBookmark(),
10505
+ meta: { statementCount: parts.length, results },
10506
+ statementCount: parts.length
10507
+ };
10508
+ }
10509
+ const canExec = typeof target.exec === "function" && !session;
10510
+ if (canExec) {
10511
+ const execResult = await target.exec(query);
10512
+ return {
10513
+ ok: true,
10514
+ rows: [],
10515
+ columns: [],
10516
+ durationMs: execResult.duration,
10517
+ count: execResult.count,
10518
+ bookmark: resolveBookmark(),
10519
+ meta: { statementCount: execResult.count },
10520
+ statementCount: execResult.count
10521
+ };
10522
+ }
10523
+ return {
10524
+ ok: false,
10525
+ error: "invalid_query",
10526
+ message: "multi-statement query requires D1 batch() or exec() support"
10527
+ };
10528
+ }
10529
+ let statement = target.prepare(query);
10530
+ if (params.length > 0) {
10531
+ statement = statement.bind(...params);
10532
+ }
10533
+ const expectsRows = statementExpectsResultRows(query);
10534
+ const result = expectsRows ? await statement.all() : await statement.run();
10535
+ if (result.success === false) {
10536
+ const errorField = result.error;
10537
+ const message = typeof errorField === "string" && errorField.trim() ? errorField : "D1 query failed";
10538
+ return {
10539
+ ok: false,
10540
+ error: "query_failed",
10541
+ message
10542
+ };
10543
+ }
10544
+ const rows = Array.isArray(result.results) ? result.results : [];
10545
+ const bookmark = session?.getBookmark() ?? null;
10546
+ const meta = result.meta ?? {};
10547
+ const changes = typeof meta.changes === "number" ? meta.changes : typeof result.meta?.changes === "number" ? result.meta.changes : void 0;
10548
+ return {
10549
+ ok: true,
10550
+ rows,
10551
+ columns: resultColumns(rows),
10552
+ durationMs: typeof result.meta?.duration === "number" ? result.meta.duration : void 0,
10553
+ count: expectsRows ? rows.length : changes ?? rows.length,
10554
+ bookmark,
10555
+ meta
10556
+ };
10557
+ }
10558
+ async function executeD1Batch(db, input) {
10559
+ const statements = Array.isArray(input.statements) ? input.statements : [];
10560
+ if (statements.length === 0) {
10561
+ return {
10562
+ ok: false,
10563
+ error: "invalid_batch",
10564
+ message: "statements must contain at least one item"
10565
+ };
10566
+ }
10567
+ const { target, session } = resolveSessionTarget(db, input);
10568
+ const prepared = statements.map((item) => {
10569
+ const query = item.query?.trim();
10570
+ if (!query) {
10571
+ throw new Error("statements[].query is required");
10572
+ }
10573
+ const params = normalizeD1BindParams(Array.isArray(item.params) ? item.params : []);
10574
+ let statement = target.prepare(query);
10575
+ if (params.length > 0) {
10576
+ statement = statement.bind(...params);
10577
+ }
10578
+ return statement;
10579
+ });
10580
+ const results = await target.batch(prepared);
10581
+ const bookmark = session?.getBookmark() ?? null;
10582
+ return {
10583
+ ok: true,
10584
+ results,
10585
+ bookmark
10586
+ };
10587
+ }
10588
+
10589
+ // src/cloudflare/d1/sql.ts
10590
+ function asSingle(sql, params) {
10591
+ return { sql, params };
10592
+ }
10593
+ function asBatch(statements) {
10594
+ if (statements.length === 0) {
10595
+ throw new D1SqlCompileError("empty_insert", "batch requires at least one statement");
10596
+ }
10597
+ return {
10598
+ sql: statements[0].sql,
10599
+ params: statements[0].params,
10600
+ statements
10601
+ };
10602
+ }
10603
+ function hasPaginationBounds(payload) {
10604
+ return payload.limit !== void 0 || payload.offset !== void 0 || payload.page_size !== void 0 || payload.current_page !== void 0;
10605
+ }
10606
+ function assertEffectiveMutationBounds(payload) {
10607
+ if (payload.current_page !== void 0 && payload.page_size === void 0 && payload.limit === void 0) {
10608
+ throw new D1SqlCompileError(
10609
+ "page_without_size",
10610
+ "current_page requires page_size (or limit) for bounded update/delete on D1 edge-local"
10611
+ );
10612
+ }
10613
+ const clause = limitOffsetClause(payload);
10614
+ if (!clause.trim()) {
10615
+ throw new D1SqlCompileError(
10616
+ "invalid_pagination_bounds",
10617
+ "Bounded update/delete requires limit, offset, and/or page_size on D1 edge-local"
10618
+ );
10619
+ }
10620
+ }
10621
+ var SQLITE_ROWID_ALIASES = /* @__PURE__ */ new Set(["rowid", "oid", "_rowid_"]);
10622
+ function referencedMutationColumns(payload) {
10623
+ const names = [];
10624
+ for (const condition of payload.conditions ?? []) {
10625
+ const column = (condition.column ?? condition.eq_column ?? "").trim();
10626
+ if (column) names.push(column);
10627
+ }
10628
+ if (payload.sort_by?.field?.trim()) {
10629
+ names.push(payload.sort_by.field.trim());
10630
+ }
10631
+ return names;
10632
+ }
10633
+ function resolveBoundedIdentityColumn(payload, options) {
10634
+ const refs = referencedMutationColumns(payload);
10635
+ const lower = refs.map((name) => name.toLowerCase());
10636
+ if (lower.some((name) => SQLITE_ROWID_ALIASES.has(name))) {
10637
+ throw new D1SqlCompileError(
10638
+ "bounded_mutation_unsafe_identity",
10639
+ "Bounded update/delete cannot use rowid/oid/_rowid_ in filters or order \u2014 those names may be user columns that shadow SQLite row identity. Resolve the table primary key (or a single-column unique index) instead."
10640
+ );
10641
+ }
10642
+ const identity = options?.identityColumn?.trim();
10643
+ if (!identity) {
10644
+ throw new D1SqlCompileError(
10645
+ "bounded_mutation_no_unique_identity",
10646
+ "Bounded update/delete requires a proven unique identity column from the table schema (single-column PRIMARY KEY or UNIQUE index). Cannot assume a column named id."
10647
+ );
10648
+ }
10649
+ if (SQLITE_ROWID_ALIASES.has(identity.toLowerCase())) {
10650
+ throw new D1SqlCompileError(
10651
+ "bounded_mutation_unsafe_identity",
10652
+ `Bounded update/delete cannot use identity column "${identity}" \u2014 it may shadow SQLite row identity.`
10653
+ );
10654
+ }
10655
+ return identity;
10656
+ }
10657
+ function boundedRowidInClause(table2, whereSql, whereParams, payload, options) {
10658
+ assertEffectiveMutationBounds(payload);
10659
+ const identity = resolveBoundedIdentityColumn(payload, options);
10660
+ const identitySql = quoteIdent(identity);
10661
+ const innerWhere = whereSql.replace(/^WHERE\s+/i, "");
10662
+ const parts = [
10663
+ `SELECT ${identitySql} FROM ${quoteIdent(table2)}`,
10664
+ innerWhere ? `WHERE ${innerWhere}` : "",
10665
+ orderClause(payload.sort_by),
10666
+ limitOffsetClause(payload)
10667
+ ].filter(Boolean);
10668
+ return {
10669
+ sql: `${identitySql} IN (${parts.join(" ")})`,
10670
+ params: [...whereParams]
10671
+ };
10672
+ }
10673
+ var D1SqlCompileError = class extends Error {
10674
+ code;
10675
+ constructor(code, message) {
10676
+ super(message);
10677
+ this.name = "D1SqlCompileError";
10678
+ this.code = code;
10679
+ }
10680
+ };
10681
+ var SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
10682
+ function quoteIdent(name) {
10683
+ const trimmed = name.trim();
10684
+ if (!trimmed) {
10685
+ throw new D1SqlCompileError("invalid_identifier", "Identifier is required");
10686
+ }
10687
+ if (trimmed.includes(".")) {
10688
+ throw new D1SqlCompileError(
10689
+ "schema_qualified_name",
10690
+ `Schema-qualified names are unsupported on D1 edge-local: ${trimmed}`
10691
+ );
10692
+ }
10693
+ if (!SAFE_IDENTIFIER.test(trimmed)) {
10694
+ throw new D1SqlCompileError(
10695
+ "invalid_identifier",
10696
+ `Invalid SQL identifier for D1 edge-local: ${trimmed}`
10697
+ );
10698
+ }
10699
+ return quoteQualifiedIdentifier(trimmed);
10700
+ }
10701
+ var RESPONSE_ALIAS_PATTERN2 = /^([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([A-Za-z_][A-Za-z0-9_]*)$/;
10702
+ var SQL_ALIAS_PATTERN2 = /^([A-Za-z_][A-Za-z0-9_]*)\s+(?:as\s+)?([A-Za-z_][A-Za-z0-9_]*)$/i;
10703
+ function quoteSelectTokenStrict(token) {
10704
+ const trimmed = token.trim();
10705
+ if (!trimmed || trimmed === "*") return trimmed || "*";
10706
+ if (SAFE_IDENTIFIER.test(trimmed)) {
10707
+ return quoteQualifiedIdentifier(trimmed);
10708
+ }
10709
+ const responseAlias = RESPONSE_ALIAS_PATTERN2.exec(trimmed);
10710
+ if (responseAlias) {
10711
+ const [, aliasIdentifier, baseIdentifier] = responseAlias;
10712
+ return `${quoteQualifiedIdentifier(baseIdentifier)} AS ${quoteQualifiedIdentifier(aliasIdentifier)}`;
10713
+ }
10714
+ const sqlAlias = SQL_ALIAS_PATTERN2.exec(trimmed);
10715
+ if (sqlAlias) {
10716
+ const [, baseIdentifier, aliasIdentifier] = sqlAlias;
10717
+ return `${quoteQualifiedIdentifier(baseIdentifier)} AS ${quoteQualifiedIdentifier(aliasIdentifier)}`;
10718
+ }
10719
+ throw new D1SqlCompileError(
10720
+ "unsafe_select",
10721
+ `SELECT/RETURNING expressions are not supported on D1 edge-local; use column names or aliases only: ${token}`
10722
+ );
10723
+ }
10724
+ function selectClause(columns) {
10725
+ if (columns === void 0 || columns === "*" || columns === "") return "*";
10726
+ if (typeof columns === "string") {
10727
+ const trimmed = columns.trim();
10728
+ if (!trimmed || trimmed === "*") return "*";
10729
+ return trimmed.split(",").map((part) => quoteSelectTokenStrict(part)).join(", ");
10730
+ }
10731
+ if (columns.length === 0) return "*";
10732
+ return columns.map((column) => quoteSelectTokenStrict(column)).join(", ");
10733
+ }
10734
+ function wantsReturning(payload) {
10735
+ return Boolean(payload.columns) && payload.head !== true;
10736
+ }
10737
+ function conditionToWhere(condition) {
10738
+ const column = condition.column?.trim() || condition.eq_column?.trim() || "";
10739
+ if (!column) {
10740
+ throw new D1SqlCompileError("invalid_condition", "Condition requires a column");
10741
+ }
10742
+ const col = quoteIdent(column);
10743
+ const operator = (condition.operator || "eq").toLowerCase();
10744
+ const value = condition.value !== void 0 ? condition.value : condition.eq_value;
10745
+ switch (operator) {
10746
+ case "eq": {
10747
+ if (Array.isArray(value)) {
10748
+ if (value.length === 0) {
10749
+ return { sql: "1 = 0", params: [] };
10750
+ }
10751
+ const placeholders = value.map(() => "?").join(", ");
10752
+ return { sql: `${col} IN (${placeholders})`, params: [...value] };
10753
+ }
10754
+ if (value === null) {
10755
+ return { sql: `${col} IS NULL`, params: [] };
10756
+ }
10757
+ return { sql: `${col} = ?`, params: [value ?? null] };
10758
+ }
10759
+ case "neq":
10760
+ if (value === null) {
10761
+ return { sql: `${col} IS NOT NULL`, params: [] };
10762
+ }
10763
+ return { sql: `${col} != ?`, params: [value ?? null] };
10764
+ case "gt":
10765
+ return { sql: `${col} > ?`, params: [value ?? null] };
10766
+ case "gte":
10767
+ return { sql: `${col} >= ?`, params: [value ?? null] };
10768
+ case "lt":
10769
+ return { sql: `${col} < ?`, params: [value ?? null] };
10770
+ case "lte":
10771
+ return { sql: `${col} <= ?`, params: [value ?? null] };
10772
+ case "like":
10773
+ return { sql: `${col} LIKE ?`, params: [value ?? null] };
10774
+ case "ilike":
10775
+ return { sql: `${col} LIKE ? COLLATE NOCASE`, params: [value ?? null] };
10776
+ case "in": {
10777
+ const items = Array.isArray(value) ? value : value === void 0 ? [] : [value];
10778
+ if (items.length === 0) {
10779
+ return { sql: "1 = 0", params: [] };
10780
+ }
10781
+ const placeholders = items.map(() => "?").join(", ");
10782
+ return { sql: `${col} IN (${placeholders})`, params: [...items] };
10783
+ }
10784
+ case "is": {
10785
+ if (value === null || value === "null") {
10786
+ return { sql: `${col} IS NULL`, params: [] };
10787
+ }
10788
+ if (value === true || value === "true") {
10789
+ return { sql: `${col} IS TRUE`, params: [] };
10790
+ }
10791
+ if (value === false || value === "false") {
10792
+ return { sql: `${col} IS FALSE`, params: [] };
10793
+ }
10794
+ return { sql: `${col} IS ?`, params: [value] };
10795
+ }
10796
+ case "not":
10797
+ case "or":
10798
+ case "contains":
10799
+ case "containedby":
10800
+ throw new D1SqlCompileError(
10801
+ "unsupported_operator",
10802
+ `Condition operator "${operator}" is not supported on D1 edge-local L1`
10803
+ );
10804
+ default:
10805
+ throw new D1SqlCompileError(
10806
+ "unsupported_operator",
10807
+ `Unknown condition operator "${operator}"`
10808
+ );
10809
+ }
10810
+ }
10811
+ function buildWhere(conditions) {
10812
+ if (!conditions?.length) {
10813
+ return { sql: "", params: [] };
10814
+ }
10815
+ const parts = [];
10816
+ const params = [];
10817
+ for (const condition of conditions) {
10818
+ if (!condition.operator && condition.eq_column) {
10819
+ const clause2 = conditionToWhere({
10820
+ ...condition,
10821
+ operator: "eq",
10822
+ column: condition.eq_column,
10823
+ value: condition.eq_value
10824
+ });
10825
+ parts.push(clause2.sql);
10826
+ params.push(...clause2.params);
10827
+ continue;
10828
+ }
10829
+ const clause = conditionToWhere(condition);
10830
+ parts.push(clause.sql);
10831
+ params.push(...clause.params);
10832
+ }
10833
+ return {
10834
+ sql: parts.length ? `WHERE ${parts.join(" AND ")}` : "",
10835
+ params
10836
+ };
10837
+ }
10838
+ function orderClause(order) {
10839
+ if (!order?.field?.trim()) return "";
10840
+ const direction = order.direction === "descending" ? "DESC" : "ASC";
10841
+ return `ORDER BY ${quoteIdent(order.field)} ${direction}`;
10842
+ }
10843
+ function limitOffsetClause(payload) {
10844
+ let limit = payload.limit;
10845
+ let offset = payload.offset;
10846
+ if (limit === void 0 && payload.page_size !== void 0) {
10847
+ limit = payload.page_size;
10848
+ }
10849
+ if (payload.current_page !== void 0 && offset === void 0) {
10850
+ const pageSize = payload.page_size ?? payload.limit;
10851
+ if (pageSize !== void 0) {
10852
+ offset = Math.max(0, (payload.current_page - 1) * pageSize);
10853
+ }
10854
+ }
10855
+ const parts = [];
10856
+ if (offset !== void 0 && limit === void 0) {
10857
+ parts.push("LIMIT -1");
10858
+ parts.push(`OFFSET ${Math.max(0, Math.trunc(offset))}`);
10859
+ } else {
10860
+ if (limit !== void 0) {
10861
+ parts.push(`LIMIT ${Math.max(0, Math.trunc(limit))}`);
10862
+ }
10863
+ if (offset !== void 0) {
10864
+ parts.push(`OFFSET ${Math.max(0, Math.trunc(offset))}`);
10865
+ }
10866
+ }
10867
+ return parts.join(" ");
10868
+ }
10869
+ function rejectStructuredRelations(payload) {
10870
+ const select = payload.select;
10871
+ if (select && typeof select === "object" && !Array.isArray(select)) {
10872
+ for (const value of Object.values(select)) {
10873
+ if (value && typeof value === "object") {
10874
+ throw new D1SqlCompileError(
10875
+ "relations_unsupported",
10876
+ "Nested relation selects are unsupported on D1 edge-local"
10877
+ );
10878
+ }
10879
+ }
10880
+ }
10881
+ if (payload.view_name) {
10882
+ throw new D1SqlCompileError(
10883
+ "view_unsupported",
10884
+ "view_name is unsupported on D1 edge-local L1"
10885
+ );
10886
+ }
10887
+ }
10888
+ function jsonValue(value) {
10889
+ if (value === void 0) return null;
10890
+ if (value !== null && typeof value === "object") {
10891
+ return JSON.stringify(value);
10892
+ }
10893
+ return value;
10894
+ }
10895
+ function compileD1Fetch(payload) {
10896
+ rejectStructuredRelations(payload);
10897
+ const table2 = payload.table_name?.trim();
10898
+ if (!table2) {
10899
+ throw new D1SqlCompileError("missing_table", "table_name is required for fetch");
10900
+ }
10901
+ let columns = payload.columns;
10902
+ if (payload.select && typeof payload.select === "object" && !Array.isArray(payload.select)) {
10903
+ const keys = Object.entries(payload.select).filter(([, enabled]) => enabled === true || enabled === 1).map(([key]) => key);
10904
+ if (keys.length > 0) {
10905
+ columns = keys;
10906
+ }
10907
+ } else if (typeof payload.select === "string" && payload.select.trim()) {
10908
+ columns = payload.select;
10909
+ }
10910
+ let where = buildWhere(payload.conditions);
10911
+ if (!where.sql && payload.where && typeof payload.where === "object") {
10912
+ const eqConditions = Object.entries(
10913
+ payload.where
10914
+ ).map(([column, value]) => ({
10915
+ column,
10916
+ operator: "eq",
10917
+ value
10918
+ }));
10919
+ where = buildWhere(eqConditions);
10920
+ }
10921
+ if (payload.head === true) {
10922
+ return compileD1CountFromWhere(table2, where);
10923
+ }
10924
+ const parts = [
10925
+ `SELECT ${selectClause(columns)} FROM ${quoteIdent(table2)}`,
10926
+ where.sql,
10927
+ orderClause(payload.sort_by),
10928
+ limitOffsetClause(payload)
10929
+ ].filter(Boolean);
10930
+ return asSingle(parts.join(" "), where.params);
10931
+ }
10932
+ function compileD1Count(payload) {
10933
+ rejectStructuredRelations(payload);
10934
+ const table2 = payload.table_name?.trim();
10935
+ if (!table2) {
10936
+ throw new D1SqlCompileError("missing_table", "table_name is required for count");
10937
+ }
10938
+ let where = buildWhere(payload.conditions);
10939
+ if (!where.sql && payload.where && typeof payload.where === "object") {
10940
+ const eqConditions = Object.entries(
10941
+ payload.where
10942
+ ).map(([column, value]) => ({
10943
+ column,
10944
+ operator: "eq",
10945
+ value
10946
+ }));
10947
+ where = buildWhere(eqConditions);
10948
+ }
10949
+ return compileD1CountFromWhere(table2, where);
10950
+ }
10951
+ function compileD1CountFromWhere(table2, where) {
10952
+ const parts = [
10953
+ `SELECT COUNT(*) AS __athena_count FROM ${quoteIdent(table2)}`,
10954
+ where.sql
10955
+ ].filter(Boolean);
10956
+ return asSingle(parts.join(" "), where.params);
10957
+ }
10958
+ function extractAthenaCount(rows) {
10959
+ const first = rows[0];
10960
+ const rawCount = first && typeof first === "object" && !Array.isArray(first) ? first.__athena_count : void 0;
10961
+ const count = typeof rawCount === "number" ? rawCount : typeof rawCount === "bigint" ? Number(rawCount) : Number(rawCount ?? 0);
10962
+ return Number.isFinite(count) ? count : 0;
10963
+ }
10964
+ function compileSingleRowInsert(table2, row, payload) {
10965
+ const columns = Object.keys(row);
10966
+ if (columns.length === 0) {
10967
+ if (payload.on_conflict) {
10968
+ throw new D1SqlCompileError(
10969
+ "default_values_upsert_unsupported",
10970
+ "DEFAULT VALUES upsert is unsupported on D1 edge-local; provide insert columns or omit onConflict"
10971
+ );
10972
+ }
10973
+ const parts2 = [`INSERT INTO ${quoteIdent(table2)} DEFAULT VALUES`];
10974
+ if (wantsReturning(payload)) {
10975
+ parts2.push(`RETURNING ${selectClause(payload.columns)}`);
10976
+ }
10977
+ return { sql: parts2.join(" "), params: [] };
10978
+ }
10979
+ const params = columns.map((column) => jsonValue(row[column]));
10980
+ const parts = [
10981
+ `INSERT INTO ${quoteIdent(table2)} (${columns.map(quoteIdent).join(", ")})`,
10982
+ `VALUES (${columns.map(() => "?").join(", ")})`
10983
+ ];
10984
+ appendOnConflict(parts, params, payload, columns);
10985
+ if (wantsReturning(payload)) {
10986
+ parts.push(`RETURNING ${selectClause(payload.columns)}`);
10987
+ }
10988
+ return { sql: parts.join(" "), params };
10989
+ }
10990
+ function parseOnConflictColumns(onConflict) {
10991
+ const raw = Array.isArray(onConflict) ? onConflict : [onConflict];
10992
+ const columns = [];
10993
+ for (const item of raw) {
10994
+ for (const part of String(item).split(",")) {
10995
+ const trimmed = part.trim();
10996
+ if (trimmed) columns.push(trimmed);
10997
+ }
10998
+ }
10999
+ if (columns.length === 0) {
11000
+ throw new D1SqlCompileError(
11001
+ "invalid_on_conflict",
11002
+ "on_conflict requires at least one column"
11003
+ );
11004
+ }
11005
+ return columns;
11006
+ }
11007
+ function appendOnConflict(parts, params, payload, insertColumns) {
11008
+ if (!payload.on_conflict) return;
11009
+ const conflictCols = parseOnConflictColumns(payload.on_conflict);
11010
+ const conflictSql = conflictCols.map(quoteIdent).join(", ");
11011
+ if (payload.update_body !== void 0 && payload.update_body !== null) {
11012
+ const entries = Object.entries(payload.update_body);
11013
+ if (entries.length === 0) {
11014
+ parts.push(`ON CONFLICT (${conflictSql}) DO NOTHING`);
11015
+ return;
11016
+ }
11017
+ const assignments2 = entries.map(([column, value]) => {
11018
+ params.push(jsonValue(value));
11019
+ return `${quoteIdent(column)} = ?`;
11020
+ });
11021
+ parts.push(`ON CONFLICT (${conflictSql}) DO UPDATE SET ${assignments2.join(", ")}`);
11022
+ return;
11023
+ }
11024
+ const conflictSet = new Set(conflictCols);
11025
+ const assignments = insertColumns.filter((column) => !conflictSet.has(column)).map((column) => {
11026
+ const quoted = quoteIdent(column);
11027
+ return `${quoted} = excluded.${quoted}`;
11028
+ });
11029
+ if (assignments.length === 0) {
11030
+ parts.push(`ON CONFLICT (${conflictSql}) DO NOTHING`);
11031
+ } else {
11032
+ parts.push(`ON CONFLICT (${conflictSql}) DO UPDATE SET ${assignments.join(", ")}`);
11033
+ }
11034
+ }
11035
+ function compileD1Insert(payload) {
11036
+ const table2 = payload.table_name?.trim();
11037
+ if (!table2) {
11038
+ throw new D1SqlCompileError("missing_table", "table_name is required for insert");
11039
+ }
11040
+ const rows = Array.isArray(payload.insert_body) ? payload.insert_body : [payload.insert_body];
11041
+ if (rows.length === 0) {
11042
+ throw new D1SqlCompileError("empty_insert", "insert_body must not be empty");
11043
+ }
11044
+ const columns = [];
11045
+ const seen = /* @__PURE__ */ new Set();
11046
+ for (const row of rows) {
11047
+ for (const key of Object.keys(row ?? {})) {
11048
+ if (seen.has(key)) continue;
11049
+ seen.add(key);
11050
+ columns.push(key);
11051
+ }
11052
+ }
11053
+ if (columns.length === 0) {
11054
+ if (rows.length === 1) {
11055
+ const compiled = compileSingleRowInsert(table2, {}, payload);
11056
+ return asSingle(compiled.sql, compiled.params);
11057
+ }
11058
+ throw new D1SqlCompileError(
11059
+ "empty_insert",
11060
+ "Multi-row insert_body cannot be empty objects; use a single {} for DEFAULT VALUES"
11061
+ );
11062
+ }
11063
+ const forceNullForMissing = payload.default_to_null === true;
11064
+ const isSparse = rows.some(
11065
+ (row) => columns.some((column) => !Object.prototype.hasOwnProperty.call(row, column))
11066
+ );
11067
+ if (isSparse && !forceNullForMissing && rows.length > 1) {
11068
+ return asBatch(
11069
+ rows.map((row) => compileSingleRowInsert(table2, row, payload))
11070
+ );
11071
+ }
11072
+ if (isSparse && !forceNullForMissing && rows.length === 1) {
11073
+ const compiled = compileSingleRowInsert(table2, rows[0], payload);
11074
+ return asSingle(compiled.sql, compiled.params);
11075
+ }
11076
+ const params = [];
11077
+ const valueGroups = rows.map((row) => {
11078
+ const placeholders = columns.map((column) => {
11079
+ const has = Object.prototype.hasOwnProperty.call(row, column);
11080
+ if (!has) {
11081
+ params.push(null);
11082
+ return "?";
11083
+ }
11084
+ params.push(jsonValue(row[column]));
11085
+ return "?";
11086
+ });
11087
+ return `(${placeholders.join(", ")})`;
11088
+ });
11089
+ const parts = [
11090
+ `INSERT INTO ${quoteIdent(table2)} (${columns.map(quoteIdent).join(", ")})`,
11091
+ `VALUES ${valueGroups.join(", ")}`
11092
+ ];
11093
+ appendOnConflict(parts, params, payload, columns);
11094
+ if (wantsReturning(payload)) {
11095
+ parts.push(`RETURNING ${selectClause(payload.columns)}`);
11096
+ }
11097
+ return asSingle(parts.join(" "), params);
11098
+ }
11099
+ function compileD1Update(payload, options) {
11100
+ const table2 = payload.table_name?.trim();
11101
+ if (!table2) {
11102
+ throw new D1SqlCompileError("missing_table", "table_name is required for update");
11103
+ }
11104
+ const entries = Object.entries(payload.update_body ?? {});
11105
+ if (entries.length === 0) {
11106
+ throw new D1SqlCompileError("empty_update", "update_body must not be empty");
11107
+ }
11108
+ const params = [];
11109
+ const assignments = entries.map(([column, value]) => {
11110
+ params.push(jsonValue(value));
11111
+ return `${quoteIdent(column)} = ?`;
11112
+ });
11113
+ const where = buildWhere(payload.conditions);
11114
+ if (!where.sql) {
11115
+ throw new D1SqlCompileError(
11116
+ "unfiltered_update",
11117
+ "UPDATE requires at least one condition on D1 edge-local"
11118
+ );
11119
+ }
11120
+ if (hasPaginationBounds(payload) || payload.sort_by) {
11121
+ if (!hasPaginationBounds(payload)) {
11122
+ throw new D1SqlCompileError(
11123
+ "order_without_bounds",
11124
+ "UPDATE with sort_by requires limit/offset or page_size/current_page on D1 edge-local"
11125
+ );
11126
+ }
11127
+ const bounded = boundedRowidInClause(
11128
+ table2,
11129
+ where.sql,
11130
+ where.params,
11131
+ {
11132
+ ...payload,
11133
+ conditions: payload.conditions
11134
+ },
11135
+ options
11136
+ );
11137
+ params.push(...bounded.params);
11138
+ const parts2 = [
11139
+ `UPDATE ${quoteIdent(table2)} SET ${assignments.join(", ")}`,
11140
+ `WHERE ${bounded.sql}`
11141
+ ];
11142
+ if (wantsReturning(payload)) {
11143
+ parts2.push(`RETURNING ${selectClause(payload.columns)}`);
11144
+ }
11145
+ return asSingle(parts2.join(" "), params);
11146
+ }
11147
+ params.push(...where.params);
11148
+ const parts = [
11149
+ `UPDATE ${quoteIdent(table2)} SET ${assignments.join(", ")}`,
11150
+ where.sql
11151
+ ];
11152
+ if (wantsReturning(payload)) {
11153
+ parts.push(`RETURNING ${selectClause(payload.columns)}`);
11154
+ }
11155
+ return asSingle(parts.join(" "), params);
11156
+ }
11157
+ function compileD1Delete(payload, options) {
11158
+ const table2 = payload.table_name?.trim();
11159
+ if (!table2) {
11160
+ throw new D1SqlCompileError("missing_table", "table_name is required for delete");
11161
+ }
11162
+ const conditions = [...payload.conditions ?? []];
11163
+ if (payload.resource_id !== void 0 && payload.resource_id !== null) {
11164
+ const hasResourceIdFilter = conditions.some((condition) => {
11165
+ const column = (condition.column ?? condition.eq_column ?? "").trim();
11166
+ return column === "resource_id";
11167
+ });
11168
+ const hasIdFilter = conditions.some((condition) => {
11169
+ const column = (condition.column ?? condition.eq_column ?? "").trim();
11170
+ return column === "id";
11171
+ });
11172
+ if (!hasResourceIdFilter && !hasIdFilter) {
11173
+ conditions.unshift({
11174
+ column: "id",
11175
+ operator: "eq",
11176
+ value: payload.resource_id
11177
+ });
11178
+ }
11179
+ }
11180
+ const where = buildWhere(conditions);
11181
+ if (!where.sql) {
11182
+ throw new D1SqlCompileError(
11183
+ "unfiltered_delete",
11184
+ "DELETE requires at least one condition or resource_id on D1 edge-local"
11185
+ );
11186
+ }
11187
+ if (hasPaginationBounds(payload) || payload.sort_by) {
11188
+ if (!hasPaginationBounds(payload)) {
11189
+ throw new D1SqlCompileError(
11190
+ "order_without_bounds",
11191
+ "DELETE with sort_by requires limit/offset or page_size/current_page on D1 edge-local"
11192
+ );
11193
+ }
11194
+ const bounded = boundedRowidInClause(
11195
+ table2,
11196
+ where.sql,
11197
+ where.params,
11198
+ {
11199
+ ...payload,
11200
+ conditions
11201
+ },
11202
+ options
11203
+ );
11204
+ const parts2 = [`DELETE FROM ${quoteIdent(table2)}`, `WHERE ${bounded.sql}`];
11205
+ if (wantsReturning(payload)) {
11206
+ parts2.push(`RETURNING ${selectClause(payload.columns)}`);
11207
+ }
11208
+ return asSingle(parts2.join(" "), bounded.params);
11209
+ }
11210
+ const parts = [`DELETE FROM ${quoteIdent(table2)}`, where.sql];
11211
+ if (wantsReturning(payload)) {
11212
+ parts.push(`RETURNING ${selectClause(payload.columns)}`);
11213
+ }
11214
+ return asSingle(parts.join(" "), where.params);
11215
+ }
11216
+
11217
+ // src/cloudflare/d1/sql-rewrite.ts
11218
+ var PG_CAST_TYPES = "text|uuid|citext|varchar|bpchar|char|integer|int4|int8|bigint|smallint|boolean|bool|jsonb|json|numeric|decimal|real|float|double precision|timestamptz|timestamp|date|bytea";
11219
+ function mapSqlOutsideLiterals(sql, transform) {
11220
+ let out = "";
11221
+ let buffer = "";
11222
+ let inSingle = false;
11223
+ let inDouble = false;
11224
+ let inBacktick = false;
11225
+ let inBracket = false;
11226
+ let inLineComment = false;
11227
+ let inBlockComment = false;
11228
+ const flushCode = () => {
11229
+ if (buffer) {
11230
+ out += transform(buffer);
11231
+ buffer = "";
11232
+ }
11233
+ };
11234
+ for (let i = 0; i < sql.length; i += 1) {
11235
+ const ch = sql[i];
11236
+ const next = sql[i + 1];
11237
+ if (inLineComment) {
11238
+ out += ch;
11239
+ if (ch === "\n" || ch === "\r") inLineComment = false;
11240
+ continue;
11241
+ }
11242
+ if (inBlockComment) {
11243
+ out += ch;
11244
+ if (ch === "*" && next === "/") {
11245
+ out += next;
11246
+ i += 1;
11247
+ inBlockComment = false;
11248
+ }
11249
+ continue;
11250
+ }
11251
+ if (inSingle) {
11252
+ out += ch;
11253
+ if (ch === "'" && next === "'") {
11254
+ out += next;
11255
+ i += 1;
11256
+ continue;
11257
+ }
11258
+ if (ch === "'") inSingle = false;
11259
+ continue;
11260
+ }
11261
+ if (inDouble) {
11262
+ out += ch;
11263
+ if (ch === '"' && next === '"') {
11264
+ out += next;
11265
+ i += 1;
11266
+ continue;
11267
+ }
11268
+ if (ch === '"') inDouble = false;
11269
+ continue;
11270
+ }
11271
+ if (inBacktick) {
11272
+ out += ch;
11273
+ if (ch === "`" && next === "`") {
11274
+ out += next;
11275
+ i += 1;
11276
+ continue;
11277
+ }
11278
+ if (ch === "`") inBacktick = false;
11279
+ continue;
11280
+ }
11281
+ if (inBracket) {
11282
+ out += ch;
11283
+ if (ch === "]") inBracket = false;
11284
+ continue;
11285
+ }
11286
+ if (ch === "-" && next === "-") {
11287
+ flushCode();
11288
+ out += ch;
11289
+ out += next;
11290
+ i += 1;
11291
+ inLineComment = true;
11292
+ continue;
11293
+ }
11294
+ if (ch === "/" && next === "*") {
11295
+ flushCode();
11296
+ out += ch;
11297
+ out += next;
11298
+ i += 1;
11299
+ inBlockComment = true;
11300
+ continue;
11301
+ }
11302
+ if (ch === "'") {
11303
+ flushCode();
11304
+ out += ch;
11305
+ inSingle = true;
11306
+ continue;
11307
+ }
11308
+ if (ch === '"') {
11309
+ flushCode();
11310
+ out += ch;
11311
+ inDouble = true;
11312
+ continue;
11313
+ }
11314
+ if (ch === "`") {
11315
+ flushCode();
11316
+ out += ch;
11317
+ inBacktick = true;
11318
+ continue;
11319
+ }
11320
+ if (ch === "[") {
11321
+ flushCode();
11322
+ out += ch;
11323
+ inBracket = true;
11324
+ continue;
11325
+ }
11326
+ buffer += ch;
11327
+ }
11328
+ flushCode();
11329
+ return out;
11330
+ }
11331
+ function isIdentChar2(ch) {
11332
+ if (!ch) return false;
11333
+ return /[A-Za-z0-9_]/.test(ch);
11334
+ }
11335
+ function collectLimitOffsetKeywords(sql) {
11336
+ const hits = [];
11337
+ let depth = 0;
11338
+ let statement = 0;
11339
+ let inSingle = false;
11340
+ let inDouble = false;
11341
+ let inBacktick = false;
11342
+ let inBracket = false;
11343
+ let inLineComment = false;
11344
+ let inBlockComment = false;
11345
+ for (let i = 0; i < sql.length; i += 1) {
11346
+ const ch = sql[i];
11347
+ const next = sql[i + 1];
11348
+ if (inLineComment) {
11349
+ if (ch === "\n" || ch === "\r") inLineComment = false;
11350
+ continue;
11351
+ }
11352
+ if (inBlockComment) {
11353
+ if (ch === "*" && next === "/") {
11354
+ i += 1;
11355
+ inBlockComment = false;
11356
+ }
11357
+ continue;
11358
+ }
11359
+ if (inSingle) {
11360
+ if (ch === "'" && next === "'") {
11361
+ i += 1;
11362
+ continue;
11363
+ }
11364
+ if (ch === "'") inSingle = false;
11365
+ continue;
11366
+ }
11367
+ if (inDouble) {
11368
+ if (ch === '"' && next === '"') {
11369
+ i += 1;
11370
+ continue;
11371
+ }
11372
+ if (ch === '"') inDouble = false;
11373
+ continue;
11374
+ }
11375
+ if (inBacktick) {
11376
+ if (ch === "`" && next === "`") {
11377
+ i += 1;
11378
+ continue;
11379
+ }
11380
+ if (ch === "`") inBacktick = false;
11381
+ continue;
11382
+ }
11383
+ if (inBracket) {
11384
+ if (ch === "]") inBracket = false;
11385
+ continue;
11386
+ }
11387
+ if (ch === "-" && next === "-") {
11388
+ inLineComment = true;
11389
+ i += 1;
11390
+ continue;
11391
+ }
11392
+ if (ch === "/" && next === "*") {
11393
+ inBlockComment = true;
11394
+ i += 1;
11395
+ continue;
11396
+ }
11397
+ if (ch === "'") {
11398
+ inSingle = true;
11399
+ continue;
11400
+ }
11401
+ if (ch === '"') {
11402
+ inDouble = true;
11403
+ continue;
11404
+ }
11405
+ if (ch === "`") {
11406
+ inBacktick = true;
11407
+ continue;
11408
+ }
11409
+ if (ch === "[") {
11410
+ inBracket = true;
11411
+ continue;
11412
+ }
11413
+ if (ch === "(") {
11414
+ depth += 1;
11415
+ continue;
11416
+ }
11417
+ if (ch === ")") {
11418
+ depth = Math.max(0, depth - 1);
11419
+ continue;
11420
+ }
11421
+ if (ch === ";" && depth === 0) {
11422
+ statement += 1;
11423
+ continue;
11424
+ }
11425
+ if (!isIdentChar2(ch) || isIdentChar2(sql[i - 1])) {
11426
+ continue;
11427
+ }
11428
+ const rest = sql.slice(i);
11429
+ if (/^LIMIT\b/i.test(rest)) {
11430
+ hits.push({ kind: "limit", start: i, depth, statement });
11431
+ i += 4;
11432
+ continue;
11433
+ }
11434
+ if (/^OFFSET\b/i.test(rest)) {
11435
+ hits.push({ kind: "offset", start: i, depth, statement });
11436
+ i += 5;
11437
+ }
11438
+ }
11439
+ return hits;
11440
+ }
11441
+ function injectLimitBeforeBareOffsets(sql) {
11442
+ const hits = collectLimitOffsetKeywords(sql);
11443
+ if (hits.length === 0) return sql;
11444
+ const injectAt = [];
11445
+ for (const hit of hits) {
11446
+ if (hit.kind !== "offset") continue;
11447
+ let hasLimit = false;
11448
+ for (let i = hits.length - 1; i >= 0; i -= 1) {
11449
+ const prev = hits[i];
11450
+ if (prev.start >= hit.start) continue;
11451
+ if (prev.statement !== hit.statement) continue;
11452
+ if (prev.depth !== hit.depth) continue;
11453
+ if (prev.kind === "limit") {
11454
+ hasLimit = true;
11455
+ break;
11456
+ }
11457
+ if (prev.kind === "offset") {
11458
+ break;
11459
+ }
11460
+ }
11461
+ if (!hasLimit) {
11462
+ injectAt.push(hit.start);
11463
+ }
11464
+ }
11465
+ if (injectAt.length === 0) return sql;
11466
+ let out = sql;
11467
+ for (let i = injectAt.length - 1; i >= 0; i -= 1) {
11468
+ const at = injectAt[i];
11469
+ out = `${out.slice(0, at)}LIMIT -1 ${out.slice(at)}`;
11470
+ }
11471
+ return out;
11472
+ }
11473
+ function rewritePostgresSqlForSqlite(sql) {
11474
+ const castPattern = new RegExp(`::(?:${PG_CAST_TYPES})\\b`, "gi");
11475
+ const withoutCastsAndIlike = mapSqlOutsideLiterals(sql, (chunk) => {
11476
+ let rewritten = chunk.replace(castPattern, "");
11477
+ rewritten = rewritten.replace(/\bILIKE\b/gi, "LIKE");
11478
+ return rewritten;
11479
+ });
11480
+ return injectLimitBeforeBareOffsets(withoutCastsAndIlike);
11481
+ }
11482
+
11483
+ // src/cloudflare/d1/transport.ts
11484
+ function hasPaginationBounds2(payload) {
11485
+ return payload.limit !== void 0 || payload.offset !== void 0 || payload.page_size !== void 0 || payload.current_page !== void 0;
11486
+ }
11487
+ function normalizeSqliteCollation(name) {
11488
+ const raw = String(name ?? "").trim().replace(/^["'`[]|["'`\]]$/g, "");
11489
+ if (!raw) return "BINARY";
11490
+ return raw.toUpperCase();
11491
+ }
11492
+ function findCreateTableColumnListOpen(createSql) {
11493
+ const m = /\bCREATE\s+(?:(?:TEMP|TEMPORARY|VIRTUAL)\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?/i.exec(
11494
+ createSql
11495
+ );
11496
+ if (!m) return -1;
11497
+ let i = m.index + m[0].length;
11498
+ let inSingle = false;
11499
+ let inDouble = false;
11500
+ let inBacktick = false;
11501
+ let inBracket = false;
11502
+ while (i < createSql.length) {
11503
+ const ch = createSql[i];
11504
+ if (inSingle) {
11505
+ if (ch === "'" && createSql[i + 1] === "'") {
11506
+ i += 2;
11507
+ continue;
11508
+ }
11509
+ if (ch === "'") inSingle = false;
11510
+ i++;
11511
+ continue;
11512
+ }
11513
+ if (inDouble) {
11514
+ if (ch === '"') inDouble = false;
11515
+ i++;
11516
+ continue;
11517
+ }
11518
+ if (inBacktick) {
11519
+ if (ch === "`") inBacktick = false;
11520
+ i++;
11521
+ continue;
11522
+ }
11523
+ if (inBracket) {
11524
+ if (ch === "]") inBracket = false;
11525
+ i++;
11526
+ continue;
11527
+ }
11528
+ if (ch === "'") {
11529
+ inSingle = true;
11530
+ i++;
11531
+ continue;
11532
+ }
11533
+ if (ch === '"') {
11534
+ inDouble = true;
11535
+ i++;
11536
+ continue;
11537
+ }
11538
+ if (ch === "`") {
11539
+ inBacktick = true;
11540
+ i++;
11541
+ continue;
11542
+ }
11543
+ if (ch === "[") {
11544
+ inBracket = true;
11545
+ i++;
11546
+ continue;
11547
+ }
11548
+ if (ch === "(") return i;
11549
+ i++;
11550
+ }
11551
+ return -1;
11552
+ }
11553
+ function parseColumnCollationFromCreateSql(createSql, columnName) {
11554
+ if (!createSql || !columnName) return null;
11555
+ const listOpen = findCreateTableColumnListOpen(createSql);
11556
+ if (listOpen < 0) return null;
11557
+ const listStart = listOpen + 1;
11558
+ const escaped = columnName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11559
+ const nameRe = new RegExp(
11560
+ `(?:^|[^\\w])(?:"${escaped}"|\`${escaped}\`|\\[${escaped}\\]|${escaped})\\s+`,
11561
+ "i"
11562
+ );
11563
+ const listSlice = createSql.slice(listStart);
11564
+ let nameMatchAbs = -1;
11565
+ let nameMatchLen = 0;
11566
+ {
11567
+ let i2 = 0;
11568
+ let depth2 = 1;
11569
+ let inSingle2 = false;
11570
+ let inDouble2 = false;
11571
+ let inBacktick2 = false;
11572
+ let inBracket2 = false;
11573
+ let segmentStart = 0;
11574
+ const trySegment = (from, to) => {
11575
+ if (nameMatchAbs >= 0) return;
11576
+ const segment = listSlice.slice(from, to);
11577
+ const m = nameRe.exec(segment);
11578
+ if (!m) return;
11579
+ const leading = segment.slice(0, m.index).trim();
11580
+ if (leading.length > 0) return;
11581
+ nameMatchAbs = listStart + from + m.index;
11582
+ nameMatchLen = m[0].length;
11583
+ };
11584
+ while (i2 < listSlice.length && depth2 > 0) {
11585
+ const ch = listSlice[i2];
11586
+ if (inSingle2) {
11587
+ if (ch === "'" && listSlice[i2 + 1] === "'") {
11588
+ i2 += 2;
11589
+ continue;
11590
+ }
11591
+ if (ch === "'") inSingle2 = false;
11592
+ i2++;
11593
+ continue;
11594
+ }
11595
+ if (inDouble2) {
11596
+ if (ch === '"') inDouble2 = false;
11597
+ i2++;
11598
+ continue;
11599
+ }
11600
+ if (inBacktick2) {
11601
+ if (ch === "`") inBacktick2 = false;
11602
+ i2++;
11603
+ continue;
11604
+ }
11605
+ if (inBracket2) {
11606
+ if (ch === "]") inBracket2 = false;
11607
+ i2++;
11608
+ continue;
11609
+ }
11610
+ if (ch === "'") {
11611
+ inSingle2 = true;
11612
+ i2++;
11613
+ continue;
11614
+ }
11615
+ if (ch === '"') {
11616
+ inDouble2 = true;
11617
+ i2++;
11618
+ continue;
11619
+ }
11620
+ if (ch === "`") {
11621
+ inBacktick2 = true;
11622
+ i2++;
11623
+ continue;
11624
+ }
11625
+ if (ch === "[") {
11626
+ inBracket2 = true;
11627
+ i2++;
11628
+ continue;
11629
+ }
11630
+ if (ch === "(") {
11631
+ depth2++;
11632
+ i2++;
11633
+ continue;
11634
+ }
11635
+ if (ch === ")") {
11636
+ depth2--;
11637
+ if (depth2 === 0) {
11638
+ trySegment(segmentStart, i2);
11639
+ break;
11640
+ }
11641
+ i2++;
11642
+ continue;
11643
+ }
11644
+ if (ch === "," && depth2 === 1) {
11645
+ trySegment(segmentStart, i2);
11646
+ segmentStart = i2 + 1;
11647
+ i2++;
11648
+ continue;
11649
+ }
11650
+ i2++;
11651
+ }
11652
+ }
11653
+ if (nameMatchAbs < 0 || nameMatchLen <= 0) return null;
11654
+ const start = nameMatchAbs + nameMatchLen;
11655
+ let i = start;
11656
+ let depth = 0;
11657
+ let inSingle = false;
11658
+ let inDouble = false;
11659
+ let inBacktick = false;
11660
+ let inBracket = false;
11661
+ while (i < createSql.length) {
11662
+ const ch = createSql[i];
11663
+ if (inSingle) {
11664
+ if (ch === "'" && createSql[i + 1] === "'") {
11665
+ i += 2;
11666
+ continue;
11667
+ }
11668
+ if (ch === "'") inSingle = false;
11669
+ i++;
11670
+ continue;
11671
+ }
11672
+ if (inDouble) {
11673
+ if (ch === '"') inDouble = false;
11674
+ i++;
11675
+ continue;
11676
+ }
11677
+ if (inBacktick) {
11678
+ if (ch === "`") inBacktick = false;
11679
+ i++;
11680
+ continue;
11681
+ }
11682
+ if (inBracket) {
11683
+ if (ch === "]") inBracket = false;
11684
+ i++;
11685
+ continue;
11686
+ }
11687
+ if (ch === "'") {
11688
+ inSingle = true;
11689
+ i++;
11690
+ continue;
11691
+ }
11692
+ if (ch === '"') {
11693
+ inDouble = true;
11694
+ i++;
11695
+ continue;
11696
+ }
11697
+ if (ch === "`") {
11698
+ inBacktick = true;
11699
+ i++;
11700
+ continue;
11701
+ }
11702
+ if (ch === "[") {
11703
+ inBracket = true;
11704
+ i++;
11705
+ continue;
11706
+ }
11707
+ if (ch === "(") {
11708
+ depth++;
11709
+ i++;
11710
+ continue;
11711
+ }
11712
+ if (ch === ")") {
11713
+ if (depth === 0) {
11714
+ break;
11715
+ }
11716
+ depth--;
11717
+ i++;
11718
+ continue;
11719
+ }
11720
+ if (ch === "," && depth === 0) {
11721
+ break;
11722
+ }
11723
+ i++;
11724
+ }
11725
+ const colDef = createSql.slice(start, i);
11726
+ const collRe = /\bCOLLATE\s+("([^"]+)"|'([^']+)'|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][\w$]*))/i;
11727
+ const match = collRe.exec(colDef);
11728
+ if (!match) return null;
11729
+ return match[2] ?? match[3] ?? match[4] ?? match[5] ?? match[6] ?? match[1] ?? null;
11730
+ }
11731
+ async function indexCollationMatchesColumn(d1, table2, tableSafe, indexSafe, columnName, session) {
11732
+ const xinfo = await executeD1Query(d1, {
11733
+ query: `PRAGMA index_xinfo("${indexSafe}")`,
11734
+ params: [],
11735
+ ...session
11736
+ });
11737
+ if (!xinfo.ok) {
11738
+ return false;
11739
+ }
11740
+ const xRows = xinfo.rows ?? [];
11741
+ const keyRows = xRows.filter((row) => {
11742
+ const isKey = row.key === 1 || row.key === true || Number(row.key) === 1;
11743
+ if (!isKey) return false;
11744
+ return typeof row.name === "string" && row.name === columnName;
11745
+ });
11746
+ if (keyRows.length === 0) {
11747
+ const byName = xRows.find(
11748
+ (row) => typeof row.name === "string" && row.name === columnName
11749
+ );
11750
+ if (!byName) return false;
11751
+ keyRows.push(byName);
11752
+ }
11753
+ const indexColl = normalizeSqliteCollation(keyRows[0]?.coll);
11754
+ const master = await executeD1Query(d1, {
11755
+ query: `SELECT sql AS create_sql FROM sqlite_master WHERE type = 'table' AND name = ?`,
11756
+ params: [table2],
11757
+ ...session
11758
+ });
11759
+ let createSql = "";
11760
+ if (master.ok && Array.isArray(master.rows) && master.rows.length > 0) {
11761
+ createSql = String(
11762
+ master.rows[0]?.create_sql ?? ""
11763
+ );
11764
+ }
11765
+ const columnCollRaw = parseColumnCollationFromCreateSql(createSql, columnName);
11766
+ const columnColl = normalizeSqliteCollation(columnCollRaw);
11767
+ return indexColl === columnColl;
11768
+ }
11769
+ async function resolveD1BoundedIdentityColumn(d1, tableName, session) {
11770
+ const table2 = tableName.trim();
11771
+ if (!table2) {
11772
+ throw new D1SqlCompileError("missing_table", "table_name is required for bounded mutation");
11773
+ }
11774
+ const safe = table2.replace(/"/g, '""');
11775
+ const info = await executeD1Query(d1, {
11776
+ query: `PRAGMA table_info("${safe}")`,
11777
+ params: [],
11778
+ ...session
11779
+ });
11780
+ if (!info.ok) {
11781
+ throw new D1SqlCompileError(
11782
+ "bounded_mutation_no_unique_identity",
11783
+ `Unable to introspect table "${table2}" for bounded mutation identity: ${info.message}`
11784
+ );
11785
+ }
11786
+ const cols = info.rows.filter(
11787
+ (row) => typeof row?.name === "string" && row.name.length > 0
11788
+ );
11789
+ const colByName = new Map(cols.map((col) => [col.name, col]));
11790
+ const isNotNullColumn = (name) => {
11791
+ const col = colByName.get(name);
11792
+ if (!col) return false;
11793
+ return col.notnull === 1 || col.notnull === true || Number(col.notnull) === 1;
11794
+ };
11795
+ const isIntegerPrimaryKeyType = (col) => {
11796
+ if (typeof col.pk !== "number" || col.pk <= 0) return false;
11797
+ const declared = String(col.type ?? "").trim().toUpperCase();
11798
+ return declared === "INTEGER";
11799
+ };
11800
+ const loadIndexList = async () => {
11801
+ const indexList = await executeD1Query(d1, {
11802
+ query: `PRAGMA index_list("${safe}")`,
11803
+ params: [],
11804
+ ...session
11805
+ });
11806
+ if (!indexList.ok) return null;
11807
+ return indexList.rows;
11808
+ };
11809
+ const isDescendingIntegerPrimaryKeyException = async (colName, indexes) => {
11810
+ if (indexes) {
11811
+ const hasPkOrigin = indexes.some(
11812
+ (index) => String(index.origin ?? "").toLowerCase() === "pk"
11813
+ );
11814
+ if (hasPkOrigin) return true;
11815
+ const originReported = indexes.some(
11816
+ (index) => index.origin !== void 0 && index.origin !== null && String(index.origin).length > 0
11817
+ );
11818
+ if (indexes.length === 0 || originReported) {
11819
+ return false;
11820
+ }
11821
+ }
11822
+ const master = await executeD1Query(d1, {
11823
+ query: `SELECT sql AS create_sql FROM sqlite_master WHERE type = 'table' AND name = ?`,
11824
+ params: [table2],
11825
+ ...session
11826
+ });
11827
+ if (!master.ok || !Array.isArray(master.rows) || master.rows.length === 0) {
11828
+ return false;
11829
+ }
11830
+ const createSql = String(
11831
+ master.rows[0]?.create_sql ?? ""
11832
+ );
11833
+ if (!createSql) return false;
11834
+ const escaped = colName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11835
+ const inlineDesc = new RegExp(
11836
+ `(?:^|[^\\w])(?:"${escaped}"|${escaped})\\s+INTEGER\\s+PRIMARY\\s+KEY\\s+DESC\\b`,
11837
+ "i"
11838
+ );
11839
+ const tableDesc = new RegExp(
11840
+ `PRIMARY\\s+KEY\\s*\\(\\s*(?:"${escaped}"|${escaped})\\s+DESC\\b`,
11841
+ "i"
11842
+ );
11843
+ return inlineDesc.test(createSql) || tableDesc.test(createSql);
11844
+ };
11845
+ const pkCols = cols.filter((row) => typeof row.pk === "number" && row.pk > 0).sort((a, b) => (a.pk ?? 0) - (b.pk ?? 0));
11846
+ let indexRows;
11847
+ if (pkCols.length === 1 && pkCols[0]?.name) {
11848
+ if (isIntegerPrimaryKeyType(pkCols[0])) {
11849
+ indexRows = await loadIndexList();
11850
+ const isDescException = await isDescendingIntegerPrimaryKeyException(
11851
+ pkCols[0].name,
11852
+ indexRows
11853
+ );
11854
+ if (!isDescException) {
11855
+ return pkCols[0].name;
11856
+ }
11857
+ } else if (isNotNullColumn(pkCols[0].name)) {
11858
+ indexRows = await loadIndexList();
11859
+ const pkIndex = (indexRows ?? []).find(
11860
+ (index) => String(index.origin ?? "").toLowerCase() === "pk"
11861
+ );
11862
+ if (pkIndex && typeof pkIndex.name === "string" && pkIndex.name) {
11863
+ const indexSafe = pkIndex.name.replace(/"/g, '""');
11864
+ const collMatch = await indexCollationMatchesColumn(
11865
+ d1,
11866
+ table2,
11867
+ safe,
11868
+ indexSafe,
11869
+ pkCols[0].name,
11870
+ session
11871
+ );
11872
+ if (collMatch) {
11873
+ return pkCols[0].name;
11874
+ }
11875
+ }
11876
+ }
11877
+ }
11878
+ if (indexRows === void 0) {
11879
+ indexRows = await loadIndexList();
11880
+ }
11881
+ if (indexRows) {
11882
+ for (const index of indexRows) {
11883
+ const unique = index.unique === 1 || index.unique === true || Number(index.unique) === 1;
11884
+ if (!unique || typeof index.name !== "string" || !index.name) continue;
11885
+ const isPartial = index.partial === 1 || index.partial === true || Number(index.partial) === 1;
11886
+ if (isPartial) {
11887
+ continue;
11888
+ }
11889
+ const indexSafe = index.name.replace(/"/g, '""');
11890
+ const indexInfo = await executeD1Query(d1, {
11891
+ query: `PRAGMA index_info("${indexSafe}")`,
11892
+ params: [],
11893
+ ...session
11894
+ });
11895
+ if (!indexInfo.ok) continue;
11896
+ const rawIndexCols = indexInfo.rows ?? [];
11897
+ const hasExpressionTerm = rawIndexCols.some((row) => {
11898
+ const nameOk = typeof row?.name === "string" && row.name.length > 0;
11899
+ if (!nameOk) return true;
11900
+ if (typeof row.cid === "number" && row.cid < 0) return true;
11901
+ return false;
11902
+ });
11903
+ if (hasExpressionTerm || rawIndexCols.length === 0) {
11904
+ continue;
11905
+ }
11906
+ const indexCols = rawIndexCols.filter(
11907
+ (row) => typeof row?.name === "string" && row.name.length > 0
11908
+ );
11909
+ if (indexCols.length === 1 && indexCols[0]?.name) {
11910
+ const identity = indexCols[0].name;
11911
+ if (!isNotNullColumn(identity)) {
11912
+ continue;
11913
+ }
11914
+ const collMatch = await indexCollationMatchesColumn(
11915
+ d1,
11916
+ table2,
11917
+ safe,
11918
+ indexSafe,
11919
+ identity,
11920
+ session
11921
+ );
11922
+ if (!collMatch) {
11923
+ continue;
11924
+ }
11925
+ return identity;
11926
+ }
11927
+ }
11928
+ }
11929
+ throw new D1SqlCompileError(
11930
+ "bounded_mutation_no_unique_identity",
11931
+ `Bounded update/delete on "${table2}" requires a proven single-column PRIMARY KEY or UNIQUE index`
11932
+ );
11933
+ }
11934
+ async function compileOptionsForBoundedMutation(d1, payload, session) {
11935
+ if (!hasPaginationBounds2(payload) && !payload.sort_by) {
11936
+ return void 0;
11937
+ }
11938
+ if (!hasPaginationBounds2(payload)) {
11939
+ return void 0;
11940
+ }
11941
+ const identityColumn = await resolveD1BoundedIdentityColumn(
11942
+ d1,
11943
+ payload.table_name ?? "",
11944
+ session
11945
+ );
11946
+ return { identityColumn };
11947
+ }
11948
+ function headerValue2(options, name) {
11949
+ const headers = options?.headers;
11950
+ if (!headers) return void 0;
11951
+ const lower = name.toLowerCase();
11952
+ for (const [key, value] of Object.entries(headers)) {
11953
+ if (key.toLowerCase() === lower && value?.trim()) {
11954
+ return value.trim();
11955
+ }
11956
+ }
11957
+ return void 0;
11958
+ }
11959
+ function sessionFromOptions(options, defaults) {
11960
+ return {
11961
+ bookmark: headerValue2(options, "x-athena-d1-bookmark") ?? null,
11962
+ sessionMode: headerValue2(options, "x-athena-d1-session-mode") ?? defaults.defaultSessionMode ?? null
11963
+ };
11964
+ }
11965
+ function resolveStripNulls(payloadStrip, callOptions, defaultValue = true) {
11966
+ if (typeof payloadStrip === "boolean") return payloadStrip;
11967
+ if (typeof callOptions?.stripNulls === "boolean") return callOptions.stripNulls;
11968
+ return defaultValue;
11969
+ }
11970
+ function stripNullPropertiesFromRows(rows) {
11971
+ return rows.map((row) => {
11972
+ if (row == null || typeof row !== "object" || Array.isArray(row)) {
11973
+ return row;
11974
+ }
11975
+ const out = {};
11976
+ for (const [key, value] of Object.entries(row)) {
11977
+ if (value !== null) {
11978
+ out[key] = value;
11979
+ }
11980
+ }
11981
+ return out;
11982
+ });
11983
+ }
11984
+ function maybeStripNullRows(rows, strip) {
11985
+ return strip ? stripNullPropertiesFromRows(rows) : rows;
11986
+ }
11987
+ function successResponse(data, count, raw, bookmark) {
11988
+ const response = {
11989
+ ok: true,
11990
+ status: 200,
11991
+ statusText: "OK",
11992
+ data,
11993
+ count: count ?? null,
11994
+ error: void 0,
11995
+ errorDetails: null,
11996
+ raw
11997
+ };
11998
+ if (bookmark) {
11999
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
12000
+ const rawRecord = raw;
12001
+ rawRecord.bookmark = bookmark;
12002
+ }
12003
+ }
12004
+ return response;
12005
+ }
12006
+ function errorResponse(status, code, message, endpoint, method, hint) {
12007
+ const error = new AthenaGatewayError({
12008
+ code,
12009
+ message,
12010
+ status,
12011
+ endpoint,
12012
+ method,
12013
+ hint
12014
+ });
12015
+ return {
12016
+ ok: false,
12017
+ status,
12018
+ statusText: null,
12019
+ data: null,
12020
+ error: error.message,
12021
+ errorDetails: error.toDetails(),
12022
+ raw: { error: message, code }
12023
+ };
12024
+ }
12025
+ function compileErrorResponse(error, endpoint, method) {
12026
+ if (error instanceof D1SqlCompileError) {
12027
+ return errorResponse(
12028
+ 400,
12029
+ "HTTP_ERROR",
12030
+ error.message,
12031
+ endpoint,
12032
+ method,
12033
+ `D1 SQL compile failed (${error.code})`
12034
+ );
12035
+ }
12036
+ const message = error instanceof Error ? error.message : String(error);
12037
+ return errorResponse(500, "UNKNOWN_ERROR", message, endpoint, method);
12038
+ }
12039
+ function createCloudflareD1GatewayTransport(options) {
12040
+ const { d1 } = options;
12041
+ async function runCompiled(compiled, callOptions, endpoint, method, mapResult, stripNulls = true) {
12042
+ try {
12043
+ const session = sessionFromOptions(callOptions, options);
12044
+ if (compiled.statements && compiled.statements.length > 1) {
12045
+ const batch = await executeD1Batch(d1, {
12046
+ statements: compiled.statements.map((statement) => ({
12047
+ query: statement.sql,
12048
+ params: statement.params
12049
+ })),
12050
+ ...session
12051
+ });
12052
+ if (!batch.ok) {
12053
+ return errorResponse(400, "HTTP_ERROR", batch.message, endpoint, method);
12054
+ }
12055
+ const rows2 = maybeStripNullRows(
12056
+ batch.results.flatMap(
12057
+ (item) => Array.isArray(item.results) ? item.results : []
12058
+ ),
12059
+ stripNulls
12060
+ );
12061
+ const changes = batch.results.reduce((sum2, item) => {
12062
+ const meta = item?.meta;
12063
+ const n = meta && typeof meta === "object" && typeof meta.changes === "number" ? meta.changes : 0;
12064
+ return sum2 + n;
12065
+ }, 0);
12066
+ const count = rows2.length > 0 ? rows2.length : changes;
12067
+ const mapped2 = mapResult?.(rows2, count) ?? {
12068
+ data: rows2,
12069
+ count
12070
+ };
12071
+ return successResponse(mapped2.data, mapped2.count, batch, batch.bookmark);
12072
+ }
12073
+ const result = await executeD1Query(d1, {
12074
+ query: compiled.sql,
12075
+ params: compiled.params,
12076
+ ...session
12077
+ });
12078
+ if (!result.ok) {
12079
+ return errorResponse(400, "HTTP_ERROR", result.message, endpoint, method);
12080
+ }
12081
+ const rows = maybeStripNullRows(result.rows, stripNulls);
12082
+ const mapped = mapResult?.(rows, result.count) ?? {
12083
+ data: rows,
12084
+ count: result.count
12085
+ };
12086
+ return successResponse(mapped.data, mapped.count, result, result.bookmark);
12087
+ } catch (error) {
12088
+ const message = error instanceof Error ? error.message : String(error);
12089
+ return errorResponse(500, "UNKNOWN_ERROR", message, endpoint, method);
12090
+ }
12091
+ }
12092
+ return {
12093
+ baseUrl: CLOUDFLARE_EDGE_BASE_URL,
12094
+ buildHeaders(callOptions) {
12095
+ return { ...callOptions?.headers ?? {} };
12096
+ },
12097
+ async resolveCallOptions(callOptions) {
12098
+ return callOptions;
12099
+ },
12100
+ async verifyConnection(connectionOptions) {
12101
+ const baseUrl = CLOUDFLARE_EDGE_BASE_URL;
12102
+ try {
12103
+ const result = await executeD1Query(d1, { query: "SELECT 1 AS ok" });
12104
+ if (!result.ok) {
12105
+ return {
12106
+ ok: false,
12107
+ reachable: false,
12108
+ status: 500,
12109
+ statusText: null,
12110
+ baseUrl,
12111
+ url: `${baseUrl}/d1`,
12112
+ error: result.message,
12113
+ errorDetails: null,
12114
+ raw: result
12115
+ };
12116
+ }
12117
+ return {
12118
+ ok: true,
12119
+ reachable: true,
12120
+ status: 200,
12121
+ statusText: "OK",
12122
+ baseUrl,
12123
+ url: `${baseUrl}/d1`,
12124
+ error: void 0,
12125
+ errorDetails: null,
12126
+ raw: result
12127
+ };
12128
+ } catch (error) {
12129
+ const message = error instanceof Error ? error.message : String(error);
12130
+ return {
12131
+ ok: false,
12132
+ reachable: false,
12133
+ status: 0,
12134
+ statusText: null,
12135
+ baseUrl,
12136
+ url: `${baseUrl}/d1`,
12137
+ error: message,
12138
+ errorDetails: null,
12139
+ raw: null
12140
+ };
12141
+ }
12142
+ },
12143
+ async fetchGateway(payload, callOptions) {
12144
+ try {
12145
+ if (payload && typeof payload === "object" && "operation" in payload) {
12146
+ return errorResponse(
12147
+ 400,
12148
+ "HTTP_ERROR",
12149
+ "Direct AST operation payloads are unsupported on D1 edge-local",
12150
+ "/gateway/fetch",
12151
+ "POST"
12152
+ );
12153
+ }
12154
+ const compiled = compileD1Fetch(payload);
12155
+ const stripNulls = resolveStripNulls(payload.strip_nulls, callOptions, true);
12156
+ if (payload.head === true) {
12157
+ return runCompiled(
12158
+ compiled,
12159
+ callOptions,
12160
+ "/gateway/fetch",
12161
+ "POST",
12162
+ (rows) => ({ data: [], count: extractAthenaCount(rows) }),
12163
+ // COUNT rows are meta, not user-facing object rows
12164
+ false
12165
+ );
12166
+ }
12167
+ const wantsTotalCount = payload.count === "exact" || payload.count === "planned" || payload.count === "estimated";
12168
+ if (wantsTotalCount) {
12169
+ const session = sessionFromOptions(callOptions, options);
12170
+ const countCompiled = compileD1Count(payload);
12171
+ const batch = await executeD1Batch(d1, {
12172
+ statements: [
12173
+ {
12174
+ query: compiled.sql,
12175
+ params: compiled.params
12176
+ },
12177
+ {
12178
+ query: countCompiled.sql,
12179
+ params: countCompiled.params
12180
+ }
12181
+ ],
12182
+ ...session
12183
+ });
12184
+ if (!batch.ok) {
12185
+ return errorResponse(400, "HTTP_ERROR", batch.message, "/gateway/fetch", "POST");
12186
+ }
12187
+ const dataItem = batch.results[0];
12188
+ const countItem = batch.results[1];
12189
+ if (!dataItem || dataItem.success === false) {
12190
+ const message = dataItem && typeof dataItem.error === "string" && dataItem.error.trim() ? dataItem.error : "D1 page query failed";
12191
+ return errorResponse(400, "HTTP_ERROR", message, "/gateway/fetch", "POST");
12192
+ }
12193
+ if (!countItem || countItem.success === false) {
12194
+ const message = countItem && typeof countItem.error === "string" && countItem.error.trim() ? countItem.error : "D1 count query failed";
12195
+ return errorResponse(400, "HTTP_ERROR", message, "/gateway/fetch", "POST");
12196
+ }
12197
+ const dataRows = Array.isArray(dataItem.results) ? dataItem.results : [];
12198
+ const countRows = Array.isArray(countItem.results) ? countItem.results : [];
12199
+ const total = extractAthenaCount(countRows);
12200
+ const rows = maybeStripNullRows(dataRows, stripNulls);
12201
+ return successResponse(
12202
+ rows,
12203
+ total,
12204
+ { data: dataItem, count: countItem, batch },
12205
+ batch.bookmark
12206
+ );
12207
+ }
12208
+ return runCompiled(compiled, callOptions, "/gateway/fetch", "POST", void 0, stripNulls);
12209
+ } catch (error) {
12210
+ return compileErrorResponse(error, "/gateway/fetch", "POST");
12211
+ }
12212
+ },
12213
+ async insertGateway(payload, callOptions) {
12214
+ try {
12215
+ const compiled = compileD1Insert(payload);
12216
+ const stripNulls = resolveStripNulls(void 0, callOptions, true);
12217
+ return runCompiled(compiled, callOptions, "/gateway/insert", "PUT", void 0, stripNulls);
12218
+ } catch (error) {
12219
+ return compileErrorResponse(error, "/gateway/insert", "PUT");
12220
+ }
12221
+ },
12222
+ async updateGateway(payload, callOptions) {
12223
+ try {
12224
+ const session = sessionFromOptions(callOptions, options);
12225
+ const compileOptions = await compileOptionsForBoundedMutation(d1, payload, session);
12226
+ const compiled = compileD1Update(payload, compileOptions);
12227
+ const stripNulls = resolveStripNulls(payload.strip_nulls, callOptions, true);
12228
+ return runCompiled(compiled, callOptions, "/gateway/update", "POST", void 0, stripNulls);
12229
+ } catch (error) {
12230
+ return compileErrorResponse(error, "/gateway/update", "POST");
12231
+ }
12232
+ },
12233
+ async deleteGateway(payload, callOptions) {
12234
+ try {
12235
+ const session = sessionFromOptions(callOptions, options);
12236
+ const compileOptions = await compileOptionsForBoundedMutation(d1, payload, session);
12237
+ const compiled = compileD1Delete(payload, compileOptions);
12238
+ const stripNulls = resolveStripNulls(void 0, callOptions, true);
12239
+ return runCompiled(compiled, callOptions, "/gateway/delete", "DELETE", void 0, stripNulls);
12240
+ } catch (error) {
12241
+ return compileErrorResponse(error, "/gateway/delete", "DELETE");
12242
+ }
12243
+ },
12244
+ async rpcGateway(payload, callOptions) {
12245
+ return errorResponse(
12246
+ 400,
12247
+ "HTTP_ERROR",
12248
+ "RPC is unsupported on D1 edge-local mode",
12249
+ "/gateway/rpc",
12250
+ "POST",
12251
+ "Use flat CRUD or raw query SQL instead"
12252
+ );
12253
+ },
12254
+ async queryGateway(payload, callOptions) {
12255
+ try {
12256
+ const params = payload.params ?? callOptions?.params;
12257
+ const session = sessionFromOptions(callOptions, options);
12258
+ const query = rewritePostgresSqlForSqlite(payload.query);
12259
+ const result = await executeD1Query(d1, {
12260
+ query,
12261
+ params: Array.isArray(params) ? params : [],
12262
+ ...session
12263
+ });
12264
+ if (!result.ok) {
12265
+ return errorResponse(400, "HTTP_ERROR", result.message, "/gateway/query", "POST");
12266
+ }
12267
+ const stripNulls = resolveStripNulls(void 0, callOptions, true);
12268
+ const rows = maybeStripNullRows(result.rows, stripNulls);
12269
+ return successResponse(
12270
+ rows,
12271
+ result.count,
12272
+ { ...result, query },
12273
+ result.bookmark
12274
+ );
12275
+ } catch (error) {
12276
+ const message = error instanceof Error ? error.message : String(error);
12277
+ return errorResponse(500, "UNKNOWN_ERROR", message, "/gateway/query", "POST");
12278
+ }
12279
+ }
12280
+ };
12281
+ }
12282
+
12283
+ // src/config/errors.ts
12284
+ var AthenaConfigurationError = class extends Error {
12285
+ code;
12286
+ service;
12287
+ constructor(code, message, service) {
12288
+ super(message);
12289
+ this.name = "AthenaConfigurationError";
12290
+ this.code = code;
12291
+ this.service = service;
12292
+ }
12293
+ };
12294
+
12295
+ // src/cloudflare/execution-mode.ts
12296
+ var ATHENA_EXECUTION_MODE_ENV_KEY = "ATHENA_EXECUTION_MODE";
12297
+ var ATHENA_EXECUTION_PREFER_ENV_KEY = "ATHENA_EXECUTION_PREFER";
12298
+ var MODE_ALIASES = {
12299
+ gateway: "gateway",
12300
+ server: "gateway",
12301
+ remote: "gateway",
12302
+ http: "gateway",
12303
+ edge: "edge",
12304
+ cloudflare: "edge",
12305
+ "cloudflare-edge": "edge",
12306
+ d1: "edge",
12307
+ local: "edge",
12308
+ auto: "auto"
12309
+ };
12310
+ function normalizeOptional(value) {
12311
+ const trimmed = value?.trim();
12312
+ return trimmed || void 0;
12313
+ }
12314
+ function normalizeModeString(value) {
12315
+ if (value == null) return void 0;
12316
+ const key = value.trim().toLowerCase();
12317
+ if (!key) return void 0;
12318
+ const mapped = MODE_ALIASES[key];
12319
+ if (!mapped) {
12320
+ throw new AthenaConfigurationError(
12321
+ "ATHENA_NO_SERVICE_CONFIGURED",
12322
+ `Unknown Athena execution mode "${value}". Use gateway | edge | auto (aliases: server, remote, cloudflare, d1).`,
12323
+ "db"
12324
+ );
12325
+ }
12326
+ return mapped;
12327
+ }
12328
+ function isD1Binding(value) {
12329
+ return Boolean(
12330
+ value && typeof value === "object" && typeof value.prepare === "function"
12331
+ );
12332
+ }
12333
+ var GATEWAY_URL_ENV_KEYS = [
12334
+ "ATHENA_URL",
12335
+ "NEXT_PUBLIC_ATHENA_URL",
12336
+ "ATHENA_DB_URL",
12337
+ "ATHENA_GATEWAY_URL",
12338
+ "NEXT_PUBLIC_ATHENA_DB_API_URL"
12339
+ ];
12340
+ function resolveGatewayUrl(url, env) {
12341
+ if (normalizeOptional(url)) {
12342
+ return normalizeOptional(url);
12343
+ }
12344
+ for (const key of GATEWAY_URL_ENV_KEYS) {
12345
+ const value = normalizeOptional(env[key]);
12346
+ if (value) return value;
12347
+ }
12348
+ return void 0;
12349
+ }
12350
+ function resolvePrefer(prefer, env) {
12351
+ const raw = normalizeOptional(typeof prefer === "string" ? prefer : prefer ?? void 0) ?? normalizeOptional(env[ATHENA_EXECUTION_PREFER_ENV_KEY]) ?? "edge";
12352
+ const key = raw.toLowerCase();
12353
+ if (key === "gateway" || key === "server" || key === "remote" || key === "http") {
12354
+ return "gateway";
12355
+ }
12356
+ if (key === "edge" || key === "d1" || key === "cloudflare" || key === "local") {
12357
+ return "edge";
12358
+ }
12359
+ throw new AthenaConfigurationError(
12360
+ "ATHENA_NO_SERVICE_CONFIGURED",
12361
+ `Unknown Athena execution prefer "${raw}". Use edge | gateway.`,
12362
+ "db"
12363
+ );
12364
+ }
12365
+ function resolveAthenaExecutionMode(input = {}) {
12366
+ const env = input.env ?? {};
12367
+ const fromEnv = normalizeModeString(env[ATHENA_EXECUTION_MODE_ENV_KEY]);
12368
+ const requested = normalizeModeString(input.mode) ?? fromEnv ?? "auto";
12369
+ const url = resolveGatewayUrl(input.url, env);
12370
+ const hasD1 = isD1Binding(input.d1);
12371
+ const hasGateway = Boolean(url);
12372
+ if (requested === "gateway") {
12373
+ if (!hasGateway) {
12374
+ throw new AthenaConfigurationError(
12375
+ "ATHENA_NO_SERVICE_CONFIGURED",
12376
+ 'Athena execution mode is "gateway" but no url / ATHENA_URL / ATHENA_DB_URL / ATHENA_GATEWAY_URL was provided.',
12377
+ "db"
12378
+ );
12379
+ }
12380
+ return "gateway";
12381
+ }
12382
+ if (requested === "edge") {
12383
+ if (!hasD1) {
12384
+ throw new AthenaConfigurationError(
12385
+ "ATHENA_NO_SERVICE_CONFIGURED",
12386
+ 'Athena execution mode is "edge" but no D1 binding was provided (db.d1 / config.d1 / env.DB).',
12387
+ "db"
12388
+ );
12389
+ }
12390
+ return "edge";
12391
+ }
12392
+ if (hasD1 && hasGateway) {
12393
+ return resolvePrefer(input.prefer, env);
12394
+ }
12395
+ if (hasD1) return "edge";
12396
+ if (hasGateway) return "gateway";
12397
+ throw new AthenaConfigurationError(
12398
+ "ATHENA_NO_SERVICE_CONFIGURED",
12399
+ 'Cannot resolve Athena execution mode: provide mode "gateway" with url/key, mode "edge" with d1, or mode "auto" with either a D1 binding or a gateway URL (ATHENA_URL / ATHENA_DB_URL / ATHENA_GATEWAY_URL).',
12400
+ "db"
12401
+ );
12402
+ }
12403
+
12404
+ // src/cloudflare/r2/storage.ts
12405
+ function normalizePrefix(prefix) {
12406
+ if (!prefix?.trim()) return "";
12407
+ const normalized = prefix.replace(/^\/+/, "").replace(/\/?$/, "/");
12408
+ if (normalized.includes("\0")) {
12409
+ throw new Error("storage prefix must not contain null bytes");
12410
+ }
12411
+ if (normalized.split("/").some((segment) => segment === "..")) {
12412
+ throw new Error('storage prefix must not contain ".." path segments');
12413
+ }
12414
+ return normalized;
12415
+ }
12416
+ function assertSafeObjectKey(key) {
12417
+ if (typeof key !== "string" || !key.trim()) {
12418
+ throw new Error("Object key is required");
12419
+ }
12420
+ if (key.includes("\0")) {
12421
+ throw new Error("Object key must not contain null bytes");
12422
+ }
12423
+ const cleaned = key.replace(/^\/+/, "");
12424
+ if (!cleaned) {
12425
+ throw new Error("Object key is required");
12426
+ }
12427
+ const segments = cleaned.split("/");
12428
+ if (segments.some((segment) => segment === "..")) {
12429
+ throw new Error('Object key must not contain ".." path segments');
12430
+ }
12431
+ return cleaned;
12432
+ }
12433
+ function joinKey(prefix, key) {
12434
+ return `${prefix}${assertSafeObjectKey(key)}`;
12435
+ }
12436
+ function toLogicalKey(prefix, physicalKey) {
12437
+ if (!prefix) return physicalKey;
12438
+ if (physicalKey.startsWith(prefix)) {
12439
+ return physicalKey.slice(prefix.length);
12440
+ }
12441
+ return physicalKey;
12442
+ }
12443
+ function toPhysicalKey(prefix, key) {
12444
+ return joinKey(prefix, key);
12445
+ }
12446
+ function unsupported(method) {
12447
+ throw new Error(
12448
+ `storage.${method} is not available in Cloudflare edge-local R2 object mode. Only putObject / getObject / deleteObject / listObjects are supported (L3a).`
12449
+ );
12450
+ }
12451
+ function createCloudflareR2StorageModule(options) {
12452
+ const prefix = normalizePrefix(options.prefix);
12453
+ const { r2 } = options;
12454
+ const putObject = async (input) => {
12455
+ const logical = assertSafeObjectKey(input.key);
12456
+ const physical = toPhysicalKey(prefix, logical);
12457
+ await r2.put(physical, input.body, {
12458
+ httpMetadata: input.contentType ? { contentType: input.contentType } : void 0,
12459
+ customMetadata: input.metadata
12460
+ });
12461
+ return { key: logical };
12462
+ };
12463
+ const getObject = async (input) => {
12464
+ const logical = assertSafeObjectKey(input.key);
12465
+ const physical = toPhysicalKey(prefix, logical);
12466
+ const object = await r2.get(physical);
12467
+ if (!object) return null;
12468
+ return {
12469
+ key: toLogicalKey(prefix, object.key),
12470
+ size: object.size,
12471
+ contentType: object.httpMetadata?.contentType,
12472
+ body: object
12473
+ };
12474
+ };
12475
+ const deleteObject = async (input) => {
12476
+ const logicalKeys = (Array.isArray(input.key) ? input.key : [input.key]).map(
12477
+ (key) => assertSafeObjectKey(key)
12478
+ );
12479
+ const physicalKeys = logicalKeys.map((key) => toPhysicalKey(prefix, key));
12480
+ await r2.delete(physicalKeys.length === 1 ? physicalKeys[0] : physicalKeys);
12481
+ return { deleted: logicalKeys };
12482
+ };
12483
+ const listObjects = async (input) => {
12484
+ const relative = input?.prefix?.trim() ? assertSafeObjectKey(input.prefix) : "";
12485
+ const listPrefix = `${prefix}${relative}`;
12486
+ const listed = await r2.list({
12487
+ prefix: listPrefix || void 0,
12488
+ limit: input?.limit,
12489
+ cursor: input?.cursor
12490
+ });
12491
+ return {
12492
+ objects: listed.objects.map((object) => ({
12493
+ key: toLogicalKey(prefix, object.key),
12494
+ size: object.size,
12495
+ etag: object.etag,
12496
+ uploaded: object.uploaded
12497
+ })),
12498
+ truncated: listed.truncated,
12499
+ cursor: listed.cursor
12500
+ };
12501
+ };
12502
+ const base = {
12503
+ putObject,
12504
+ getObject,
12505
+ deleteObject,
12506
+ listObjects
12507
+ };
12508
+ return new Proxy(base, {
12509
+ get(target, property, receiver) {
12510
+ if (property in target) {
12511
+ return Reflect.get(target, property, receiver);
12512
+ }
12513
+ if (typeof property === "string") {
12514
+ return (...args) => {
12515
+ return unsupported(property);
12516
+ };
12517
+ }
12518
+ return void 0;
12519
+ }
12520
+ });
12521
+ }
12522
+
12523
+ // src/billing/module.ts
12524
+ var SDK_NAME5 = "xylex-group/athena-billing";
12525
+ var SDK_HEADER_VALUE4 = buildSdkHeaderValue(SDK_NAME5);
12526
+ var AthenaBillingError = class extends Error {
12527
+ status;
12528
+ endpoint;
12529
+ method;
12530
+ body;
12531
+ constructor(input) {
12532
+ super(input.message);
12533
+ this.name = "AthenaBillingError";
12534
+ this.status = input.status;
12535
+ this.endpoint = input.endpoint;
12536
+ this.method = input.method;
12537
+ this.body = input.body;
12538
+ }
12539
+ };
12540
+ var billingSdkManifest = {
12541
+ namespace: "billing",
12542
+ envelopeKind: "athena",
12543
+ methods: [
12544
+ { name: "getCapabilities", method: "GET", path: "/billing/v1/capabilities" },
12545
+ { name: "createCheckout", method: "POST", path: "/billing/v1/checkouts" },
12546
+ { name: "listProducts", method: "GET", path: "/billing/v1/products" },
12547
+ { name: "listPrices", method: "GET", path: "/billing/v1/prices" },
12548
+ { name: "listCustomers", method: "GET", path: "/billing/v1/customers" },
12549
+ { name: "createCustomer", method: "POST", path: "/billing/v1/customers" },
12550
+ { name: "getCustomer", method: "GET", path: "/billing/v1/customers/{id}" },
12551
+ { name: "updateCustomer", method: "PATCH", path: "/billing/v1/customers/{id}" },
12552
+ { name: "deleteCustomer", method: "DELETE", path: "/billing/v1/customers/{id}" },
12553
+ { name: "listPayments", method: "GET", path: "/billing/v1/payments" },
12554
+ { name: "createPayment", method: "POST", path: "/billing/v1/payments" },
12555
+ { name: "getPayment", method: "GET", path: "/billing/v1/payments/{id}" },
12556
+ { name: "cancelPayment", method: "POST", path: "/billing/v1/payments/{id}/cancel" },
12557
+ { name: "listPaymentLinks", method: "GET", path: "/billing/v1/payment-links" },
12558
+ { name: "createPaymentLink", method: "POST", path: "/billing/v1/payment-links" },
12559
+ { name: "getPaymentLink", method: "GET", path: "/billing/v1/payment-links/{id}" },
12560
+ { name: "updatePaymentLink", method: "PATCH", path: "/billing/v1/payment-links/{id}" },
12561
+ { name: "deletePaymentLink", method: "DELETE", path: "/billing/v1/payment-links/{id}" },
12562
+ { name: "listRefunds", method: "GET", path: "/billing/v1/refunds" },
12563
+ { name: "createRefund", method: "POST", path: "/billing/v1/refunds" },
12564
+ { name: "getRefund", method: "GET", path: "/billing/v1/refunds/{id}" },
12565
+ { name: "cancelRefund", method: "POST", path: "/billing/v1/refunds/{id}/cancel" },
12566
+ { name: "listSubscriptions", method: "GET", path: "/billing/v1/subscriptions" },
12567
+ { name: "createSubscription", method: "POST", path: "/billing/v1/subscriptions" },
12568
+ { name: "getSubscription", method: "GET", path: "/billing/v1/subscriptions/{id}" },
12569
+ { name: "updateSubscription", method: "PATCH", path: "/billing/v1/subscriptions/{id}" },
12570
+ { name: "cancelSubscription", method: "POST", path: "/billing/v1/subscriptions/{id}/cancel" },
12571
+ { name: "listInvoices", method: "GET", path: "/billing/v1/invoices" },
12572
+ { name: "getInvoice", method: "GET", path: "/billing/v1/invoices/{id}" },
12573
+ { name: "listWebhooks", method: "GET", path: "/billing/v1/webhooks" },
12574
+ { name: "createWebhook", method: "POST", path: "/billing/v1/webhooks" },
12575
+ { name: "getWebhook", method: "GET", path: "/billing/v1/webhooks/{id}" },
12576
+ { name: "updateWebhook", method: "PATCH", path: "/billing/v1/webhooks/{id}" },
12577
+ { name: "deleteWebhook", method: "DELETE", path: "/billing/v1/webhooks/{id}" },
12578
+ { name: "testWebhook", method: "POST", path: "/billing/v1/webhooks/{id}/test" },
12579
+ {
12580
+ name: "listConnections",
12581
+ method: "GET",
12582
+ path: "/admin/billing/clients/{client_name}/connections"
12583
+ },
12584
+ {
12585
+ name: "createConnection",
12586
+ method: "POST",
12587
+ path: "/admin/billing/clients/{client_name}/connections"
12588
+ },
12589
+ {
12590
+ name: "getConnection",
12591
+ method: "GET",
12592
+ path: "/admin/billing/clients/{client_name}/connections/{connection_id}"
12593
+ },
12594
+ {
12595
+ name: "updateConnection",
12596
+ method: "PATCH",
12597
+ path: "/admin/billing/clients/{client_name}/connections/{connection_id}"
12598
+ },
12599
+ {
12600
+ name: "deleteConnection",
12601
+ method: "DELETE",
12602
+ path: "/admin/billing/clients/{client_name}/connections/{connection_id}"
12603
+ },
12604
+ {
12605
+ name: "reconcileDocument",
12606
+ method: "POST",
12607
+ path: "/admin/billing/clients/{client_name}/connections/{connection_id}/reconcile"
12608
+ },
12609
+ {
12610
+ name: "listWebhookEvents",
12611
+ method: "GET",
12612
+ path: "/admin/billing/clients/{client_name}/webhook-events"
12613
+ },
12614
+ {
12615
+ name: "provisionWebhookSinks",
12616
+ method: "POST",
12617
+ path: "/admin/billing/clients/{client_name}/webhook-sinks/provision"
12618
+ },
12619
+ { name: "listGrants", method: "GET", path: "/admin/billing/grants" },
12620
+ { name: "listProviders", method: "GET", path: "/admin/billing/providers" },
12621
+ {
12622
+ name: "listSinkHelpers",
12623
+ method: "GET",
12624
+ path: "/admin/webhook-sinks/helpers/billing"
12625
+ },
12626
+ {
12627
+ name: "ingestProviderWebhook",
12628
+ method: "POST",
12629
+ path: "/billing/providers/{provider}/clients/{client_name}/connections/{connection_id}/webhook"
12630
+ },
12631
+ { name: "getDebugBilling", method: "GET", path: "/debug/billing" }
12632
+ ]
12633
+ };
12634
+ function withPathParam2(path, name, value) {
12635
+ return path.replace(`{${name}}`, encodeURIComponent(value));
12636
+ }
12637
+ function appendQuery3(path, query) {
12638
+ if (!query) return path;
12639
+ const params = new URLSearchParams();
12640
+ for (const [key, value] of Object.entries(query)) {
12641
+ if (value === void 0 || value === null) continue;
12642
+ params.set(key, String(value));
12643
+ }
12644
+ const serialized = params.toString();
12645
+ return serialized ? `${path}?${serialized}` : path;
12646
+ }
12647
+ function connectionQuery(input) {
12648
+ const query = {
12649
+ connectionId: input.connectionId
12650
+ };
12651
+ if (input.clientName) query.clientName = input.clientName;
12652
+ if ("cursor" in input && input.cursor) query.cursor = input.cursor;
12653
+ if ("source" in input && input.source) query.source = input.source;
12654
+ if ("limit" in input && input.limit !== void 0) query.limit = String(input.limit);
12655
+ if ("offset" in input && input.offset !== void 0) query.offset = String(input.offset);
12656
+ return query;
12657
+ }
12658
+ function parseEnvelopeData(body) {
12659
+ if (body && typeof body === "object" && "data" in body) {
12660
+ return body.data;
12661
+ }
12662
+ return body;
12663
+ }
12664
+ function createBillingModule(config) {
12665
+ const baseUrl = normalizeAthenaGatewayBaseUrl(config.baseUrl, {
12666
+ label: "Athena billing base URL"
12667
+ });
12668
+ const fetchImpl = config.fetchImpl ?? globalThis.fetch.bind(globalThis);
12669
+ async function call(method, path, body, options, responseType = "json") {
12670
+ const headers = buildAthenaRequestHeaders({
12671
+ profile: "gateway",
12672
+ sdkHeaderValue: SDK_HEADER_VALUE4,
12673
+ apiKey: options?.apiKey ?? config.apiKey,
12674
+ client: config.client,
12675
+ configHeaders: {
12676
+ ...config.headers ?? {}
12677
+ },
12678
+ callHeaders: options?.headers,
12679
+ contentType: "application/json"
12680
+ });
12681
+ let requestBody;
12682
+ if (body !== void 0 && body !== null) {
12683
+ if (typeof body === "string" || body instanceof Blob || body instanceof ArrayBuffer || ArrayBuffer.isView(body) || body instanceof FormData || body instanceof URLSearchParams) {
12684
+ requestBody = body;
12685
+ } else {
12686
+ requestBody = JSON.stringify(body);
12687
+ if (!hasHeaderIgnoreCase(headers, "Content-Type")) {
12688
+ headers["Content-Type"] = "application/json";
12689
+ }
12690
+ }
12691
+ }
12692
+ const targetUrl = `${baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
12693
+ const response = await fetchImpl(targetUrl, {
12694
+ method,
12695
+ headers,
12696
+ body: requestBody,
12697
+ signal: options?.signal
12698
+ });
12699
+ if (responseType === "text") {
12700
+ const text = await response.text();
12701
+ if (!response.ok) {
12702
+ throw new AthenaBillingError({
12703
+ message: `Billing request failed (${response.status})`,
12704
+ status: response.status,
12705
+ endpoint: path,
12706
+ method,
12707
+ body: text
12708
+ });
12709
+ }
12710
+ return text;
12711
+ }
12712
+ const rawText = await response.text();
12713
+ let parsed = rawText;
12714
+ if (rawText) {
12715
+ try {
12716
+ parsed = JSON.parse(rawText);
12717
+ } catch {
12718
+ parsed = rawText;
12719
+ }
12720
+ } else {
12721
+ parsed = null;
10063
12722
  }
10064
12723
  if (!response.ok) {
10065
12724
  const message = parsed && typeof parsed === "object" && "message" in parsed && typeof parsed.message === "string" ? parsed.message : `Billing request failed (${response.status})`;
@@ -10551,18 +13210,6 @@ function createBillingModule(config) {
10551
13210
  };
10552
13211
  }
10553
13212
 
10554
- // src/config/errors.ts
10555
- var AthenaConfigurationError = class extends Error {
10556
- code;
10557
- service;
10558
- constructor(code, message, service) {
10559
- super(message);
10560
- this.name = "AthenaConfigurationError";
10561
- this.code = code;
10562
- this.service = service;
10563
- }
10564
- };
10565
-
10566
13213
  // src/context/merge.ts
10567
13214
  function mergeAthenaRequestContexts(base, override) {
10568
13215
  if (!base && !override) return void 0;
@@ -10576,6 +13223,82 @@ function mergeAthenaRequestContexts(base, override) {
10576
13223
  };
10577
13224
  }
10578
13225
 
13226
+ // src/diagnostics.ts
13227
+ function readProcessEnv2() {
13228
+ try {
13229
+ return globalThis.process?.env ?? {};
13230
+ } catch {
13231
+ return {};
13232
+ }
13233
+ }
13234
+ function isTruthyEnv(value) {
13235
+ if (!value) return false;
13236
+ const normalized = value.trim().toLowerCase();
13237
+ return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
13238
+ }
13239
+ function isQuietAthenaDiagnosticsEnvironment(env = readProcessEnv2()) {
13240
+ const nodeEnv = env.NODE_ENV?.trim().toLowerCase();
13241
+ if (nodeEnv === "production") {
13242
+ return true;
13243
+ }
13244
+ if (isTruthyEnv(env.OPENNEXT_BUILD)) {
13245
+ return true;
13246
+ }
13247
+ const nextPhase = env.NEXT_PHASE?.trim();
13248
+ if (nextPhase === "phase-production-build") {
13249
+ return true;
13250
+ }
13251
+ if (isTruthyEnv(env.CI) && nodeEnv !== "test") {
13252
+ if (nodeEnv === "production" || isTruthyEnv(env.OPENNEXT_BUILD)) {
13253
+ return true;
13254
+ }
13255
+ }
13256
+ return false;
13257
+ }
13258
+ function resolveBooleanFlag(explicit, mode, quiet) {
13259
+ if (typeof explicit === "boolean") {
13260
+ return explicit;
13261
+ }
13262
+ if (mode === true) {
13263
+ return true;
13264
+ }
13265
+ if (mode === false) {
13266
+ return false;
13267
+ }
13268
+ if (mode === "auto") {
13269
+ return false;
13270
+ }
13271
+ return false;
13272
+ }
13273
+ function resolveAthenaClientDiagnostics(input) {
13274
+ const env = input.env ?? readProcessEnv2();
13275
+ const quiet = isQuietAthenaDiagnosticsEnvironment(env);
13276
+ const mode = input.diagnostics;
13277
+ const effectiveMode = mode === "auto" && quiet ? false : mode;
13278
+ const debugAst = resolveBooleanFlag(input.debugAst, effectiveMode);
13279
+ const findManyAst = resolveBooleanFlag(input.findManyAst, effectiveMode);
13280
+ let traceQueries;
13281
+ if (input.traceQueries !== void 0) {
13282
+ if (typeof input.traceQueries === "boolean") {
13283
+ traceQueries = input.traceQueries;
13284
+ } else if (effectiveMode === false || mode === "auto" && quiet) {
13285
+ const enabled = input.traceQueries.enabled;
13286
+ traceQueries = typeof enabled === "boolean" ? enabled ? input.traceQueries : false : false;
13287
+ } else {
13288
+ traceQueries = input.traceQueries;
13289
+ }
13290
+ } else if (effectiveMode === true) {
13291
+ traceQueries = true;
13292
+ } else {
13293
+ traceQueries = false;
13294
+ }
13295
+ return {
13296
+ debugAst,
13297
+ findManyAst,
13298
+ traceQueries
13299
+ };
13300
+ }
13301
+
10579
13302
  // src/v3-client.ts
10580
13303
  var ENV_URL_KEYS = ["ATHENA_URL", "NEXT_PUBLIC_ATHENA_URL"];
10581
13304
  var ENV_DB_URL_KEYS = ["ATHENA_DB_URL", "ATHENA_GATEWAY_URL", "NEXT_PUBLIC_ATHENA_DB_API_URL"];
@@ -10584,7 +13307,13 @@ var ENV_CHAT_URL_KEYS = ["ATHENA_CHAT_URL", "NEXT_PUBLIC_ATHENA_CHAT_URL"];
10584
13307
  var ENV_CHAT_WS_URL_KEYS = ["ATHENA_CHAT_WS_URL", "NEXT_PUBLIC_ATHENA_CHAT_WS_URL"];
10585
13308
  var ENV_STORAGE_URL_KEYS = ["ATHENA_STORAGE_URL", "NEXT_PUBLIC_ATHENA_STORAGE_URL"];
10586
13309
  var ENV_KEY_KEYS = ["ATHENA_API_KEY", "NEXT_PUBLIC_ATHENA_API_KEY", "ATHENA_GATEWAY_API_KEY", "X_API_KEY"];
10587
- var ENV_CLIENT_KEYS = ["ATHENA_CLIENT", "NEXT_PUBLIC_ATHENA_CLIENT"];
13310
+ var ENV_CLIENT_KEYS = [
13311
+ "ATHENA_CLIENT",
13312
+ "ATHENA_GATEWAY_CLIENT",
13313
+ "ATHENA_GENERATOR_CLIENT",
13314
+ "NEXT_PUBLIC_ATHENA_CLIENT",
13315
+ "NEXT_PUBLIC_ATHENA_GATEWAY_CLIENT"
13316
+ ];
10588
13317
  var MISSING_DB_SENTINEL = "https://athena.invalid/db";
10589
13318
  function readFirstEnv(env, keys) {
10590
13319
  for (const key of keys) {
@@ -10593,14 +13322,30 @@ function readFirstEnv(env, keys) {
10593
13322
  }
10594
13323
  return void 0;
10595
13324
  }
10596
- function normalizeOptional(value) {
13325
+ function readFirstEnvHttpUrl(env, keys) {
13326
+ for (const key of keys) {
13327
+ const value = env?.[key]?.trim();
13328
+ if (value && isAbsoluteHttpUrl(value)) return value;
13329
+ }
13330
+ return void 0;
13331
+ }
13332
+ function normalizeOptional2(value) {
10597
13333
  const normalized = value?.trim();
10598
13334
  return normalized || void 0;
10599
13335
  }
13336
+ function isAbsoluteHttpUrl(value) {
13337
+ try {
13338
+ const url = new URL(value);
13339
+ return url.protocol === "http:" || url.protocol === "https:";
13340
+ } catch {
13341
+ return false;
13342
+ }
13343
+ }
10600
13344
  function appendPath(baseUrl, path) {
10601
13345
  return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
10602
13346
  }
10603
13347
  function toWebSocketUrl(baseUrl) {
13348
+ if (!isAbsoluteHttpUrl(baseUrl)) return void 0;
10604
13349
  const url = new URL(baseUrl);
10605
13350
  url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
10606
13351
  url.pathname = `${url.pathname.replace(/\/+$/, "")}/wss/gateway`;
@@ -10610,11 +13355,11 @@ function toWebSocketUrl(baseUrl) {
10610
13355
  }
10611
13356
  function resolveCore(config) {
10612
13357
  const env = config.env;
10613
- const explicitRoot = normalizeOptional(config.url);
10614
- const envRoot = readFirstEnv(env, ENV_URL_KEYS);
10615
- const root = explicitRoot ?? envRoot;
10616
- const explicitRootWinsOverEnvServices = explicitRoot !== void 0;
10617
- const resolveService = (explicit, envKeys, path) => normalizeOptional(explicit) ?? (explicitRootWinsOverEnvServices && root ? appendPath(root, path) : void 0) ?? readFirstEnv(env, envKeys) ?? (root ? appendPath(root, path) : void 0);
13358
+ const explicitRoot = normalizeOptional2(config.url);
13359
+ const envRoot = readFirstEnvHttpUrl(env, ENV_URL_KEYS);
13360
+ const root = explicitRoot && isAbsoluteHttpUrl(explicitRoot) ? explicitRoot : explicitRoot ? void 0 : envRoot;
13361
+ const explicitRootWinsOverEnvServices = Boolean(root && explicitRoot && isAbsoluteHttpUrl(explicitRoot));
13362
+ const resolveService = (explicit, envKeys, path) => normalizeOptional2(explicit) ?? (explicitRootWinsOverEnvServices && root ? appendPath(root, path) : void 0) ?? readFirstEnvHttpUrl(env, envKeys) ?? (root ? appendPath(root, path) : void 0);
10618
13363
  const dbUrl = resolveService(config.db?.url, ENV_DB_URL_KEYS, "db");
10619
13364
  const urls = {
10620
13365
  db: dbUrl,
@@ -10622,8 +13367,8 @@ function resolveCore(config) {
10622
13367
  chat: resolveService(config.chat?.url, ENV_CHAT_URL_KEYS, "chat"),
10623
13368
  storage: resolveService(config.storage?.url, ENV_STORAGE_URL_KEYS, "storage"),
10624
13369
  // Billing lives on the main Athena HTTP surface (same host as gateway/db).
10625
- billing: normalizeOptional(config.billing?.url) ?? dbUrl ?? root ?? void 0,
10626
- chatWs: normalizeOptional(config.chat?.wsUrl) ?? (explicitRootWinsOverEnvServices && root ? toWebSocketUrl(root) : void 0) ?? readFirstEnv(env, ENV_CHAT_WS_URL_KEYS) ?? (root ? toWebSocketUrl(root) : void 0)
13370
+ billing: normalizeOptional2(config.billing?.url) ?? dbUrl ?? root ?? void 0,
13371
+ chatWs: normalizeOptional2(config.chat?.wsUrl) ?? (explicitRootWinsOverEnvServices && root ? toWebSocketUrl(root) : void 0) ?? readFirstEnvHttpUrl(env, ENV_CHAT_WS_URL_KEYS) ?? (root ? toWebSocketUrl(root) : void 0)
10627
13372
  };
10628
13373
  if (!urls.db && !urls.auth && !urls.chat && !urls.storage && !urls.billing) {
10629
13374
  throw new AthenaConfigurationError(
@@ -10632,7 +13377,7 @@ function resolveCore(config) {
10632
13377
  "db"
10633
13378
  );
10634
13379
  }
10635
- const key = normalizeOptional(config.key) ?? readFirstEnv(env, ENV_KEY_KEYS);
13380
+ const key = normalizeOptional2(config.key) ?? readFirstEnv(env, ENV_KEY_KEYS);
10636
13381
  if (!key) {
10637
13382
  throw new AthenaConfigurationError(
10638
13383
  "ATHENA_API_KEY_REQUIRED",
@@ -10643,7 +13388,7 @@ function resolveCore(config) {
10643
13388
  config,
10644
13389
  urls,
10645
13390
  key,
10646
- client: normalizeOptional(config.client) ?? readFirstEnv(env, ENV_CLIENT_KEYS)
13391
+ client: normalizeOptional2(config.client) ?? readFirstEnv(env, ENV_CLIENT_KEYS)
10647
13392
  };
10648
13393
  return {
10649
13394
  ...base,
@@ -10658,7 +13403,20 @@ async function resolveConfiguredContext(core, viewContext) {
10658
13403
  function createInternalConfig(core) {
10659
13404
  const { config, urls } = core;
10660
13405
  const { url: _authUrl, ...authOptions } = config.auth ?? {};
10661
- const { url: _storageUrl, directUpload, ...storageOptions } = config.storage ?? {};
13406
+ const {
13407
+ url: _storageUrl,
13408
+ directUpload,
13409
+ r2: _r2,
13410
+ prefix: _r2Prefix,
13411
+ ...storageOptions
13412
+ } = config.storage ?? {};
13413
+ const diagnostics = resolveAthenaClientDiagnostics({
13414
+ diagnostics: config.diagnostics,
13415
+ debugAst: config.debugAst,
13416
+ findManyAst: config.findManyAst,
13417
+ traceQueries: config.traceQueries,
13418
+ env: config.env
13419
+ });
10662
13420
  return {
10663
13421
  baseUrl: urls.db ?? MISSING_DB_SENTINEL,
10664
13422
  apiKey: core.key,
@@ -10675,14 +13433,15 @@ function createInternalConfig(core) {
10675
13433
  models: config.models,
10676
13434
  behavior: {
10677
13435
  retryReads: config.retryReads,
10678
- traceQueries: config.traceQueries,
10679
- debugAst: config.debugAst,
10680
- findManyAst: config.findManyAst
13436
+ traceQueries: diagnostics.traceQueries,
13437
+ debugAst: diagnostics.debugAst,
13438
+ findManyAst: diagnostics.findManyAst
10681
13439
  },
10682
13440
  storage: {
10683
13441
  ...storageOptions,
10684
13442
  ...directUpload ? { directUpload } : {}
10685
- }
13443
+ },
13444
+ gatewayTransport: config.gatewayTransport
10686
13445
  };
10687
13446
  }
10688
13447
  function serviceGuard(urls, service) {
@@ -10703,7 +13462,233 @@ function createUnavailableNamespace(service, urls, path = []) {
10703
13462
  serviceGuard(urls, service);
10704
13463
  throw new TypeError(`Athena service property ${path.map(String).join(".")} is not callable.`);
10705
13464
  }
10706
- });
13465
+ });
13466
+ }
13467
+ function isD1Binding2(value) {
13468
+ return Boolean(
13469
+ value && typeof value === "object" && typeof value.prepare === "function"
13470
+ );
13471
+ }
13472
+ function isR2Binding(value) {
13473
+ return Boolean(
13474
+ value && typeof value === "object" && typeof value.put === "function" && typeof value.get === "function"
13475
+ );
13476
+ }
13477
+ function foldBindingAliases(config) {
13478
+ const d1 = config.db?.d1 ?? config.d1;
13479
+ const r2 = config.storage?.r2 ?? config.r2;
13480
+ const sessionMode = config.db?.sessionMode ?? config.sessionMode;
13481
+ const prefix = config.storage?.prefix ?? config.storagePrefix;
13482
+ let next = { ...config };
13483
+ if (d1 !== void 0 || sessionMode !== void 0) {
13484
+ next = {
13485
+ ...next,
13486
+ db: {
13487
+ ...next.db,
13488
+ ...d1 !== void 0 ? { d1 } : {},
13489
+ ...sessionMode !== void 0 ? { sessionMode } : {}
13490
+ }
13491
+ };
13492
+ }
13493
+ if (r2 !== void 0 || prefix !== void 0) {
13494
+ next = {
13495
+ ...next,
13496
+ storage: {
13497
+ ...next.storage,
13498
+ ...r2 !== void 0 ? { r2 } : {},
13499
+ ...prefix !== void 0 ? { prefix } : {}
13500
+ }
13501
+ };
13502
+ }
13503
+ const {
13504
+ d1: _d1,
13505
+ r2: _r2,
13506
+ storagePrefix: _storagePrefix,
13507
+ sessionMode: _sessionMode,
13508
+ ...rest
13509
+ } = next;
13510
+ return rest;
13511
+ }
13512
+ function applyExecutionMode(config) {
13513
+ const d1 = config.db?.d1;
13514
+ const hasD1 = isD1Binding2(d1);
13515
+ const hasUrl = Boolean(
13516
+ normalizeOptional2(config.url) ?? normalizeOptional2(config.db?.url) ?? (config.env ? normalizeOptional2(config.env.ATHENA_URL) ?? normalizeOptional2(config.env.NEXT_PUBLIC_ATHENA_URL) : void 0)
13517
+ );
13518
+ const hasModeHint = config.mode != null || config.prefer != null || Boolean(config.env?.ATHENA_EXECUTION_MODE) || Boolean(config.env?.ATHENA_EXECUTION_PREFER);
13519
+ if (!hasD1 && !hasModeHint) {
13520
+ return config;
13521
+ }
13522
+ if (hasD1 && !hasUrl && !hasModeHint) {
13523
+ return config;
13524
+ }
13525
+ let resolved;
13526
+ try {
13527
+ resolved = resolveAthenaExecutionMode({
13528
+ mode: config.mode,
13529
+ prefer: config.prefer,
13530
+ d1: hasD1 ? d1 : null,
13531
+ url: config.url ?? config.db?.url,
13532
+ env: config.env
13533
+ });
13534
+ } catch (error) {
13535
+ if (!hasModeHint) return config;
13536
+ throw error;
13537
+ }
13538
+ if (resolved === "gateway" && hasD1) {
13539
+ const { d1: _drop, sessionMode: _sm, ...dbRest } = config.db ?? {};
13540
+ return {
13541
+ ...config,
13542
+ db: Object.keys(dbRest).length > 0 ? dbRest : void 0,
13543
+ gatewayTransport: void 0
13544
+ };
13545
+ }
13546
+ return config;
13547
+ }
13548
+ function resolveUnifiedRemoteRoot(config) {
13549
+ return normalizeOptional2(config.url) ?? readFirstEnv(config.env, ENV_URL_KEYS);
13550
+ }
13551
+ function isEdgeLocalSentinelUrl(url) {
13552
+ if (!url) return false;
13553
+ return url === CLOUDFLARE_EDGE_BASE_URL || url.startsWith("https://athena.local/") || url.startsWith("http://athena.local/");
13554
+ }
13555
+ function hasRemoteDbGatewayUrl(config) {
13556
+ const dbUrl = normalizeOptional2(config.db?.url) ?? readFirstEnv(config.env, ENV_DB_URL_KEYS);
13557
+ return Boolean(dbUrl && !isEdgeLocalSentinelUrl(dbUrl));
13558
+ }
13559
+ function hasRemoteHttpServices(config) {
13560
+ return Boolean(
13561
+ resolveUnifiedRemoteRoot(config) || hasRemoteDbGatewayUrl(config) || normalizeOptional2(config.auth?.url) || readFirstEnv(config.env, ENV_AUTH_URL_KEYS) || normalizeOptional2(config.storage?.url) || readFirstEnv(config.env, ENV_STORAGE_URL_KEYS) || normalizeOptional2(config.chat?.url) || readFirstEnv(config.env, ENV_CHAT_URL_KEYS) || normalizeOptional2(config.billing?.url)
13562
+ );
13563
+ }
13564
+ function hasRemoteHttpStorage(config) {
13565
+ return Boolean(
13566
+ normalizeOptional2(config.storage?.url) || readFirstEnv(config.env, ENV_STORAGE_URL_KEYS) || resolveUnifiedRemoteRoot(config)
13567
+ );
13568
+ }
13569
+ function hasRemoteAuthService(config) {
13570
+ return Boolean(
13571
+ normalizeOptional2(config.auth?.url) || readFirstEnv(config.env, ENV_AUTH_URL_KEYS) || resolveUnifiedRemoteRoot(config)
13572
+ );
13573
+ }
13574
+ function materializeEdgeBindings(config) {
13575
+ const d1 = config.db?.d1;
13576
+ const r2 = config.storage?.r2;
13577
+ const hasD1 = isD1Binding2(d1);
13578
+ const hasR2 = isR2Binding(r2);
13579
+ if (!hasD1 && !hasR2) {
13580
+ return config;
13581
+ }
13582
+ if (hasD1 && d1 && typeof d1.prepare !== "function") {
13583
+ throw new AthenaConfigurationError(
13584
+ "ATHENA_NO_SERVICE_CONFIGURED",
13585
+ "db.d1 must be a D1 binding with prepare().",
13586
+ "db"
13587
+ );
13588
+ }
13589
+ const remoteRoot = resolveUnifiedRemoteRoot(config);
13590
+ const remoteServices = hasRemoteHttpServices(config);
13591
+ const remoteStorage = hasRemoteHttpStorage(config);
13592
+ const remoteAuth = hasRemoteAuthService(config);
13593
+ const next = { ...config };
13594
+ if (hasD1 && d1) {
13595
+ if (!config.gatewayTransport) {
13596
+ next.gatewayTransport = createCloudflareD1GatewayTransport({
13597
+ d1,
13598
+ defaultSessionMode: config.db?.sessionMode
13599
+ });
13600
+ }
13601
+ const explicitDbUrl = normalizeOptional2(config.db?.url);
13602
+ const remoteDbGateway = hasRemoteDbGatewayUrl(config);
13603
+ next.db = {
13604
+ ...config.db,
13605
+ d1,
13606
+ url: explicitDbUrl ?? (remoteDbGateway ? void 0 : CLOUDFLARE_EDGE_BASE_URL)
13607
+ };
13608
+ const explicitKey = normalizeOptional2(config.key);
13609
+ if (explicitKey) {
13610
+ next.key = explicitKey;
13611
+ } else if (!remoteServices) {
13612
+ next.key = CLOUDFLARE_EDGE_API_KEY;
13613
+ } else {
13614
+ next.key = void 0;
13615
+ }
13616
+ if (remoteRoot) {
13617
+ next.billing = {
13618
+ ...config.billing ?? {},
13619
+ url: normalizeOptional2(config.billing?.url) ?? remoteRoot
13620
+ };
13621
+ }
13622
+ if (!config.capabilities) {
13623
+ next.capabilities = createCloudflareEdgeCapabilities({
13624
+ hasR2,
13625
+ // Explicit storage.url / env storage URL / unified remote root all count.
13626
+ hasRemoteStorage: remoteStorage,
13627
+ authRemote: remoteAuth,
13628
+ findManyAst: false
13629
+ });
13630
+ }
13631
+ } else if (hasR2 && r2) {
13632
+ if (!remoteRoot && !normalizeOptional2(config.db?.url) && !normalizeOptional2(config.storage?.url) && !readFirstEnv(config.env, ENV_STORAGE_URL_KEYS)) {
13633
+ next.storage = {
13634
+ ...config.storage,
13635
+ r2,
13636
+ // Local sentinel so resolveCore accepts a storage-only binding client.
13637
+ url: CLOUDFLARE_EDGE_BASE_URL
13638
+ };
13639
+ if (!remoteServices) {
13640
+ next.key = normalizeOptional2(config.key) ?? CLOUDFLARE_EDGE_API_KEY;
13641
+ } else if (normalizeOptional2(config.key)) {
13642
+ next.key = normalizeOptional2(config.key);
13643
+ } else {
13644
+ next.key = void 0;
13645
+ }
13646
+ }
13647
+ if (!config.capabilities) {
13648
+ if (remoteRoot || normalizeOptional2(config.db?.url) || readFirstEnv(config.env, ENV_DB_URL_KEYS)) {
13649
+ const base = createGatewayCapabilities({
13650
+ authRemote: remoteAuth,
13651
+ storageConfigured: true
13652
+ });
13653
+ next.capabilities = {
13654
+ ...base,
13655
+ storage: {
13656
+ ...base.storage,
13657
+ local: true,
13658
+ objects: true
13659
+ }
13660
+ };
13661
+ } else {
13662
+ next.capabilities = {
13663
+ mode: "cloudflare-edge",
13664
+ db: {
13665
+ engine: "unknown",
13666
+ local: false,
13667
+ layers: {
13668
+ query: false,
13669
+ flatCrud: false,
13670
+ findManyAst: false,
13671
+ rpc: false,
13672
+ relations: false
13673
+ }
13674
+ },
13675
+ storage: {
13676
+ local: true,
13677
+ objects: true,
13678
+ catalogs: false,
13679
+ backups: false
13680
+ },
13681
+ auth: {
13682
+ remote: remoteAuth
13683
+ }
13684
+ };
13685
+ }
13686
+ }
13687
+ }
13688
+ return next;
13689
+ }
13690
+ function normalizeCreateClientConfig(config) {
13691
+ return materializeEdgeBindings(applyExecutionMode(foldBindingAliases(config)));
10707
13692
  }
10708
13693
  function createClientView(core, viewContext) {
10709
13694
  const resolved = createInternalClientView(
@@ -10722,12 +13707,23 @@ function createClientView(core, viewContext) {
10722
13707
  },
10723
13708
  ...billingOptions
10724
13709
  }) : createUnavailableNamespace("billing", core.urls);
13710
+ const capabilities = core.config.capabilities ?? createGatewayCapabilities({
13711
+ authRemote: Boolean(core.urls.auth),
13712
+ // Match unavailable storage proxy when no storage URL was resolved.
13713
+ storageConfigured: Boolean(core.urls.storage)
13714
+ });
13715
+ const r2 = core.config.storage?.r2;
13716
+ const storageModule = isR2Binding(r2) ? createCloudflareR2StorageModule({
13717
+ r2,
13718
+ prefix: core.config.storage?.prefix ?? void 0
13719
+ }) : core.urls.storage ? resolved.storage : createUnavailableNamespace("storage", core.urls);
10725
13720
  const client = {
10726
13721
  db: core.urls.db ? resolved.db : createUnavailableNamespace("db", core.urls),
10727
13722
  auth: core.urls.auth ? resolved.auth : createUnavailableNamespace("auth", core.urls),
10728
13723
  chat: core.urls.chat ? resolved.chat : createUnavailableNamespace("chat", core.urls),
10729
- storage: core.urls.storage ? resolved.storage : createUnavailableNamespace("storage", core.urls),
13724
+ storage: storageModule,
10730
13725
  billing: billingModule,
13726
+ capabilities,
10731
13727
  from: ((...args) => {
10732
13728
  requireDb();
10733
13729
  return Reflect.apply(resolved.from, resolved, args);
@@ -10751,13 +13747,34 @@ function createClientView(core, viewContext) {
10751
13747
  return resolved.verifyConnection(options);
10752
13748
  },
10753
13749
  withContext(context) {
13750
+ warnIfEmptyRequestContext(context);
10754
13751
  return createClientView(core, mergeAthenaRequestContexts(viewContext, context));
10755
13752
  }
10756
13753
  };
10757
13754
  return Object.freeze(client);
10758
13755
  }
13756
+ function isEmptyAthenaRequestContext(context) {
13757
+ if (!context) return true;
13758
+ const hasHeaders = context.headers != null && Object.keys(context.headers).length > 0;
13759
+ return context.userId == null && context.organizationId == null && !normalizeOptionalContextString(context.cookie) && !normalizeOptionalContextString(context.bearerToken) && !normalizeOptionalContextString(context.sessionToken) && !context.forceNoCache && !hasHeaders;
13760
+ }
13761
+ function normalizeOptionalContextString(value) {
13762
+ const trimmed = value?.trim();
13763
+ return trimmed || void 0;
13764
+ }
13765
+ function warnIfEmptyRequestContext(context) {
13766
+ if (!isEmptyAthenaRequestContext(context)) return;
13767
+ const nodeEnv = globalThis.process?.env?.NODE_ENV;
13768
+ if (nodeEnv === "production") {
13769
+ return;
13770
+ }
13771
+ console.warn(
13772
+ "[athena] withContext({}) has no userId, organizationId, cookie, bearerToken, sessionToken, headers, or forceNoCache. Gateway scope headers will not change. Pass identity fields, or use createAthenaServerClient({ session, scope })."
13773
+ );
13774
+ }
10759
13775
  function createClient(config) {
10760
- return createClientView(resolveCore(config));
13776
+ const normalized = normalizeCreateClientConfig(config);
13777
+ return createClientView(resolveCore(normalized));
10761
13778
  }
10762
13779
 
10763
13780
  // src/gateway/types.ts
@@ -10994,6 +14011,27 @@ function resolveTotalItemsFromPage({
10994
14011
  }
10995
14012
  return clampAthenaReadQueryTotalItems(exactCount, limit);
10996
14013
  }
14014
+ function resolveAthenaReadQueryPageFetch({
14015
+ page,
14016
+ pageSize,
14017
+ limit
14018
+ }) {
14019
+ const safePage = Math.max(1, Math.trunc(page) || 1);
14020
+ const safePageSize = Math.max(1, Math.trunc(pageSize) || 1);
14021
+ if (!limit || limit < 1) {
14022
+ return { page: safePage, pageSize: safePageSize, shouldFetch: true };
14023
+ }
14024
+ const totalCap = Math.trunc(limit);
14025
+ const offset = (safePage - 1) * safePageSize;
14026
+ if (offset >= totalCap) {
14027
+ return { page: safePage, pageSize: safePageSize, shouldFetch: false };
14028
+ }
14029
+ return {
14030
+ page: safePage,
14031
+ pageSize: Math.min(safePageSize, totalCap - offset),
14032
+ shouldFetch: true
14033
+ };
14034
+ }
10997
14035
  async function executeAthenaReadQuery({
10998
14036
  client,
10999
14037
  page,
@@ -11012,15 +14050,29 @@ async function executeAthenaReadQuery({
11012
14050
  count: "exact",
11013
14051
  head: true
11014
14052
  });
14053
+ const pageFetch = resolveAthenaReadQueryPageFetch({
14054
+ limit: query.limit,
14055
+ page,
14056
+ pageSize
14057
+ });
14058
+ if (!pageFetch.shouldFetch) {
14059
+ return {
14060
+ rows: [],
14061
+ totalItems: resolveTotalItemsFromPage({
14062
+ countCandidates: [countResult.count],
14063
+ limit: query.limit,
14064
+ page: pageFetch.page,
14065
+ pageSize,
14066
+ rowCount: 0
14067
+ })
14068
+ };
14069
+ }
11015
14070
  if ((query.mode ?? "findMany") === "select") {
11016
- const selectBuilder = applyAthenaReadQuerySelectLimit(
11017
- applyAthenaReadQuerySelectOrder(
11018
- applyAthenaReadQueryFilters(baseBuilder, query.filters),
11019
- query.orderBy
11020
- ),
11021
- query.limit
14071
+ const selectBuilder = applyAthenaReadQuerySelectOrder(
14072
+ applyAthenaReadQueryFilters(baseBuilder, query.filters),
14073
+ query.orderBy
11022
14074
  );
11023
- const result2 = await selectBuilder.currentPage(page).pageSize(pageSize).select(buildAthenaReadQuerySelectString(query.columns), {
14075
+ const result2 = await selectBuilder.currentPage(pageFetch.page).pageSize(pageFetch.pageSize).select(buildAthenaReadQuerySelectString(query.columns), {
11024
14076
  count: "exact"
11025
14077
  });
11026
14078
  const rows2 = flattenAthenaReadQueryRows(
@@ -11034,7 +14086,7 @@ async function executeAthenaReadQuery({
11034
14086
  totalItems: resolveTotalItemsFromPage({
11035
14087
  countCandidates: [countResult.count, result2.count],
11036
14088
  limit: query.limit,
11037
- page,
14089
+ page: pageFetch.page,
11038
14090
  pageSize,
11039
14091
  rowCount: rows2.length
11040
14092
  })
@@ -11042,12 +14094,11 @@ async function executeAthenaReadQuery({
11042
14094
  }
11043
14095
  const findManyOrderBy = buildAthenaReadQueryFindManyOrderBy(query.orderBy);
11044
14096
  const findManyOptions = {
11045
- ...query.limit ? { limit: query.limit } : {},
11046
14097
  ...findManyOrderBy ? { orderBy: findManyOrderBy } : {},
11047
14098
  select: buildAthenaReadQueryFindManySelect(query.columns),
11048
14099
  ...query.filters?.length ? { where: buildAthenaReadQueryFindManyWhere(query.filters) } : {}
11049
14100
  };
11050
- const result = await baseBuilder.currentPage(page).pageSize(pageSize).findMany(findManyOptions);
14101
+ const result = await baseBuilder.currentPage(pageFetch.page).pageSize(pageFetch.pageSize).findMany(findManyOptions);
11051
14102
  const rows = flattenAthenaReadQueryRows(
11052
14103
  Array.isArray(result.data) ? result.data : [],
11053
14104
  query.columns,
@@ -11059,7 +14110,7 @@ async function executeAthenaReadQuery({
11059
14110
  totalItems: resolveTotalItemsFromPage({
11060
14111
  countCandidates: [countResult.count, result.count],
11061
14112
  limit: query.limit,
11062
- page,
14113
+ page: pageFetch.page,
11063
14114
  pageSize,
11064
14115
  rowCount: rows.length
11065
14116
  })
@@ -12054,12 +15105,19 @@ var DIRECT_CONNECTION_STRING_ENV_KEYS = [
12054
15105
  ];
12055
15106
  var POSTGRES_DATABASE_ENV_KEYS = ["ATHENA_GENERATOR_DB", "ATHENA_DATABASE", "PGDATABASE"];
12056
15107
  var POSTGRES_PASSWORD_ENV_KEYS = ["ATHENA_GENERATOR_PG_PASSWORD", "PGPASSWORD"];
12057
- var GATEWAY_URL_ENV_KEYS = ["ATHENA_URL", "ATHENA_GATEWAY_URL", "ATHENA_GENERATOR_URL"];
15108
+ var GATEWAY_URL_ENV_KEYS2 = ["ATHENA_URL", "ATHENA_GATEWAY_URL", "ATHENA_GENERATOR_URL"];
12058
15109
  var GATEWAY_API_KEY_ENV_KEYS = [
12059
15110
  "ATHENA_API_KEY",
12060
15111
  "ATHENA_GATEWAY_API_KEY",
12061
15112
  "ATHENA_GENERATOR_API_KEY"
12062
15113
  ];
15114
+ var GATEWAY_CLIENT_ENV_KEYS = [
15115
+ "ATHENA_CLIENT",
15116
+ "ATHENA_GATEWAY_CLIENT",
15117
+ "ATHENA_GENERATOR_CLIENT",
15118
+ "NEXT_PUBLIC_ATHENA_CLIENT",
15119
+ "NEXT_PUBLIC_ATHENA_GATEWAY_CLIENT"
15120
+ ];
12063
15121
  var GENERATOR_SCHEMA_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMAS"];
12064
15122
  var OUTPUT_FORMAT_ENV_KEYS = ["ATHENA_GENERATOR_OUTPUT_FORMAT"];
12065
15123
  var OUTPUT_PRESET_ENV_KEYS = ["ATHENA_GENERATOR_OUTPUT_PRESET"];
@@ -12352,7 +15410,7 @@ function normalizeProviderConfig(provider) {
12352
15410
  const gatewayUrl = normalizeRequiredString(
12353
15411
  provider.gatewayUrl,
12354
15412
  "provider.gatewayUrl",
12355
- GATEWAY_URL_ENV_KEYS
15413
+ GATEWAY_URL_ENV_KEYS2
12356
15414
  );
12357
15415
  const apiKey = normalizeRequiredString(
12358
15416
  provider.apiKey,
@@ -12360,11 +15418,13 @@ function normalizeProviderConfig(provider) {
12360
15418
  GATEWAY_API_KEY_ENV_KEYS
12361
15419
  );
12362
15420
  const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS) ?? "postgres";
15421
+ const client = normalizeOptionalString(provider.client, GATEWAY_CLIENT_ENV_KEYS);
12363
15422
  return {
12364
15423
  ...provider,
12365
15424
  gatewayUrl,
12366
15425
  apiKey,
12367
15426
  database,
15427
+ ...client ? { client } : {},
12368
15428
  schemas: normalizeSchemaSelection(provider.schemas)
12369
15429
  };
12370
15430
  }
@@ -12554,10 +15614,11 @@ function buildEnvironmentProviderConfig() {
12554
15614
  schemas: normalizeSchemaSelection(resolveFallbackValue(GENERATOR_SCHEMA_ENV_KEYS))
12555
15615
  };
12556
15616
  }
12557
- const gatewayUrl = resolveFallbackValue(GATEWAY_URL_ENV_KEYS);
15617
+ const gatewayUrl = resolveFallbackValue(GATEWAY_URL_ENV_KEYS2);
12558
15618
  const apiKey = resolveFallbackValue(GATEWAY_API_KEY_ENV_KEYS);
12559
15619
  if (gatewayUrl && apiKey) {
12560
15620
  const backend = resolveOptionalOneOf(GATEWAY_BACKEND_ENV_KEYS, BACKEND_TYPE_VALUES);
15621
+ const client = resolveFallbackValue(GATEWAY_CLIENT_ENV_KEYS);
12561
15622
  return {
12562
15623
  kind: "postgres",
12563
15624
  mode: "gateway",
@@ -12565,7 +15626,8 @@ function buildEnvironmentProviderConfig() {
12565
15626
  apiKey,
12566
15627
  database: normalizeOptionalString(void 0, POSTGRES_DATABASE_ENV_KEYS),
12567
15628
  schemas: normalizeSchemaSelection(resolveFallbackValue(GENERATOR_SCHEMA_ENV_KEYS)),
12568
- backend
15629
+ backend,
15630
+ ...client ? { client } : {}
12569
15631
  };
12570
15632
  }
12571
15633
  return void 0;
@@ -12709,6 +15771,8 @@ async function discoverGatewaySchemas(config) {
12709
15771
  const client = createClient({
12710
15772
  db: { url: config.gatewayUrl },
12711
15773
  key: config.apiKey,
15774
+ client: config.client,
15775
+ env: typeof process !== "undefined" ? process.env : void 0,
12712
15776
  backend: {
12713
15777
  type: config.backend ?? "postgresql"
12714
15778
  }
@@ -12795,6 +15859,7 @@ function buildGatewayProviderBlock(schemas) {
12795
15859
  mode: "gateway",
12796
15860
  gatewayUrl: generatorEnv("ATHENA_URL"),
12797
15861
  apiKey: generatorEnv("ATHENA_API_KEY"),
15862
+ client: generatorEnv("ATHENA_CLIENT", { optional: true }),
12798
15863
  database: generatorEnv("ATHENA_GENERATOR_DB", { default: "postgres" }),
12799
15864
  schemas: ${formatStringArray(schemas, " ")},
12800
15865
  }`;
@@ -13818,7 +16883,7 @@ function renderModelArtifact(descriptor, config) {
13818
16883
  const relationsAssignment = config.features.emitRelations && relationEntries.length > 0 ? `
13819
16884
  Object.assign(${descriptor.tableConstName}.meta, {
13820
16885
  relations: {
13821
- ${relationEntries.map(([relationKey2, relationValue]) => ` ${renderObjectKey(relationKey2)}: ${renderRelationLiteral(relationValue)}`).join(",\n")}
16886
+ ${relationEntries.map(([relationKey3, relationValue]) => ` ${renderObjectKey(relationKey3)}: ${renderRelationLiteral(relationValue)}`).join(",\n")}
13822
16887
  }
13823
16888
  })
13824
16889
  ` : "";
@@ -13895,7 +16960,7 @@ function renderModelArtifact2(databaseName, descriptor, config) {
13895
16960
  const relationEntries = Object.entries(descriptor.table.relations);
13896
16961
  const relationBlock = config.features.emitRelations && relationEntries.length > 0 ? `,
13897
16962
  relations: {
13898
- ${relationEntries.map(([relationKey2, relationValue]) => ` ${renderObjectKey(relationKey2)}: ${renderRelationLiteral(relationValue)}`).join(",\n")}
16963
+ ${relationEntries.map(([relationKey3, relationValue]) => ` ${renderObjectKey(relationKey3)}: ${renderRelationLiteral(relationValue)}`).join(",\n")}
13899
16964
  }` : "";
13900
16965
  const content = `import { defineModel } from '@xylex-group/athena'
13901
16966
 
@@ -14002,8 +17067,14 @@ var AthenaGatewayPostgresIntrospectionProvider = class {
14002
17067
  constructor(config) {
14003
17068
  this.config = config;
14004
17069
  this.client = createClient({
17070
+ url: this.config.gatewayUrl,
14005
17071
  db: { url: this.config.gatewayUrl },
14006
17072
  key: this.config.apiKey,
17073
+ // Multi-tenant gateways reject DEFAULT_CLIENT; prefer explicit config.
17074
+ // Also pass process.env so ATHENA_CLIENT / ATHENA_GATEWAY_CLIENT still resolve
17075
+ // when the field was not normalized into provider config.
17076
+ client: this.config.client,
17077
+ env: typeof process !== "undefined" ? process.env : void 0,
14007
17078
  backend: {
14008
17079
  type: this.config.backend ?? "postgresql"
14009
17080
  }
@@ -15484,6 +18555,432 @@ async function ensureActiveOrganization(options) {
15484
18555
  }
15485
18556
  }
15486
18557
 
15487
- export { ATHENA_AUTH_ADMIN_LIMITS, ATHENA_AUTH_BASE_ERROR_CODES, ATHENA_AUTH_MAX_ADMIN_JSON_BYTES, ATHENA_AUTH_MAX_ADMIN_JSON_DEPTH, ATHENA_AUTH_MAX_TEMPLATE_VARIABLES, ATHENA_AUTH_MAX_TEMPLATE_VARIABLE_LENGTH, AthenaBillingError, AthenaChatError, AthenaConfigurationError, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, AthenaStorageError, AthenaStorageErrorCode, Backend, DEFAULT_MULTIPART_PART_SIZE_BYTES, DEFAULT_MULTIPART_THRESHOLD_BYTES, DEFAULT_POSTGRES_SCHEMAS, applyAthenaReadQueryFilters, applyAthenaReadQuerySelectLimit, applyAthenaReadQuerySelectOrder, applyAthenaTableFilters, applyAthenaTableSelectLimit, applyAthenaTableSelectOrder, assertInt, athenaAuth, billingSdkManifest, boolean, buildAthenaReadQueryFindManyOrderBy, buildAthenaReadQueryFindManySelect, buildAthenaReadQueryFindManyWhere, buildAthenaReadQuerySelectString, buildAthenaTableFindManyOrderBy, buildAthenaTableFindManySelect, buildAthenaTableFindManyWhere, buildAthenaTableSelectString, chatSdkManifest, clampAthenaReadQueryTotalItems, clampAthenaTableTotalItems, coerceInt, createAthenaStorageError, createAuthReactEmailInput, createBillingModule, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createStorageFileModule, defineAthenaAuthConfig, defineAuthEmailTemplate, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, detectGeneratorProviderMode, discoverPostgresSchemas, ensureActiveOrganization, ensureGeneratorConfigFile, enumeration, executeAthenaReadQuery, executeAthenaTableQuery, filterIntrospectionSnapshot, findGeneratorConfigPath, flattenAthenaReadQueryRows, flattenAthenaRows, generateArtifactsFromSnapshot, generatorEnv, getAthenaDebugAst, identifier, isAthenaGatewayError, isOk, json, loadGeneratorConfig, mergeSchemaSelections, normalizeAthenaError, normalizeAthenaGatewayBaseUrl, normalizeAthenaReadQueryOrderBy, normalizeAthenaTableOrderBy, normalizeDiscoveredSchemas, normalizeGeneratorConfig, normalizeSchemaSelection, normalizeTableSelection, number, parseBooleanFlag2 as parseBooleanFlag, patchSchemasInConfigSource, renderAthenaReactEmail, renderGeneratorConfigFile, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, resolveStoragePath, runSchemaGenerator, schemasEqual, storageSdkManifest, string, table, toModelFormDefaults, toModelPayload, unwrap, unwrapChatMessage, unwrapChatRoom, unwrapOne, unwrapRows, verifyAthenaGatewayUrl, withRetry };
18558
+ // src/tables/catalog.ts
18559
+ var POSTGRES_CATALOG_SQL2 = {
18560
+ columns: `
18561
+ SELECT
18562
+ n.nspname AS schema_name,
18563
+ c.relname AS table_name,
18564
+ a.attname AS column_name,
18565
+ format_type(a.atttypid, a.atttypmod) AS data_type,
18566
+ NOT a.attnotnull AS is_nullable
18567
+ FROM pg_attribute a
18568
+ JOIN pg_class c ON c.oid = a.attrelid
18569
+ JOIN pg_namespace n ON n.oid = c.relnamespace
18570
+ WHERE c.relkind IN ('r', 'p')
18571
+ AND a.attnum > 0
18572
+ AND NOT a.attisdropped
18573
+ AND n.nspname = ANY($1::text[])
18574
+ ORDER BY n.nspname, c.relname, a.attnum;
18575
+ `,
18576
+ foreignKeys: `
18577
+ SELECT
18578
+ sn.nspname AS source_schema,
18579
+ sc.relname AS source_table,
18580
+ con.conname AS constraint_name,
18581
+ ARRAY_AGG(sa.attname ORDER BY cols.ordinality) AS source_columns,
18582
+ tn.nspname AS target_schema,
18583
+ tc.relname AS target_table,
18584
+ ARRAY_AGG(ta.attname ORDER BY cols.ordinality) AS target_columns,
18585
+ EXISTS (
18586
+ SELECT 1
18587
+ FROM pg_constraint uq
18588
+ WHERE uq.conrelid = con.conrelid
18589
+ AND uq.contype IN ('p', 'u')
18590
+ AND uq.conkey = con.conkey
18591
+ ) AS source_is_unique
18592
+ FROM pg_constraint con
18593
+ JOIN pg_class sc ON sc.oid = con.conrelid
18594
+ JOIN pg_namespace sn ON sn.oid = sc.relnamespace
18595
+ JOIN pg_class tc ON tc.oid = con.confrelid
18596
+ JOIN pg_namespace tn ON tn.oid = tc.relnamespace
18597
+ JOIN unnest(con.conkey, con.confkey) WITH ORDINALITY AS cols(source_attnum, target_attnum, ordinality) ON TRUE
18598
+ JOIN pg_attribute sa ON sa.attrelid = con.conrelid AND sa.attnum = cols.source_attnum
18599
+ JOIN pg_attribute ta ON ta.attrelid = con.confrelid AND ta.attnum = cols.target_attnum
18600
+ WHERE con.contype = 'f'
18601
+ AND sn.nspname = ANY($1::text[])
18602
+ AND tn.nspname = ANY($1::text[])
18603
+ GROUP BY
18604
+ sn.nspname,
18605
+ sc.relname,
18606
+ con.conname,
18607
+ tn.nspname,
18608
+ tc.relname,
18609
+ con.conkey,
18610
+ con.conrelid
18611
+ ORDER BY sn.nspname, sc.relname, con.conname;
18612
+ `,
18613
+ primaryKeys: `
18614
+ SELECT
18615
+ n.nspname AS schema_name,
18616
+ c.relname AS table_name,
18617
+ ARRAY_AGG(a.attname ORDER BY ck.ordinality) AS columns
18618
+ FROM pg_constraint con
18619
+ JOIN pg_class c ON c.oid = con.conrelid
18620
+ JOIN pg_namespace n ON n.oid = c.relnamespace
18621
+ JOIN unnest(con.conkey) WITH ORDINALITY AS ck(attnum, ordinality) ON TRUE
18622
+ JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = ck.attnum
18623
+ WHERE con.contype = 'p'
18624
+ AND n.nspname = ANY($1::text[])
18625
+ GROUP BY n.nspname, c.relname
18626
+ ORDER BY n.nspname, c.relname;
18627
+ `
18628
+ };
18629
+ function parseAthenaTableSchemaScope(value) {
18630
+ return value.split(",").map((entry) => entry.trim()).filter(
18631
+ (entry, index, values) => entry.length > 0 && values.indexOf(entry) === index
18632
+ );
18633
+ }
18634
+ function escapeSqlLiteral2(value) {
18635
+ return value.replace(/'/g, "''");
18636
+ }
18637
+ function buildSchemaArrayLiteral2(schemas) {
18638
+ const literals = schemas.map((schema) => `'${escapeSqlLiteral2(schema)}'`).join(", ");
18639
+ return `ARRAY[${literals}]`;
18640
+ }
18641
+ function inlineSchemaLiteral2(sql, schemas) {
18642
+ return sql.replace(
18643
+ /\$1::text\[\]/g,
18644
+ `${buildSchemaArrayLiteral2(schemas)}::text[]`
18645
+ );
18646
+ }
18647
+ function buildAthenaTableCatalogQueries(schemas) {
18648
+ return {
18649
+ columns: inlineSchemaLiteral2(POSTGRES_CATALOG_SQL2.columns, schemas),
18650
+ foreignKeys: inlineSchemaLiteral2(POSTGRES_CATALOG_SQL2.foreignKeys, schemas),
18651
+ primaryKeys: inlineSchemaLiteral2(POSTGRES_CATALOG_SQL2.primaryKeys, schemas)
18652
+ };
18653
+ }
18654
+ function tableKey2(schema, table2) {
18655
+ return `${schema}.${table2}`;
18656
+ }
18657
+ function relationKey2(...parts) {
18658
+ const base = parts.join("_").replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
18659
+ return base.length > 0 ? base : "relation";
18660
+ }
18661
+ function parsePostgresArrayLiteral2(text) {
18662
+ const body = text.slice(1, -1).trim();
18663
+ if (!body) {
18664
+ return [];
18665
+ }
18666
+ const values = [];
18667
+ let current = "";
18668
+ let inQuotes = false;
18669
+ let escaped = false;
18670
+ for (const char of body) {
18671
+ if (escaped) {
18672
+ current += char;
18673
+ escaped = false;
18674
+ continue;
18675
+ }
18676
+ if (char === "\\") {
18677
+ escaped = true;
18678
+ continue;
18679
+ }
18680
+ if (char === '"') {
18681
+ inQuotes = !inQuotes;
18682
+ continue;
18683
+ }
18684
+ if (char === "," && !inQuotes) {
18685
+ values.push(current);
18686
+ current = "";
18687
+ continue;
18688
+ }
18689
+ current += char;
18690
+ }
18691
+ values.push(current);
18692
+ return values.map((value) => value.trim()).filter((value) => value.length > 0);
18693
+ }
18694
+ function coerceStringArray2(value) {
18695
+ if (value == null) {
18696
+ return [];
18697
+ }
18698
+ if (Array.isArray(value)) {
18699
+ return value.map((entry) => entry.trim()).filter(Boolean);
18700
+ }
18701
+ if (typeof value !== "string") {
18702
+ return [];
18703
+ }
18704
+ const trimmedValue = value.trim();
18705
+ if (!trimmedValue) {
18706
+ return [];
18707
+ }
18708
+ if (trimmedValue.startsWith("{") && trimmedValue.endsWith("}")) {
18709
+ return parsePostgresArrayLiteral2(trimmedValue);
18710
+ }
18711
+ return trimmedValue.split(",").map((entry) => entry.trim()).filter(Boolean);
18712
+ }
18713
+ function createTableCatalog() {
18714
+ const tables = /* @__PURE__ */ new Map();
18715
+ const ensureTable = (schema, name) => {
18716
+ const id = tableKey2(schema, name);
18717
+ const existingTable = tables.get(id);
18718
+ if (existingTable) {
18719
+ return existingTable;
18720
+ }
18721
+ const nextTable = {
18722
+ columns: [],
18723
+ id,
18724
+ name,
18725
+ primaryKey: [],
18726
+ relationMap: /* @__PURE__ */ new Map(),
18727
+ schema
18728
+ };
18729
+ tables.set(id, nextTable);
18730
+ return nextTable;
18731
+ };
18732
+ const upsertRelation = (table2, key, relation) => {
18733
+ table2.relationMap.set(key, relation);
18734
+ };
18735
+ return {
18736
+ addColumnRows(columnRows) {
18737
+ for (const row of columnRows) {
18738
+ const table2 = ensureTable(row.schema_name, row.table_name);
18739
+ table2.columns.push({
18740
+ dataType: row.data_type,
18741
+ isNullable: row.is_nullable,
18742
+ isPrimaryKey: false,
18743
+ name: row.column_name
18744
+ });
18745
+ }
18746
+ },
18747
+ addForeignKeyRows(foreignKeyRows) {
18748
+ for (const row of foreignKeyRows) {
18749
+ const sourceTable = ensureTable(row.source_schema, row.source_table);
18750
+ const targetTable = ensureTable(row.target_schema, row.target_table);
18751
+ upsertRelation(
18752
+ sourceTable,
18753
+ relationKey2(row.constraint_name, row.target_table),
18754
+ {
18755
+ name: row.constraint_name,
18756
+ targetSchema: row.target_schema,
18757
+ targetTable: row.target_table
18758
+ }
18759
+ );
18760
+ upsertRelation(targetTable, relationKey2(row.source_table), {
18761
+ name: relationKey2(row.source_table, row.constraint_name),
18762
+ targetSchema: row.source_schema,
18763
+ targetTable: row.source_table
18764
+ });
18765
+ }
18766
+ },
18767
+ addManyToManyRows(foreignKeyRows) {
18768
+ const foreignKeysBySourceTable = /* @__PURE__ */ new Map();
18769
+ for (const foreignKey of foreignKeyRows) {
18770
+ const key = tableKey2(foreignKey.source_schema, foreignKey.source_table);
18771
+ const current = foreignKeysBySourceTable.get(key) ?? {
18772
+ foreignKeys: [],
18773
+ schema: foreignKey.source_schema,
18774
+ table: foreignKey.source_table
18775
+ };
18776
+ current.foreignKeys.push(foreignKey);
18777
+ foreignKeysBySourceTable.set(key, current);
18778
+ }
18779
+ for (const candidate of foreignKeysBySourceTable.values()) {
18780
+ const bridgeTable = tables.get(
18781
+ tableKey2(candidate.schema, candidate.table)
18782
+ );
18783
+ if (!bridgeTable || candidate.foreignKeys.length !== 2) {
18784
+ continue;
18785
+ }
18786
+ const combinedForeignColumns = Array.from(
18787
+ new Set(
18788
+ candidate.foreignKeys.flatMap(
18789
+ (foreignKey) => coerceStringArray2(foreignKey.source_columns)
18790
+ )
18791
+ )
18792
+ );
18793
+ if (bridgeTable.primaryKey.length === 0 || combinedForeignColumns.length !== bridgeTable.primaryKey.length || !bridgeTable.primaryKey.every(
18794
+ (column) => combinedForeignColumns.includes(column)
18795
+ )) {
18796
+ continue;
18797
+ }
18798
+ const [firstForeignKey, secondForeignKey] = candidate.foreignKeys;
18799
+ const firstTarget = tables.get(
18800
+ tableKey2(firstForeignKey.target_schema, firstForeignKey.target_table)
18801
+ );
18802
+ const secondTarget = tables.get(
18803
+ tableKey2(
18804
+ secondForeignKey.target_schema,
18805
+ secondForeignKey.target_table
18806
+ )
18807
+ );
18808
+ if (!(firstTarget && secondTarget)) {
18809
+ continue;
18810
+ }
18811
+ upsertRelation(
18812
+ firstTarget,
18813
+ relationKey2(candidate.table, secondForeignKey.target_table),
18814
+ {
18815
+ name: relationKey2(
18816
+ candidate.table,
18817
+ secondForeignKey.constraint_name
18818
+ ),
18819
+ targetSchema: secondForeignKey.target_schema,
18820
+ targetTable: secondForeignKey.target_table
18821
+ }
18822
+ );
18823
+ upsertRelation(
18824
+ secondTarget,
18825
+ relationKey2(candidate.table, firstForeignKey.target_table),
18826
+ {
18827
+ name: relationKey2(candidate.table, firstForeignKey.constraint_name),
18828
+ targetSchema: firstForeignKey.target_schema,
18829
+ targetTable: firstForeignKey.target_table
18830
+ }
18831
+ );
18832
+ }
18833
+ },
18834
+ addPrimaryKeyRows(primaryKeyRows) {
18835
+ for (const row of primaryKeyRows) {
18836
+ const table2 = ensureTable(row.schema_name, row.table_name);
18837
+ const primaryKey = coerceStringArray2(row.columns);
18838
+ table2.primaryKey = primaryKey;
18839
+ for (const columnName of primaryKey) {
18840
+ const column = table2.columns.find(
18841
+ (candidate) => candidate.name === columnName
18842
+ );
18843
+ if (column) {
18844
+ column.isPrimaryKey = true;
18845
+ }
18846
+ }
18847
+ }
18848
+ },
18849
+ toResponse(database) {
18850
+ return {
18851
+ database,
18852
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
18853
+ tables: [...tables.values()].map((table2) => ({
18854
+ columns: [...table2.columns].sort(
18855
+ (left, right) => left.name.localeCompare(right.name)
18856
+ ),
18857
+ id: table2.id,
18858
+ name: table2.name,
18859
+ primaryKey: [...table2.primaryKey],
18860
+ relations: [...table2.relationMap.values()].map((relation) => ({
18861
+ columns: tables.get(
18862
+ tableKey2(relation.targetSchema, relation.targetTable)
18863
+ )?.columns ?? [],
18864
+ name: relation.name,
18865
+ targetSchema: relation.targetSchema,
18866
+ targetTable: relation.targetTable
18867
+ })).sort(
18868
+ (left, right) => left.name.localeCompare(right.name)
18869
+ ),
18870
+ schema: table2.schema
18871
+ })).sort(
18872
+ (left, right) => left.id.localeCompare(right.id)
18873
+ )
18874
+ };
18875
+ }
18876
+ };
18877
+ }
18878
+ async function queryRows(client, query) {
18879
+ const result = await client.query(query);
18880
+ if (result.error || result.status < 200 || result.status >= 300) {
18881
+ const errorMessage = typeof result.error === "string" ? result.error : result.error && typeof result.error === "object" && "message" in result.error && typeof result.error.message === "string" ? result.error.message : `Athena gateway query failed with status ${result.status}.`;
18882
+ throw new Error(errorMessage);
18883
+ }
18884
+ return Array.isArray(result.data) ? result.data : [];
18885
+ }
18886
+ function isAthenaTableSchemaConfig(value) {
18887
+ if (typeof value !== "object" || value === null) {
18888
+ return false;
18889
+ }
18890
+ const config = value;
18891
+ return typeof config.gatewayUrl === "string" && typeof config.gatewayKey === "string" && typeof config.gatewayDatabase === "string" && typeof config.schemaScope === "string" && typeof config.clientName === "string";
18892
+ }
18893
+ function hasAthenaTableSchemaCredentials(config) {
18894
+ return config.gatewayUrl.trim().length > 0 && config.gatewayKey.trim().length > 0 && config.gatewayDatabase.trim().length > 0;
18895
+ }
18896
+ async function fetchAthenaTableCatalog(config, options = {}) {
18897
+ const schemas = parseAthenaTableSchemaScope(config.schemaScope);
18898
+ if (schemas.length === 0) {
18899
+ return {
18900
+ database: config.gatewayDatabase,
18901
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
18902
+ tables: []
18903
+ };
18904
+ }
18905
+ const queries = buildAthenaTableCatalogQueries(schemas);
18906
+ const client = options.client ?? createClient({
18907
+ url: config.gatewayUrl.trim(),
18908
+ key: config.gatewayKey.trim(),
18909
+ client: config.clientName.trim() || void 0
18910
+ });
18911
+ const [columnRows, primaryKeyRows, foreignKeyRows] = await Promise.all([
18912
+ queryRows(client, queries.columns),
18913
+ queryRows(client, queries.primaryKeys),
18914
+ queryRows(client, queries.foreignKeys)
18915
+ ]);
18916
+ const catalog = createTableCatalog();
18917
+ catalog.addColumnRows(columnRows);
18918
+ catalog.addPrimaryKeyRows(primaryKeyRows);
18919
+ catalog.addForeignKeyRows(foreignKeyRows);
18920
+ catalog.addManyToManyRows(foreignKeyRows);
18921
+ return catalog.toResponse(config.gatewayDatabase);
18922
+ }
18923
+ var fetchTableCatalog = fetchAthenaTableCatalog;
18924
+
18925
+ // src/tables/schema-handlers.ts
18926
+ var ATHENA_TABLE_SCHEMA_ROUTE = "/api/tables/schema";
18927
+ function json2(body, init) {
18928
+ const headers = new Headers(init?.headers);
18929
+ if (!headers.has("content-type")) {
18930
+ headers.set("content-type", "application/json; charset=utf-8");
18931
+ }
18932
+ return new Response(JSON.stringify(body), {
18933
+ status: init?.status ?? 200,
18934
+ headers
18935
+ });
18936
+ }
18937
+ async function handleAthenaTableSchemaPost(request2, options) {
18938
+ const payload = await request2.json().catch(() => null);
18939
+ let config = isAthenaTableSchemaConfig(
18940
+ payload?.config
18941
+ ) ? payload.config : null;
18942
+ if (config && options?.resolveConfig) {
18943
+ config = await options.resolveConfig(config, request2);
18944
+ }
18945
+ if (!config || !isAthenaTableSchemaConfig(config)) {
18946
+ return json2(
18947
+ {
18948
+ error: "The Athena tables showcase config is invalid."
18949
+ },
18950
+ { status: 400 }
18951
+ );
18952
+ }
18953
+ if (!hasAthenaTableSchemaCredentials(config)) {
18954
+ return json2(
18955
+ {
18956
+ error: "Gateway URL, API key, and database are required for schema introspection."
18957
+ },
18958
+ { status: 400 }
18959
+ );
18960
+ }
18961
+ try {
18962
+ const response = await fetchAthenaTableCatalog(
18963
+ config,
18964
+ {
18965
+ client: options?.client
18966
+ }
18967
+ );
18968
+ return json2(response);
18969
+ } catch (error) {
18970
+ return json2(
18971
+ {
18972
+ error: error instanceof Error ? error.message : "Athena schema introspection failed."
18973
+ },
18974
+ { status: 500 }
18975
+ );
18976
+ }
18977
+ }
18978
+ function createAthenaTableSchemaHandlers(options) {
18979
+ return {
18980
+ POST: (request2) => handleAthenaTableSchemaPost(request2, options)
18981
+ };
18982
+ }
18983
+
18984
+ export { ATHENA_AUTH_ADMIN_LIMITS, ATHENA_AUTH_BASE_ERROR_CODES, ATHENA_AUTH_MAX_ADMIN_JSON_BYTES, ATHENA_AUTH_MAX_ADMIN_JSON_DEPTH, ATHENA_AUTH_MAX_TEMPLATE_VARIABLES, ATHENA_AUTH_MAX_TEMPLATE_VARIABLE_LENGTH, ATHENA_TABLE_SCHEMA_ROUTE, AthenaBillingError, AthenaChatError, AthenaConfigurationError, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, AthenaStorageError, AthenaStorageErrorCode, Backend, DEFAULT_MULTIPART_PART_SIZE_BYTES, DEFAULT_MULTIPART_THRESHOLD_BYTES, DEFAULT_POSTGRES_SCHEMAS, applyAthenaReadQueryFilters, applyAthenaReadQuerySelectLimit, applyAthenaReadQuerySelectOrder, applyAthenaTableFilters, applyAthenaTableSelectLimit, applyAthenaTableSelectOrder, assertInt, athenaAuth, billingSdkManifest, boolean, buildAthenaReadQueryFindManyOrderBy, buildAthenaReadQueryFindManySelect, buildAthenaReadQueryFindManyWhere, buildAthenaReadQuerySelectString, buildAthenaTableCatalogQueries, buildAthenaTableFindManyOrderBy, buildAthenaTableFindManySelect, buildAthenaTableFindManyWhere, buildAthenaTableSelectString, chatSdkManifest, clampAthenaReadQueryTotalItems, clampAthenaTableTotalItems, coerceInt, createAthenaStorageError, createAthenaTableSchemaHandlers, createAuthReactEmailInput, createBillingModule, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createStorageFileModule, defineAthenaAuthConfig, defineAuthEmailTemplate, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, detectGeneratorProviderMode, discoverPostgresSchemas, ensureActiveOrganization, ensureGeneratorConfigFile, enumeration, executeAthenaReadQuery, executeAthenaTableQuery, fetchAthenaTableCatalog, fetchTableCatalog, filterIntrospectionSnapshot, findGeneratorConfigPath, flattenAthenaReadQueryRows, flattenAthenaRows, generateArtifactsFromSnapshot, generatorEnv, getAthenaDebugAst, handleAthenaTableSchemaPost, hasAthenaTableSchemaCredentials, identifier, isAthenaGatewayError, isAthenaTableSchemaConfig, isOk, json, loadGeneratorConfig, mergeSchemaSelections, normalizeAthenaError, normalizeAthenaGatewayBaseUrl, normalizeAthenaReadQueryOrderBy, normalizeAthenaTableOrderBy, normalizeDiscoveredSchemas, normalizeGeneratorConfig, normalizeSchemaSelection, normalizeTableSelection, number, parseAthenaTableSchemaScope, parseBooleanFlag2 as parseBooleanFlag, patchSchemasInConfigSource, renderAthenaReactEmail, renderGeneratorConfigFile, requireAffected, requireSuccess, resolveAthenaExecutionMode, resolveAthenaReadQueryPageFetch, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, resolveStoragePath, runSchemaGenerator, schemasEqual, storageSdkManifest, string, table, toModelFormDefaults, toModelPayload, unwrap, unwrapChatMessage, unwrapChatRoom, unwrapOne, unwrapRows, verifyAthenaGatewayUrl, withRetry };
15488
18985
  //# sourceMappingURL=index.js.map
15489
18986
  //# sourceMappingURL=index.js.map