@xylex-group/athena 2.4.0 → 2.4.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.
package/dist/cli/index.js CHANGED
@@ -661,6 +661,54 @@ function normalizeAthenaError(resultOrError, context) {
661
661
  raw: resultOrError
662
662
  };
663
663
  }
664
+ function defaultShouldRetry(error) {
665
+ const normalized = normalizeAthenaError(error);
666
+ return normalized.kind === "transient" || normalized.kind === "rate_limit";
667
+ }
668
+ function computeDelayMs(attempt, error, config) {
669
+ const baseDelay = config.baseDelayMs;
670
+ const rawDelay = typeof config.backoff === "function" ? config.backoff(attempt, error) : config.backoff === "linear" ? baseDelay * attempt : baseDelay * Math.pow(2, attempt - 1);
671
+ const safeDelay = Number.isFinite(rawDelay) ? Math.max(0, rawDelay) : 0;
672
+ const clamped = Math.min(config.maxDelayMs, safeDelay);
673
+ const jitterFactor = typeof config.jitter === "number" ? Math.max(0, Math.min(1, config.jitter)) : config.jitter ? 0.2 : 0;
674
+ if (!jitterFactor) return clamped;
675
+ const deviation = clamped * jitterFactor;
676
+ const offset = (Math.random() * 2 - 1) * deviation;
677
+ return Math.max(0, clamped + offset);
678
+ }
679
+ function sleep(ms) {
680
+ if (ms <= 0) return Promise.resolve();
681
+ return new Promise((resolve3) => {
682
+ setTimeout(resolve3, ms);
683
+ });
684
+ }
685
+ async function withRetry(config, fn) {
686
+ const retries = Math.max(0, Math.trunc(config.retries));
687
+ const shouldRetry = config.shouldRetry ?? defaultShouldRetry;
688
+ const resolvedConfig = {
689
+ baseDelayMs: config.baseDelayMs ?? 100,
690
+ maxDelayMs: config.maxDelayMs ?? 1e4,
691
+ backoff: config.backoff ?? "exponential",
692
+ jitter: config.jitter ?? false
693
+ };
694
+ for (let attempts = 0; attempts <= retries; attempts += 1) {
695
+ try {
696
+ return await fn();
697
+ } catch (error) {
698
+ if (attempts >= retries) {
699
+ throw error;
700
+ }
701
+ const currentAttempt = attempts + 1;
702
+ const retry = await shouldRetry(error, currentAttempt);
703
+ if (!retry) {
704
+ throw error;
705
+ }
706
+ const delay = computeDelayMs(currentAttempt, error, resolvedConfig);
707
+ await sleep(delay);
708
+ }
709
+ }
710
+ throw new Error("withRetry reached an unexpected state");
711
+ }
664
712
 
665
713
  // src/generator/schema-selection.ts
666
714
  var DEFAULT_POSTGRES_SCHEMAS = ["public"];
@@ -1428,12 +1476,47 @@ function buildAthenaGatewayUrl(baseUrl, path) {
1428
1476
  return `${baseUrl}${path}`;
1429
1477
  }
1430
1478
 
1479
+ // src/cookies/cookie-utils.ts
1480
+ var SECURE_COOKIE_PREFIX = "__Secure-";
1481
+ function parseCookies(cookieHeader) {
1482
+ const cookies = cookieHeader.split("; ");
1483
+ const cookieMap = /* @__PURE__ */ new Map();
1484
+ cookies.forEach((cookie) => {
1485
+ const [name, value] = cookie.split(/=(.*)/s);
1486
+ cookieMap.set(name, value);
1487
+ });
1488
+ return cookieMap;
1489
+ }
1490
+ var getSessionCookie = (request, config) => {
1491
+ const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
1492
+ if (!cookies) {
1493
+ return null;
1494
+ }
1495
+ const { cookieName = "session_token", cookiePrefix = "athena-auth" } = {};
1496
+ const parsedCookie = parseCookies(cookies);
1497
+ const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
1498
+ const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
1499
+ if (sessionToken) {
1500
+ return sessionToken;
1501
+ }
1502
+ return null;
1503
+ };
1504
+
1505
+ // package.json
1506
+ var package_default = {
1507
+ version: "2.4.1"
1508
+ };
1509
+
1510
+ // src/sdk-version.ts
1511
+ var PACKAGE_VERSION = package_default.version;
1512
+ function buildSdkHeaderValue(sdkName) {
1513
+ return `${sdkName} ${PACKAGE_VERSION}`;
1514
+ }
1515
+
1431
1516
  // src/gateway/client.ts
