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