@xylex-group/athena 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +124 -106
  2. package/dist/browser.cjs +584 -99
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.cts +7 -7
  5. package/dist/browser.d.ts +7 -7
  6. package/dist/browser.js +583 -100
  7. package/dist/browser.js.map +1 -1
  8. package/dist/cli/index.cjs +573 -97
  9. package/dist/cli/index.cjs.map +1 -1
  10. package/dist/cli/index.d.cts +3 -3
  11. package/dist/cli/index.d.ts +3 -3
  12. package/dist/cli/index.js +573 -97
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/index.cjs +584 -99
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +7 -7
  17. package/dist/index.d.ts +7 -7
  18. package/dist/index.js +583 -100
  19. package/dist/index.js.map +1 -1
  20. package/dist/{model-form-BpDXlbxb.d.ts → model-form-C0FAbOaf.d.ts} +1 -1
  21. package/dist/{model-form-hoE2jHIi.d.cts → model-form-GzTqhEzM.d.cts} +1 -1
  22. package/dist/{pipeline-BNIw8pDQ.d.ts → pipeline-CR4V15jF.d.ts} +1 -1
  23. package/dist/{pipeline-DNIpEsN8.d.cts → pipeline-DZeExYMA.d.cts} +1 -1
  24. package/dist/{react-email-BvyCZnfW.d.cts → react-email-BuApZuyG.d.ts} +19 -6
  25. package/dist/{react-email-qPA1wjFV.d.ts → react-email-CQJq92zQ.d.cts} +19 -6
  26. package/dist/react.cjs +249 -12
  27. package/dist/react.cjs.map +1 -1
  28. package/dist/react.d.cts +4 -4
  29. package/dist/react.d.ts +4 -4
  30. package/dist/react.js +249 -12
  31. package/dist/react.js.map +1 -1
  32. package/dist/{types-A5e97acl.d.cts → types-09Q4D86N.d.cts} +23 -2
  33. package/dist/{types-A5e97acl.d.ts → types-09Q4D86N.d.ts} +23 -2
  34. package/dist/{types-bDlr4u7p.d.cts → types-D1JvL21V.d.cts} +1 -1
  35. package/dist/{types-BnD22-vb.d.ts → types-DU3gNdFv.d.ts} +1 -1
  36. package/package.json +40 -40
package/dist/index.cjs CHANGED
@@ -65,8 +65,74 @@ function isAthenaGatewayError(error) {
65
65
  return error instanceof AthenaGatewayError;
66
66
  }
67
67
 
68
+ // src/gateway/url.ts
69
+ var ATHENA_DEFAULT_BASE_URL = "https://athena-db.com";
70
+ function describeReceivedValue(value) {
71
+ if (value === void 0) return "undefined";
72
+ if (value === null) return "null";
73
+ if (typeof value === "string") {
74
+ return value.trim().length > 0 ? JSON.stringify(value) : "an empty string";
75
+ }
76
+ return `${typeof value} ${JSON.stringify(value)}`;
77
+ }
78
+ function invalidBaseUrlError(message, hint) {
79
+ return new AthenaGatewayError({
80
+ code: "INVALID_URL",
81
+ message,
82
+ status: 0,
83
+ hint
84
+ });
85
+ }
86
+ function normalizeAthenaGatewayBaseUrl(input, options = {}) {
87
+ const label = options.label ?? "Athena gateway base URL";
88
+ const candidate = input ?? options.defaultBaseUrl;
89
+ if (candidate === void 0 || candidate === null) {
90
+ throw invalidBaseUrlError(
91
+ `${label} must be a non-empty absolute http(s) URL. Received ${describeReceivedValue(input)}.`,
92
+ 'Set ATHENA_URL (or pass createClient(url, ...)) to a full URL such as "https://mirror3.athena-db.com".'
93
+ );
94
+ }
95
+ const trimmed = candidate.trim();
96
+ if (!trimmed) {
97
+ throw invalidBaseUrlError(
98
+ `${label} must be a non-empty absolute http(s) URL. Received ${describeReceivedValue(candidate)}.`,
99
+ 'Set ATHENA_URL (or pass createClient(url, ...)) to a full URL such as "https://mirror3.athena-db.com".'
100
+ );
101
+ }
102
+ let parsed;
103
+ try {
104
+ parsed = new URL(trimmed);
105
+ } catch {
106
+ throw invalidBaseUrlError(
107
+ `${label} must be a valid absolute http(s) URL. Received ${describeReceivedValue(candidate)}.`,
108
+ 'Use a full URL including the protocol, for example "https://mirror3.athena-db.com".'
109
+ );
110
+ }
111
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
112
+ throw invalidBaseUrlError(
113
+ `${label} must use http or https. Received ${JSON.stringify(trimmed)}.`,
114
+ 'Use an Athena gateway URL such as "https://mirror3.athena-db.com".'
115
+ );
116
+ }
117
+ if (parsed.search || parsed.hash) {
118
+ throw invalidBaseUrlError(
119
+ `${label} must not include query parameters or hash fragments. Received ${JSON.stringify(trimmed)}.`,
120
+ 'Pass only the base URL. Endpoint paths such as "/gateway/fetch" are appended by the SDK.'
121
+ );
122
+ }
123
+ return parsed.toString().replace(/\/+$/, "");
124
+ }
125
+ function buildAthenaGatewayUrl(baseUrl, path) {
126
+ if (!path.startsWith("/")) {
127
+ throw invalidBaseUrlError(
128
+ `Athena gateway path must start with "/". Received ${JSON.stringify(path)}.`,
129
+ 'Use a leading slash such as "/gateway/fetch" or "/".'
130
+ );
131
+ }
132
+ return `${baseUrl}${path}`;
133
+ }
134
+
68
135
  // src/gateway/client.ts