1432
1517
  var DEFAULT_CLIENT = "railway_direct";
1433
- var FALLBACK_SDK_VERSION = "1.3.0";
1434
1518
  var SDK_NAME = "xylex-group/athena";
1435
- var SDK_VERSION = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION;
1436
- var SDK_HEADER_VALUE = `${SDK_NAME} ${SDK_VERSION}`;
1519
+ var SDK_HEADER_VALUE = buildSdkHeaderValue(SDK_NAME);
1437
1520
  function parseResponseBody(rawText, contentType) {
1438
1521
  if (!rawText) {
1439
1522
  return { parsed: null, parseFailed: false };
@@ -1452,6 +1535,37 @@ function parseResponseBody(rawText, contentType) {
1452
1535
  function normalizeHeaderValue(value) {
1453
1536
  return value ? value : void 0;
1454
1537
  }
1538
+ function resolveHeaderValue(headers, candidates) {
1539
+ for (const candidate of candidates) {
1540
+ const direct = normalizeHeaderValue(headers[candidate]);
1541
+ if (direct) return direct;
1542
+ }
1543
+ const loweredCandidates = new Set(candidates.map((candidate) => candidate.toLowerCase()));
1544
+ for (const [key, value] of Object.entries(headers)) {
1545
+ if (!loweredCandidates.has(key.toLowerCase())) {
1546
+ continue;
1547
+ }
1548
+ const normalized = normalizeHeaderValue(value);
1549
+ if (normalized) return normalized;
1550
+ }
1551
+ return void 0;
1552
+ }
1553
+ function resolveBearerTokenFromAuthorizationHeader(headers) {
1554
+ const authorization = resolveHeaderValue(headers, ["Authorization"]);
1555
+ if (!authorization) {
1556
+ return void 0;
1557
+ }
1558
+ const match = authorization.match(/^Bearer\s+(.+)$/i);
1559
+ const token = match?.[1]?.trim();
1560
+ return token ? token : void 0;
1561
+ }
1562
+ function resolveSessionTokenFromCookieHeader(headers) {
1563
+ const cookie = resolveHeaderValue(headers, ["Cookie"]);
1564
+ if (!cookie) {
1565
+ return void 0;
1566
+ }
1567
+ return getSessionCookie(new Headers({ cookie })) ?? void 0;
1568
+ }
1455
1569
  function isRecord2(value) {
1456
1570
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1457
1571
  }
@@ -1569,7 +1683,7 @@ function buildRpcGetEndpoint(payload) {
1569
1683
  status: 0
1570
1684
  });
1571
1685
  }
1572
- query.set(filter.column, toRpcFilterQueryValue(filter));
1686
+ query.append(filter.column, toRpcFilterQueryValue(filter));
1573
1687
  }
1574
1688
  }
1575
1689
  const endpoint = `/rpc/${encodeURIComponent(functionName)}`;
@@ -1615,6 +1729,20 @@ function buildHeaders(config, options) {
1615
1729
  headers["apikey"] = finalApiKey;
1616
1730
  headers["x-api-key"] = headers["x-api-key"] ?? finalApiKey;
1617
1731
  }
