@xylex-group/athena 3.3.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 (82) hide show
  1. package/README.md +17 -1
  2. package/dist/{athena-request-headers-Lr_m8xCV.d.cts → athena-request-headers-BnFN2mbd.d.cts} +1 -1
  3. package/dist/{athena-request-headers-DzimbvOA.d.ts → athena-request-headers-Dwdkq2WR.d.ts} +1 -1
  4. package/dist/billing.cjs +1 -1
  5. package/dist/billing.cjs.map +1 -1
  6. package/dist/billing.js +1 -1
  7. package/dist/billing.js.map +1 -1
  8. package/dist/browser.cjs +3064 -163
  9. package/dist/browser.cjs.map +1 -1
  10. package/dist/browser.d.cts +10 -10
  11. package/dist/browser.d.ts +10 -10
  12. package/dist/browser.js +3064 -163
  13. package/dist/browser.js.map +1 -1
  14. package/dist/cli/index.cjs +2990 -83
  15. package/dist/cli/index.cjs.map +1 -1
  16. package/dist/cli/index.d.cts +4 -4
  17. package/dist/cli/index.d.ts +4 -4
  18. package/dist/cli/index.js +2990 -83
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/cloudflare.cjs +12914 -0
  21. package/dist/cloudflare.cjs.map +1 -0
  22. package/dist/cloudflare.d.cts +368 -0
  23. package/dist/cloudflare.d.ts +368 -0
  24. package/dist/cloudflare.js +12885 -0
  25. package/dist/cloudflare.js.map +1 -0
  26. package/dist/cookies.cjs +4 -3
  27. package/dist/cookies.cjs.map +1 -1
  28. package/dist/cookies.js +4 -3
  29. package/dist/cookies.js.map +1 -1
  30. package/dist/env.cjs +1 -1
  31. package/dist/env.cjs.map +1 -1
  32. package/dist/env.js +1 -1
  33. package/dist/env.js.map +1 -1
  34. package/dist/index.cjs +2989 -86
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +10 -10
  37. package/dist/index.d.ts +10 -10
  38. package/dist/index.js +2989 -87
  39. package/dist/index.js.map +1 -1
  40. package/dist/{model-form-3Gr8rkdT.d.cts → model-form-D0ykVVOs.d.cts} +3 -3
  41. package/dist/{model-form-CotpEL7z.d.ts → model-form-U8NVtfSA.d.ts} +3 -3
  42. package/dist/{module-CQmOaDzP.d.cts → module-CMWlJ1z3.d.cts} +4 -4
  43. package/dist/{module-CWkUTcUc.d.ts → module-CZ-wPcf2.d.ts} +4 -4
  44. package/dist/next/client.cjs +3025 -125
  45. package/dist/next/client.cjs.map +1 -1
  46. package/dist/next/client.d.cts +4 -4
  47. package/dist/next/client.d.ts +4 -4
  48. package/dist/next/client.js +3025 -125
  49. package/dist/next/client.js.map +1 -1
  50. package/dist/next/server.cjs +3108 -194
  51. package/dist/next/server.cjs.map +1 -1
  52. package/dist/next/server.d.cts +22 -9
  53. package/dist/next/server.d.ts +22 -9
  54. package/dist/next/server.js +3108 -194
  55. package/dist/next/server.js.map +1 -1
  56. package/dist/{pipeline-BnRKO_Pd.d.cts → pipeline-BCpb4BX1.d.cts} +1 -1
  57. package/dist/{pipeline-sWCmlFqu.d.ts → pipeline-CgmXwMeX.d.ts} +1 -1
  58. package/dist/react.cjs +1 -1
  59. package/dist/react.cjs.map +1 -1
  60. package/dist/react.d.cts +6 -6
  61. package/dist/react.d.ts +6 -6
  62. package/dist/react.js +1 -1
  63. package/dist/react.js.map +1 -1
  64. package/dist/{schema-handlers-VjFDhIMw.d.ts → schema-handlers-CvWqF-dW.d.ts} +1 -1
  65. package/dist/{schema-handlers-BtT_IQFi.d.cts → schema-handlers-Dr8h9Jg-.d.cts} +1 -1
  66. package/dist/social-providers.cjs +1 -1
  67. package/dist/social-providers.cjs.map +1 -1
  68. package/dist/social-providers.js +1 -1
  69. package/dist/social-providers.js.map +1 -1
  70. package/dist/{types-Bltx6iL6.d.cts → types-B2RZPivM.d.cts} +8 -1
  71. package/dist/{types-Bltx6iL6.d.ts → types-B2RZPivM.d.ts} +8 -1
  72. package/dist/{types-BDX8zS7w.d.ts → types-BKklrX4J.d.ts} +2 -2
  73. package/dist/{types-CgCv5o6R.d.cts → types-D5dj1v5Z.d.cts} +1 -1
  74. package/dist/{types-D-Am7YSd.d.cts → types-DqBFwfhn.d.cts} +2 -2
  75. package/dist/{types-B75PdABb.d.ts → types-S-bTMPiM.d.ts} +1 -1
  76. package/dist/utils.cjs.map +1 -1
  77. package/dist/utils.d.cts +2 -2
  78. package/dist/utils.d.ts +2 -2
  79. package/dist/utils.js.map +1 -1
  80. package/dist/{v3-client-G1SLeHRa.d.cts → v3-client-DP-qg82X.d.cts} +300 -4
  81. package/dist/{v3-client-ao8BWQ8v.d.ts → v3-client-OAai_JNs.d.ts} +300 -4
  82. package/package.json +10 -3
package/dist/index.cjs CHANGED
@@ -1844,6 +1844,8 @@ function buildUpdateDebugSql(payload) {
1844
1844
  sqlParts.push(`WHERE ${whereClauses.join(" AND ")}`);
1845
1845
  }
1846
1846
  const pagination = resolvePagination({
1847
+ limit: payload.limit,
1848
+ offset: payload.offset,
1847
1849
  currentPage: payload.current_page,
1848
1850
  pageSize: payload.page_size
1849
1851
  });
@@ -1866,6 +1868,8 @@ function buildDeleteDebugSql(payload) {
1866
1868
  sqlParts.push(`WHERE ${whereClauses.join(" AND ")}`);
1867
1869
  }
1868
1870
  const pagination = resolvePagination({
1871
+ limit: payload.limit,
1872
+ offset: payload.offset,
1869
1873
  currentPage: payload.current_page,
1870
1874
  pageSize: payload.page_size
1871
1875
  });