69
- var DEFAULT_BASE_URL = "https://athena-db.com";
70
136
  var DEFAULT_CLIENT = "railway_direct";
71
137
  var FALLBACK_SDK_VERSION = "1.3.0";
72
138
  var SDK_NAME = "xylex-group/athena";
@@ -263,9 +329,172 @@ function buildHeaders(config, options) {
263
329
  });
264
330
  return headers;
265
331
  }
332
+ function toInvalidUrlResponse(error, endpoint, method) {
333
+ const message = error instanceof Error ? error.message : String(error);
334
+ const gatewayError = error instanceof AthenaGatewayError ? error : new AthenaGatewayError({
335
+ code: "INVALID_URL",
336
+ message,
337
+ status: 0,
338
+ endpoint,
339
+ method,
340
+ cause: message,
341
+ hint: "Set ATHENA_URL to a full http(s) URL before running queries."
342
+ });
343
+ return {
344
+ ok: false,
345
+ status: 0,
346
+ statusText: null,
347
+ data: null,
348
+ error: gatewayError.message,
349
+ errorDetails: detailsFromError(
350
+ new AthenaGatewayError({
351
+ code: gatewayError.code,
352
+ message: gatewayError.message,
353
+ status: gatewayError.status,
354
+ endpoint,
355
+ method,
356
+ requestId: gatewayError.requestId,
357
+ hint: gatewayError.hint,
358
+ cause: gatewayError.causeDetail
359
+ })
360
+ ),
361
+ raw: null
362
+ };
363
+ }
364
+ function resolveGatewayBaseUrl(input) {
365
+ return normalizeAthenaGatewayBaseUrl(input, {
366
+ defaultBaseUrl: ATHENA_DEFAULT_BASE_URL
367
+ });
368
+ }
369
+ function resolveProbePath(path) {
370
+ if (!path) return "/";
371
+ if (!path.startsWith("/")) {
372
+ throw new AthenaGatewayError({
373
+ code: "INVALID_URL",
374
+ message: `Athena gateway probe path must start with "/". Received ${JSON.stringify(path)}.`,
375
+ status: 0,
376
+ hint: 'Use a leading slash such as "/" or "/health".'
377
+ });
378
+ }
379
+ return path;
380
+ }
381
+ function mergeConnectionHeaders(baseHeaders, headers) {
382
+ const merged = {
383
+ ...baseHeaders,
384
+ ...headers ?? {}
385
+ };
386
+ if (!merged["X-Athena-Sdk"] && !merged["x-athena-sdk"]) {
387
+ merged["X-Athena-Sdk"] = SDK_HEADER_VALUE;
388
+ }
389
+ return merged;
390
+ }
391
+ async function performConnectionCheck(baseUrl, requestHeaders, options) {
392
+ const path = resolveProbePath(options?.path);
393
+ const url = buildAthenaGatewayUrl(baseUrl, path);
394
+ try {
395
+ const response = await fetch(url, {
396
+ method: "GET",
397
+ headers: mergeConnectionHeaders(requestHeaders, options?.headers),
398
+ signal: options?.signal
399
+ });
400
+ const rawText = await response.text();
401
+ const requestId = resolveRequestId(response.headers);
402
+ const parsedBody = parseResponseBody(
403
+ rawText ?? "",
404
+ response.headers.get("content-type")
405
+ );
406
+ if (parsedBody.parseFailed) {
407
+ const invalidJsonError = new AthenaGatewayError({
408
+ code: "INVALID_JSON",
409
+ message: "Gateway probe returned malformed JSON",
410
+ status: response.status,
411
+ method: "GET",
412
+ requestId,
413
+ hint: "Verify the gateway response body is valid JSON.",
414
+ cause: rawText.slice(0, 300)
415
+ });
416
+ return {
417
+ ok: false,
418
+ reachable: true,
419
+ status: response.status,
420
+ statusText: resolveStatusText(response, parsedBody.parsed),
421
+ baseUrl,
422
+ url,
423
+ error: invalidJsonError.message,
424
+ errorDetails: detailsFromError(invalidJsonError),
425
+ raw: parsedBody.parsed
426
+ };
427
+ }
428
+ const parsed = parsedBody.parsed;
429
+ if (!response.ok) {
430
+ const httpError = new AthenaGatewayError({
431
+ code: "HTTP_ERROR",
432
+ message: resolveErrorMessage(
433
+ parsed,
434
+ `Athena gateway GET ${path} failed with status ${response.status}`
435
+ ),
436
+ status: response.status,
437
+ method: "GET",
438
+ requestId,
439
+ hint: resolveErrorHint(parsed)
440
+ });
441
+ return {
442
+ ok: false,
443
+ reachable: true,
444
+ status: response.status,
445
+ statusText: resolveStatusText(response, parsed),
446
+ baseUrl,
447
+ url,
448
+ error: httpError.message,
449
+ errorDetails: detailsFromError(httpError),
450
+ raw: parsed
451
+ };
452
+ }
453
+ return {
454
+ ok: true,
455
+ reachable: true,
456
+ status: response.status,
457
+ statusText: resolveStatusText(response, parsed),
458
+ baseUrl,
459
+ url,
460
+ error: void 0,
461
+ errorDetails: null,
462
+ raw: parsed
463
+ };
464
+ } catch (callError) {
465
+ const message = callError instanceof Error ? callError.message : String(callError);
466
+ const networkError = new AthenaGatewayError({
467
+ code: "NETWORK_ERROR",
468
+ message: `Network error while probing Athena gateway ${url}: ${message}`,
469
+ method: "GET",
470
+ cause: message,
471
+ hint: "Check gateway URL, DNS, and network reachability."
472
+ });
473
+ return {
474
+ ok: false,
475
+ reachable: false,
476
+ status: 0,
477
+ statusText: null,
478
+ baseUrl,
479
+ url,
480
+ error: networkError.message,
481
+ errorDetails: detailsFromError(networkError),
482
+ raw: null
483
+ };
484
+ }
485
+ }
486
+ async function verifyAthenaGatewayUrl(baseUrl, options) {
487
+ const normalizedBaseUrl = normalizeAthenaGatewayBaseUrl(baseUrl);
488
+ return performConnectionCheck(normalizedBaseUrl, { "X-Athena-Sdk": SDK_HEADER_VALUE }, options);
489
+ }
266
490
  async function callAthena(config, endpoint, method, payload, options) {
267
- const baseUrl = (options?.baseUrl ?? config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
268
- const url = `${baseUrl}${endpoint}`;
491
+ let baseUrl;
492
+ try {
493
+ baseUrl = resolveGatewayBaseUrl(options?.baseUrl ?? config.baseUrl);
494
+ } catch (error) {
495
+ return toInvalidUrlResponse(error, endpoint, method);
496
+ }
497
+ const url = buildAthenaGatewayUrl(baseUrl, endpoint);
269
498
  const headers = buildHeaders(config, options);
270
499
  try {
271
500
  const requestInit = {
@@ -362,32 +591,44 @@ async function callAthena(config, endpoint, method, payload, options) {
362
591
  }
363
592
  }
364
593
  function createAthenaGatewayClient(config = {}) {
594
+ const normalizedBaseUrl = resolveGatewayBaseUrl(config.baseUrl);
595
+ const normalizedConfig = {
596
+ ...config,
597
+ baseUrl: normalizedBaseUrl
598
+ };
365
599
  return {
366
- baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, ""),
600
+ baseUrl: normalizedBaseUrl,
367
601
  buildHeaders(options) {
368
- return buildHeaders(config, options);
602
+ return buildHeaders(normalizedConfig, options);
603
+ },
604
+ verifyConnection(options) {
605
+ return performConnectionCheck(
606
+ normalizedBaseUrl,
607
+ buildHeaders(normalizedConfig),
608
+ options
609
+ );
369
610
  },
370
611
  fetchGateway(payload, options) {
371
- return callAthena(config, "/gateway/fetch", "POST", payload, options);
612
+ return callAthena(normalizedConfig, "/gateway/fetch", "POST", payload, options);
372
613
  },
373
614
  insertGateway(payload, options) {
374
- return callAthena(config, "/gateway/insert", "PUT", payload, options);
615
+ return callAthena(normalizedConfig, "/gateway/insert", "PUT", payload, options);
375
616
  },
376
617
  updateGateway(payload, options) {
377
- return callAthena(config, "/gateway/update", "POST", payload, options);
618
+ return callAthena(normalizedConfig, "/gateway/update", "POST", payload, options);
378
619
  },
379
620
  deleteGateway(payload, options) {
380
- return callAthena(config, "/gateway/delete", "DELETE", payload, options);
621
+ return callAthena(normalizedConfig, "/gateway/delete", "DELETE", payload, options);
381
622
  },
382
623
  rpcGateway(payload, options) {
383
624
  if (options?.get) {
384
625
  const endpoint = buildRpcGetEndpoint(payload);
385
- return callAthena(config, endpoint, "GET", null, options);
626
+ return callAthena(normalizedConfig, endpoint, "GET", null, options);
386
627
  }
387
- return callAthena(config, "/gateway/rpc", "POST", payload, options);
628
+ return callAthena(normalizedConfig, "/gateway/rpc", "POST", payload, options);
388
629
  },
389
630
  queryGateway(payload, options) {
390
- return callAthena(config, "/gateway/query", "POST", payload, options);
631
+ return callAthena(normalizedConfig, "/gateway/query", "POST", payload, options);
391
632
  }
392
633
  };
393
634
  }
@@ -2029,6 +2270,7 @@ function classifyKind(status, code, message) {
2029
2270
  if (status === 404 || hasNotFoundPattern) return "not_found";
2030
2271
  if (status === 401 || status === 403 || hasAuthPattern) return "auth";
2031
2272
  if (status === 429 || hasRateLimitPattern) return "rate_limit";
2273
+ if (code === "INVALID_URL") return "validation";
2032
2274
  if (status === 400 || status === 422 || hasValidationPattern) return "validation";
2033
2275
  if (code === "NETWORK_ERROR" || status === 0 || status !== void 0 && status >= 500 || hasTransientPattern) {
2034
2276
  return "transient";
@@ -2036,6 +2278,9 @@ function classifyKind(status, code, message) {
2036
2278
  return "unknown";
2037
2279
  }
2038
2280
  function toAthenaErrorCode(kind, status, gatewayCode) {
2281
+ if (gatewayCode === "INVALID_URL") {
2282
+ return AthenaErrorCode.ValidationFailed;
2283
+ }
2039
2284
  if (gatewayCode === "NETWORK_ERROR" || kind === "transient" && status === 0) {
2040
2285
  return AthenaErrorCode.NetworkUnavailable;
2041
2286
  }
@@ -2384,8 +2629,8 @@ async function withRetry(config, fn) {
2384
2629
  // src/db/module.ts
2385
2630
  function createDbModule(input) {
2386
2631
  const db = {
2387
- from(table) {
2388
- return input.from(table);
2632
+ from(table, options) {
2633
+ return input.from(table, options);
2389
2634
  },
2390
2635
  select(table, columns, options) {
2391
2636
  return input.from(table).select(columns, options);
@@ -2490,7 +2735,19 @@ function buildGatewayCondition(operator, column, value) {
2490
2735
  function compileRelationToken(key, node) {
2491
2736
  const nested = compileSelectShape(node.select);
2492
2737
  const propertyKey = normalizeIdentifier(key, "select relation key");
2493
- const relationToken = normalizeIdentifier(node.via ?? propertyKey, "select relation token");
2738
+ if (node.schema && node.via) {
2739
+ throw new Error(
2740
+ `findMany relation "${propertyKey}" cannot combine schema and via yet; use schema with the relation key, or use via without schema`
2741
+ );
2742
+ }
2743
+ const relationTokenBase = normalizeIdentifier(node.via ?? propertyKey, "select relation token");
2744
+ if (node.schema && relationTokenBase.includes(".")) {
2745
+ throw new Error(
2746
+ `findMany relation "${propertyKey}" already resolves to a qualified relation token; do not also set schema`
2747
+ );
2748
+ }
2749
+ const relationSchema = node.schema?.trim();
2750
+ const relationToken = relationSchema ? `${normalizeIdentifier(relationSchema, "select relation schema")}.${relationTokenBase}` : relationTokenBase;
2494
2751
  const alias = node.as?.trim() || (relationToken !== propertyKey ? propertyKey : "");
2495
2752
  const prefix = alias ? `${alias}:` : "";
2496
2753
  return `${prefix}${relationToken}(${nested})`;
@@ -2519,6 +2776,23 @@ function compileSelectShape(select) {
2519
2776
  }
2520
2777
  return tokens.join(",");
2521
2778
  }
2779
+ function selectShapeUsesRelationSchema(select) {
2780
+ if (!isRecord5(select)) {
2781
+ return false;
2782
+ }
2783
+ for (const rawValue of Object.values(select)) {
2784
+ if (!isRelationSelectNode(rawValue)) {
2785
+ continue;
2786
+ }
2787
+ if (typeof rawValue.schema === "string" && rawValue.schema.trim().length > 0) {
2788
+ return true;
2789
+ }
2790
+ if (selectShapeUsesRelationSchema(rawValue.select)) {
2791
+ return true;
2792
+ }
2793
+ }
2794
+ return false;
2795
+ }
2522
2796
  function compileColumnWhere(column, input) {
2523
2797
  const normalizedColumn = normalizeIdentifier(column, "where column");
2524
2798
  if (!isRecord5(input)) {
@@ -2655,6 +2929,258 @@ function compileOrderBy(orderBy) {
2655
2929
  };
2656
2930
  }
2657
2931
 
2932
+ // src/gateway/structured-select.ts
2933
+ var IDENTIFIER_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
2934
+ function isIdentifierPath(value) {
2935
+ const segments = value.split(".").map((segment) => segment.trim());
2936
+ return segments.length > 1 && segments.every((segment) => IDENTIFIER_SEGMENT_PATTERN.test(segment));
2937
+ }
2938
+ function extractRelationHead(raw) {
2939
+ const trimmed = raw.trim();
2940
+ if (!trimmed) return "";
2941
+ const aliasIndex = trimmed.indexOf(":");
2942
+ const withoutAlias = aliasIndex >= 0 ? trimmed.slice(aliasIndex + 1).trim() : trimmed;
2943
+ const modifierIndex = withoutAlias.indexOf("!");
2944
+ return (modifierIndex >= 0 ? withoutAlias.slice(0, modifierIndex) : withoutAlias).trim();
2945
+ }
2946
+ function hasSchemaQualifiedRelationToken(select) {
2947
+ let singleQuoted = false;
2948
+ let doubleQuoted = false;
2949
+ let tokenStart = 0;
2950
+ for (let index = 0; index < select.length; index += 1) {
2951
+ const char = select[index];
2952
+ const next = index + 1 < select.length ? select[index + 1] : "";
2953
+ if (singleQuoted) {
2954
+ if (char === "'" && next === "'") {
2955
+ index += 1;
2956
+ continue;
2957
+ }
2958
+ if (char === "'") {
2959
+ singleQuoted = false;
2960
+ }
2961
+ continue;
2962
+ }
2963
+ if (doubleQuoted) {
2964
+ if (char === '"' && next === '"') {
2965
+ index += 1;
2966
+ continue;
2967
+ }
2968
+ if (char === '"') {
2969
+ doubleQuoted = false;
2970
+ }
2971
+ continue;
2972
+ }
2973
+ if (char === "'") {
2974
+ singleQuoted = true;
2975
+ continue;
2976
+ }
2977
+ if (char === '"') {
2978
+ doubleQuoted = true;
2979
+ continue;
2980
+ }
2981
+ if (char === "(") {
2982
+ const relationHead = extractRelationHead(select.slice(tokenStart, index));
2983
+ if (isIdentifierPath(relationHead)) {
2984
+ return true;
2985
+ }
2986
+ tokenStart = index + 1;
2987
+ continue;
2988
+ }
2989
+ if (char === "," || char === ")") {
2990
+ tokenStart = index + 1;
2991
+ }
2992
+ }
2993
+ return false;
2994
+ }
2995
+ function toStructuredSelectString(columns) {
2996
+ return Array.isArray(columns) ? columns.join(",") : columns;
2997
+ }
2998
+ function buildStructuredWhere(conditions) {
2999
+ if (!conditions?.length) return void 0;
3000
+ const where = {};
3001
+ for (const condition of conditions) {
3002
+ if (!condition.column) {
3003
+ return null;
3004
+ }
3005
+ if (condition.column_cast !== void 0 || condition.value_cast !== void 0) {
3006
+ return null;
3007
+ }
3008
+ const operand = condition.value;
3009
+ const operator = condition.operator;
3010
+ if (operator === "eq") {
3011
+ if (operand === void 0) return null;
3012
+ } else if (operator === "neq" || operator === "gt" || operator === "lt") {
3013
+ if (operand === void 0) return null;
3014
+ } else if (operator === "in") {
3015
+ if (!Array.isArray(operand)) return null;
3016
+ } else {
3017
+ return null;
3018
+ }
3019
+ const existing = where[condition.column];
3020
+ if (existing !== void 0 && (typeof existing !== "object" || existing === null || Array.isArray(existing))) {
3021
+ return null;
3022
+ }
3023
+ const next = existing ?? {};
3024
+ if (Object.prototype.hasOwnProperty.call(next, operator)) {
3025
+ return null;
3026
+ }
3027
+ next[operator] = operand;
3028
+ where[condition.column] = next;
3029
+ }
3030
+ return where;
3031
+ }
3032
+ function buildStructuredOrderBy(order) {
3033
+ if (!order?.field) return void 0;
3034
+ return {
3035
+ [order.field]: order.direction === "descending" ? "desc" : "asc"
3036
+ };
3037
+ }
3038
+ function buildStructuredSelectTransport(input) {
3039
+ const select = toStructuredSelectString(input.columns).trim();
3040
+ if (!select || select === "*") {
3041
+ return null;
3042
+ }
3043
+ if (!hasSchemaQualifiedRelationToken(select)) {
3044
+ return null;
3045
+ }
3046
+ if (input.count !== void 0 || input.head !== void 0) {
3047
+ return {
3048
+ error: "Schema-qualified nested select strings require structured select transport, which does not support count/head options in athena-js yet."
3049
+ };
3050
+ }
3051
+ const where = buildStructuredWhere(input.conditions);
3052
+ if (where === null) {
3053
+ return {
3054
+ error: "Schema-qualified nested select strings only support eq, neq, gt, lt, and in filters in athena-js structured select transport."
3055
+ };
3056
+ }
3057
+ return {
3058
+ select,
3059
+ payload: {
3060
+ table_name: input.tableName,
3061
+ select,
3062
+ where,
3063
+ orderBy: buildStructuredOrderBy(input.order),
3064
+ limit: input.limit,
3065
+ offset: input.offset,
3066
+ strip_nulls: input.stripNulls
3067
+ }
3068
+ };
3069
+ }
3070
+
3071
+ // src/query-transport.ts
3072
+ function canUseFindManyAstTransport(state) {
3073
+ return state.conditions.length === 0 && state.offset === void 0 && state.currentPage === void 0 && state.pageSize === void 0 && state.totalPages === void 0;
3074
+ }
3075
+ function toFindManyAstOrder(order) {
3076
+ if (!order) {
3077
+ return void 0;
3078
+ }
3079
+ return {
3080
+ column: order.field,
3081
+ ascending: order.direction !== "descending"
3082
+ };
3083
+ }
3084
+ function resolvePagination(input) {
3085
+ let limit = input.limit;
3086
+ let offset = input.offset;
3087
+ if (limit === void 0 && input.pageSize !== void 0) {
3088
+ limit = Math.max(0, Math.trunc(input.pageSize));
3089
+ }
3090
+ if (offset === void 0 && input.pageSize !== void 0 && input.currentPage !== void 0 && input.currentPage > 0) {
3091
+ offset = (Math.trunc(input.currentPage) - 1) * Math.max(0, Math.trunc(input.pageSize));
3092
+ }
3093
+ return { limit, offset };
3094
+ }
3095
+ function hasTypedEqualityComparison(conditions) {
3096
+ return conditions?.some(
3097
+ (condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
3098
+ ) ?? false;
3099
+ }
3100
+ function createSelectTransportPlan(input) {
3101
+ const conditions = input.state.conditions.length ? input.state.conditions.map((condition) => ({ ...condition })) : void 0;
3102
+ if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
3103
+ const query = input.buildTypedSelectQuery({
3104
+ tableName: input.tableName,
3105
+ columns: input.columns,
3106
+ conditions,
3107
+ limit: input.state.limit,
3108
+ offset: input.state.offset,
3109
+ currentPage: input.state.currentPage,
3110
+ pageSize: input.state.pageSize,
3111
+ order: input.state.order
3112
+ });
3113
+ if (query) {
3114
+ return {
3115
+ kind: "query",
3116
+ query,
3117
+ payload: { query }
3118
+ };
3119
+ }
3120
+ }
3121
+ const pagination = resolvePagination({
3122
+ limit: input.state.limit,
3123
+ offset: input.state.offset,
3124
+ currentPage: input.state.currentPage,
3125
+ pageSize: input.state.pageSize
3126
+ });
3127
+ const stripNulls = input.options?.stripNulls ?? true;
3128
+ const structuredSelectTransport = buildStructuredSelectTransport({
3129
+ tableName: input.tableName,
3130
+ columns: input.columns,
3131
+ conditions,
3132
+ limit: pagination.limit,
3133
+ offset: pagination.offset,
3134
+ order: input.state.order,
3135
+ stripNulls,
3136
+ count: input.options?.count,
3137
+ head: input.options?.head
3138
+ });
3139
+ if (structuredSelectTransport && "error" in structuredSelectTransport) {
3140
+ throw new Error(structuredSelectTransport.error);
3141
+ }
3142
+ if (structuredSelectTransport) {
3143
+ const { payload, select } = structuredSelectTransport;
3144
+ return {
3145
+ kind: "fetch",
3146
+ payload,
3147
+ debug: {
3148
+ columns: select,
3149
+ conditions,
3150
+ limit: pagination.limit,
3151
+ offset: pagination.offset,
3152
+ order: input.state.order
3153
+ }
3154
+ };
3155
+ }
3156
+ return {
3157
+ kind: "fetch",
3158
+ payload: {
3159
+ table_name: input.tableName,
3160
+ columns: input.columns,
3161
+ conditions,
3162
+ limit: input.state.limit,
3163
+ offset: input.state.offset,
3164
+ current_page: input.state.currentPage,
3165
+ page_size: input.state.pageSize,
3166
+ total_pages: input.state.totalPages,
3167
+ sort_by: input.state.order,
3168
+ strip_nulls: stripNulls,
3169
+ count: input.options?.count,
3170
+ head: input.options?.head
3171
+ },
3172
+ debug: {
3173
+ columns: input.columns,
3174
+ conditions,
3175
+ limit: input.state.limit,
3176
+ offset: input.state.offset,
3177
+ currentPage: input.state.currentPage,
3178
+ pageSize: input.state.pageSize,
3179
+ order: input.state.order
3180
+ }
3181
+ };
3182
+ }
3183
+
2658
3184
  // src/client.ts
2659
3185
  var DEFAULT_COLUMNS = "*";
2660
3186
  var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
@@ -2669,18 +3195,6 @@ var QUERY_TRACE_STACK_SKIP_PATTERNS = [
2669
3195
  "node:internal",
2670
3196
  "internal/process"
2671
3197
  ];
2672
- function canUseFindManyAstTransport(state) {
2673
- return state.conditions.length === 0 && state.offset === void 0 && state.currentPage === void 0 && state.pageSize === void 0 && state.totalPages === void 0;
2674
- }
2675
- function toFindManyAstOrder(order) {
2676
- if (!order) {
2677
- return void 0;
2678
- }
2679
- return {
2680
- column: order.field,
2681
- ascending: order.direction !== "descending"
2682
- };
2683
- }
2684
3198
  function formatResult(response) {
2685
3199
  const result = {
2686
3200
  data: response.data ?? null,
@@ -3226,17 +3740,6 @@ function conditionToDebugSqlClause(condition) {
3226
3740
  return `TRUE /* unsupported condition: ${rawCondition} */`;
3227
3741
  }
3228
3742
  }
3229
- function resolvePagination(input) {
3230
- let limit = input.limit;
3231
- let offset = input.offset;
3232
- if (limit === void 0 && input.pageSize !== void 0) {
3233
- limit = input.pageSize;
3234
- }
3235
- if (offset === void 0 && input.pageSize !== void 0 && input.currentPage !== void 0 && input.currentPage > 0) {
3236
- offset = (input.currentPage - 1) * input.pageSize;
3237
- }
3238
- return { limit, offset };
3239
- }
3240
3743
  function appendOrderLimitOffset(sqlParts, order, limit, offset) {
3241
3744
  if (order?.field) {
3242
3745
  const direction = order.direction === "descending" ? "DESC" : "ASC";
@@ -3740,64 +4243,34 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
3740
4243
  );
3741
4244
  const runSelect = async (columns = DEFAULT_COLUMNS, options, executionState = snapshotState(), callsite) => {
3742
4245
  const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
3743
- const conditions = executionState.conditions.length ? executionState.conditions.map((condition) => ({ ...condition })) : void 0;
3744
- const hasTypedEqualityComparison = conditions?.some(
3745
- (condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
3746
- ) ?? false;
3747
- if (hasTypedEqualityComparison && !options?.head && !options?.count && conditions) {
3748
- const query = buildTypedSelectQuery({
3749
- tableName: resolvedTableName,
3750
- columns,
3751
- conditions,
3752
- limit: executionState.limit,
3753
- offset: executionState.offset,
3754
- currentPage: executionState.currentPage,
3755
- pageSize: executionState.pageSize,
3756
- order: executionState.order
3757
- });
3758
- if (query) {
3759
- const payload2 = { query };
3760
- return executeWithQueryTrace(
3761
- tracer,
3762
- {
3763
- operation: "select",
3764
- endpoint: "/gateway/query",
3765
- table: resolvedTableName,
3766
- sql: query,
3767
- payload: payload2,
3768
- options
3769
- },
3770
- async () => {
3771
- const queryResponse = await client.queryGateway(payload2, options);
3772
- return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
3773
- },
3774
- callsite
3775
- );
3776
- }
3777
- }
3778
- const payload = {
3779
- table_name: resolvedTableName,
4246
+ const plan = createSelectTransportPlan({
4247
+ tableName: resolvedTableName,
3780
4248
  columns,
3781
- conditions,
3782
- limit: executionState.limit,
3783
- offset: executionState.offset,
3784
- current_page: executionState.currentPage,
3785
- page_size: executionState.pageSize,
3786
- total_pages: executionState.totalPages,
3787
- sort_by: executionState.order,
3788
- strip_nulls: options?.stripNulls ?? true,
3789
- count: options?.count,
3790
- head: options?.head
3791
- };
4249
+ state: executionState,
4250
+ options,
4251
+ buildTypedSelectQuery
4252
+ });
4253
+ if (plan.kind === "query") {
4254
+ return executeWithQueryTrace(
4255
+ tracer,
4256
+ {
4257
+ operation: "select",
4258
+ endpoint: "/gateway/query",
4259
+ table: resolvedTableName,
4260
+ sql: plan.query,
4261
+ payload: plan.payload,
4262
+ options
4263
+ },
4264
+ async () => {
4265
+ const queryResponse = await client.queryGateway(plan.payload, options);
4266
+ return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
4267
+ },
4268
+ callsite
4269
+ );
4270
+ }
3792
4271
  const sql = buildDebugSelectQuery({
3793
4272
  tableName: resolvedTableName,
3794
- columns,
3795
- conditions,
3796
- limit: executionState.limit,
3797
- offset: executionState.offset,
3798
- currentPage: executionState.currentPage,
3799
- pageSize: executionState.pageSize,
3800
- order: executionState.order
4273
+ ...plan.debug
3801
4274
  });
3802
4275
  return executeWithQueryTrace(
3803
4276
  tracer,
@@ -3806,11 +4279,11 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
3806
4279
  endpoint: "/gateway/fetch",
3807
4280
  table: resolvedTableName,
3808
4281
  sql,
3809
- payload,
4282
+ payload: plan.payload,
3810
4283
  options
3811
4284
  },
3812
4285
  async () => {
3813
- const response = await client.fetchGateway(payload, options);
4286
+ const response = await client.fetchGateway(plan.payload, options);
3814
4287
  return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
3815
4288
  },
3816
4289
  callsite
@@ -3883,7 +4356,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
3883
4356
  if (options.limit !== void 0) {
3884
4357
  executionState.limit = options.limit;
3885
4358
  }
3886
- if (experimental?.findManyAst && canUseFindManyAstTransport(baseState)) {
4359
+ if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select)) {
3887
4360
  const resolvedTableName = resolveTableNameForCall(tableName, void 0);
3888
4361
  const payload = {
3889
4362
  table_name: resolvedTableName,
@@ -4205,7 +4678,13 @@ function createClientFromConfig(config) {
4205
4678
  const formatGatewayResult = createResultFormatter(config.experimental);
4206
4679
  const queryTracer = createQueryTracer(config.experimental);
4207
4680
  const auth = createAuthClient(config.auth);
4208
- const from = (table) => createTableBuilder(table, gateway, formatGatewayResult, queryTracer, config.experimental);
4681
+ const from = (table, options) => createTableBuilder(
4682
+ resolveTableNameForCall(table, options?.schema),
4683
+ gateway,
4684
+ formatGatewayResult,
4685
+ queryTracer,
4686
+ config.experimental
4687
+ );
4209
4688
  const rpc = (fn, args, options) => {
4210
4689
  const normalizedFn = fn.trim();
4211
4690
  if (!normalizedFn) {
@@ -4228,6 +4707,7 @@ function createClientFromConfig(config) {
4228
4707
  db,
4229
4708
  rpc,
4230
4709
  query,
4710
+ verifyConnection: gateway.verifyConnection,
4231
4711
  auth: auth.auth
4232
4712
  };
4233
4713
  }
@@ -4471,8 +4951,8 @@ var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
4471
4951
  });
4472
4952
  this.db = this.baseClient.db;
4473
4953
  }
4474
- from(table) {
4475
- return this.baseClient.from(table);
4954
+ from(table, options) {
4955
+ return this.baseClient.from(table, options);
4476
4956
  }
4477
4957
  rpc(fn, args, options) {
4478
4958
  return this.baseClient.rpc(fn, args, options);
@@ -4480,6 +4960,9 @@ var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
4480
4960
  query(query, options) {
4481
4961
  return this.baseClient.query(query, options);
4482
4962
  }
4963
+ verifyConnection(options) {
4964
+ return this.baseClient.verifyConnection(options);
4965
+ }
4483
4966
  withTenantContext(context) {
4484
4967
  return new _TypedAthenaClientImpl({
4485
4968
  registry: this.registry,
@@ -6177,6 +6660,7 @@ exports.isAthenaGatewayError = isAthenaGatewayError;
6177
6660
  exports.isOk = isOk;
6178
6661
  exports.loadGeneratorConfig = loadGeneratorConfig;
6179
6662
  exports.normalizeAthenaError = normalizeAthenaError;
6663
+ exports.normalizeAthenaGatewayBaseUrl = normalizeAthenaGatewayBaseUrl;
6180
6664
  exports.normalizeGeneratorConfig = normalizeGeneratorConfig;
6181
6665
  exports.normalizeSchemaSelection = normalizeSchemaSelection;
6182
6666
  exports.parseBooleanFlag = parseBooleanFlag2;
@@ -6192,6 +6676,7 @@ exports.toModelPayload = toModelPayload;
6192
6676
  exports.unwrap = unwrap;
6193
6677
  exports.unwrapOne = unwrapOne;
6194
6678
  exports.unwrapRows = unwrapRows;
6679
+ exports.verifyAthenaGatewayUrl = verifyAthenaGatewayUrl;
6195
6680
  exports.withRetry = withRetry;
6196
6681
  //# sourceMappingURL=index.cjs.map
6197
6682
  //# sourceMappingURL=index.cjs.map