1732
+ const explicitSessionToken = resolveHeaderValue(extraHeaders, [
1733
+ "X-Athena-Auth-Session-Token"
1734
+ ]);
1735
+ const derivedSessionToken = explicitSessionToken ?? resolveSessionTokenFromCookieHeader(extraHeaders);
1736
+ if (derivedSessionToken) {
1737
+ headers["X-Athena-Auth-Session-Token"] = derivedSessionToken;
1738
+ }
1739
+ const explicitBearerToken = resolveHeaderValue(extraHeaders, [
1740
+ "X-Athena-Auth-Bearer-Token"
1741
+ ]);
1742
+ const derivedBearerToken = explicitBearerToken ?? resolveBearerTokenFromAuthorizationHeader(extraHeaders);
1743
+ if (derivedBearerToken) {
1744
+ headers["X-Athena-Auth-Bearer-Token"] = derivedBearerToken;
1745
+ }
1618
1746
  const athenaClientKeys = ["x-athena-client", "X-Athena-Client"];
1619
1747
  Object.entries(extraHeaders).forEach(([key, value]) => {
1620
1748
  if (athenaClientKeys.includes(key)) return;
@@ -2249,10 +2377,8 @@ async function resolveReactEmailPayloadFields(input, fields, options) {
2249
2377
 
2250
2378
  // src/auth/client.ts
2251
2379
  var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
2252
- var FALLBACK_SDK_VERSION2 = "1.0.0";
2253
2380
  var SDK_NAME2 = "xylex-group/athena-auth";
2254
- var SDK_VERSION2 = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION2;
2255
- var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
2381
+ var SDK_HEADER_VALUE2 = buildSdkHeaderValue(SDK_NAME2);
2256
2382
  function normalizeBaseUrl(baseUrl) {
2257
2383
  return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
2258
2384
  }
@@ -3698,7 +3824,7 @@ function buildStructuredWhere(conditions) {
3698
3824
  if (!condition.column) {
3699
3825
  return null;
3700
3826
  }
3701
- if (condition.column_cast !== void 0 || condition.value_cast !== void 0) {
3827
+ if (condition.value_cast !== void 0) {
3702
3828
  return null;
3703
3829
  }
3704
3830
  const operand = condition.value;
@@ -3777,6 +3903,104 @@ function toFindManyAstOrder(order) {
3777
3903
  ascending: order.direction !== "descending"
3778
3904
  };
3779
3905
  }
3906
+ function isRecord6(value) {
3907
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3908
+ }
3909
+ function normalizeFindManyAstColumnPredicate(value) {
3910
+ if (!isRecord6(value)) {
3911
+ return {
3912
+ eq: value
3913
+ };
3914
+ }
3915
+ const normalized = {};
3916
+ for (const [key, operand] of Object.entries(value)) {
3917
+ if (operand !== void 0) {
3918
+ normalized[key] = operand;
3919
+ }
3920
+ }
3921
+ return normalized;
3922
+ }
3923
+ function normalizeFindManyAstBooleanOperand(clause) {
3924
+ const normalized = {};
3925
+ for (const [column, value] of Object.entries(clause)) {
3926
+ if (value === void 0) {
3927
+ continue;
3928
+ }
3929
+ normalized[column] = normalizeFindManyAstColumnPredicate(value);
3930
+ }
3931
+ return normalized;
3932
+ }
3933
+ function normalizeFindManyAstWhere(where) {
3934
+ if (!where || !isRecord6(where)) {
3935
+ return where;
3936
+ }
3937
+ const normalized = {};
3938
+ for (const [key, value] of Object.entries(where)) {
3939
+ if (value === void 0) {
3940
+ continue;
3941
+ }
3942
+ if (key === "or" && Array.isArray(value)) {
3943
+ normalized.or = value.map(
3944
+ (clause) => normalizeFindManyAstBooleanOperand(clause)
3945
+ );
3946
+ continue;
3947
+ }
3948
+ if (key === "not" && isRecord6(value)) {
3949
+ normalized.not = normalizeFindManyAstBooleanOperand(
3950
+ value
3951
+ );
3952
+ continue;
3953
+ }
3954
+ normalized[key] = normalizeFindManyAstColumnPredicate(value);
3955
+ }
3956
+ return normalized;
3957
+ }
3958
+ function predicateRequiresUuidQueryFallback(column, value) {
3959
+ if (!isRecord6(value)) {
3960
+ return shouldUseUuidTextComparison(column, value);
3961
+ }
3962
+ const eqValue = value.eq;
3963
+ return eqValue !== void 0 && shouldUseUuidTextComparison(column, eqValue);
3964
+ }
3965
+ function booleanOperandRequiresUuidQueryFallback(clause) {
3966
+ for (const [column, value] of Object.entries(clause)) {
3967
+ if (value === void 0) {
3968
+ continue;
3969
+ }
3970
+ if (predicateRequiresUuidQueryFallback(column, value)) {
3971
+ return true;
3972
+ }
3973
+ }
3974
+ return false;
3975
+ }
3976
+ function findManyAstWhereRequiresLegacyTransport(where) {
3977
+ if (!where || !isRecord6(where)) {
3978
+ return false;
3979
+ }
3980
+ for (const [key, value] of Object.entries(where)) {
3981
+ if (value === void 0) {
3982
+ continue;
3983
+ }
3984
+ if (key === "or" && Array.isArray(value)) {
3985
+ if (value.some(
3986
+ (clause) => booleanOperandRequiresUuidQueryFallback(clause)
3987
+ )) {
3988
+ return true;
3989
+ }
3990
+ continue;
3991
+ }
3992
+ if (key === "not" && isRecord6(value)) {
3993
+ if (booleanOperandRequiresUuidQueryFallback(value)) {
3994
+ return true;
3995
+ }
3996
+ continue;
3997
+ }
3998
+ if (predicateRequiresUuidQueryFallback(key, value)) {
3999
+ return true;
4000
+ }
4001
+ }
4002
+ return false;
4003
+ }
3780
4004
  function resolvePagination(input) {
3781
4005
  let limit = input.limit;
3782
4006
  let offset = input.offset;
@@ -3795,25 +4019,6 @@ function hasTypedEqualityComparison(conditions) {
3795
4019
  }
3796
4020
  function createSelectTransportPlan(input) {
3797
4021
  const conditions = input.state.conditions.length ? input.state.conditions.map((condition) => ({ ...condition })) : void 0;
3798
- if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
3799
- const query = input.buildTypedSelectQuery({
3800
- tableName: input.tableName,
3801
- columns: input.columns,
3802
- conditions,
3803
- limit: input.state.limit,
3804
- offset: input.state.offset,
3805
- currentPage: input.state.currentPage,
3806
- pageSize: input.state.pageSize,
3807
- order: input.state.order
3808
- });
3809
- if (query) {
3810
- return {
3811
- kind: "query",
3812
- query,
3813
- payload: { query }
3814
- };
3815
- }
3816
- }
3817
4022
  const pagination = resolvePagination({
3818
4023
  limit: input.state.limit,
3819
4024
  offset: input.state.offset,
@@ -3849,6 +4054,25 @@ function createSelectTransportPlan(input) {
3849
4054
  }
3850
4055
  };
3851
4056
  }
4057
+ if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
4058
+ const query = input.buildTypedSelectQuery({
4059
+ tableName: input.tableName,
4060
+ columns: input.columns,
4061
+ conditions,
4062
+ limit: input.state.limit,
4063
+ offset: input.state.offset,
4064
+ currentPage: input.state.currentPage,
4065
+ pageSize: input.state.pageSize,
4066
+ order: input.state.order
4067
+ });
4068
+ if (query) {
4069
+ return {
4070
+ kind: "query",
4071
+ query,
4072
+ payload: { query }
4073
+ };
4074
+ }
4075
+ }
3852
4076
  return {
3853
4077
  kind: "fetch",
3854
4078
  payload: {
@@ -3905,6 +4129,13 @@ function formatResult(response) {
3905
4129
  }
3906
4130
  return result;
3907
4131
  }
4132
+ var EXPERIMENTAL_READ_RETRY_CONFIG = {
4133
+ retries: 2,
4134
+ baseDelayMs: 100,
4135
+ maxDelayMs: 1e3,
4136
+ backoff: "exponential",
4137
+ jitter: true
4138
+ };
3908
4139
  function attachNormalizedError(result, normalizedError) {
3909
4140
  Object.defineProperty(result, ATHENA_NORMALIZED_ERROR_KEY, {
3910
4141
  value: normalizedError,
@@ -3931,7 +4162,36 @@ function createResultFormatter(experimental) {
3931
4162
  return result;
3932
4163
  };
3933
4164
  }
3934
- function isRecord6(value) {
4165
+ async function executeExperimentalRead(experimental, runner) {
4166
+ if (!experimental?.retryReads) {
4167
+ return runner();
4168
+ }
4169
+ let lastRetryableResult;
4170
+ let lastRetrySignal = null;
4171
+ try {
4172
+ return await withRetry(
4173
+ {
4174
+ ...EXPERIMENTAL_READ_RETRY_CONFIG,
4175
+ shouldRetry: (error) => error === lastRetrySignal || normalizeAthenaError(error).retryable
4176
+ },
4177
+ async () => {
4178
+ const result = await runner();
4179
+ if (result.error?.retryable) {
4180
+ lastRetryableResult = result;
4181
+ lastRetrySignal = result.error;
4182
+ throw lastRetrySignal;
4183
+ }
4184
+ return result;
4185
+ }
4186
+ );
4187
+ } catch (error) {
4188
+ if (lastRetryableResult && error === lastRetrySignal) {
4189
+ return lastRetryableResult;
4190
+ }
4191
+ throw error;
4192
+ }
4193
+ }
4194
+ function isRecord7(value) {
3935
4195
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3936
4196
  }
3937
4197
  function firstNonEmptyString2(...values) {
@@ -3943,8 +4203,8 @@ function firstNonEmptyString2(...values) {
3943
4203
  return void 0;
3944
4204
  }
3945
4205
  function resolveStructuredErrorPayload2(raw) {
3946
- if (!isRecord6(raw)) return null;
3947
- return isRecord6(raw.error) ? raw.error : raw;
4206
+ if (!isRecord7(raw)) return null;
4207
+ return isRecord7(raw.error) ? raw.error : raw;
3948
4208
  }
3949
4209
  function resolveStructuredErrorDetails(payload, message) {
3950
4210
  if (!payload || !("details" in payload)) {
@@ -3960,7 +4220,7 @@ function resolveStructuredErrorDetails(payload, message) {
3960
4220
  return details;
3961
4221
  }
3962
4222
  function createResultError(response, result, normalized) {
3963
- const rawRecord = isRecord6(response.raw) ? response.raw : null;
4223
+ const rawRecord = isRecord7(response.raw) ? response.raw : null;
3964
4224
  const payload = resolveStructuredErrorPayload2(response.raw);
3965
4225
  const message = firstNonEmptyString2(
3966
4226
  response.error,
@@ -4155,7 +4415,14 @@ function toSingleResult(response) {
4155
4415
  function mergeOptions(...options) {
4156
4416
  return options.reduce((acc, next) => {
4157
4417
  if (!next) return acc;
4158
- return { ...acc, ...next };
4418
+ const merged = { ...acc ?? {}, ...next };
4419
+ if (acc?.headers || next.headers) {
4420
+ merged.headers = {
4421
+ ...acc?.headers ?? {},
4422
+ ...next.headers ?? {}
4423
+ };
4424
+ }
4425
+ return merged;
4159
4426
  }, void 0);
4160
4427
  }
4161
4428
  function asAthenaJsonObject(value) {
@@ -4947,42 +5214,48 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
4947
5214
  buildTypedSelectQuery
4948
5215
  });
4949
5216
  if (plan.kind === "query") {
4950
- return executeWithQueryTrace(
5217
+ return executeExperimentalRead(
5218
+ experimental,
5219
+ () => executeWithQueryTrace(
5220
+ tracer,
5221
+ {
5222
+ operation: "select",
5223
+ endpoint: "/gateway/query",
5224
+ table: resolvedTableName,
5225
+ sql: plan.query,
5226
+ payload: plan.payload,
5227
+ options
5228
+ },
5229
+ async () => {
5230
+ const queryResponse = await client.queryGateway(plan.payload, options);
5231
+ return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
5232
+ },
5233
+ callsite
5234
+ )
5235
+ );
5236
+ }
5237
+ const sql = buildDebugSelectQuery({
5238
+ tableName: resolvedTableName,
5239
+ ...plan.debug
5240
+ });
5241
+ return executeExperimentalRead(
5242
+ experimental,
5243
+ () => executeWithQueryTrace(
4951
5244
  tracer,
4952
5245
  {
4953
5246
  operation: "select",
4954
- endpoint: "/gateway/query",
5247
+ endpoint: "/gateway/fetch",
4955
5248
  table: resolvedTableName,
4956
- sql: plan.query,
5249
+ sql,
4957
5250
  payload: plan.payload,
4958
5251
  options
4959
5252
  },
4960
5253
  async () => {
4961
- const queryResponse = await client.queryGateway(plan.payload, options);
4962
- return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
5254
+ const response = await client.fetchGateway(plan.payload, options);
5255
+ return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
4963
5256
  },
4964
5257
  callsite
4965
- );
4966
- }
4967
- const sql = buildDebugSelectQuery({
4968
- tableName: resolvedTableName,
4969
- ...plan.debug
4970
- });
4971
- return executeWithQueryTrace(
4972
- tracer,
4973
- {
4974
- operation: "select",
4975
- endpoint: "/gateway/fetch",
4976
- table: resolvedTableName,
4977
- sql,
4978
- payload: plan.payload,
4979
- options
4980
- },
4981
- async () => {
4982
- const response = await client.fetchGateway(plan.payload, options);
4983
- return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
4984
- },
4985
- callsite
5258
+ )
4986
5259
  );
4987
5260
  };
4988
5261
  const createSelectChain = (columns, options, initialCallsite) => {
@@ -5052,14 +5325,14 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5052
5325
  if (options.limit !== void 0) {
5053
5326
  executionState.limit = options.limit;
5054
5327
  }
5055
- if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select)) {
5328
+ if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select) && !findManyAstWhereRequiresLegacyTransport(options.where)) {
5056
5329
  const resolvedTableName = resolveTableNameForCall(tableName, void 0);
5057
5330
  const payload = {
5058
5331
  table_name: resolvedTableName,
5059
5332
  select: options.select
5060
5333
  };
5061
5334
  if (options.where !== void 0) {
5062
- payload.where = options.where;
5335
+ payload.where = normalizeFindManyAstWhere(options.where);
5063
5336
  }
5064
5337
  const astOrder = toFindManyAstOrder(executionState.order);
5065
5338
  if (astOrder !== void 0) {
@@ -5075,22 +5348,25 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5075
5348
  limit: executionState.limit,
5076
5349
  order: executionState.order
5077
5350
  });
5078
- return executeWithQueryTrace(
5079
- tracer,
5080
- {
5081
- operation: "select",
5082
- endpoint: "/gateway/fetch",
5083
- table: resolvedTableName,
5084
- sql,
5085
- payload
5086
- },
5087
- async () => {
5088
- const response = await client.fetchGateway(
5351
+ return executeExperimentalRead(
5352
+ experimental,
5353
+ () => executeWithQueryTrace(
5354
+ tracer,
5355
+ {
5356
+ operation: "select",
5357
+ endpoint: "/gateway/fetch",
5358
+ table: resolvedTableName,
5359
+ sql,
5089
5360
  payload
5090
- );
5091
- return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
5092
- },
5093
- callsite
5361
+ },
5362
+ async () => {
5363
+ const response = await client.fetchGateway(
5364
+ payload
5365
+ );
5366
+ return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
5367
+ },
5368
+ callsite
5369
+ )
5094
5370
  );
5095
5371
  }
5096
5372
  return runSelect(
@@ -5338,7 +5614,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
5338
5614
  });
5339
5615
  return builder;
5340
5616
  }
5341
- function createQueryBuilder(client, formatGatewayResult, tracer) {
5617
+ function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
5342
5618
  return async function query(query, options) {
5343
5619
  const normalizedQuery = query.trim();
5344
5620
  if (!normalizedQuery) {
@@ -5346,30 +5622,39 @@ function createQueryBuilder(client, formatGatewayResult, tracer) {
5346
5622
  }
5347
5623
  const payload = { query: normalizedQuery };
5348
5624
  const callsite = captureTraceCallsite(tracer);
5349
- return executeWithQueryTrace(
5350
- tracer,
5351
- {
5352
- operation: "query",
5353
- endpoint: "/gateway/query",
5354
- sql: normalizedQuery,
5355
- payload,
5356
- options
5357
- },
5358
- async () => {
5359
- const response = await client.queryGateway(payload, options);
5360
- return formatGatewayResult(response, { operation: "query" });
5361
- },
5362
- callsite
5625
+ return executeExperimentalRead(
5626
+ experimental,
5627
+ () => executeWithQueryTrace(
5628
+ tracer,
5629
+ {
5630
+ operation: "query",
5631
+ endpoint: "/gateway/query",
5632
+ sql: normalizedQuery,
5633
+ payload,
5634
+ options
5635
+ },
5636
+ async () => {
5637
+ const response = await client.queryGateway(payload, options);
5638
+ return formatGatewayResult(response, { operation: "query" });
5639
+ },
5640
+ callsite
5641
+ )
5363
5642
  );
5364
5643
  };
5365
5644
  }
5366
5645
  function createClientFromConfig(config) {
5646
+ const gatewayHeaders = {
5647
+ ...config.headers ?? {}
5648
+ };
5649
+ if (config.auth?.bearerToken && gatewayHeaders["X-Athena-Auth-Bearer-Token"] === void 0 && gatewayHeaders["x-athena-auth-bearer-token"] === void 0) {
5650
+ gatewayHeaders["X-Athena-Auth-Bearer-Token"] = config.auth.bearerToken;
5651
+ }
5367
5652
  const gateway = createAthenaGatewayClient({
5368
5653
  baseUrl: config.baseUrl,
5369
5654
  apiKey: config.apiKey,
5370
5655
  client: config.client,
5371
5656
  backend: config.backend,
5372
- headers: config.headers
5657
+ headers: gatewayHeaders
5373
5658
  });
5374
5659
  const formatGatewayResult = createResultFormatter();
5375
5660
  const queryTracer = createQueryTracer(config.experimental);
@@ -5396,7 +5681,7 @@ function createClientFromConfig(config) {
5396
5681
  captureTraceCallsite(queryTracer)
5397
5682
  );
5398
5683
  };
5399
- const query = createQueryBuilder(gateway, formatGatewayResult, queryTracer);
5684
+ const query = createQueryBuilder(gateway, formatGatewayResult, config.experimental, queryTracer);
5400
5685
  const db = createDbModule({ from, rpc, query });
5401
5686
  return {
5402
5687
  from,