@@ -2009,7 +2013,7 @@ function buildAthenaGatewayUrl(baseUrl, path) {
2009
2013
 
2010
2014
  // package.json
2011
2015
  var package_default = {
2012
- version: "3.3.0"
2016
+ version: "3.5.1"
2013
2017
  };
2014
2018
 
2015
2019
  // src/sdk-version.ts
@@ -2306,13 +2310,14 @@ var LEGACY_COOKIE_PREFIX = "better-auth";
2306
2310
  var DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60;
2307
2311
  var DEFAULT_CACHE_MAX_AGE = 60 * 5;
2308
2312
  function isProductionRuntime() {
2309
- return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
2313
+ return globalThis.process?.env?.NODE_ENV === "production";
2310
2314
  }
2311
2315
  function getEnvironmentSecret() {
2312
- if (typeof process === "undefined") {
2316
+ const env = globalThis.process?.env;
2317
+ if (!env) {
2313
2318
  return void 0;
2314
2319
  }
2315
- return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET;
2320
+ return env.ATHENA_AUTH_SECRET || env.BETTER_AUTH_SECRET || env.AUTH_SECRET;
2316
2321
  }
2317
2322
  function isDynamicBaseURLConfig(baseURL) {
2318
2323
  return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
@@ -5882,9 +5887,9 @@ function readHeadersField(value) {
5882
5887
  const headers = value.headers;
5883
5888
  if (!isRecord8(headers)) return {};
5884
5889
  const result = {};
5885
- for (const [key, headerValue2] of Object.entries(headers)) {
5886
- if (typeof headerValue2 === "string") {
5887
- result[key] = headerValue2;
5890
+ for (const [key, headerValue3] of Object.entries(headers)) {
5891
+ if (typeof headerValue3 === "string") {
5892
+ result[key] = headerValue3;
5888
5893
  }
5889
5894
  }
5890
5895
  return result;
@@ -9562,6 +9567,8 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, beha
9562
9567
  strip_nulls: mergedOptions?.stripNulls ?? true
9563
9568
  };
9564
9569
  if (executionState.order) payload.sort_by = executionState.order;
9570
+ if (executionState.limit !== void 0) payload.limit = executionState.limit;
9571
+ if (executionState.offset !== void 0) payload.offset = executionState.offset;
9565
9572
  if (executionState.currentPage !== void 0) payload.current_page = executionState.currentPage;
9566
9573
  if (executionState.pageSize !== void 0) payload.page_size = executionState.pageSize;
9567
9574
  if (executionState.totalPages !== void 0) payload.total_pages = executionState.totalPages;
@@ -9616,6 +9623,8 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, beha
9616
9623
  conditions: filters
9617
9624
  };
9618
9625
  if (executionState.order) payload.sort_by = executionState.order;
9626
+ if (executionState.limit !== void 0) payload.limit = executionState.limit;
9627
+ if (executionState.offset !== void 0) payload.offset = executionState.offset;
9619
9628
  if (executionState.currentPage !== void 0) payload.current_page = executionState.currentPage;
9620
9629
  if (executionState.pageSize !== void 0) payload.page_size = executionState.pageSize;
9621
9630
  if (executionState.totalPages !== void 0) payload.total_pages = executionState.totalPages;
@@ -9667,7 +9676,11 @@ function createQueryBuilder(client, formatGatewayResult, behavior, tracer) {
9667
9676
  if (!normalizedQuery) {
9668
9677
  throw new Error("query requires a non-empty string");
9669
9678
  }
9670
- const payload = { query: normalizedQuery };
9679
+ const params = options?.params;
9680
+ const payload = {
9681
+ query: normalizedQuery,
9682
+ ...Array.isArray(params) ? { params } : {}
9683
+ };
9671
9684
  const callsite = captureTraceCallsite(tracer);
9672
9685
  return executeRead(
9673
9686
  behavior,
@@ -9716,7 +9729,7 @@ function normalizeAuthClientConfig(auth, defaultBaseUrl) {
9716
9729
  }
9717
9730
  function createInternalClientCore(config) {
9718
9731
  const normalizedAuthConfig = normalizeAuthClientConfig(config.auth, config.authUrl);
9719
- const gatewayTransport = createAthenaGatewayClient({
9732
+ const gatewayTransport = config.gatewayTransport ?? createAthenaGatewayClient({
9720
9733
  baseUrl: config.baseUrl,
9721
9734
  apiKey: config.apiKey,
9722
9735
  client: config.client ?? void 0,
@@ -9814,61 +9827,2699 @@ function createInternalClientView(core, resolveContext) {
9814
9827
  if (first && typeof first === "object" && !Array.isArray(first)) {
9815
9828
  return untypedDbFrom(table2).select(void 0, first);
9816
9829
  }
9817
- return untypedDbFrom(table2).select(first, second);
9830
+ return untypedDbFrom(table2).select(first, second);
9831
+ },
9832
+ insert(table2, values, options) {
9833
+ return Array.isArray(values) ? untypedDbFrom(table2).insert(values, options) : untypedDbFrom(table2).insert(values, options);
9834
+ },
9835
+ upsert(table2, values, options) {
9836
+ return Array.isArray(values) ? untypedDbFrom(table2).upsert(values, options) : untypedDbFrom(table2).upsert(values, options);
9837
+ },
9838
+ update(table2, values, options) {
9839
+ return untypedDbFrom(table2).update(values, options);
9840
+ },
9841
+ delete(table2, options) {
9842
+ return untypedDbFrom(table2).delete(options);
9843
+ },
9844
+ rpc,
9845
+ query
9846
+ };
9847
+ const chat = createChatModule({
9848
+ baseUrl: config.chatUrl,
9849
+ apiKey: config.apiKey,
9850
+ client: config.client ?? void 0,
9851
+ headers: config.headers,
9852
+ wsUrl: config.chatWsUrl,
9853
+ webSocketFactory: config.chat?.webSocketFactory ?? void 0
9854
+ }, {
9855
+ async resolveCallOptions() {
9856
+ const context = await resolveContext();
9857
+ return context ? {
9858
+ headers: buildContextHeaders(context),
9859
+ bearerToken: context.bearerToken,
9860
+ cookie: context.cookie,
9861
+ sessionToken: context.sessionToken,
9862
+ forceNoCache: context.forceNoCache
9863
+ } : void 0;
9864
+ }
9865
+ });
9866
+ const request2 = createAthenaRequest(config, resolveContext);
9867
+ const storage = createStorageModule(gateway, {
9868
+ ...config.storage,
9869
+ ...config.storageUrl ? {
9870
+ baseUrl: config.storageUrl,
9871
+ stripBasePath: true
9872
+ } : {}
9873
+ });
9874
+ return {
9875
+ from,
9876
+ db,
9877
+ rpc,
9878
+ query,
9879
+ request: request2,
9880
+ verifyConnection: gateway.verifyConnection,
9881
+ auth: auth.auth,
9882
+ chat,
9883
+ storage
9884
+ };
9885
+ }
9886
+
9887
+ // src/cloudflare/types.ts
9888
+ var CLOUDFLARE_EDGE_BASE_URL = "https://athena.local/cloudflare-edge";
9889
+ var CLOUDFLARE_EDGE_API_KEY = "cloudflare-edge-local";
9890
+
9891
+ // src/cloudflare/capabilities.ts
9892
+ function createGatewayCapabilities(options) {
9893
+ const storageConfigured = options?.storageConfigured ?? true;
9894
+ return {
9895
+ mode: "gateway",
9896
+ db: {
9897
+ engine: options?.engine ?? "postgresql",
9898
+ local: false,
9899
+ layers: {
9900
+ query: true,
9901
+ flatCrud: true,
9902
+ findManyAst: true,
9903
+ rpc: true,
9904
+ relations: true
9905
+ }
9906
+ },
9907
+ storage: {
9908
+ local: false,
9909
+ objects: storageConfigured,
9910
+ catalogs: storageConfigured ? options?.storageCatalogs ?? true : false,
9911
+ backups: storageConfigured ? options?.storageBackups ?? true : false
9912
+ },
9913
+ auth: {
9914
+ remote: options?.authRemote ?? true
9915
+ }
9916
+ };
9917
+ }
9918
+ function createCloudflareEdgeCapabilities(options) {
9919
+ const hasObjects = options.hasR2 || Boolean(options.hasRemoteStorage);
9920
+ return {
9921
+ mode: "cloudflare-edge",
9922
+ db: {
9923
+ engine: "cloudflare-d1",
9924
+ local: true,
9925
+ layers: {
9926
+ query: true,
9927
+ flatCrud: true,
9928
+ findManyAst: options.findManyAst ?? false,
9929
+ rpc: false,
9930
+ relations: false
9931
+ }
9932
+ },
9933
+ storage: {
9934
+ // Local objects only when an R2 binding is present.
9935
+ local: options.hasR2,
9936
+ // Remote hybrid root can still expose storage.objects via the HTTP API.
9937
+ objects: hasObjects,
9938
+ catalogs: false,
9939
+ backups: false
9940
+ },
9941
+ auth: {
9942
+ remote: options.authRemote
9943
+ }
9944
+ };
9945
+ }
9946
+
9947
+ // src/cloudflare/d1/runner.ts
9948
+ function resultColumns(rows) {
9949
+ const first = rows.find((value) => value && typeof value === "object" && !Array.isArray(value));
9950
+ if (!first) return [];
9951
+ return Object.keys(first);
9952
+ }
9953
+ function isIdentChar(ch) {
9954
+ if (!ch) return false;
9955
+ return /[A-Za-z0-9_]/.test(ch);
9956
+ }
9957
+ function scanSqlKeywordsOutsideLiterals(sql, onKeyword) {
9958
+ let inSingle = false;
9959
+ let inDouble = false;
9960
+ let inBacktick = false;
9961
+ let inBracket = false;
9962
+ let inLineComment = false;
9963
+ let inBlockComment = false;
9964
+ for (let i = 0; i < sql.length; i += 1) {
9965
+ const ch = sql[i];
9966
+ const next = sql[i + 1];
9967
+ if (inLineComment) {
9968
+ if (ch === "\n" || ch === "\r") inLineComment = false;
9969
+ continue;
9970
+ }
9971
+ if (inBlockComment) {
9972
+ if (ch === "*" && next === "/") {
9973
+ i += 1;
9974
+ inBlockComment = false;
9975
+ }
9976
+ continue;
9977
+ }
9978
+ if (inSingle) {
9979
+ if (ch === "'" && next === "'") {
9980
+ i += 1;
9981
+ continue;
9982
+ }
9983
+ if (ch === "'") inSingle = false;
9984
+ continue;
9985
+ }
9986
+ if (inDouble) {
9987
+ if (ch === '"' && next === '"') {
9988
+ i += 1;
9989
+ continue;
9990
+ }
9991
+ if (ch === '"') inDouble = false;
9992
+ continue;
9993
+ }
9994
+ if (inBacktick) {
9995
+ if (ch === "`" && next === "`") {
9996
+ i += 1;
9997
+ continue;
9998
+ }
9999
+ if (ch === "`") inBacktick = false;
10000
+ continue;
10001
+ }
10002
+ if (inBracket) {
10003
+ if (ch === "]") inBracket = false;
10004
+ continue;
10005
+ }
10006
+ if (ch === "-" && next === "-") {
10007
+ inLineComment = true;
10008
+ i += 1;
10009
+ continue;
10010
+ }
10011
+ if (ch === "/" && next === "*") {
10012
+ inBlockComment = true;
10013
+ i += 1;
10014
+ continue;
10015
+ }
10016
+ if (ch === "'") {
10017
+ inSingle = true;
10018
+ continue;
10019
+ }
10020
+ if (ch === '"') {
10021
+ inDouble = true;
10022
+ continue;
10023
+ }
10024
+ if (ch === "`") {
10025
+ inBacktick = true;
10026
+ continue;
10027
+ }
10028
+ if (ch === "[") {
10029
+ inBracket = true;
10030
+ continue;
10031
+ }
10032
+ if (!isIdentChar(ch) || isIdentChar(sql[i - 1])) {
10033
+ continue;
10034
+ }
10035
+ let end = i + 1;
10036
+ while (end < sql.length && isIdentChar(sql[end])) {
10037
+ end += 1;
10038
+ }
10039
+ const keyword = sql.slice(i, end);
10040
+ if (onKeyword(keyword, i)) {
10041
+ return;
10042
+ }
10043
+ i = end - 1;
10044
+ }
10045
+ }
10046
+ function sqlContainsKeywordOutsideLiterals(sql, keyword) {
10047
+ const target = keyword.toUpperCase();
10048
+ let found = false;
10049
+ scanSqlKeywordsOutsideLiterals(sql, (token) => {
10050
+ if (token.toUpperCase() === target) {
10051
+ found = true;
10052
+ return true;
10053
+ }
10054
+ return false;
10055
+ });
10056
+ return found;
10057
+ }
10058
+ function sqlFirstKeywordOutsideLiterals(sql) {
10059
+ let first = null;
10060
+ scanSqlKeywordsOutsideLiterals(sql, (token) => {
10061
+ first = token;
10062
+ return true;
10063
+ });
10064
+ return first;
10065
+ }
10066
+ var ROW_PRODUCING_LEAD_KEYWORDS = /* @__PURE__ */ new Set(["SELECT", "PRAGMA", "EXPLAIN", "VALUES"]);
10067
+ var MUTATION_LEAD_KEYWORDS = /* @__PURE__ */ new Set(["INSERT", "UPDATE", "DELETE", "REPLACE"]);
10068
+ var WITH_TERMINAL_KEYWORDS = /* @__PURE__ */ new Set([
10069
+ "SELECT",
10070
+ "INSERT",
10071
+ "UPDATE",
10072
+ "DELETE",
10073
+ "REPLACE",
10074
+ "VALUES",
10075
+ "PRAGMA",
10076
+ "EXPLAIN"
10077
+ ]);
10078
+ function sqlTerminalKeywordAfterWith(sql) {
10079
+ let inSingle = false;
10080
+ let inDouble = false;
10081
+ let inBacktick = false;
10082
+ let inBracket = false;
10083
+ let inLineComment = false;
10084
+ let inBlockComment = false;
10085
+ let depth = 0;
10086
+ let sawWith = false;
10087
+ for (let i = 0; i < sql.length; i += 1) {
10088
+ const ch = sql[i];
10089
+ const next = sql[i + 1];
10090
+ if (inLineComment) {
10091
+ if (ch === "\n" || ch === "\r") inLineComment = false;
10092
+ continue;
10093
+ }
10094
+ if (inBlockComment) {
10095
+ if (ch === "*" && next === "/") {
10096
+ i += 1;
10097
+ inBlockComment = false;
10098
+ }
10099
+ continue;
10100
+ }
10101
+ if (inSingle) {
10102
+ if (ch === "'" && next === "'") {
10103
+ i += 1;
10104
+ continue;
10105
+ }
10106
+ if (ch === "'") inSingle = false;
10107
+ continue;
10108
+ }
10109
+ if (inDouble) {
10110
+ if (ch === '"' && next === '"') {
10111
+ i += 1;
10112
+ continue;
10113
+ }
10114
+ if (ch === '"') inDouble = false;
10115
+ continue;
10116
+ }
10117
+ if (inBacktick) {
10118
+ if (ch === "`" && next === "`") {
10119
+ i += 1;
10120
+ continue;
10121
+ }
10122
+ if (ch === "`") inBacktick = false;
10123
+ continue;
10124
+ }
10125
+ if (inBracket) {
10126
+ if (ch === "]") inBracket = false;
10127
+ continue;
10128
+ }
10129
+ if (ch === "-" && next === "-") {
10130
+ inLineComment = true;
10131
+ i += 1;
10132
+ continue;
10133
+ }
10134
+ if (ch === "/" && next === "*") {
10135
+ inBlockComment = true;
10136
+ i += 1;
10137
+ continue;
10138
+ }
10139
+ if (ch === "'") {
10140
+ inSingle = true;
10141
+ continue;
10142
+ }
10143
+ if (ch === '"') {
10144
+ inDouble = true;
10145
+ continue;
10146
+ }
10147
+ if (ch === "`") {
10148
+ inBacktick = true;
10149
+ continue;
10150
+ }
10151
+ if (ch === "[") {
10152
+ inBracket = true;
10153
+ continue;
10154
+ }
10155
+ if (ch === "(") {
10156
+ depth += 1;
10157
+ continue;
10158
+ }
10159
+ if (ch === ")") {
10160
+ if (depth > 0) depth -= 1;
10161
+ continue;
10162
+ }
10163
+ if (depth !== 0 || !isIdentChar(ch) || isIdentChar(sql[i - 1])) {
10164
+ continue;
10165
+ }
10166
+ let end = i + 1;
10167
+ while (end < sql.length && isIdentChar(sql[end])) {
10168
+ end += 1;
10169
+ }
10170
+ const keyword = sql.slice(i, end);
10171
+ const upper = keyword.toUpperCase();
10172
+ if (!sawWith) {
10173
+ if (upper === "WITH") {
10174
+ sawWith = true;
10175
+ }
10176
+ i = end - 1;
10177
+ continue;
10178
+ }
10179
+ if (WITH_TERMINAL_KEYWORDS.has(upper)) {
10180
+ return keyword;
10181
+ }
10182
+ i = end - 1;
10183
+ }
10184
+ return null;
10185
+ }
10186
+ function sqlLeadStatementKeyword(sql) {
10187
+ const first = sqlFirstKeywordOutsideLiterals(sql);
10188
+ if (!first) return null;
10189
+ if (first.toUpperCase() !== "WITH") return first;
10190
+ return sqlTerminalKeywordAfterWith(sql) ?? first;
10191
+ }
10192
+ function statementExpectsResultRows(sql) {
10193
+ const lead = sqlLeadStatementKeyword(sql);
10194
+ if (lead) {
10195
+ const upper = lead.toUpperCase();
10196
+ if (ROW_PRODUCING_LEAD_KEYWORDS.has(upper)) {
10197
+ return true;
10198
+ }
10199
+ if (MUTATION_LEAD_KEYWORDS.has(upper)) {
10200
+ return sqlContainsKeywordOutsideLiterals(sql, "RETURNING");
10201
+ }
10202
+ }
10203
+ return sqlContainsKeywordOutsideLiterals(sql, "RETURNING");
10204
+ }
10205
+ function collectRowsFromBatchResults(results) {
10206
+ const rows = [];
10207
+ for (const item of results) {
10208
+ if (Array.isArray(item.results) && item.results.length > 0) {
10209
+ rows.push(...item.results);
10210
+ }
10211
+ }
10212
+ return rows;
10213
+ }
10214
+ function sumBatchAffectedRows(results, statementCount) {
10215
+ let sum2 = 0;
10216
+ let sawChanges = false;
10217
+ for (const item of results) {
10218
+ const changes = item.meta?.changes;
10219
+ if (typeof changes === "number") {
10220
+ sum2 += changes;
10221
+ sawChanges = true;
10222
+ }
10223
+ }
10224
+ return sawChanges ? sum2 : statementCount;
10225
+ }
10226
+ function matchSqlKeywordAt(query, index, keyword) {
10227
+ const len = keyword.length;
10228
+ if (index + len > query.length) {
10229
+ return null;
10230
+ }
10231
+ const slice = query.slice(index, index + len);
10232
+ if (slice.toLowerCase() !== keyword.toLowerCase()) {
10233
+ return null;
10234
+ }
10235
+ const before = index === 0 ? "" : query[index - 1];
10236
+ const after = index + len >= query.length ? "" : query[index + len];
10237
+ const isIdent = (c) => /[A-Za-z0-9_]/.test(c);
10238
+ if (before && isIdent(before)) {
10239
+ return null;
10240
+ }
10241
+ if (after && isIdent(after)) {
10242
+ return null;
10243
+ }
10244
+ return len;
10245
+ }
10246
+ function splitSqlStatements(query) {
10247
+ const statements = [];
10248
+ let inSingle = false;
10249
+ let inDouble = false;
10250
+ let inBacktick = false;
10251
+ let inBracket = false;
10252
+ let inLineComment = false;
10253
+ let inBlockComment = false;
10254
+ let segmentStart = 0;
10255
+ let segmentHasContent = false;
10256
+ let awaitTriggerBegin = false;
10257
+ let triggerBodyDepth = 0;
10258
+ let caseDepth = 0;
10259
+ const flushSegment = (end) => {
10260
+ if (!segmentHasContent) {
10261
+ segmentStart = end + 1;
10262
+ return;
10263
+ }
10264
+ const sql = query.slice(segmentStart, end).trim();
10265
+ if (sql) {
10266
+ statements.push(sql);
10267
+ }
10268
+ segmentHasContent = false;
10269
+ segmentStart = end + 1;
10270
+ awaitTriggerBegin = false;
10271
+ triggerBodyDepth = 0;
10272
+ caseDepth = 0;
10273
+ };
10274
+ for (let i = 0; i < query.length; i += 1) {
10275
+ const ch = query[i];
10276
+ const next = query[i + 1];
10277
+ if (inLineComment) {
10278
+ if (ch === "\n" || ch === "\r") {
10279
+ inLineComment = false;
10280
+ }
10281
+ continue;
10282
+ }
10283
+ if (inBlockComment) {
10284
+ if (ch === "*" && next === "/") {
10285
+ inBlockComment = false;
10286
+ i += 1;
10287
+ }
10288
+ continue;
10289
+ }
10290
+ if (inSingle) {
10291
+ if (ch === "'" && next === "'") {
10292
+ i += 1;
10293
+ continue;
10294
+ }
10295
+ if (ch === "'") {
10296
+ inSingle = false;
10297
+ }
10298
+ continue;
10299
+ }
10300
+ if (inDouble) {
10301
+ if (ch === '"' && next === '"') {
10302
+ i += 1;
10303
+ continue;
10304
+ }
10305
+ if (ch === '"') {
10306
+ inDouble = false;
10307
+ }
10308
+ continue;
10309
+ }
10310
+ if (inBacktick) {
10311
+ if (ch === "`" && next === "`") {
10312
+ i += 1;
10313
+ continue;
10314
+ }
10315
+ if (ch === "`") {
10316
+ inBacktick = false;
10317
+ }
10318
+ continue;
10319
+ }
10320
+ if (inBracket) {
10321
+ if (ch === "]") {
10322
+ inBracket = false;
10323
+ }
10324
+ continue;
10325
+ }
10326
+ if (ch === "-" && next === "-") {
10327
+ inLineComment = true;
10328
+ i += 1;
10329
+ continue;
10330
+ }
10331
+ if (ch === "/" && next === "*") {
10332
+ inBlockComment = true;
10333
+ i += 1;
10334
+ continue;
10335
+ }
10336
+ if (ch === "'") {
10337
+ inSingle = true;
10338
+ segmentHasContent = true;
10339
+ continue;
10340
+ }
10341
+ if (ch === '"') {
10342
+ inDouble = true;
10343
+ segmentHasContent = true;
10344
+ continue;
10345
+ }
10346
+ if (ch === "`") {
10347
+ inBacktick = true;
10348
+ segmentHasContent = true;
10349
+ continue;
10350
+ }
10351
+ if (ch === "[") {
10352
+ inBracket = true;
10353
+ segmentHasContent = true;
10354
+ continue;
10355
+ }
10356
+ if (/[A-Za-z_]/.test(ch)) {
10357
+ const createLen = matchSqlKeywordAt(query, i, "CREATE");
10358
+ if (createLen != null) {
10359
+ let j2 = i + createLen;
10360
+ const skipWsAndComments = () => {
10361
+ while (j2 < query.length) {
10362
+ const c = query[j2];
10363
+ const n = query[j2 + 1];
10364
+ if (/\s/.test(c)) {
10365
+ j2 += 1;
10366
+ continue;
10367
+ }
10368
+ if (c === "-" && n === "-") {
10369
+ j2 += 2;
10370
+ while (j2 < query.length && query[j2] !== "\n" && query[j2] !== "\r") {
10371
+ j2 += 1;
10372
+ }
10373
+ continue;
10374
+ }
10375
+ if (c === "/" && n === "*") {
10376
+ j2 += 2;
10377
+ while (j2 < query.length) {
10378
+ if (query[j2] === "*" && query[j2 + 1] === "/") {
10379
+ j2 += 2;
10380
+ break;
10381
+ }
10382
+ j2 += 1;
10383
+ }
10384
+ continue;
10385
+ }
10386
+ break;
10387
+ }
10388
+ };
10389
+ skipWsAndComments();
10390
+ const tempLen = matchSqlKeywordAt(query, j2, "TEMPORARY") ?? matchSqlKeywordAt(query, j2, "TEMP");
10391
+ if (tempLen != null) {
10392
+ j2 += tempLen;
10393
+ skipWsAndComments();
10394
+ }
10395
+ const triggerLen = matchSqlKeywordAt(query, j2, "TRIGGER");
10396
+ if (triggerLen != null) {
10397
+ awaitTriggerBegin = true;
10398
+ segmentHasContent = true;
10399
+ i += createLen - 1;
10400
+ continue;
10401
+ }
10402
+ segmentHasContent = true;
10403
+ i += createLen - 1;
10404
+ continue;
10405
+ }
10406
+ const caseLen = matchSqlKeywordAt(query, i, "CASE");
10407
+ if (caseLen != null) {
10408
+ caseDepth += 1;
10409
+ segmentHasContent = true;
10410
+ i += caseLen - 1;
10411
+ continue;
10412
+ }
10413
+ const beginLen = matchSqlKeywordAt(query, i, "BEGIN");
10414
+ if (beginLen != null) {
10415
+ if (awaitTriggerBegin) {
10416
+ triggerBodyDepth += 1;
10417
+ awaitTriggerBegin = false;
10418
+ }
10419
+ segmentHasContent = true;
10420
+ i += beginLen - 1;
10421
+ continue;
10422
+ }
10423
+ const endLen = matchSqlKeywordAt(query, i, "END");
10424
+ if (endLen != null) {
10425
+ if (caseDepth > 0) {
10426
+ caseDepth -= 1;
10427
+ } else if (triggerBodyDepth > 0) {
10428
+ triggerBodyDepth -= 1;
10429
+ }
10430
+ segmentHasContent = true;
10431
+ i += endLen - 1;
10432
+ continue;
10433
+ }
10434
+ let j = i + 1;
10435
+ while (j < query.length && /[A-Za-z0-9_]/.test(query[j])) {
10436
+ j += 1;
10437
+ }
10438
+ segmentHasContent = true;
10439
+ i = j - 1;
10440
+ continue;
10441
+ }
10442
+ if (ch === ";") {
10443
+ if (triggerBodyDepth > 0 || caseDepth > 0) {
10444
+ segmentHasContent = true;
10445
+ continue;
10446
+ }
10447
+ flushSegment(i);
10448
+ continue;
10449
+ }
10450
+ if (!/\s/.test(ch)) {
10451
+ segmentHasContent = true;
10452
+ }
10453
+ }
10454
+ flushSegment(query.length);
10455
+ return statements;
10456
+ }
10457
+ function isMultiStatement(query) {
10458
+ return splitSqlStatements(query).length > 1;
10459
+ }
10460
+ function resolveSessionTarget(db, input) {
10461
+ const sessionValue = input.bookmark?.trim() || input.sessionMode?.trim();
10462
+ if (!sessionValue) {
10463
+ return { target: db, session: null };
10464
+ }
10465
+ if (typeof db.withSession !== "function") {
10466
+ throw new Error("D1 session mode/bookmark requested but withSession is not available");
10467
+ }
10468
+ const session = db.withSession(sessionValue);
10469
+ return { target: session, session };
10470
+ }
10471
+ function normalizeD1BindParams(params) {
10472
+ return params.map((value) => {
10473
+ if (typeof value === "boolean") {
10474
+ return value ? 1 : 0;
10475
+ }
10476
+ return value;
10477
+ });
10478
+ }
10479
+ async function executeD1Query(db, input) {
10480
+ const query = input.query?.trim();
10481
+ if (!query) {
10482
+ return { ok: false, error: "invalid_query", message: "query is required" };
10483
+ }
10484
+ const params = normalizeD1BindParams(Array.isArray(input.params) ? input.params : []);
10485
+ const { target, session } = resolveSessionTarget(db, input);
10486
+ if (isMultiStatement(query)) {
10487
+ if (params.length > 0) {
10488
+ return {
10489
+ ok: false,
10490
+ error: "invalid_query",
10491
+ message: "params are only supported for single prepared statements"
10492
+ };
10493
+ }
10494
+ const resolveBookmark = () => session?.getBookmark() ?? null;
10495
+ const parts = splitSqlStatements(query);
10496
+ if (typeof target.batch === "function") {
10497
+ const prepared = parts.map((part) => target.prepare(part));
10498
+ const results = await target.batch(prepared);
10499
+ const rows2 = collectRowsFromBatchResults(results);
10500
+ return {
10501
+ ok: true,
10502
+ rows: rows2,
10503
+ columns: resultColumns(rows2),
10504
+ // Prefer returned rows; otherwise sum mutation meta.changes (not statement count).
10505
+ count: rows2.length > 0 ? rows2.length : sumBatchAffectedRows(results, parts.length),
10506
+ bookmark: resolveBookmark(),
10507
+ meta: { statementCount: parts.length, results },
10508
+ statementCount: parts.length
10509
+ };
10510
+ }
10511
+ const canExec = typeof target.exec === "function" && !session;
10512
+ if (canExec) {
10513
+ const execResult = await target.exec(query);
10514
+ return {
10515
+ ok: true,
10516
+ rows: [],
10517
+ columns: [],
10518
+ durationMs: execResult.duration,
10519
+ count: execResult.count,
10520
+ bookmark: resolveBookmark(),
10521
+ meta: { statementCount: execResult.count },
10522
+ statementCount: execResult.count
10523
+ };
10524
+ }
10525
+ return {
10526
+ ok: false,
10527
+ error: "invalid_query",
10528
+ message: "multi-statement query requires D1 batch() or exec() support"
10529
+ };
10530
+ }
10531
+ let statement = target.prepare(query);
10532
+ if (params.length > 0) {
10533
+ statement = statement.bind(...params);
10534
+ }
10535
+ const expectsRows = statementExpectsResultRows(query);
10536
+ const result = expectsRows ? await statement.all() : await statement.run();
10537
+ if (result.success === false) {
10538
+ const errorField = result.error;
10539
+ const message = typeof errorField === "string" && errorField.trim() ? errorField : "D1 query failed";
10540
+ return {
10541
+ ok: false,
10542
+ error: "query_failed",
10543
+ message
10544
+ };
10545
+ }
10546
+ const rows = Array.isArray(result.results) ? result.results : [];
10547
+ const bookmark = session?.getBookmark() ?? null;
10548
+ const meta = result.meta ?? {};
10549
+ const changes = typeof meta.changes === "number" ? meta.changes : typeof result.meta?.changes === "number" ? result.meta.changes : void 0;
10550
+ return {
10551
+ ok: true,
10552
+ rows,
10553
+ columns: resultColumns(rows),
10554
+ durationMs: typeof result.meta?.duration === "number" ? result.meta.duration : void 0,
10555
+ count: expectsRows ? rows.length : changes ?? rows.length,
10556
+ bookmark,
10557
+ meta
10558
+ };
10559
+ }
10560
+ async function executeD1Batch(db, input) {
10561
+ const statements = Array.isArray(input.statements) ? input.statements : [];
10562
+ if (statements.length === 0) {
10563
+ return {
10564
+ ok: false,
10565
+ error: "invalid_batch",
10566
+ message: "statements must contain at least one item"
10567
+ };
10568
+ }
10569
+ const { target, session } = resolveSessionTarget(db, input);
10570
+ const prepared = statements.map((item) => {
10571
+ const query = item.query?.trim();
10572
+ if (!query) {
10573
+ throw new Error("statements[].query is required");
10574
+ }
10575
+ const params = normalizeD1BindParams(Array.isArray(item.params) ? item.params : []);
10576
+ let statement = target.prepare(query);
10577
+ if (params.length > 0) {
10578
+ statement = statement.bind(...params);
10579
+ }
10580
+ return statement;
10581
+ });
10582
+ const results = await target.batch(prepared);
10583
+ const bookmark = session?.getBookmark() ?? null;
10584
+ return {
10585
+ ok: true,
10586
+ results,
10587
+ bookmark
10588
+ };
10589
+ }
10590
+
10591
+ // src/cloudflare/d1/sql.ts
10592
+ function asSingle(sql, params) {
10593
+ return { sql, params };
10594
+ }
10595
+ function asBatch(statements) {
10596
+ if (statements.length === 0) {
10597
+ throw new D1SqlCompileError("empty_insert", "batch requires at least one statement");
10598
+ }
10599
+ return {
10600
+ sql: statements[0].sql,
10601
+ params: statements[0].params,
10602
+ statements
10603
+ };
10604
+ }
10605
+ function hasPaginationBounds(payload) {
10606
+ return payload.limit !== void 0 || payload.offset !== void 0 || payload.page_size !== void 0 || payload.current_page !== void 0;
10607
+ }
10608
+ function assertEffectiveMutationBounds(payload) {
10609
+ if (payload.current_page !== void 0 && payload.page_size === void 0 && payload.limit === void 0) {
10610
+ throw new D1SqlCompileError(
10611
+ "page_without_size",
10612
+ "current_page requires page_size (or limit) for bounded update/delete on D1 edge-local"
10613
+ );
10614
+ }
10615
+ const clause = limitOffsetClause(payload);
10616
+ if (!clause.trim()) {
10617
+ throw new D1SqlCompileError(
10618
+ "invalid_pagination_bounds",
10619
+ "Bounded update/delete requires limit, offset, and/or page_size on D1 edge-local"
10620
+ );
10621
+ }
10622
+ }
10623
+ var SQLITE_ROWID_ALIASES = /* @__PURE__ */ new Set(["rowid", "oid", "_rowid_"]);
10624
+ function referencedMutationColumns(payload) {
10625
+ const names = [];
10626
+ for (const condition of payload.conditions ?? []) {
10627
+ const column = (condition.column ?? condition.eq_column ?? "").trim();
10628
+ if (column) names.push(column);
10629
+ }
10630
+ if (payload.sort_by?.field?.trim()) {
10631
+ names.push(payload.sort_by.field.trim());
10632
+ }
10633
+ return names;
10634
+ }
10635
+ function resolveBoundedIdentityColumn(payload, options) {
10636
+ const refs = referencedMutationColumns(payload);
10637
+ const lower = refs.map((name) => name.toLowerCase());
10638
+ if (lower.some((name) => SQLITE_ROWID_ALIASES.has(name))) {
10639
+ throw new D1SqlCompileError(
10640
+ "bounded_mutation_unsafe_identity",
10641
+ "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."
10642
+ );
10643
+ }
10644
+ const identity = options?.identityColumn?.trim();
10645
+ if (!identity) {
10646
+ throw new D1SqlCompileError(
10647
+ "bounded_mutation_no_unique_identity",
10648
+ "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."
10649
+ );
10650
+ }
10651
+ if (SQLITE_ROWID_ALIASES.has(identity.toLowerCase())) {
10652
+ throw new D1SqlCompileError(
10653
+ "bounded_mutation_unsafe_identity",
10654
+ `Bounded update/delete cannot use identity column "${identity}" \u2014 it may shadow SQLite row identity.`
10655
+ );
10656
+ }
10657
+ return identity;
10658
+ }
10659
+ function boundedRowidInClause(table2, whereSql, whereParams, payload, options) {
10660
+ assertEffectiveMutationBounds(payload);
10661
+ const identity = resolveBoundedIdentityColumn(payload, options);
10662
+ const identitySql = quoteIdent(identity);
10663
+ const innerWhere = whereSql.replace(/^WHERE\s+/i, "");
10664
+ const parts = [
10665
+ `SELECT ${identitySql} FROM ${quoteIdent(table2)}`,
10666
+ innerWhere ? `WHERE ${innerWhere}` : "",
10667
+ orderClause(payload.sort_by),
10668
+ limitOffsetClause(payload)
10669
+ ].filter(Boolean);
10670
+ return {
10671
+ sql: `${identitySql} IN (${parts.join(" ")})`,
10672
+ params: [...whereParams]
10673
+ };
10674
+ }
10675
+ var D1SqlCompileError = class extends Error {
10676
+ code;
10677
+ constructor(code, message) {
10678
+ super(message);
10679
+ this.name = "D1SqlCompileError";
10680
+ this.code = code;
10681
+ }
10682
+ };
10683
+ var SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
10684
+ function quoteIdent(name) {
10685
+ const trimmed = name.trim();
10686
+ if (!trimmed) {
10687
+ throw new D1SqlCompileError("invalid_identifier", "Identifier is required");
10688
+ }
10689
+ if (trimmed.includes(".")) {
10690
+ throw new D1SqlCompileError(
10691
+ "schema_qualified_name",
10692
+ `Schema-qualified names are unsupported on D1 edge-local: ${trimmed}`
10693
+ );
10694
+ }
10695
+ if (!SAFE_IDENTIFIER.test(trimmed)) {
10696
+ throw new D1SqlCompileError(
10697
+ "invalid_identifier",
10698
+ `Invalid SQL identifier for D1 edge-local: ${trimmed}`
10699
+ );
10700
+ }
10701
+ return quoteQualifiedIdentifier(trimmed);
10702
+ }
10703
+ var RESPONSE_ALIAS_PATTERN2 = /^([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([A-Za-z_][A-Za-z0-9_]*)$/;
10704
+ var SQL_ALIAS_PATTERN2 = /^([A-Za-z_][A-Za-z0-9_]*)\s+(?:as\s+)?([A-Za-z_][A-Za-z0-9_]*)$/i;
10705
+ function quoteSelectTokenStrict(token) {
10706
+ const trimmed = token.trim();
10707
+ if (!trimmed || trimmed === "*") return trimmed || "*";
10708
+ if (SAFE_IDENTIFIER.test(trimmed)) {
10709
+ return quoteQualifiedIdentifier(trimmed);
10710
+ }
10711
+ const responseAlias = RESPONSE_ALIAS_PATTERN2.exec(trimmed);
10712
+ if (responseAlias) {
10713
+ const [, aliasIdentifier, baseIdentifier] = responseAlias;
10714
+ return `${quoteQualifiedIdentifier(baseIdentifier)} AS ${quoteQualifiedIdentifier(aliasIdentifier)}`;
10715
+ }
10716
+ const sqlAlias = SQL_ALIAS_PATTERN2.exec(trimmed);
10717
+ if (sqlAlias) {
10718
+ const [, baseIdentifier, aliasIdentifier] = sqlAlias;
10719
+ return `${quoteQualifiedIdentifier(baseIdentifier)} AS ${quoteQualifiedIdentifier(aliasIdentifier)}`;
10720
+ }
10721
+ throw new D1SqlCompileError(
10722
+ "unsafe_select",
10723
+ `SELECT/RETURNING expressions are not supported on D1 edge-local; use column names or aliases only: ${token}`
10724
+ );
10725
+ }
10726
+ function selectClause(columns) {
10727
+ if (columns === void 0 || columns === "*" || columns === "") return "*";
10728
+ if (typeof columns === "string") {
10729
+ const trimmed = columns.trim();
10730
+ if (!trimmed || trimmed === "*") return "*";
10731
+ return trimmed.split(",").map((part) => quoteSelectTokenStrict(part)).join(", ");
10732
+ }
10733
+ if (columns.length === 0) return "*";
10734
+ return columns.map((column) => quoteSelectTokenStrict(column)).join(", ");
10735
+ }
10736
+ function wantsReturning(payload) {
10737
+ return Boolean(payload.columns) && payload.head !== true;
10738
+ }
10739
+ function conditionToWhere(condition) {
10740
+ const column = condition.column?.trim() || condition.eq_column?.trim() || "";
10741
+ if (!column) {
10742
+ throw new D1SqlCompileError("invalid_condition", "Condition requires a column");
10743
+ }
10744
+ const col = quoteIdent(column);
10745
+ const operator = (condition.operator || "eq").toLowerCase();
10746
+ const value = condition.value !== void 0 ? condition.value : condition.eq_value;
10747
+ switch (operator) {
10748
+ case "eq": {
10749
+ if (Array.isArray(value)) {
10750
+ if (value.length === 0) {
10751
+ return { sql: "1 = 0", params: [] };
10752
+ }
10753
+ const placeholders = value.map(() => "?").join(", ");
10754
+ return { sql: `${col} IN (${placeholders})`, params: [...value] };
10755
+ }
10756
+ if (value === null) {
10757
+ return { sql: `${col} IS NULL`, params: [] };
10758
+ }
10759
+ return { sql: `${col} = ?`, params: [value ?? null] };
10760
+ }
10761
+ case "neq":
10762
+ if (value === null) {
10763
+ return { sql: `${col} IS NOT NULL`, params: [] };
10764
+ }
10765
+ return { sql: `${col} != ?`, params: [value ?? null] };
10766
+ case "gt":
10767
+ return { sql: `${col} > ?`, params: [value ?? null] };
10768
+ case "gte":
10769
+ return { sql: `${col} >= ?`, params: [value ?? null] };
10770
+ case "lt":
10771
+ return { sql: `${col} < ?`, params: [value ?? null] };
10772
+ case "lte":
10773
+ return { sql: `${col} <= ?`, params: [value ?? null] };
10774
+ case "like":
10775
+ return { sql: `${col} LIKE ?`, params: [value ?? null] };
10776
+ case "ilike":
10777
+ return { sql: `${col} LIKE ? COLLATE NOCASE`, params: [value ?? null] };
10778
+ case "in": {
10779
+ const items = Array.isArray(value) ? value : value === void 0 ? [] : [value];
10780
+ if (items.length === 0) {
10781
+ return { sql: "1 = 0", params: [] };
10782
+ }
10783
+ const placeholders = items.map(() => "?").join(", ");
10784
+ return { sql: `${col} IN (${placeholders})`, params: [...items] };
10785
+ }
10786
+ case "is": {
10787
+ if (value === null || value === "null") {
10788
+ return { sql: `${col} IS NULL`, params: [] };
10789
+ }
10790
+ if (value === true || value === "true") {
10791
+ return { sql: `${col} IS TRUE`, params: [] };
10792
+ }
10793
+ if (value === false || value === "false") {
10794
+ return { sql: `${col} IS FALSE`, params: [] };
10795
+ }
10796
+ return { sql: `${col} IS ?`, params: [value] };
10797
+ }
10798
+ case "not":
10799
+ case "or":
10800
+ case "contains":
10801
+ case "containedby":
10802
+ throw new D1SqlCompileError(
10803
+ "unsupported_operator",
10804
+ `Condition operator "${operator}" is not supported on D1 edge-local L1`
10805
+ );
10806
+ default:
10807
+ throw new D1SqlCompileError(
10808
+ "unsupported_operator",
10809
+ `Unknown condition operator "${operator}"`
10810
+ );
10811
+ }
10812
+ }
10813
+ function buildWhere(conditions) {
10814
+ if (!conditions?.length) {
10815
+ return { sql: "", params: [] };
10816
+ }
10817
+ const parts = [];
10818
+ const params = [];
10819
+ for (const condition of conditions) {
10820
+ if (!condition.operator && condition.eq_column) {
10821
+ const clause2 = conditionToWhere({
10822
+ ...condition,
10823
+ operator: "eq",
10824
+ column: condition.eq_column,
10825
+ value: condition.eq_value
10826
+ });
10827
+ parts.push(clause2.sql);
10828
+ params.push(...clause2.params);
10829
+ continue;
10830
+ }
10831
+ const clause = conditionToWhere(condition);
10832
+ parts.push(clause.sql);
10833
+ params.push(...clause.params);
10834
+ }
10835
+ return {
10836
+ sql: parts.length ? `WHERE ${parts.join(" AND ")}` : "",
10837
+ params
10838
+ };
10839
+ }
10840
+ function orderClause(order) {
10841
+ if (!order?.field?.trim()) return "";
10842
+ const direction = order.direction === "descending" ? "DESC" : "ASC";
10843
+ return `ORDER BY ${quoteIdent(order.field)} ${direction}`;
10844
+ }
10845
+ function limitOffsetClause(payload) {
10846
+ let limit = payload.limit;
10847
+ let offset = payload.offset;
10848
+ if (limit === void 0 && payload.page_size !== void 0) {
10849
+ limit = payload.page_size;
10850
+ }
10851
+ if (payload.current_page !== void 0 && offset === void 0) {
10852
+ const pageSize = payload.page_size ?? payload.limit;
10853
+ if (pageSize !== void 0) {
10854
+ offset = Math.max(0, (payload.current_page - 1) * pageSize);
10855
+ }
10856
+ }
10857
+ const parts = [];
10858
+ if (offset !== void 0 && limit === void 0) {
10859
+ parts.push("LIMIT -1");
10860
+ parts.push(`OFFSET ${Math.max(0, Math.trunc(offset))}`);
10861
+ } else {
10862
+ if (limit !== void 0) {
10863
+ parts.push(`LIMIT ${Math.max(0, Math.trunc(limit))}`);
10864
+ }
10865
+ if (offset !== void 0) {
10866
+ parts.push(`OFFSET ${Math.max(0, Math.trunc(offset))}`);
10867
+ }
10868
+ }
10869
+ return parts.join(" ");
10870
+ }
10871
+ function rejectStructuredRelations(payload) {
10872
+ const select = payload.select;
10873
+ if (select && typeof select === "object" && !Array.isArray(select)) {
10874
+ for (const value of Object.values(select)) {
10875
+ if (value && typeof value === "object") {
10876
+ throw new D1SqlCompileError(
10877
+ "relations_unsupported",
10878
+ "Nested relation selects are unsupported on D1 edge-local"
10879
+ );
10880
+ }
10881
+ }
10882
+ }
10883
+ if (payload.view_name) {
10884
+ throw new D1SqlCompileError(
10885
+ "view_unsupported",
10886
+ "view_name is unsupported on D1 edge-local L1"
10887
+ );
10888
+ }
10889
+ }
10890
+ function jsonValue(value) {
10891
+ if (value === void 0) return null;
10892
+ if (value !== null && typeof value === "object") {
10893
+ return JSON.stringify(value);
10894
+ }
10895
+ return value;
10896
+ }
10897
+ function compileD1Fetch(payload) {
10898
+ rejectStructuredRelations(payload);
10899
+ const table2 = payload.table_name?.trim();
10900
+ if (!table2) {
10901
+ throw new D1SqlCompileError("missing_table", "table_name is required for fetch");
10902
+ }
10903
+ let columns = payload.columns;
10904
+ if (payload.select && typeof payload.select === "object" && !Array.isArray(payload.select)) {
10905
+ const keys = Object.entries(payload.select).filter(([, enabled]) => enabled === true || enabled === 1).map(([key]) => key);
10906
+ if (keys.length > 0) {
10907
+ columns = keys;
10908
+ }
10909
+ } else if (typeof payload.select === "string" && payload.select.trim()) {
10910
+ columns = payload.select;
10911
+ }
10912
+ let where = buildWhere(payload.conditions);
10913
+ if (!where.sql && payload.where && typeof payload.where === "object") {
10914
+ const eqConditions = Object.entries(
10915
+ payload.where
10916
+ ).map(([column, value]) => ({
10917
+ column,
10918
+ operator: "eq",
10919
+ value
10920
+ }));
10921
+ where = buildWhere(eqConditions);
10922
+ }
10923
+ if (payload.head === true) {
10924
+ return compileD1CountFromWhere(table2, where);
10925
+ }
10926
+ const parts = [
10927
+ `SELECT ${selectClause(columns)} FROM ${quoteIdent(table2)}`,
10928
+ where.sql,
10929
+ orderClause(payload.sort_by),
10930
+ limitOffsetClause(payload)
10931
+ ].filter(Boolean);
10932
+ return asSingle(parts.join(" "), where.params);
10933
+ }
10934
+ function compileD1Count(payload) {
10935
+ rejectStructuredRelations(payload);
10936
+ const table2 = payload.table_name?.trim();
10937
+ if (!table2) {
10938
+ throw new D1SqlCompileError("missing_table", "table_name is required for count");
10939
+ }
10940
+ let where = buildWhere(payload.conditions);
10941
+ if (!where.sql && payload.where && typeof payload.where === "object") {
10942
+ const eqConditions = Object.entries(
10943
+ payload.where
10944
+ ).map(([column, value]) => ({
10945
+ column,
10946
+ operator: "eq",
10947
+ value
10948
+ }));
10949
+ where = buildWhere(eqConditions);
10950
+ }
10951
+ return compileD1CountFromWhere(table2, where);
10952
+ }
10953
+ function compileD1CountFromWhere(table2, where) {
10954
+ const parts = [
10955
+ `SELECT COUNT(*) AS __athena_count FROM ${quoteIdent(table2)}`,
10956
+ where.sql
10957
+ ].filter(Boolean);
10958
+ return asSingle(parts.join(" "), where.params);
10959
+ }
10960
+ function extractAthenaCount(rows) {
10961
+ const first = rows[0];
10962
+ const rawCount = first && typeof first === "object" && !Array.isArray(first) ? first.__athena_count : void 0;
10963
+ const count = typeof rawCount === "number" ? rawCount : typeof rawCount === "bigint" ? Number(rawCount) : Number(rawCount ?? 0);
10964
+ return Number.isFinite(count) ? count : 0;
10965
+ }
10966
+ function compileSingleRowInsert(table2, row, payload) {
10967
+ const columns = Object.keys(row);
10968
+ if (columns.length === 0) {
10969
+ if (payload.on_conflict) {
10970
+ throw new D1SqlCompileError(
10971
+ "default_values_upsert_unsupported",
10972
+ "DEFAULT VALUES upsert is unsupported on D1 edge-local; provide insert columns or omit onConflict"
10973
+ );
10974
+ }
10975
+ const parts2 = [`INSERT INTO ${quoteIdent(table2)} DEFAULT VALUES`];
10976
+ if (wantsReturning(payload)) {
10977
+ parts2.push(`RETURNING ${selectClause(payload.columns)}`);
10978
+ }
10979
+ return { sql: parts2.join(" "), params: [] };
10980
+ }
10981
+ const params = columns.map((column) => jsonValue(row[column]));
10982
+ const parts = [
10983
+ `INSERT INTO ${quoteIdent(table2)} (${columns.map(quoteIdent).join(", ")})`,
10984
+ `VALUES (${columns.map(() => "?").join(", ")})`
10985
+ ];
10986
+ appendOnConflict(parts, params, payload, columns);
10987
+ if (wantsReturning(payload)) {
10988
+ parts.push(`RETURNING ${selectClause(payload.columns)}`);
10989
+ }
10990
+ return { sql: parts.join(" "), params };
10991
+ }
10992
+ function parseOnConflictColumns(onConflict) {
10993
+ const raw = Array.isArray(onConflict) ? onConflict : [onConflict];
10994
+ const columns = [];
10995
+ for (const item of raw) {
10996
+ for (const part of String(item).split(",")) {
10997
+ const trimmed = part.trim();
10998
+ if (trimmed) columns.push(trimmed);
10999
+ }
11000
+ }
11001
+ if (columns.length === 0) {
11002
+ throw new D1SqlCompileError(
11003
+ "invalid_on_conflict",
11004
+ "on_conflict requires at least one column"
11005
+ );
11006
+ }
11007
+ return columns;
11008
+ }
11009
+ function appendOnConflict(parts, params, payload, insertColumns) {
11010
+ if (!payload.on_conflict) return;
11011
+ const conflictCols = parseOnConflictColumns(payload.on_conflict);
11012
+ const conflictSql = conflictCols.map(quoteIdent).join(", ");
11013
+ if (payload.update_body !== void 0 && payload.update_body !== null) {
11014
+ const entries = Object.entries(payload.update_body);
11015
+ if (entries.length === 0) {
11016
+ parts.push(`ON CONFLICT (${conflictSql}) DO NOTHING`);
11017
+ return;
11018
+ }
11019
+ const assignments2 = entries.map(([column, value]) => {
11020
+ params.push(jsonValue(value));
11021
+ return `${quoteIdent(column)} = ?`;
11022
+ });
11023
+ parts.push(`ON CONFLICT (${conflictSql}) DO UPDATE SET ${assignments2.join(", ")}`);
11024
+ return;
11025
+ }
11026
+ const conflictSet = new Set(conflictCols);
11027
+ const assignments = insertColumns.filter((column) => !conflictSet.has(column)).map((column) => {
11028
+ const quoted = quoteIdent(column);
11029
+ return `${quoted} = excluded.${quoted}`;
11030
+ });
11031
+ if (assignments.length === 0) {
11032
+ parts.push(`ON CONFLICT (${conflictSql}) DO NOTHING`);
11033
+ } else {
11034
+ parts.push(`ON CONFLICT (${conflictSql}) DO UPDATE SET ${assignments.join(", ")}`);
11035
+ }
11036
+ }
11037
+ function compileD1Insert(payload) {
11038
+ const table2 = payload.table_name?.trim();
11039
+ if (!table2) {
11040
+ throw new D1SqlCompileError("missing_table", "table_name is required for insert");
11041
+ }
11042
+ const rows = Array.isArray(payload.insert_body) ? payload.insert_body : [payload.insert_body];
11043
+ if (rows.length === 0) {
11044
+ throw new D1SqlCompileError("empty_insert", "insert_body must not be empty");
11045
+ }
11046
+ const columns = [];
11047
+ const seen = /* @__PURE__ */ new Set();
11048
+ for (const row of rows) {
11049
+ for (const key of Object.keys(row ?? {})) {
11050
+ if (seen.has(key)) continue;
11051
+ seen.add(key);
11052
+ columns.push(key);
11053
+ }
11054
+ }
11055
+ if (columns.length === 0) {
11056
+ if (rows.length === 1) {
11057
+ const compiled = compileSingleRowInsert(table2, {}, payload);
11058
+ return asSingle(compiled.sql, compiled.params);
11059
+ }
11060
+ throw new D1SqlCompileError(
11061
+ "empty_insert",
11062
+ "Multi-row insert_body cannot be empty objects; use a single {} for DEFAULT VALUES"
11063
+ );
11064
+ }
11065
+ const forceNullForMissing = payload.default_to_null === true;
11066
+ const isSparse = rows.some(
11067
+ (row) => columns.some((column) => !Object.prototype.hasOwnProperty.call(row, column))
11068
+ );
11069
+ if (isSparse && !forceNullForMissing && rows.length > 1) {
11070
+ return asBatch(
11071
+ rows.map((row) => compileSingleRowInsert(table2, row, payload))
11072
+ );
11073
+ }
11074
+ if (isSparse && !forceNullForMissing && rows.length === 1) {
11075
+ const compiled = compileSingleRowInsert(table2, rows[0], payload);
11076
+ return asSingle(compiled.sql, compiled.params);
11077
+ }
11078
+ const params = [];
11079
+ const valueGroups = rows.map((row) => {
11080
+ const placeholders = columns.map((column) => {
11081
+ const has = Object.prototype.hasOwnProperty.call(row, column);
11082
+ if (!has) {
11083
+ params.push(null);
11084
+ return "?";
11085
+ }
11086
+ params.push(jsonValue(row[column]));
11087
+ return "?";
11088
+ });
11089
+ return `(${placeholders.join(", ")})`;
11090
+ });
11091
+ const parts = [
11092
+ `INSERT INTO ${quoteIdent(table2)} (${columns.map(quoteIdent).join(", ")})`,
11093
+ `VALUES ${valueGroups.join(", ")}`
11094
+ ];
11095
+ appendOnConflict(parts, params, payload, columns);
11096
+ if (wantsReturning(payload)) {
11097
+ parts.push(`RETURNING ${selectClause(payload.columns)}`);
11098
+ }
11099
+ return asSingle(parts.join(" "), params);
11100
+ }
11101
+ function compileD1Update(payload, options) {
11102
+ const table2 = payload.table_name?.trim();
11103
+ if (!table2) {
11104
+ throw new D1SqlCompileError("missing_table", "table_name is required for update");
11105
+ }
11106
+ const entries = Object.entries(payload.update_body ?? {});
11107
+ if (entries.length === 0) {
11108
+ throw new D1SqlCompileError("empty_update", "update_body must not be empty");
11109
+ }
11110
+ const params = [];
11111
+ const assignments = entries.map(([column, value]) => {
11112
+ params.push(jsonValue(value));
11113
+ return `${quoteIdent(column)} = ?`;
11114
+ });
11115
+ const where = buildWhere(payload.conditions);
11116
+ if (!where.sql) {
11117
+ throw new D1SqlCompileError(
11118
+ "unfiltered_update",
11119
+ "UPDATE requires at least one condition on D1 edge-local"
11120
+ );
11121
+ }
11122
+ if (hasPaginationBounds(payload) || payload.sort_by) {
11123
+ if (!hasPaginationBounds(payload)) {
11124
+ throw new D1SqlCompileError(
11125
+ "order_without_bounds",
11126
+ "UPDATE with sort_by requires limit/offset or page_size/current_page on D1 edge-local"
11127
+ );
11128
+ }
11129
+ const bounded = boundedRowidInClause(
11130
+ table2,
11131
+ where.sql,
11132
+ where.params,
11133
+ {
11134
+ ...payload,
11135
+ conditions: payload.conditions
11136
+ },
11137
+ options
11138
+ );
11139
+ params.push(...bounded.params);
11140
+ const parts2 = [
11141
+ `UPDATE ${quoteIdent(table2)} SET ${assignments.join(", ")}`,
11142
+ `WHERE ${bounded.sql}`
11143
+ ];
11144
+ if (wantsReturning(payload)) {
11145
+ parts2.push(`RETURNING ${selectClause(payload.columns)}`);
11146
+ }
11147
+ return asSingle(parts2.join(" "), params);
11148
+ }
11149
+ params.push(...where.params);
11150
+ const parts = [
11151
+ `UPDATE ${quoteIdent(table2)} SET ${assignments.join(", ")}`,
11152
+ where.sql
11153
+ ];
11154
+ if (wantsReturning(payload)) {
11155
+ parts.push(`RETURNING ${selectClause(payload.columns)}`);
11156
+ }
11157
+ return asSingle(parts.join(" "), params);
11158
+ }
11159
+ function compileD1Delete(payload, options) {
11160
+ const table2 = payload.table_name?.trim();
11161
+ if (!table2) {
11162
+ throw new D1SqlCompileError("missing_table", "table_name is required for delete");
11163
+ }
11164
+ const conditions = [...payload.conditions ?? []];
11165
+ if (payload.resource_id !== void 0 && payload.resource_id !== null) {
11166
+ const hasResourceIdFilter = conditions.some((condition) => {
11167
+ const column = (condition.column ?? condition.eq_column ?? "").trim();
11168
+ return column === "resource_id";
11169
+ });
11170
+ const hasIdFilter = conditions.some((condition) => {
11171
+ const column = (condition.column ?? condition.eq_column ?? "").trim();
11172
+ return column === "id";
11173
+ });
11174
+ if (!hasResourceIdFilter && !hasIdFilter) {
11175
+ conditions.unshift({
11176
+ column: "id",
11177
+ operator: "eq",
11178
+ value: payload.resource_id
11179
+ });
11180
+ }
11181
+ }
11182
+ const where = buildWhere(conditions);
11183
+ if (!where.sql) {
11184
+ throw new D1SqlCompileError(
11185
+ "unfiltered_delete",
11186
+ "DELETE requires at least one condition or resource_id on D1 edge-local"
11187
+ );
11188
+ }
11189
+ if (hasPaginationBounds(payload) || payload.sort_by) {
11190
+ if (!hasPaginationBounds(payload)) {
11191
+ throw new D1SqlCompileError(
11192
+ "order_without_bounds",
11193
+ "DELETE with sort_by requires limit/offset or page_size/current_page on D1 edge-local"
11194
+ );
11195
+ }
11196
+ const bounded = boundedRowidInClause(
11197
+ table2,
11198
+ where.sql,
11199
+ where.params,
11200
+ {
11201
+ ...payload,
11202
+ conditions
11203
+ },
11204
+ options
11205
+ );
11206
+ const parts2 = [`DELETE FROM ${quoteIdent(table2)}`, `WHERE ${bounded.sql}`];
11207
+ if (wantsReturning(payload)) {
11208
+ parts2.push(`RETURNING ${selectClause(payload.columns)}`);
11209
+ }
11210
+ return asSingle(parts2.join(" "), bounded.params);
11211
+ }
11212
+ const parts = [`DELETE FROM ${quoteIdent(table2)}`, where.sql];
11213
+ if (wantsReturning(payload)) {
11214
+ parts.push(`RETURNING ${selectClause(payload.columns)}`);
11215
+ }
11216
+ return asSingle(parts.join(" "), where.params);
11217
+ }
11218
+
11219
+ // src/cloudflare/d1/sql-rewrite.ts
11220
+ 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";
11221
+ function mapSqlOutsideLiterals(sql, transform) {
11222
+ let out = "";
11223
+ let buffer = "";
11224
+ let inSingle = false;
11225
+ let inDouble = false;
11226
+ let inBacktick = false;
11227
+ let inBracket = false;
11228
+ let inLineComment = false;
11229
+ let inBlockComment = false;
11230
+ const flushCode = () => {
11231
+ if (buffer) {
11232
+ out += transform(buffer);
11233
+ buffer = "";
11234
+ }
11235
+ };
11236
+ for (let i = 0; i < sql.length; i += 1) {
11237
+ const ch = sql[i];
11238
+ const next = sql[i + 1];
11239
+ if (inLineComment) {
11240
+ out += ch;
11241
+ if (ch === "\n" || ch === "\r") inLineComment = false;
11242
+ continue;
11243
+ }
11244
+ if (inBlockComment) {
11245
+ out += ch;
11246
+ if (ch === "*" && next === "/") {
11247
+ out += next;
11248
+ i += 1;
11249
+ inBlockComment = false;
11250
+ }
11251
+ continue;
11252
+ }
11253
+ if (inSingle) {
11254
+ out += ch;
11255
+ if (ch === "'" && next === "'") {
11256
+ out += next;
11257
+ i += 1;
11258
+ continue;
11259
+ }
11260
+ if (ch === "'") inSingle = false;
11261
+ continue;
11262
+ }
11263
+ if (inDouble) {
11264
+ out += ch;
11265
+ if (ch === '"' && next === '"') {
11266
+ out += next;
11267
+ i += 1;
11268
+ continue;
11269
+ }
11270
+ if (ch === '"') inDouble = false;
11271
+ continue;
11272
+ }
11273
+ if (inBacktick) {
11274
+ out += ch;
11275
+ if (ch === "`" && next === "`") {
11276
+ out += next;
11277
+ i += 1;
11278
+ continue;
11279
+ }
11280
+ if (ch === "`") inBacktick = false;
11281
+ continue;
11282
+ }
11283
+ if (inBracket) {
11284
+ out += ch;
11285
+ if (ch === "]") inBracket = false;
11286
+ continue;
11287
+ }
11288
+ if (ch === "-" && next === "-") {
11289
+ flushCode();
11290
+ out += ch;
11291
+ out += next;
11292
+ i += 1;
11293
+ inLineComment = true;
11294
+ continue;
11295
+ }
11296
+ if (ch === "/" && next === "*") {
11297
+ flushCode();
11298
+ out += ch;
11299
+ out += next;
11300
+ i += 1;
11301
+ inBlockComment = true;
11302
+ continue;
11303
+ }
11304
+ if (ch === "'") {
11305
+ flushCode();
11306
+ out += ch;
11307
+ inSingle = true;
11308
+ continue;
11309
+ }
11310
+ if (ch === '"') {
11311
+ flushCode();
11312
+ out += ch;
11313
+ inDouble = true;
11314
+ continue;
11315
+ }
11316
+ if (ch === "`") {
11317
+ flushCode();
11318
+ out += ch;
11319
+ inBacktick = true;
11320
+ continue;
11321
+ }
11322
+ if (ch === "[") {
11323
+ flushCode();
11324
+ out += ch;
11325
+ inBracket = true;
11326
+ continue;
11327
+ }
11328
+ buffer += ch;
11329
+ }
11330
+ flushCode();
11331
+ return out;
11332
+ }
11333
+ function isIdentChar2(ch) {
11334
+ if (!ch) return false;
11335
+ return /[A-Za-z0-9_]/.test(ch);
11336
+ }
11337
+ function collectLimitOffsetKeywords(sql) {
11338
+ const hits = [];
11339
+ let depth = 0;
11340
+ let statement = 0;
11341
+ let inSingle = false;
11342
+ let inDouble = false;
11343
+ let inBacktick = false;
11344
+ let inBracket = false;
11345
+ let inLineComment = false;
11346
+ let inBlockComment = false;
11347
+ for (let i = 0; i < sql.length; i += 1) {
11348
+ const ch = sql[i];
11349
+ const next = sql[i + 1];
11350
+ if (inLineComment) {
11351
+ if (ch === "\n" || ch === "\r") inLineComment = false;
11352
+ continue;
11353
+ }
11354
+ if (inBlockComment) {
11355
+ if (ch === "*" && next === "/") {
11356
+ i += 1;
11357
+ inBlockComment = false;
11358
+ }
11359
+ continue;
11360
+ }
11361
+ if (inSingle) {
11362
+ if (ch === "'" && next === "'") {
11363
+ i += 1;
11364
+ continue;
11365
+ }
11366
+ if (ch === "'") inSingle = false;
11367
+ continue;
11368
+ }
11369
+ if (inDouble) {
11370
+ if (ch === '"' && next === '"') {
11371
+ i += 1;
11372
+ continue;
11373
+ }
11374
+ if (ch === '"') inDouble = false;
11375
+ continue;
11376
+ }
11377
+ if (inBacktick) {
11378
+ if (ch === "`" && next === "`") {
11379
+ i += 1;
11380
+ continue;
11381
+ }
11382
+ if (ch === "`") inBacktick = false;
11383
+ continue;
11384
+ }
11385
+ if (inBracket) {
11386
+ if (ch === "]") inBracket = false;
11387
+ continue;
11388
+ }
11389
+ if (ch === "-" && next === "-") {
11390
+ inLineComment = true;
11391
+ i += 1;
11392
+ continue;
11393
+ }
11394
+ if (ch === "/" && next === "*") {
11395
+ inBlockComment = true;
11396
+ i += 1;
11397
+ continue;
11398
+ }
11399
+ if (ch === "'") {
11400
+ inSingle = true;
11401
+ continue;
11402
+ }
11403
+ if (ch === '"') {
11404
+ inDouble = true;
11405
+ continue;
11406
+ }
11407
+ if (ch === "`") {
11408
+ inBacktick = true;
11409
+ continue;
11410
+ }
11411
+ if (ch === "[") {
11412
+ inBracket = true;
11413
+ continue;
11414
+ }
11415
+ if (ch === "(") {
11416
+ depth += 1;
11417
+ continue;
11418
+ }
11419
+ if (ch === ")") {
11420
+ depth = Math.max(0, depth - 1);
11421
+ continue;
11422
+ }
11423
+ if (ch === ";" && depth === 0) {
11424
+ statement += 1;
11425
+ continue;
11426
+ }
11427
+ if (!isIdentChar2(ch) || isIdentChar2(sql[i - 1])) {
11428
+ continue;
11429
+ }
11430
+ const rest = sql.slice(i);
11431
+ if (/^LIMIT\b/i.test(rest)) {
11432
+ hits.push({ kind: "limit", start: i, depth, statement });
11433
+ i += 4;
11434
+ continue;
11435
+ }
11436
+ if (/^OFFSET\b/i.test(rest)) {
11437
+ hits.push({ kind: "offset", start: i, depth, statement });
11438
+ i += 5;
11439
+ }
11440
+ }
11441
+ return hits;
11442
+ }
11443
+ function injectLimitBeforeBareOffsets(sql) {
11444
+ const hits = collectLimitOffsetKeywords(sql);
11445
+ if (hits.length === 0) return sql;
11446
+ const injectAt = [];
11447
+ for (const hit of hits) {
11448
+ if (hit.kind !== "offset") continue;
11449
+ let hasLimit = false;
11450
+ for (let i = hits.length - 1; i >= 0; i -= 1) {
11451
+ const prev = hits[i];
11452
+ if (prev.start >= hit.start) continue;
11453
+ if (prev.statement !== hit.statement) continue;
11454
+ if (prev.depth !== hit.depth) continue;
11455
+ if (prev.kind === "limit") {
11456
+ hasLimit = true;
11457
+ break;
11458
+ }
11459
+ if (prev.kind === "offset") {
11460
+ break;
11461
+ }
11462
+ }
11463
+ if (!hasLimit) {
11464
+ injectAt.push(hit.start);
11465
+ }
11466
+ }
11467
+ if (injectAt.length === 0) return sql;
11468
+ let out = sql;
11469
+ for (let i = injectAt.length - 1; i >= 0; i -= 1) {
11470
+ const at = injectAt[i];
11471
+ out = `${out.slice(0, at)}LIMIT -1 ${out.slice(at)}`;
11472
+ }
11473
+ return out;
11474
+ }
11475
+ function rewritePostgresSqlForSqlite(sql) {
11476
+ const castPattern = new RegExp(`::(?:${PG_CAST_TYPES})\\b`, "gi");
11477
+ const withoutCastsAndIlike = mapSqlOutsideLiterals(sql, (chunk) => {
11478
+ let rewritten = chunk.replace(castPattern, "");
11479
+ rewritten = rewritten.replace(/\bILIKE\b/gi, "LIKE");
11480
+ return rewritten;
11481
+ });
11482
+ return injectLimitBeforeBareOffsets(withoutCastsAndIlike);
11483
+ }
11484
+
11485
+ // src/cloudflare/d1/transport.ts
11486
+ function hasPaginationBounds2(payload) {
11487
+ return payload.limit !== void 0 || payload.offset !== void 0 || payload.page_size !== void 0 || payload.current_page !== void 0;
11488
+ }
11489
+ function normalizeSqliteCollation(name) {
11490
+ const raw = String(name ?? "").trim().replace(/^["'`[]|["'`\]]$/g, "");
11491
+ if (!raw) return "BINARY";
11492
+ return raw.toUpperCase();
11493
+ }
11494
+ function findCreateTableColumnListOpen(createSql) {
11495
+ const m = /\bCREATE\s+(?:(?:TEMP|TEMPORARY|VIRTUAL)\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?/i.exec(
11496
+ createSql
11497
+ );
11498
+ if (!m) return -1;
11499
+ let i = m.index + m[0].length;
11500
+ let inSingle = false;
11501
+ let inDouble = false;
11502
+ let inBacktick = false;
11503
+ let inBracket = false;
11504
+ while (i < createSql.length) {
11505
+ const ch = createSql[i];
11506
+ if (inSingle) {
11507
+ if (ch === "'" && createSql[i + 1] === "'") {
11508
+ i += 2;
11509
+ continue;
11510
+ }
11511
+ if (ch === "'") inSingle = false;
11512
+ i++;
11513
+ continue;
11514
+ }
11515
+ if (inDouble) {
11516
+ if (ch === '"') inDouble = false;
11517
+ i++;
11518
+ continue;
11519
+ }
11520
+ if (inBacktick) {
11521
+ if (ch === "`") inBacktick = false;
11522
+ i++;
11523
+ continue;
11524
+ }
11525
+ if (inBracket) {
11526
+ if (ch === "]") inBracket = false;
11527
+ i++;
11528
+ continue;
11529
+ }
11530
+ if (ch === "'") {
11531
+ inSingle = true;
11532
+ i++;
11533
+ continue;
11534
+ }
11535
+ if (ch === '"') {
11536
+ inDouble = true;
11537
+ i++;
11538
+ continue;
11539
+ }
11540
+ if (ch === "`") {
11541
+ inBacktick = true;
11542
+ i++;
11543
+ continue;
11544
+ }
11545
+ if (ch === "[") {
11546
+ inBracket = true;
11547
+ i++;
11548
+ continue;
11549
+ }
11550
+ if (ch === "(") return i;
11551
+ i++;
11552
+ }
11553
+ return -1;
11554
+ }
11555
+ function parseColumnCollationFromCreateSql(createSql, columnName) {
11556
+ if (!createSql || !columnName) return null;
11557
+ const listOpen = findCreateTableColumnListOpen(createSql);
11558
+ if (listOpen < 0) return null;
11559
+ const listStart = listOpen + 1;
11560
+ const escaped = columnName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11561
+ const nameRe = new RegExp(
11562
+ `(?:^|[^\\w])(?:"${escaped}"|\`${escaped}\`|\\[${escaped}\\]|${escaped})\\s+`,
11563
+ "i"
11564
+ );
11565
+ const listSlice = createSql.slice(listStart);
11566
+ let nameMatchAbs = -1;
11567
+ let nameMatchLen = 0;
11568
+ {
11569
+ let i2 = 0;
11570
+ let depth2 = 1;
11571
+ let inSingle2 = false;
11572
+ let inDouble2 = false;
11573
+ let inBacktick2 = false;
11574
+ let inBracket2 = false;
11575
+ let segmentStart = 0;
11576
+ const trySegment = (from, to) => {
11577
+ if (nameMatchAbs >= 0) return;
11578
+ const segment = listSlice.slice(from, to);
11579
+ const m = nameRe.exec(segment);
11580
+ if (!m) return;
11581
+ const leading = segment.slice(0, m.index).trim();
11582
+ if (leading.length > 0) return;
11583
+ nameMatchAbs = listStart + from + m.index;
11584
+ nameMatchLen = m[0].length;
11585
+ };
11586
+ while (i2 < listSlice.length && depth2 > 0) {
11587
+ const ch = listSlice[i2];
11588
+ if (inSingle2) {
11589
+ if (ch === "'" && listSlice[i2 + 1] === "'") {
11590
+ i2 += 2;
11591
+ continue;
11592
+ }
11593
+ if (ch === "'") inSingle2 = false;
11594
+ i2++;
11595
+ continue;
11596
+ }
11597
+ if (inDouble2) {
11598
+ if (ch === '"') inDouble2 = false;
11599
+ i2++;
11600
+ continue;
11601
+ }
11602
+ if (inBacktick2) {
11603
+ if (ch === "`") inBacktick2 = false;
11604
+ i2++;
11605
+ continue;
11606
+ }
11607
+ if (inBracket2) {
11608
+ if (ch === "]") inBracket2 = false;
11609
+ i2++;
11610
+ continue;
11611
+ }
11612
+ if (ch === "'") {
11613
+ inSingle2 = true;
11614
+ i2++;
11615
+ continue;
11616
+ }
11617
+ if (ch === '"') {
11618
+ inDouble2 = true;
11619
+ i2++;
11620
+ continue;
11621
+ }
11622
+ if (ch === "`") {
11623
+ inBacktick2 = true;
11624
+ i2++;
11625
+ continue;
11626
+ }
11627
+ if (ch === "[") {
11628
+ inBracket2 = true;
11629
+ i2++;
11630
+ continue;
11631
+ }
11632
+ if (ch === "(") {
11633
+ depth2++;
11634
+ i2++;
11635
+ continue;
11636
+ }
11637
+ if (ch === ")") {
11638
+ depth2--;
11639
+ if (depth2 === 0) {
11640
+ trySegment(segmentStart, i2);
11641
+ break;
11642
+ }
11643
+ i2++;
11644
+ continue;
11645
+ }
11646
+ if (ch === "," && depth2 === 1) {
11647
+ trySegment(segmentStart, i2);
11648
+ segmentStart = i2 + 1;
11649
+ i2++;
11650
+ continue;
11651
+ }
11652
+ i2++;
11653
+ }
11654
+ }
11655
+ if (nameMatchAbs < 0 || nameMatchLen <= 0) return null;
11656
+ const start = nameMatchAbs + nameMatchLen;
11657
+ let i = start;
11658
+ let depth = 0;
11659
+ let inSingle = false;
11660
+ let inDouble = false;
11661
+ let inBacktick = false;
11662
+ let inBracket = false;
11663
+ while (i < createSql.length) {
11664
+ const ch = createSql[i];
11665
+ if (inSingle) {
11666
+ if (ch === "'" && createSql[i + 1] === "'") {
11667
+ i += 2;
11668
+ continue;
11669
+ }
11670
+ if (ch === "'") inSingle = false;
11671
+ i++;
11672
+ continue;
11673
+ }
11674
+ if (inDouble) {
11675
+ if (ch === '"') inDouble = false;
11676
+ i++;
11677
+ continue;
11678
+ }
11679
+ if (inBacktick) {
11680
+ if (ch === "`") inBacktick = false;
11681
+ i++;
11682
+ continue;
11683
+ }
11684
+ if (inBracket) {
11685
+ if (ch === "]") inBracket = false;
11686
+ i++;
11687
+ continue;
11688
+ }
11689
+ if (ch === "'") {
11690
+ inSingle = true;
11691
+ i++;
11692
+ continue;
11693
+ }
11694
+ if (ch === '"') {
11695
+ inDouble = true;
11696
+ i++;
11697
+ continue;
11698
+ }
11699
+ if (ch === "`") {
11700
+ inBacktick = true;
11701
+ i++;
11702
+ continue;
11703
+ }
11704
+ if (ch === "[") {
11705
+ inBracket = true;
11706
+ i++;
11707
+ continue;
11708
+ }
11709
+ if (ch === "(") {
11710
+ depth++;
11711
+ i++;
11712
+ continue;
11713
+ }
11714
+ if (ch === ")") {
11715
+ if (depth === 0) {
11716
+ break;
11717
+ }
11718
+ depth--;
11719
+ i++;
11720
+ continue;
11721
+ }
11722
+ if (ch === "," && depth === 0) {
11723
+ break;
11724
+ }
11725
+ i++;
11726
+ }
11727
+ const colDef = createSql.slice(start, i);
11728
+ const collRe = /\bCOLLATE\s+("([^"]+)"|'([^']+)'|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][\w$]*))/i;
11729
+ const match = collRe.exec(colDef);
11730
+ if (!match) return null;
11731
+ return match[2] ?? match[3] ?? match[4] ?? match[5] ?? match[6] ?? match[1] ?? null;
11732
+ }
11733
+ async function indexCollationMatchesColumn(d1, table2, tableSafe, indexSafe, columnName, session) {
11734
+ const xinfo = await executeD1Query(d1, {
11735
+ query: `PRAGMA index_xinfo("${indexSafe}")`,
11736
+ params: [],
11737
+ ...session
11738
+ });
11739
+ if (!xinfo.ok) {
11740
+ return false;
11741
+ }
11742
+ const xRows = xinfo.rows ?? [];
11743
+ const keyRows = xRows.filter((row) => {
11744
+ const isKey = row.key === 1 || row.key === true || Number(row.key) === 1;
11745
+ if (!isKey) return false;
11746
+ return typeof row.name === "string" && row.name === columnName;
11747
+ });
11748
+ if (keyRows.length === 0) {
11749
+ const byName = xRows.find(
11750
+ (row) => typeof row.name === "string" && row.name === columnName
11751
+ );
11752
+ if (!byName) return false;
11753
+ keyRows.push(byName);
11754
+ }
11755
+ const indexColl = normalizeSqliteCollation(keyRows[0]?.coll);
11756
+ const master = await executeD1Query(d1, {
11757
+ query: `SELECT sql AS create_sql FROM sqlite_master WHERE type = 'table' AND name = ?`,
11758
+ params: [table2],
11759
+ ...session
11760
+ });
11761
+ let createSql = "";
11762
+ if (master.ok && Array.isArray(master.rows) && master.rows.length > 0) {
11763
+ createSql = String(
11764
+ master.rows[0]?.create_sql ?? ""
11765
+ );
11766
+ }
11767
+ const columnCollRaw = parseColumnCollationFromCreateSql(createSql, columnName);
11768
+ const columnColl = normalizeSqliteCollation(columnCollRaw);
11769
+ return indexColl === columnColl;
11770
+ }
11771
+ async function resolveD1BoundedIdentityColumn(d1, tableName, session) {
11772
+ const table2 = tableName.trim();
11773
+ if (!table2) {
11774
+ throw new D1SqlCompileError("missing_table", "table_name is required for bounded mutation");
11775
+ }
11776
+ const safe = table2.replace(/"/g, '""');
11777
+ const info = await executeD1Query(d1, {
11778
+ query: `PRAGMA table_info("${safe}")`,
11779
+ params: [],
11780
+ ...session
11781
+ });
11782
+ if (!info.ok) {
11783
+ throw new D1SqlCompileError(
11784
+ "bounded_mutation_no_unique_identity",
11785
+ `Unable to introspect table "${table2}" for bounded mutation identity: ${info.message}`
11786
+ );
11787
+ }
11788
+ const cols = info.rows.filter(
11789
+ (row) => typeof row?.name === "string" && row.name.length > 0
11790
+ );
11791
+ const colByName = new Map(cols.map((col) => [col.name, col]));
11792
+ const isNotNullColumn = (name) => {
11793
+ const col = colByName.get(name);
11794
+ if (!col) return false;
11795
+ return col.notnull === 1 || col.notnull === true || Number(col.notnull) === 1;
11796
+ };
11797
+ const isIntegerPrimaryKeyType = (col) => {
11798
+ if (typeof col.pk !== "number" || col.pk <= 0) return false;
11799
+ const declared = String(col.type ?? "").trim().toUpperCase();
11800
+ return declared === "INTEGER";
11801
+ };
11802
+ const loadIndexList = async () => {
11803
+ const indexList = await executeD1Query(d1, {
11804
+ query: `PRAGMA index_list("${safe}")`,
11805
+ params: [],
11806
+ ...session
11807
+ });
11808
+ if (!indexList.ok) return null;
11809
+ return indexList.rows;
11810
+ };
11811
+ const isDescendingIntegerPrimaryKeyException = async (colName, indexes) => {
11812
+ if (indexes) {
11813
+ const hasPkOrigin = indexes.some(
11814
+ (index) => String(index.origin ?? "").toLowerCase() === "pk"
11815
+ );
11816
+ if (hasPkOrigin) return true;
11817
+ const originReported = indexes.some(
11818
+ (index) => index.origin !== void 0 && index.origin !== null && String(index.origin).length > 0
11819
+ );
11820
+ if (indexes.length === 0 || originReported) {
11821
+ return false;
11822
+ }
11823
+ }
11824
+ const master = await executeD1Query(d1, {
11825
+ query: `SELECT sql AS create_sql FROM sqlite_master WHERE type = 'table' AND name = ?`,
11826
+ params: [table2],
11827
+ ...session
11828
+ });
11829
+ if (!master.ok || !Array.isArray(master.rows) || master.rows.length === 0) {
11830
+ return false;
11831
+ }
11832
+ const createSql = String(
11833
+ master.rows[0]?.create_sql ?? ""
11834
+ );
11835
+ if (!createSql) return false;
11836
+ const escaped = colName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11837
+ const inlineDesc = new RegExp(
11838
+ `(?:^|[^\\w])(?:"${escaped}"|${escaped})\\s+INTEGER\\s+PRIMARY\\s+KEY\\s+DESC\\b`,
11839
+ "i"
11840
+ );
11841
+ const tableDesc = new RegExp(
11842
+ `PRIMARY\\s+KEY\\s*\\(\\s*(?:"${escaped}"|${escaped})\\s+DESC\\b`,
11843
+ "i"
11844
+ );
11845
+ return inlineDesc.test(createSql) || tableDesc.test(createSql);
11846
+ };
11847
+ const pkCols = cols.filter((row) => typeof row.pk === "number" && row.pk > 0).sort((a, b) => (a.pk ?? 0) - (b.pk ?? 0));
11848
+ let indexRows;
11849
+ if (pkCols.length === 1 && pkCols[0]?.name) {
11850
+ if (isIntegerPrimaryKeyType(pkCols[0])) {
11851
+ indexRows = await loadIndexList();
11852
+ const isDescException = await isDescendingIntegerPrimaryKeyException(
11853
+ pkCols[0].name,
11854
+ indexRows
11855
+ );
11856
+ if (!isDescException) {
11857
+ return pkCols[0].name;
11858
+ }
11859
+ } else if (isNotNullColumn(pkCols[0].name)) {
11860
+ indexRows = await loadIndexList();
11861
+ const pkIndex = (indexRows ?? []).find(
11862
+ (index) => String(index.origin ?? "").toLowerCase() === "pk"
11863
+ );
11864
+ if (pkIndex && typeof pkIndex.name === "string" && pkIndex.name) {
11865
+ const indexSafe = pkIndex.name.replace(/"/g, '""');
11866
+ const collMatch = await indexCollationMatchesColumn(
11867
+ d1,
11868
+ table2,
11869
+ safe,
11870
+ indexSafe,
11871
+ pkCols[0].name,
11872
+ session
11873
+ );
11874
+ if (collMatch) {
11875
+ return pkCols[0].name;
11876
+ }
11877
+ }
11878
+ }
11879
+ }
11880
+ if (indexRows === void 0) {
11881
+ indexRows = await loadIndexList();
11882
+ }
11883
+ if (indexRows) {
11884
+ for (const index of indexRows) {
11885
+ const unique = index.unique === 1 || index.unique === true || Number(index.unique) === 1;
11886
+ if (!unique || typeof index.name !== "string" || !index.name) continue;
11887
+ const isPartial = index.partial === 1 || index.partial === true || Number(index.partial) === 1;
11888
+ if (isPartial) {
11889
+ continue;
11890
+ }
11891
+ const indexSafe = index.name.replace(/"/g, '""');
11892
+ const indexInfo = await executeD1Query(d1, {
11893
+ query: `PRAGMA index_info("${indexSafe}")`,
11894
+ params: [],
11895
+ ...session
11896
+ });
11897
+ if (!indexInfo.ok) continue;
11898
+ const rawIndexCols = indexInfo.rows ?? [];
11899
+ const hasExpressionTerm = rawIndexCols.some((row) => {
11900
+ const nameOk = typeof row?.name === "string" && row.name.length > 0;
11901
+ if (!nameOk) return true;
11902
+ if (typeof row.cid === "number" && row.cid < 0) return true;
11903
+ return false;
11904
+ });
11905
+ if (hasExpressionTerm || rawIndexCols.length === 0) {
11906
+ continue;
11907
+ }
11908
+ const indexCols = rawIndexCols.filter(
11909
+ (row) => typeof row?.name === "string" && row.name.length > 0
11910
+ );
11911
+ if (indexCols.length === 1 && indexCols[0]?.name) {
11912
+ const identity = indexCols[0].name;
11913
+ if (!isNotNullColumn(identity)) {
11914
+ continue;
11915
+ }
11916
+ const collMatch = await indexCollationMatchesColumn(
11917
+ d1,
11918
+ table2,
11919
+ safe,
11920
+ indexSafe,
11921
+ identity,
11922
+ session
11923
+ );
11924
+ if (!collMatch) {
11925
+ continue;
11926
+ }
11927
+ return identity;
11928
+ }
11929
+ }
11930
+ }
11931
+ throw new D1SqlCompileError(
11932
+ "bounded_mutation_no_unique_identity",
11933
+ `Bounded update/delete on "${table2}" requires a proven single-column PRIMARY KEY or UNIQUE index`
11934
+ );
11935
+ }
11936
+ async function compileOptionsForBoundedMutation(d1, payload, session) {
11937
+ if (!hasPaginationBounds2(payload) && !payload.sort_by) {
11938
+ return void 0;
11939
+ }
11940
+ if (!hasPaginationBounds2(payload)) {
11941
+ return void 0;
11942
+ }
11943
+ const identityColumn = await resolveD1BoundedIdentityColumn(
11944
+ d1,
11945
+ payload.table_name ?? "",
11946
+ session
11947
+ );
11948
+ return { identityColumn };
11949
+ }
11950
+ function headerValue2(options, name) {
11951
+ const headers = options?.headers;
11952
+ if (!headers) return void 0;
11953
+ const lower = name.toLowerCase();
11954
+ for (const [key, value] of Object.entries(headers)) {
11955
+ if (key.toLowerCase() === lower && value?.trim()) {
11956
+ return value.trim();
11957
+ }
11958
+ }
11959
+ return void 0;
11960
+ }
11961
+ function sessionFromOptions(options, defaults) {
11962
+ return {
11963
+ bookmark: headerValue2(options, "x-athena-d1-bookmark") ?? null,
11964
+ sessionMode: headerValue2(options, "x-athena-d1-session-mode") ?? defaults.defaultSessionMode ?? null
11965
+ };
11966
+ }
11967
+ function resolveStripNulls(payloadStrip, callOptions, defaultValue = true) {
11968
+ if (typeof payloadStrip === "boolean") return payloadStrip;
11969
+ if (typeof callOptions?.stripNulls === "boolean") return callOptions.stripNulls;
11970
+ return defaultValue;
11971
+ }
11972
+ function stripNullPropertiesFromRows(rows) {
11973
+ return rows.map((row) => {
11974
+ if (row == null || typeof row !== "object" || Array.isArray(row)) {
11975
+ return row;
11976
+ }
11977
+ const out = {};
11978
+ for (const [key, value] of Object.entries(row)) {
11979
+ if (value !== null) {
11980
+ out[key] = value;
11981
+ }
11982
+ }
11983
+ return out;
11984
+ });
11985
+ }
11986
+ function maybeStripNullRows(rows, strip) {
11987
+ return strip ? stripNullPropertiesFromRows(rows) : rows;
11988
+ }
11989
+ function successResponse(data, count, raw, bookmark) {
11990
+ const response = {
11991
+ ok: true,
11992
+ status: 200,
11993
+ statusText: "OK",
11994
+ data,
11995
+ count: count ?? null,
11996
+ error: void 0,
11997
+ errorDetails: null,
11998
+ raw
11999
+ };
12000
+ if (bookmark) {
12001
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
12002
+ const rawRecord = raw;
12003
+ rawRecord.bookmark = bookmark;
12004
+ }
12005
+ }
12006
+ return response;
12007
+ }
12008
+ function errorResponse(status, code, message, endpoint, method, hint) {
12009
+ const error = new AthenaGatewayError({
12010
+ code,
12011
+ message,
12012
+ status,
12013
+ endpoint,
12014
+ method,
12015
+ hint
12016
+ });
12017
+ return {
12018
+ ok: false,
12019
+ status,
12020
+ statusText: null,
12021
+ data: null,
12022
+ error: error.message,
12023
+ errorDetails: error.toDetails(),
12024
+ raw: { error: message, code }
12025
+ };
12026
+ }
12027
+ function compileErrorResponse(error, endpoint, method) {
12028
+ if (error instanceof D1SqlCompileError) {
12029
+ return errorResponse(
12030
+ 400,
12031
+ "HTTP_ERROR",
12032
+ error.message,
12033
+ endpoint,
12034
+ method,
12035
+ `D1 SQL compile failed (${error.code})`
12036
+ );
12037
+ }
12038
+ const message = error instanceof Error ? error.message : String(error);
12039
+ return errorResponse(500, "UNKNOWN_ERROR", message, endpoint, method);
12040
+ }
12041
+ function createCloudflareD1GatewayTransport(options) {
12042
+ const { d1 } = options;
12043
+ async function runCompiled(compiled, callOptions, endpoint, method, mapResult, stripNulls = true) {
12044
+ try {
12045
+ const session = sessionFromOptions(callOptions, options);
12046
+ if (compiled.statements && compiled.statements.length > 1) {
12047
+ const batch = await executeD1Batch(d1, {
12048
+ statements: compiled.statements.map((statement) => ({
12049
+ query: statement.sql,
12050
+ params: statement.params
12051
+ })),
12052
+ ...session
12053
+ });
12054
+ if (!batch.ok) {
12055
+ return errorResponse(400, "HTTP_ERROR", batch.message, endpoint, method);
12056
+ }
12057
+ const rows2 = maybeStripNullRows(
12058
+ batch.results.flatMap(
12059
+ (item) => Array.isArray(item.results) ? item.results : []
12060
+ ),
12061
+ stripNulls
12062
+ );
12063
+ const changes = batch.results.reduce((sum2, item) => {
12064
+ const meta = item?.meta;
12065
+ const n = meta && typeof meta === "object" && typeof meta.changes === "number" ? meta.changes : 0;
12066
+ return sum2 + n;
12067
+ }, 0);
12068
+ const count = rows2.length > 0 ? rows2.length : changes;
12069
+ const mapped2 = mapResult?.(rows2, count) ?? {
12070
+ data: rows2,
12071
+ count
12072
+ };
12073
+ return successResponse(mapped2.data, mapped2.count, batch, batch.bookmark);
12074
+ }
12075
+ const result = await executeD1Query(d1, {
12076
+ query: compiled.sql,
12077
+ params: compiled.params,
12078
+ ...session
12079
+ });
12080
+ if (!result.ok) {
12081
+ return errorResponse(400, "HTTP_ERROR", result.message, endpoint, method);
12082
+ }
12083
+ const rows = maybeStripNullRows(result.rows, stripNulls);
12084
+ const mapped = mapResult?.(rows, result.count) ?? {
12085
+ data: rows,
12086
+ count: result.count
12087
+ };
12088
+ return successResponse(mapped.data, mapped.count, result, result.bookmark);
12089
+ } catch (error) {
12090
+ const message = error instanceof Error ? error.message : String(error);
12091
+ return errorResponse(500, "UNKNOWN_ERROR", message, endpoint, method);
12092
+ }
12093
+ }
12094
+ return {
12095
+ baseUrl: CLOUDFLARE_EDGE_BASE_URL,
12096
+ buildHeaders(callOptions) {
12097
+ return { ...callOptions?.headers ?? {} };
12098
+ },
12099
+ async resolveCallOptions(callOptions) {
12100
+ return callOptions;
12101
+ },
12102
+ async verifyConnection(connectionOptions) {
12103
+ const baseUrl = CLOUDFLARE_EDGE_BASE_URL;
12104
+ try {
12105
+ const result = await executeD1Query(d1, { query: "SELECT 1 AS ok" });
12106
+ if (!result.ok) {
12107
+ return {
12108
+ ok: false,
12109
+ reachable: false,
12110
+ status: 500,
12111
+ statusText: null,
12112
+ baseUrl,
12113
+ url: `${baseUrl}/d1`,
12114
+ error: result.message,
12115
+ errorDetails: null,
12116
+ raw: result
12117
+ };
12118
+ }
12119
+ return {
12120
+ ok: true,
12121
+ reachable: true,
12122
+ status: 200,
12123
+ statusText: "OK",
12124
+ baseUrl,
12125
+ url: `${baseUrl}/d1`,
12126
+ error: void 0,
12127
+ errorDetails: null,
12128
+ raw: result
12129
+ };
12130
+ } catch (error) {
12131
+ const message = error instanceof Error ? error.message : String(error);
12132
+ return {
12133
+ ok: false,
12134
+ reachable: false,
12135
+ status: 0,
12136
+ statusText: null,
12137
+ baseUrl,
12138
+ url: `${baseUrl}/d1`,
12139
+ error: message,
12140
+ errorDetails: null,
12141
+ raw: null
12142
+ };
12143
+ }
12144
+ },
12145
+ async fetchGateway(payload, callOptions) {
12146
+ try {
12147
+ if (payload && typeof payload === "object" && "operation" in payload) {
12148
+ return errorResponse(
12149
+ 400,
12150
+ "HTTP_ERROR",
12151
+ "Direct AST operation payloads are unsupported on D1 edge-local",
12152
+ "/gateway/fetch",
12153
+ "POST"
12154
+ );
12155
+ }
12156
+ const compiled = compileD1Fetch(payload);
12157
+ const stripNulls = resolveStripNulls(payload.strip_nulls, callOptions, true);
12158
+ if (payload.head === true) {
12159
+ return runCompiled(
12160
+ compiled,
12161
+ callOptions,
12162
+ "/gateway/fetch",
12163
+ "POST",
12164
+ (rows) => ({ data: [], count: extractAthenaCount(rows) }),
12165
+ // COUNT rows are meta, not user-facing object rows
12166
+ false
12167
+ );
12168
+ }
12169
+ const wantsTotalCount = payload.count === "exact" || payload.count === "planned" || payload.count === "estimated";
12170
+ if (wantsTotalCount) {
12171
+ const session = sessionFromOptions(callOptions, options);
12172
+ const countCompiled = compileD1Count(payload);
12173
+ const batch = await executeD1Batch(d1, {
12174
+ statements: [
12175
+ {
12176
+ query: compiled.sql,
12177
+ params: compiled.params
12178
+ },
12179
+ {
12180
+ query: countCompiled.sql,
12181
+ params: countCompiled.params
12182
+ }
12183
+ ],
12184
+ ...session
12185
+ });
12186
+ if (!batch.ok) {
12187
+ return errorResponse(400, "HTTP_ERROR", batch.message, "/gateway/fetch", "POST");
12188
+ }
12189
+ const dataItem = batch.results[0];
12190
+ const countItem = batch.results[1];
12191
+ if (!dataItem || dataItem.success === false) {
12192
+ const message = dataItem && typeof dataItem.error === "string" && dataItem.error.trim() ? dataItem.error : "D1 page query failed";
12193
+ return errorResponse(400, "HTTP_ERROR", message, "/gateway/fetch", "POST");
12194
+ }
12195
+ if (!countItem || countItem.success === false) {
12196
+ const message = countItem && typeof countItem.error === "string" && countItem.error.trim() ? countItem.error : "D1 count query failed";
12197
+ return errorResponse(400, "HTTP_ERROR", message, "/gateway/fetch", "POST");
12198
+ }
12199
+ const dataRows = Array.isArray(dataItem.results) ? dataItem.results : [];
12200
+ const countRows = Array.isArray(countItem.results) ? countItem.results : [];
12201
+ const total = extractAthenaCount(countRows);
12202
+ const rows = maybeStripNullRows(dataRows, stripNulls);
12203
+ return successResponse(
12204
+ rows,
12205
+ total,
12206
+ { data: dataItem, count: countItem, batch },
12207
+ batch.bookmark
12208
+ );
12209
+ }
12210
+ return runCompiled(compiled, callOptions, "/gateway/fetch", "POST", void 0, stripNulls);
12211
+ } catch (error) {
12212
+ return compileErrorResponse(error, "/gateway/fetch", "POST");
12213
+ }
9818
12214
  },
9819
- insert(table2, values, options) {
9820
- return Array.isArray(values) ? untypedDbFrom(table2).insert(values, options) : untypedDbFrom(table2).insert(values, options);
12215
+ async insertGateway(payload, callOptions) {
12216
+ try {
12217
+ const compiled = compileD1Insert(payload);
12218
+ const stripNulls = resolveStripNulls(void 0, callOptions, true);
12219
+ return runCompiled(compiled, callOptions, "/gateway/insert", "PUT", void 0, stripNulls);
12220
+ } catch (error) {
12221
+ return compileErrorResponse(error, "/gateway/insert", "PUT");
12222
+ }
9821
12223
  },
9822
- upsert(table2, values, options) {
9823
- return Array.isArray(values) ? untypedDbFrom(table2).upsert(values, options) : untypedDbFrom(table2).upsert(values, options);
12224
+ async updateGateway(payload, callOptions) {
12225
+ try {
12226
+ const session = sessionFromOptions(callOptions, options);
12227
+ const compileOptions = await compileOptionsForBoundedMutation(d1, payload, session);
12228
+ const compiled = compileD1Update(payload, compileOptions);
12229
+ const stripNulls = resolveStripNulls(payload.strip_nulls, callOptions, true);
12230
+ return runCompiled(compiled, callOptions, "/gateway/update", "POST", void 0, stripNulls);
12231
+ } catch (error) {
12232
+ return compileErrorResponse(error, "/gateway/update", "POST");
12233
+ }
9824
12234
  },
9825
- update(table2, values, options) {
9826
- return untypedDbFrom(table2).update(values, options);
12235
+ async deleteGateway(payload, callOptions) {
12236
+ try {
12237
+ const session = sessionFromOptions(callOptions, options);
12238
+ const compileOptions = await compileOptionsForBoundedMutation(d1, payload, session);
12239
+ const compiled = compileD1Delete(payload, compileOptions);
12240
+ const stripNulls = resolveStripNulls(void 0, callOptions, true);
12241
+ return runCompiled(compiled, callOptions, "/gateway/delete", "DELETE", void 0, stripNulls);
12242
+ } catch (error) {
12243
+ return compileErrorResponse(error, "/gateway/delete", "DELETE");
12244
+ }
9827
12245
  },
9828
- delete(table2, options) {
9829
- return untypedDbFrom(table2).delete(options);
12246
+ async rpcGateway(payload, callOptions) {
12247
+ return errorResponse(
12248
+ 400,
12249
+ "HTTP_ERROR",
12250
+ "RPC is unsupported on D1 edge-local mode",
12251
+ "/gateway/rpc",
12252
+ "POST",
12253
+ "Use flat CRUD or raw query SQL instead"
12254
+ );
9830
12255
  },
9831
- rpc,
9832
- query
12256
+ async queryGateway(payload, callOptions) {
12257
+ try {
12258
+ const params = payload.params ?? callOptions?.params;
12259
+ const session = sessionFromOptions(callOptions, options);
12260
+ const query = rewritePostgresSqlForSqlite(payload.query);
12261
+ const result = await executeD1Query(d1, {
12262
+ query,
12263
+ params: Array.isArray(params) ? params : [],
12264
+ ...session
12265
+ });
12266
+ if (!result.ok) {
12267
+ return errorResponse(400, "HTTP_ERROR", result.message, "/gateway/query", "POST");
12268
+ }
12269
+ const stripNulls = resolveStripNulls(void 0, callOptions, true);
12270
+ const rows = maybeStripNullRows(result.rows, stripNulls);
12271
+ return successResponse(
12272
+ rows,
12273
+ result.count,
12274
+ { ...result, query },
12275
+ result.bookmark
12276
+ );
12277
+ } catch (error) {
12278
+ const message = error instanceof Error ? error.message : String(error);
12279
+ return errorResponse(500, "UNKNOWN_ERROR", message, "/gateway/query", "POST");
12280
+ }
12281
+ }
9833
12282
  };
9834
- const chat = createChatModule({
9835
- baseUrl: config.chatUrl,
9836
- apiKey: config.apiKey,
9837
- client: config.client ?? void 0,
9838
- headers: config.headers,
9839
- wsUrl: config.chatWsUrl,
9840
- webSocketFactory: config.chat?.webSocketFactory ?? void 0
9841
- }, {
9842
- async resolveCallOptions() {
9843
- const context = await resolveContext();
9844
- return context ? {
9845
- headers: buildContextHeaders(context),
9846
- bearerToken: context.bearerToken,
9847
- cookie: context.cookie,
9848
- sessionToken: context.sessionToken,
9849
- forceNoCache: context.forceNoCache
9850
- } : void 0;
12283
+ }
12284
+
12285
+ // src/config/errors.ts
12286
+ var AthenaConfigurationError = class extends Error {
12287
+ code;
12288
+ service;
12289
+ constructor(code, message, service) {
12290
+ super(message);
12291
+ this.name = "AthenaConfigurationError";
12292
+ this.code = code;
12293
+ this.service = service;
12294
+ }
12295
+ };
12296
+
12297
+ // src/cloudflare/execution-mode.ts
12298
+ var ATHENA_EXECUTION_MODE_ENV_KEY = "ATHENA_EXECUTION_MODE";
12299
+ var ATHENA_EXECUTION_PREFER_ENV_KEY = "ATHENA_EXECUTION_PREFER";
12300
+ var MODE_ALIASES = {
12301
+ gateway: "gateway",
12302
+ server: "gateway",
12303
+ remote: "gateway",
12304
+ http: "gateway",
12305
+ edge: "edge",
12306
+ cloudflare: "edge",
12307
+ "cloudflare-edge": "edge",
12308
+ d1: "edge",
12309
+ local: "edge",
12310
+ auto: "auto"
12311
+ };
12312
+ function normalizeOptional(value) {
12313
+ const trimmed = value?.trim();
12314
+ return trimmed || void 0;
12315
+ }
12316
+ function normalizeModeString(value) {
12317
+ if (value == null) return void 0;
12318
+ const key = value.trim().toLowerCase();
12319
+ if (!key) return void 0;
12320
+ const mapped = MODE_ALIASES[key];
12321
+ if (!mapped) {
12322
+ throw new AthenaConfigurationError(
12323
+ "ATHENA_NO_SERVICE_CONFIGURED",
12324
+ `Unknown Athena execution mode "${value}". Use gateway | edge | auto (aliases: server, remote, cloudflare, d1).`,
12325
+ "db"
12326
+ );
12327
+ }
12328
+ return mapped;
12329
+ }
12330
+ function isD1Binding(value) {
12331
+ return Boolean(
12332
+ value && typeof value === "object" && typeof value.prepare === "function"
12333
+ );
12334
+ }
12335
+ var GATEWAY_URL_ENV_KEYS = [
12336
+ "ATHENA_URL",
12337
+ "NEXT_PUBLIC_ATHENA_URL",
12338
+ "ATHENA_DB_URL",
12339
+ "ATHENA_GATEWAY_URL",
12340
+ "NEXT_PUBLIC_ATHENA_DB_API_URL"
12341
+ ];
12342
+ function resolveGatewayUrl(url, env) {
12343
+ if (normalizeOptional(url)) {
12344
+ return normalizeOptional(url);
12345
+ }
12346
+ for (const key of GATEWAY_URL_ENV_KEYS) {
12347
+ const value = normalizeOptional(env[key]);
12348
+ if (value) return value;
12349
+ }
12350
+ return void 0;
12351
+ }
12352
+ function resolvePrefer(prefer, env) {
12353
+ const raw = normalizeOptional(typeof prefer === "string" ? prefer : prefer ?? void 0) ?? normalizeOptional(env[ATHENA_EXECUTION_PREFER_ENV_KEY]) ?? "edge";
12354
+ const key = raw.toLowerCase();
12355
+ if (key === "gateway" || key === "server" || key === "remote" || key === "http") {
12356
+ return "gateway";
12357
+ }
12358
+ if (key === "edge" || key === "d1" || key === "cloudflare" || key === "local") {
12359
+ return "edge";
12360
+ }
12361
+ throw new AthenaConfigurationError(
12362
+ "ATHENA_NO_SERVICE_CONFIGURED",
12363
+ `Unknown Athena execution prefer "${raw}". Use edge | gateway.`,
12364
+ "db"
12365
+ );
12366
+ }
12367
+ function resolveAthenaExecutionMode(input = {}) {
12368
+ const env = input.env ?? {};
12369
+ const fromEnv = normalizeModeString(env[ATHENA_EXECUTION_MODE_ENV_KEY]);
12370
+ const requested = normalizeModeString(input.mode) ?? fromEnv ?? "auto";
12371
+ const url = resolveGatewayUrl(input.url, env);
12372
+ const hasD1 = isD1Binding(input.d1);
12373
+ const hasGateway = Boolean(url);
12374
+ if (requested === "gateway") {
12375
+ if (!hasGateway) {
12376
+ throw new AthenaConfigurationError(
12377
+ "ATHENA_NO_SERVICE_CONFIGURED",
12378
+ 'Athena execution mode is "gateway" but no url / ATHENA_URL / ATHENA_DB_URL / ATHENA_GATEWAY_URL was provided.',
12379
+ "db"
12380
+ );
9851
12381
  }
9852
- });
9853
- const request2 = createAthenaRequest(config, resolveContext);
9854
- const storage = createStorageModule(gateway, {
9855
- ...config.storage,
9856
- ...config.storageUrl ? {
9857
- baseUrl: config.storageUrl,
9858
- stripBasePath: true
9859
- } : {}
9860
- });
9861
- return {
9862
- from,
9863
- db,
9864
- rpc,
9865
- query,
9866
- request: request2,
9867
- verifyConnection: gateway.verifyConnection,
9868
- auth: auth.auth,
9869
- chat,
9870
- storage
12382
+ return "gateway";
12383
+ }
12384
+ if (requested === "edge") {
12385
+ if (!hasD1) {
12386
+ throw new AthenaConfigurationError(
12387
+ "ATHENA_NO_SERVICE_CONFIGURED",
12388
+ 'Athena execution mode is "edge" but no D1 binding was provided (db.d1 / config.d1 / env.DB).',
12389
+ "db"
12390
+ );
12391
+ }
12392
+ return "edge";
12393
+ }
12394
+ if (hasD1 && hasGateway) {
12395
+ return resolvePrefer(input.prefer, env);
12396
+ }
12397
+ if (hasD1) return "edge";
12398
+ if (hasGateway) return "gateway";
12399
+ throw new AthenaConfigurationError(
12400
+ "ATHENA_NO_SERVICE_CONFIGURED",
12401
+ '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).',
12402
+ "db"
12403
+ );
12404
+ }
12405
+
12406
+ // src/cloudflare/r2/storage.ts
12407
+ function normalizePrefix(prefix) {
12408
+ if (!prefix?.trim()) return "";
12409
+ const normalized = prefix.replace(/^\/+/, "").replace(/\/?$/, "/");
12410
+ if (normalized.includes("\0")) {
12411
+ throw new Error("storage prefix must not contain null bytes");
12412
+ }
12413
+ if (normalized.split("/").some((segment) => segment === "..")) {
12414
+ throw new Error('storage prefix must not contain ".." path segments');
12415
+ }
12416
+ return normalized;
12417
+ }
12418
+ function assertSafeObjectKey(key) {
12419
+ if (typeof key !== "string" || !key.trim()) {
12420
+ throw new Error("Object key is required");
12421
+ }
12422
+ if (key.includes("\0")) {
12423
+ throw new Error("Object key must not contain null bytes");
12424
+ }
12425
+ const cleaned = key.replace(/^\/+/, "");
12426
+ if (!cleaned) {
12427
+ throw new Error("Object key is required");
12428
+ }
12429
+ const segments = cleaned.split("/");
12430
+ if (segments.some((segment) => segment === "..")) {
12431
+ throw new Error('Object key must not contain ".." path segments');
12432
+ }
12433
+ return cleaned;
12434
+ }
12435
+ function joinKey(prefix, key) {
12436
+ return `${prefix}${assertSafeObjectKey(key)}`;
12437
+ }
12438
+ function toLogicalKey(prefix, physicalKey) {
12439
+ if (!prefix) return physicalKey;
12440
+ if (physicalKey.startsWith(prefix)) {
12441
+ return physicalKey.slice(prefix.length);
12442
+ }
12443
+ return physicalKey;
12444
+ }
12445
+ function toPhysicalKey(prefix, key) {
12446
+ return joinKey(prefix, key);
12447
+ }
12448
+ function unsupported(method) {
12449
+ throw new Error(
12450
+ `storage.${method} is not available in Cloudflare edge-local R2 object mode. Only putObject / getObject / deleteObject / listObjects are supported (L3a).`
12451
+ );
12452
+ }
12453
+ function createCloudflareR2StorageModule(options) {
12454
+ const prefix = normalizePrefix(options.prefix);
12455
+ const { r2 } = options;
12456
+ const putObject = async (input) => {
12457
+ const logical = assertSafeObjectKey(input.key);
12458
+ const physical = toPhysicalKey(prefix, logical);
12459
+ await r2.put(physical, input.body, {
12460
+ httpMetadata: input.contentType ? { contentType: input.contentType } : void 0,
12461
+ customMetadata: input.metadata
12462
+ });
12463
+ return { key: logical };
9871
12464
  };
12465
+ const getObject = async (input) => {
12466
+ const logical = assertSafeObjectKey(input.key);
12467
+ const physical = toPhysicalKey(prefix, logical);
12468
+ const object = await r2.get(physical);
12469
+ if (!object) return null;
12470
+ return {
12471
+ key: toLogicalKey(prefix, object.key),
12472
+ size: object.size,
12473
+ contentType: object.httpMetadata?.contentType,
12474
+ body: object
12475
+ };
12476
+ };
12477
+ const deleteObject = async (input) => {
12478
+ const logicalKeys = (Array.isArray(input.key) ? input.key : [input.key]).map(
12479
+ (key) => assertSafeObjectKey(key)
12480
+ );
12481
+ const physicalKeys = logicalKeys.map((key) => toPhysicalKey(prefix, key));
12482
+ await r2.delete(physicalKeys.length === 1 ? physicalKeys[0] : physicalKeys);
12483
+ return { deleted: logicalKeys };
12484
+ };
12485
+ const listObjects = async (input) => {
12486
+ const relative = input?.prefix?.trim() ? assertSafeObjectKey(input.prefix) : "";
12487
+ const listPrefix = `${prefix}${relative}`;
12488
+ const listed = await r2.list({
12489
+ prefix: listPrefix || void 0,
12490
+ limit: input?.limit,
12491
+ cursor: input?.cursor
12492
+ });
12493
+ return {
12494
+ objects: listed.objects.map((object) => ({
12495
+ key: toLogicalKey(prefix, object.key),
12496
+ size: object.size,
12497
+ etag: object.etag,
12498
+ uploaded: object.uploaded
12499
+ })),
12500
+ truncated: listed.truncated,
12501
+ cursor: listed.cursor
12502
+ };
12503
+ };
12504
+ const base = {
12505
+ putObject,
12506
+ getObject,
12507
+ deleteObject,
12508
+ listObjects
12509
+ };
12510
+ return new Proxy(base, {
12511
+ get(target, property, receiver) {
12512
+ if (property in target) {
12513
+ return Reflect.get(target, property, receiver);
12514
+ }
12515
+ if (typeof property === "string") {
12516
+ return (...args) => {
12517
+ return unsupported(property);
12518
+ };
12519
+ }
12520
+ return void 0;
12521
+ }
12522
+ });
9872
12523
  }
9873
12524
 
9874
12525
  // src/billing/module.ts
@@ -10561,18 +13212,6 @@ function createBillingModule(config) {
10561
13212
  };
10562
13213
  }
10563
13214
 
10564
- // src/config/errors.ts
10565
- var AthenaConfigurationError = class extends Error {
10566
- code;
10567
- service;
10568
- constructor(code, message, service) {
10569
- super(message);
10570
- this.name = "AthenaConfigurationError";
10571
- this.code = code;
10572
- this.service = service;
10573
- }
10574
- };
10575
-
10576
13215
  // src/context/merge.ts
10577
13216
  function mergeAthenaRequestContexts(base, override) {
10578
13217
  if (!base && !override) return void 0;
@@ -10685,14 +13324,30 @@ function readFirstEnv(env, keys) {
10685
13324
  }
10686
13325
  return void 0;
10687
13326
  }
10688
- function normalizeOptional(value) {
13327
+ function readFirstEnvHttpUrl(env, keys) {
13328
+ for (const key of keys) {
13329
+ const value = env?.[key]?.trim();
13330
+ if (value && isAbsoluteHttpUrl(value)) return value;
13331
+ }
13332
+ return void 0;
13333
+ }
13334
+ function normalizeOptional2(value) {
10689
13335
  const normalized = value?.trim();
10690
13336
  return normalized || void 0;
10691
13337
  }
13338
+ function isAbsoluteHttpUrl(value) {
13339
+ try {
13340
+ const url = new URL(value);
13341
+ return url.protocol === "http:" || url.protocol === "https:";
13342
+ } catch {
13343
+ return false;
13344
+ }
13345
+ }
10692
13346
  function appendPath(baseUrl, path) {
10693
13347
  return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
10694
13348
  }
10695
13349
  function toWebSocketUrl(baseUrl) {
13350
+ if (!isAbsoluteHttpUrl(baseUrl)) return void 0;
10696
13351
  const url = new URL(baseUrl);
10697
13352
  url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
10698
13353
  url.pathname = `${url.pathname.replace(/\/+$/, "")}/wss/gateway`;
@@ -10702,11 +13357,11 @@ function toWebSocketUrl(baseUrl) {
10702
13357
  }
10703
13358
  function resolveCore(config) {
10704
13359
  const env = config.env;
10705
- const explicitRoot = normalizeOptional(config.url);
10706
- const envRoot = readFirstEnv(env, ENV_URL_KEYS);
10707
- const root = explicitRoot ?? envRoot;
10708
- const explicitRootWinsOverEnvServices = explicitRoot !== void 0;
10709
- const resolveService = (explicit, envKeys, path) => normalizeOptional(explicit) ?? (explicitRootWinsOverEnvServices && root ? appendPath(root, path) : void 0) ?? readFirstEnv(env, envKeys) ?? (root ? appendPath(root, path) : void 0);
13360
+ const explicitRoot = normalizeOptional2(config.url);
13361
+ const envRoot = readFirstEnvHttpUrl(env, ENV_URL_KEYS);
13362
+ const root = explicitRoot && isAbsoluteHttpUrl(explicitRoot) ? explicitRoot : explicitRoot ? void 0 : envRoot;
13363
+ const explicitRootWinsOverEnvServices = Boolean(root && explicitRoot && isAbsoluteHttpUrl(explicitRoot));
13364
+ const resolveService = (explicit, envKeys, path) => normalizeOptional2(explicit) ?? (explicitRootWinsOverEnvServices && root ? appendPath(root, path) : void 0) ?? readFirstEnvHttpUrl(env, envKeys) ?? (root ? appendPath(root, path) : void 0);
10710
13365
  const dbUrl = resolveService(config.db?.url, ENV_DB_URL_KEYS, "db");
10711
13366
  const urls = {
10712
13367
  db: dbUrl,
@@ -10714,8 +13369,8 @@ function resolveCore(config) {
10714
13369
  chat: resolveService(config.chat?.url, ENV_CHAT_URL_KEYS, "chat"),
10715
13370
  storage: resolveService(config.storage?.url, ENV_STORAGE_URL_KEYS, "storage"),
10716
13371
  // Billing lives on the main Athena HTTP surface (same host as gateway/db).
10717
- billing: normalizeOptional(config.billing?.url) ?? dbUrl ?? root ?? void 0,
10718
- chatWs: normalizeOptional(config.chat?.wsUrl) ?? (explicitRootWinsOverEnvServices && root ? toWebSocketUrl(root) : void 0) ?? readFirstEnv(env, ENV_CHAT_WS_URL_KEYS) ?? (root ? toWebSocketUrl(root) : void 0)
13372
+ billing: normalizeOptional2(config.billing?.url) ?? dbUrl ?? root ?? void 0,
13373
+ chatWs: normalizeOptional2(config.chat?.wsUrl) ?? (explicitRootWinsOverEnvServices && root ? toWebSocketUrl(root) : void 0) ?? readFirstEnvHttpUrl(env, ENV_CHAT_WS_URL_KEYS) ?? (root ? toWebSocketUrl(root) : void 0)
10719
13374
  };
10720
13375
  if (!urls.db && !urls.auth && !urls.chat && !urls.storage && !urls.billing) {
10721
13376
  throw new AthenaConfigurationError(
@@ -10724,7 +13379,7 @@ function resolveCore(config) {
10724
13379
  "db"
10725
13380
  );
10726
13381
  }
10727
- const key = normalizeOptional(config.key) ?? readFirstEnv(env, ENV_KEY_KEYS);
13382
+ const key = normalizeOptional2(config.key) ?? readFirstEnv(env, ENV_KEY_KEYS);
10728
13383
  if (!key) {
10729
13384
  throw new AthenaConfigurationError(
10730
13385
  "ATHENA_API_KEY_REQUIRED",
@@ -10735,7 +13390,7 @@ function resolveCore(config) {
10735
13390
  config,
10736
13391
  urls,
10737
13392
  key,
10738
- client: normalizeOptional(config.client) ?? readFirstEnv(env, ENV_CLIENT_KEYS)
13393
+ client: normalizeOptional2(config.client) ?? readFirstEnv(env, ENV_CLIENT_KEYS)
10739
13394
  };
10740
13395
  return {
10741
13396
  ...base,
@@ -10750,7 +13405,13 @@ async function resolveConfiguredContext(core, viewContext) {
10750
13405
  function createInternalConfig(core) {
10751
13406
  const { config, urls } = core;
10752
13407
  const { url: _authUrl, ...authOptions } = config.auth ?? {};
10753
- const { url: _storageUrl, directUpload, ...storageOptions } = config.storage ?? {};
13408
+ const {
13409
+ url: _storageUrl,
13410
+ directUpload,
13411
+ r2: _r2,
13412
+ prefix: _r2Prefix,
13413
+ ...storageOptions
13414
+ } = config.storage ?? {};
10754
13415
  const diagnostics = resolveAthenaClientDiagnostics({
10755
13416
  diagnostics: config.diagnostics,
10756
13417
  debugAst: config.debugAst,
@@ -10781,7 +13442,8 @@ function createInternalConfig(core) {
10781
13442
  storage: {
10782
13443
  ...storageOptions,
10783
13444
  ...directUpload ? { directUpload } : {}
10784
- }
13445
+ },
13446
+ gatewayTransport: config.gatewayTransport
10785
13447
  };
10786
13448
  }
10787
13449
  function serviceGuard(urls, service) {
@@ -10804,6 +13466,232 @@ function createUnavailableNamespace(service, urls, path = []) {
10804
13466
  }
10805
13467
  });
10806
13468
  }
13469
+ function isD1Binding2(value) {
13470
+ return Boolean(
13471
+ value && typeof value === "object" && typeof value.prepare === "function"
13472
+ );
13473
+ }
13474
+ function isR2Binding(value) {
13475
+ return Boolean(
13476
+ value && typeof value === "object" && typeof value.put === "function" && typeof value.get === "function"
13477
+ );
13478
+ }
13479
+ function foldBindingAliases(config) {
13480
+ const d1 = config.db?.d1 ?? config.d1;
13481
+ const r2 = config.storage?.r2 ?? config.r2;
13482
+ const sessionMode = config.db?.sessionMode ?? config.sessionMode;
13483
+ const prefix = config.storage?.prefix ?? config.storagePrefix;
13484
+ let next = { ...config };
13485
+ if (d1 !== void 0 || sessionMode !== void 0) {
13486
+ next = {
13487
+ ...next,
13488
+ db: {
13489
+ ...next.db,
13490
+ ...d1 !== void 0 ? { d1 } : {},
13491
+ ...sessionMode !== void 0 ? { sessionMode } : {}
13492
+ }
13493
+ };
13494
+ }
13495
+ if (r2 !== void 0 || prefix !== void 0) {
13496
+ next = {
13497
+ ...next,
13498
+ storage: {
13499
+ ...next.storage,
13500
+ ...r2 !== void 0 ? { r2 } : {},
13501
+ ...prefix !== void 0 ? { prefix } : {}
13502
+ }
13503
+ };
13504
+ }
13505
+ const {
13506
+ d1: _d1,
13507
+ r2: _r2,
13508
+ storagePrefix: _storagePrefix,
13509
+ sessionMode: _sessionMode,
13510
+ ...rest
13511
+ } = next;
13512
+ return rest;
13513
+ }
13514
+ function applyExecutionMode(config) {
13515
+ const d1 = config.db?.d1;
13516
+ const hasD1 = isD1Binding2(d1);
13517
+ const hasUrl = Boolean(
13518
+ normalizeOptional2(config.url) ?? normalizeOptional2(config.db?.url) ?? (config.env ? normalizeOptional2(config.env.ATHENA_URL) ?? normalizeOptional2(config.env.NEXT_PUBLIC_ATHENA_URL) : void 0)
13519
+ );
13520
+ const hasModeHint = config.mode != null || config.prefer != null || Boolean(config.env?.ATHENA_EXECUTION_MODE) || Boolean(config.env?.ATHENA_EXECUTION_PREFER);
13521
+ if (!hasD1 && !hasModeHint) {
13522
+ return config;
13523
+ }
13524
+ if (hasD1 && !hasUrl && !hasModeHint) {
13525
+ return config;
13526
+ }
13527
+ let resolved;
13528
+ try {
13529
+ resolved = resolveAthenaExecutionMode({
13530
+ mode: config.mode,
13531
+ prefer: config.prefer,
13532
+ d1: hasD1 ? d1 : null,
13533
+ url: config.url ?? config.db?.url,
13534
+ env: config.env
13535
+ });
13536
+ } catch (error) {
13537
+ if (!hasModeHint) return config;
13538
+ throw error;
13539
+ }
13540
+ if (resolved === "gateway" && hasD1) {
13541
+ const { d1: _drop, sessionMode: _sm, ...dbRest } = config.db ?? {};
13542
+ return {
13543
+ ...config,
13544
+ db: Object.keys(dbRest).length > 0 ? dbRest : void 0,
13545
+ gatewayTransport: void 0
13546
+ };
13547
+ }
13548
+ return config;
13549
+ }
13550
+ function resolveUnifiedRemoteRoot(config) {
13551
+ return normalizeOptional2(config.url) ?? readFirstEnv(config.env, ENV_URL_KEYS);
13552
+ }
13553
+ function isEdgeLocalSentinelUrl(url) {
13554
+ if (!url) return false;
13555
+ return url === CLOUDFLARE_EDGE_BASE_URL || url.startsWith("https://athena.local/") || url.startsWith("http://athena.local/");
13556
+ }
13557
+ function hasRemoteDbGatewayUrl(config) {
13558
+ const dbUrl = normalizeOptional2(config.db?.url) ?? readFirstEnv(config.env, ENV_DB_URL_KEYS);
13559
+ return Boolean(dbUrl && !isEdgeLocalSentinelUrl(dbUrl));
13560
+ }
13561
+ function hasRemoteHttpServices(config) {
13562
+ return Boolean(
13563
+ 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)
13564
+ );
13565
+ }
13566
+ function hasRemoteHttpStorage(config) {
13567
+ return Boolean(
13568
+ normalizeOptional2(config.storage?.url) || readFirstEnv(config.env, ENV_STORAGE_URL_KEYS) || resolveUnifiedRemoteRoot(config)
13569
+ );
13570
+ }
13571
+ function hasRemoteAuthService(config) {
13572
+ return Boolean(
13573
+ normalizeOptional2(config.auth?.url) || readFirstEnv(config.env, ENV_AUTH_URL_KEYS) || resolveUnifiedRemoteRoot(config)
13574
+ );
13575
+ }
13576
+ function materializeEdgeBindings(config) {
13577
+ const d1 = config.db?.d1;
13578
+ const r2 = config.storage?.r2;
13579
+ const hasD1 = isD1Binding2(d1);
13580
+ const hasR2 = isR2Binding(r2);
13581
+ if (!hasD1 && !hasR2) {
13582
+ return config;
13583
+ }
13584
+ if (hasD1 && d1 && typeof d1.prepare !== "function") {
13585
+ throw new AthenaConfigurationError(
13586
+ "ATHENA_NO_SERVICE_CONFIGURED",
13587
+ "db.d1 must be a D1 binding with prepare().",
13588
+ "db"
13589
+ );
13590
+ }
13591
+ const remoteRoot = resolveUnifiedRemoteRoot(config);
13592
+ const remoteServices = hasRemoteHttpServices(config);
13593
+ const remoteStorage = hasRemoteHttpStorage(config);
13594
+ const remoteAuth = hasRemoteAuthService(config);
13595
+ const next = { ...config };
13596
+ if (hasD1 && d1) {
13597
+ if (!config.gatewayTransport) {
13598
+ next.gatewayTransport = createCloudflareD1GatewayTransport({
13599
+ d1,
13600
+ defaultSessionMode: config.db?.sessionMode
13601
+ });
13602
+ }
13603
+ const explicitDbUrl = normalizeOptional2(config.db?.url);
13604
+ const remoteDbGateway = hasRemoteDbGatewayUrl(config);
13605
+ next.db = {
13606
+ ...config.db,
13607
+ d1,
13608
+ url: explicitDbUrl ?? (remoteDbGateway ? void 0 : CLOUDFLARE_EDGE_BASE_URL)
13609
+ };
13610
+ const explicitKey = normalizeOptional2(config.key);
13611
+ if (explicitKey) {
13612
+ next.key = explicitKey;
13613
+ } else if (!remoteServices) {
13614
+ next.key = CLOUDFLARE_EDGE_API_KEY;
13615
+ } else {
13616
+ next.key = void 0;
13617
+ }
13618
+ if (remoteRoot) {
13619
+ next.billing = {
13620
+ ...config.billing ?? {},
13621
+ url: normalizeOptional2(config.billing?.url) ?? remoteRoot
13622
+ };
13623
+ }
13624
+ if (!config.capabilities) {
13625
+ next.capabilities = createCloudflareEdgeCapabilities({
13626
+ hasR2,
13627
+ // Explicit storage.url / env storage URL / unified remote root all count.
13628
+ hasRemoteStorage: remoteStorage,
13629
+ authRemote: remoteAuth,
13630
+ findManyAst: false
13631
+ });
13632
+ }
13633
+ } else if (hasR2 && r2) {
13634
+ if (!remoteRoot && !normalizeOptional2(config.db?.url) && !normalizeOptional2(config.storage?.url) && !readFirstEnv(config.env, ENV_STORAGE_URL_KEYS)) {
13635
+ next.storage = {
13636
+ ...config.storage,
13637
+ r2,
13638
+ // Local sentinel so resolveCore accepts a storage-only binding client.
13639
+ url: CLOUDFLARE_EDGE_BASE_URL
13640
+ };
13641
+ if (!remoteServices) {
13642
+ next.key = normalizeOptional2(config.key) ?? CLOUDFLARE_EDGE_API_KEY;
13643
+ } else if (normalizeOptional2(config.key)) {
13644
+ next.key = normalizeOptional2(config.key);
13645
+ } else {
13646
+ next.key = void 0;
13647
+ }
13648
+ }
13649
+ if (!config.capabilities) {
13650
+ if (remoteRoot || normalizeOptional2(config.db?.url) || readFirstEnv(config.env, ENV_DB_URL_KEYS)) {
13651
+ const base = createGatewayCapabilities({
13652
+ authRemote: remoteAuth,
13653
+ storageConfigured: true
13654
+ });
13655
+ next.capabilities = {
13656
+ ...base,
13657
+ storage: {
13658
+ ...base.storage,
13659
+ local: true,
13660
+ objects: true
13661
+ }
13662
+ };
13663
+ } else {
13664
+ next.capabilities = {
13665
+ mode: "cloudflare-edge",
13666
+ db: {
13667
+ engine: "unknown",
13668
+ local: false,
13669
+ layers: {
13670
+ query: false,
13671
+ flatCrud: false,
13672
+ findManyAst: false,
13673
+ rpc: false,
13674
+ relations: false
13675
+ }
13676
+ },
13677
+ storage: {
13678
+ local: true,
13679
+ objects: true,
13680
+ catalogs: false,
13681
+ backups: false
13682
+ },
13683
+ auth: {
13684
+ remote: remoteAuth
13685
+ }
13686
+ };
13687
+ }
13688
+ }
13689
+ }
13690
+ return next;
13691
+ }
13692
+ function normalizeCreateClientConfig(config) {
13693
+ return materializeEdgeBindings(applyExecutionMode(foldBindingAliases(config)));
13694
+ }
10807
13695
  function createClientView(core, viewContext) {
10808
13696
  const resolved = createInternalClientView(
10809
13697
  core.internalCore,
@@ -10821,12 +13709,23 @@ function createClientView(core, viewContext) {
10821
13709
  },
10822
13710
  ...billingOptions
10823
13711
  }) : createUnavailableNamespace("billing", core.urls);
13712
+ const capabilities = core.config.capabilities ?? createGatewayCapabilities({
13713
+ authRemote: Boolean(core.urls.auth),
13714
+ // Match unavailable storage proxy when no storage URL was resolved.
13715
+ storageConfigured: Boolean(core.urls.storage)
13716
+ });
13717
+ const r2 = core.config.storage?.r2;
13718
+ const storageModule = isR2Binding(r2) ? createCloudflareR2StorageModule({
13719
+ r2,
13720
+ prefix: core.config.storage?.prefix ?? void 0
13721
+ }) : core.urls.storage ? resolved.storage : createUnavailableNamespace("storage", core.urls);
10824
13722
  const client = {
10825
13723
  db: core.urls.db ? resolved.db : createUnavailableNamespace("db", core.urls),
10826
13724
  auth: core.urls.auth ? resolved.auth : createUnavailableNamespace("auth", core.urls),
10827
13725
  chat: core.urls.chat ? resolved.chat : createUnavailableNamespace("chat", core.urls),
10828
- storage: core.urls.storage ? resolved.storage : createUnavailableNamespace("storage", core.urls),
13726
+ storage: storageModule,
10829
13727
  billing: billingModule,
13728
+ capabilities,
10830
13729
  from: ((...args) => {
10831
13730
  requireDb();
10832
13731
  return Reflect.apply(resolved.from, resolved, args);
@@ -10867,7 +13766,8 @@ function normalizeOptionalContextString(value) {
10867
13766
  }
10868
13767
  function warnIfEmptyRequestContext(context) {
10869
13768
  if (!isEmptyAthenaRequestContext(context)) return;
10870
- if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
13769
+ const nodeEnv = globalThis.process?.env?.NODE_ENV;
13770
+ if (nodeEnv === "production") {
10871
13771
  return;
10872
13772
  }
10873
13773
  console.warn(
@@ -10875,7 +13775,8 @@ function warnIfEmptyRequestContext(context) {
10875
13775
  );
10876
13776
  }
10877
13777
  function createClient(config) {
10878
- return createClientView(resolveCore(config));
13778
+ const normalized = normalizeCreateClientConfig(config);
13779
+ return createClientView(resolveCore(normalized));
10879
13780
  }
10880
13781
 
10881
13782
  // src/gateway/types.ts
@@ -12206,7 +15107,7 @@ var DIRECT_CONNECTION_STRING_ENV_KEYS = [
12206
15107
  ];
12207
15108
  var POSTGRES_DATABASE_ENV_KEYS = ["ATHENA_GENERATOR_DB", "ATHENA_DATABASE", "PGDATABASE"];
12208
15109
  var POSTGRES_PASSWORD_ENV_KEYS = ["ATHENA_GENERATOR_PG_PASSWORD", "PGPASSWORD"];
12209
- var GATEWAY_URL_ENV_KEYS = ["ATHENA_URL", "ATHENA_GATEWAY_URL", "ATHENA_GENERATOR_URL"];
15110
+ var GATEWAY_URL_ENV_KEYS2 = ["ATHENA_URL", "ATHENA_GATEWAY_URL", "ATHENA_GENERATOR_URL"];
12210
15111
  var GATEWAY_API_KEY_ENV_KEYS = [
12211
15112
  "ATHENA_API_KEY",
12212
15113
  "ATHENA_GATEWAY_API_KEY",
@@ -12511,7 +15412,7 @@ function normalizeProviderConfig(provider) {
12511
15412
  const gatewayUrl = normalizeRequiredString(
12512
15413
  provider.gatewayUrl,
12513
15414
  "provider.gatewayUrl",
12514
- GATEWAY_URL_ENV_KEYS
15415
+ GATEWAY_URL_ENV_KEYS2
12515
15416
  );
12516
15417
  const apiKey = normalizeRequiredString(
12517
15418
  provider.apiKey,
@@ -12715,7 +15616,7 @@ function buildEnvironmentProviderConfig() {
12715
15616
  schemas: normalizeSchemaSelection(resolveFallbackValue(GENERATOR_SCHEMA_ENV_KEYS))
12716
15617
  };
12717
15618
  }
12718
- const gatewayUrl = resolveFallbackValue(GATEWAY_URL_ENV_KEYS);
15619
+ const gatewayUrl = resolveFallbackValue(GATEWAY_URL_ENV_KEYS2);
12719
15620
  const apiKey = resolveFallbackValue(GATEWAY_API_KEY_ENV_KEYS);
12720
15621
  if (gatewayUrl && apiKey) {
12721
15622
  const backend = resolveOptionalOneOf(GATEWAY_BACKEND_ENV_KEYS, BACKEND_TYPE_VALUES);
@@ -14168,6 +17069,7 @@ var AthenaGatewayPostgresIntrospectionProvider = class {
14168
17069
  constructor(config) {
14169
17070
  this.config = config;
14170
17071
  this.client = createClient({
17072
+ url: this.config.gatewayUrl,
14171
17073
  db: { url: this.config.gatewayUrl },
14172
17074
  key: this.config.apiKey,
14173
17075
  // Multi-tenant gateways reject DEFAULT_CLIENT; prefer explicit config.
@@ -16181,6 +19083,7 @@ exports.renderAthenaReactEmail = renderAthenaReactEmail;
16181
19083
  exports.renderGeneratorConfigFile = renderGeneratorConfigFile;
16182
19084
  exports.requireAffected = requireAffected;
16183
19085
  exports.requireSuccess = requireSuccess;
19086
+ exports.resolveAthenaExecutionMode = resolveAthenaExecutionMode;
16184
19087
  exports.resolveAthenaReadQueryPageFetch = resolveAthenaReadQueryPageFetch;
16185
19088
  exports.resolveGeneratorProvider = resolveGeneratorProvider;
16186
19089
  exports.resolvePostgresColumnType = resolvePostgresColumnType;