@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/browser.js CHANGED
@@ -58,8 +58,74 @@ function isAthenaGatewayError(error) {
58
58
  return error instanceof AthenaGatewayError;
59
59
  }
60
60
 
61
+ // src/gateway/url.ts
62
+ var ATHENA_DEFAULT_BASE_URL = "https://athena-db.com";
63
+ function describeReceivedValue(value) {
64
+ if (value === void 0) return "undefined";
65
+ if (value === null) return "null";
66
+ if (typeof value === "string") {
67
+ return value.trim().length > 0 ? JSON.stringify(value) : "an empty string";
68
+ }
69
+ return `${typeof value} ${JSON.stringify(value)}`;
70
+ }
71
+ function invalidBaseUrlError(message, hint) {
72
+ return new AthenaGatewayError({
73
+ code: "INVALID_URL",
74
+ message,
75
+ status: 0,
76
+ hint
77
+ });
78
+ }
79
+ function normalizeAthenaGatewayBaseUrl(input, options = {}) {
80
+ const label = options.label ?? "Athena gateway base URL";
81
+ const candidate = input ?? options.defaultBaseUrl;
82
+ if (candidate === void 0 || candidate === null) {
83
+ throw invalidBaseUrlError(
84
+ `${label} must be a non-empty absolute http(s) URL. Received ${describeReceivedValue(input)}.`,
85
+ 'Set ATHENA_URL (or pass createClient(url, ...)) to a full URL such as "https://mirror3.athena-db.com".'
86
+ );
87
+ }
88
+ const trimmed = candidate.trim();
89
+ if (!trimmed) {
90
+ throw invalidBaseUrlError(
91
+ `${label} must be a non-empty absolute http(s) URL. Received ${describeReceivedValue(candidate)}.`,
92
+ 'Set ATHENA_URL (or pass createClient(url, ...)) to a full URL such as "https://mirror3.athena-db.com".'
93
+ );
94
+ }
95
+ let parsed;
96
+ try {
97
+ parsed = new URL(trimmed);
98
+ } catch {
99
+ throw invalidBaseUrlError(
100
+ `${label} must be a valid absolute http(s) URL. Received ${describeReceivedValue(candidate)}.`,
101
+ 'Use a full URL including the protocol, for example "https://mirror3.athena-db.com".'
102
+ );
103
+ }
104
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
105
+ throw invalidBaseUrlError(
106
+ `${label} must use http or https. Received ${JSON.stringify(trimmed)}.`,
107
+ 'Use an Athena gateway URL such as "https://mirror3.athena-db.com".'
108
+ );
109
+ }
110
+ if (parsed.search || parsed.hash) {
111
+ throw invalidBaseUrlError(
112
+ `${label} must not include query parameters or hash fragments. Received ${JSON.stringify(trimmed)}.`,
113
+ 'Pass only the base URL. Endpoint paths such as "/gateway/fetch" are appended by the SDK.'
114
+ );
115
+ }
116
+ return parsed.toString().replace(/\/+$/, "");
117
+ }
118
+ function buildAthenaGatewayUrl(baseUrl, path) {
119
+ if (!path.startsWith("/")) {
120
+ throw invalidBaseUrlError(
121
+ `Athena gateway path must start with "/". Received ${JSON.stringify(path)}.`,
122
+ 'Use a leading slash such as "/gateway/fetch" or "/".'
123
+ );
124
+ }
125
+ return `${baseUrl}${path}`;
126
+ }
127
+
61
128
  // src/gateway/client.ts
62
- var DEFAULT_BASE_URL = "https://athena-db.com";
63
129
  var DEFAULT_CLIENT = "railway_direct";
64
130
  var FALLBACK_SDK_VERSION = "1.3.0";
65
131
  var SDK_NAME = "xylex-group/athena";
@@ -256,9 +322,172 @@ function buildHeaders(config, options) {
256
322
  });
257
323
  return headers;
258
324
  }
325
+ function toInvalidUrlResponse(error, endpoint, method) {
326
+ const message = error instanceof Error ? error.message : String(error);
327
+ const gatewayError = error instanceof AthenaGatewayError ? error : new AthenaGatewayError({
328
+ code: "INVALID_URL",
329
+ message,
330
+ status: 0,
331
+ endpoint,
332
+ method,
333
+ cause: message,
334
+ hint: "Set ATHENA_URL to a full http(s) URL before running queries."
335
+ });
336
+ return {
337
+ ok: false,
338
+ status: 0,
339
+ statusText: null,
340
+ data: null,
341
+ error: gatewayError.message,
342
+ errorDetails: detailsFromError(
343
+ new AthenaGatewayError({
344
+ code: gatewayError.code,
345
+ message: gatewayError.message,
346
+ status: gatewayError.status,
347
+ endpoint,
348
+ method,
349
+ requestId: gatewayError.requestId,
350
+ hint: gatewayError.hint,
351
+ cause: gatewayError.causeDetail
352
+ })
353
+ ),
354
+ raw: null
355
+ };
356
+ }
357
+ function resolveGatewayBaseUrl(input) {
358
+ return normalizeAthenaGatewayBaseUrl(input, {
359
+ defaultBaseUrl: ATHENA_DEFAULT_BASE_URL
360
+ });
361
+ }
362
+ function resolveProbePath(path) {
363
+ if (!path) return "/";
364
+ if (!path.startsWith("/")) {
365
+ throw new AthenaGatewayError({
366
+ code: "INVALID_URL",
367
+ message: `Athena gateway probe path must start with "/". Received ${JSON.stringify(path)}.`,
368
+ status: 0,
369
+ hint: 'Use a leading slash such as "/" or "/health".'
370
+ });
371
+ }
372
+ return path;
373
+ }
374
+ function mergeConnectionHeaders(baseHeaders, headers) {
375
+ const merged = {
376
+ ...baseHeaders,
377
+ ...headers ?? {}
378
+ };
379
+ if (!merged["X-Athena-Sdk"] && !merged["x-athena-sdk"]) {
380
+ merged["X-Athena-Sdk"] = SDK_HEADER_VALUE;
381
+ }
382
+ return merged;
383
+ }
384
+ async function performConnectionCheck(baseUrl, requestHeaders, options) {
385
+ const path = resolveProbePath(options?.path);
386
+ const url = buildAthenaGatewayUrl(baseUrl, path);
387
+ try {
388
+ const response = await fetch(url, {
389
+ method: "GET",
390
+ headers: mergeConnectionHeaders(requestHeaders, options?.headers),
391
+ signal: options?.signal
392
+ });
393
+ const rawText = await response.text();
394
+ const requestId = resolveRequestId(response.headers);
395
+ const parsedBody = parseResponseBody(
396
+ rawText ?? "",
397
+ response.headers.get("content-type")
398
+ );
399
+ if (parsedBody.parseFailed) {
400
+ const invalidJsonError = new AthenaGatewayError({
401
+ code: "INVALID_JSON",
402
+ message: "Gateway probe returned malformed JSON",
403
+ status: response.status,
404
+ method: "GET",
405
+ requestId,
406
+ hint: "Verify the gateway response body is valid JSON.",
407
+ cause: rawText.slice(0, 300)
408
+ });
409
+ return {
410
+ ok: false,
411
+ reachable: true,
412
+ status: response.status,
413
+ statusText: resolveStatusText(response, parsedBody.parsed),
414
+ baseUrl,
415
+ url,
416
+ error: invalidJsonError.message,
417
+ errorDetails: detailsFromError(invalidJsonError),
418
+ raw: parsedBody.parsed
419
+ };
420
+ }
421
+ const parsed = parsedBody.parsed;
422
+ if (!response.ok) {
423
+ const httpError = new AthenaGatewayError({
424
+ code: "HTTP_ERROR",
425
+ message: resolveErrorMessage(
426
+ parsed,
427
+ `Athena gateway GET ${path} failed with status ${response.status}`
428
+ ),
429
+ status: response.status,
430
+ method: "GET",
431
+ requestId,
432
+ hint: resolveErrorHint(parsed)
433
+ });
434
+ return {
435
+ ok: false,
436
+ reachable: true,
437
+ status: response.status,
438
+ statusText: resolveStatusText(response, parsed),
439
+ baseUrl,
440
+ url,
441
+ error: httpError.message,
442
+ errorDetails: detailsFromError(httpError),
443
+ raw: parsed
444
+ };
445
+ }
446
+ return {
447
+ ok: true,
448
+ reachable: true,
449
+ status: response.status,
450
+ statusText: resolveStatusText(response, parsed),
451
+ baseUrl,
452
+ url,
453
+ error: void 0,
454
+ errorDetails: null,
455
+ raw: parsed
456
+ };
457
+ } catch (callError) {
458
+ const message = callError instanceof Error ? callError.message : String(callError);
459
+ const networkError = new AthenaGatewayError({
460
+ code: "NETWORK_ERROR",
461
+ message: `Network error while probing Athena gateway ${url}: ${message}`,
462
+ method: "GET",
463
+ cause: message,
464
+ hint: "Check gateway URL, DNS, and network reachability."
465
+ });
466
+ return {
467
+ ok: false,
468
+ reachable: false,
469
+ status: 0,
470
+ statusText: null,
471
+ baseUrl,
472
+ url,
473
+ error: networkError.message,
474
+ errorDetails: detailsFromError(networkError),
475
+ raw: null
476
+ };
477
+ }
478
+ }
479
+ async function verifyAthenaGatewayUrl(baseUrl, options) {
480
+ const normalizedBaseUrl = normalizeAthenaGatewayBaseUrl(baseUrl);
481
+ return performConnectionCheck(normalizedBaseUrl, { "X-Athena-Sdk": SDK_HEADER_VALUE }, options);
482
+ }
259
483
  async function callAthena(config, endpoint, method, payload, options) {
260
- const baseUrl = (options?.baseUrl ?? config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
261
- const url = `${baseUrl}${endpoint}`;
484
+ let baseUrl;
485
+ try {
486
+ baseUrl = resolveGatewayBaseUrl(options?.baseUrl ?? config.baseUrl);
487
+ } catch (error) {
488
+ return toInvalidUrlResponse(error, endpoint, method);
489
+ }
490
+ const url = buildAthenaGatewayUrl(baseUrl, endpoint);
262
491
  const headers = buildHeaders(config, options);
263
492
  try {
264
493
  const requestInit = {
@@ -355,32 +584,44 @@ async function callAthena(config, endpoint, method, payload, options) {
355
584
  }
356
585
  }
357
586
  function createAthenaGatewayClient(config = {}) {
587
+ const normalizedBaseUrl = resolveGatewayBaseUrl(config.baseUrl);
588
+ const normalizedConfig = {
589
+ ...config,
590
+ baseUrl: normalizedBaseUrl
591
+ };
358
592
  return {
359
- baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, ""),
593
+ baseUrl: normalizedBaseUrl,
360
594
  buildHeaders(options) {
361
- return buildHeaders(config, options);
595
+ return buildHeaders(normalizedConfig, options);
596
+ },
597
+ verifyConnection(options) {
598
+ return performConnectionCheck(
599
+ normalizedBaseUrl,
600
+ buildHeaders(normalizedConfig),
601
+ options
602
+ );
362
603
  },
363
604
  fetchGateway(payload, options) {
364
- return callAthena(config, "/gateway/fetch", "POST", payload, options);
605
+ return callAthena(normalizedConfig, "/gateway/fetch", "POST", payload, options);
365
606
  },
366
607
  insertGateway(payload, options) {
367
- return callAthena(config, "/gateway/insert", "PUT", payload, options);
608
+ return callAthena(normalizedConfig, "/gateway/insert", "PUT", payload, options);
368
609
  },
369
610
  updateGateway(payload, options) {
370
- return callAthena(config, "/gateway/update", "POST", payload, options);
611
+ return callAthena(normalizedConfig, "/gateway/update", "POST", payload, options);
371
612
  },
372
613
  deleteGateway(payload, options) {
373
- return callAthena(config, "/gateway/delete", "DELETE", payload, options);
614
+ return callAthena(normalizedConfig, "/gateway/delete", "DELETE", payload, options);
374
615
  },
375
616
  rpcGateway(payload, options) {
376
617
  if (options?.get) {
377
618
  const endpoint = buildRpcGetEndpoint(payload);
378
- return callAthena(config, endpoint, "GET", null, options);
619
+ return callAthena(normalizedConfig, endpoint, "GET", null, options);
379
620
  }
380
- return callAthena(config, "/gateway/rpc", "POST", payload, options);
621
+ return callAthena(normalizedConfig, "/gateway/rpc", "POST", payload, options);
381
622
  },
382
623
  queryGateway(payload, options) {
383
- return callAthena(config, "/gateway/query", "POST", payload, options);
624
+ return callAthena(normalizedConfig, "/gateway/query", "POST", payload, options);
384
625
  }
385
626
  };
386
627
  }
@@ -2022,6 +2263,7 @@ function classifyKind(status, code, message) {
2022
2263
  if (status === 404 || hasNotFoundPattern) return "not_found";
2023
2264
  if (status === 401 || status === 403 || hasAuthPattern) return "auth";
2024
2265
  if (status === 429 || hasRateLimitPattern) return "rate_limit";
2266
+ if (code === "INVALID_URL") return "validation";
2025
2267
  if (status === 400 || status === 422 || hasValidationPattern) return "validation";
2026
2268
  if (code === "NETWORK_ERROR" || status === 0 || status !== void 0 && status >= 500 || hasTransientPattern) {
2027
2269
  return "transient";
@@ -2029,6 +2271,9 @@ function classifyKind(status, code, message) {
2029
2271
  return "unknown";
2030
2272
  }
2031
2273
  function toAthenaErrorCode(kind, status, gatewayCode) {
2274
+ if (gatewayCode === "INVALID_URL") {
2275
+ return AthenaErrorCode.ValidationFailed;
2276
+ }
2032
2277
  if (gatewayCode === "NETWORK_ERROR" || kind === "transient" && status === 0) {
2033
2278
  return AthenaErrorCode.NetworkUnavailable;
2034
2279
  }
@@ -2377,8 +2622,8 @@ async function withRetry(config, fn) {
2377
2622
  // src/db/module.ts
2378
2623
  function createDbModule(input) {
2379
2624
  const db = {
2380
- from(table) {
2381
- return input.from(table);
2625
+ from(table, options) {
2626
+ return input.from(table, options);
2382
2627
  },
2383
2628
  select(table, columns, options) {
2384
2629
  return input.from(table).select(columns, options);
@@ -2483,7 +2728,19 @@ function buildGatewayCondition(operator, column, value) {
2483
2728
  function compileRelationToken(key, node) {
2484
2729
  const nested = compileSelectShape(node.select);
2485
2730
  const propertyKey = normalizeIdentifier(key, "select relation key");
2486
- const relationToken = normalizeIdentifier(node.via ?? propertyKey, "select relation token");
2731
+ if (node.schema && node.via) {
2732
+ throw new Error(
2733
+ `findMany relation "${propertyKey}" cannot combine schema and via yet; use schema with the relation key, or use via without schema`
2734
+ );
2735
+ }
2736
+ const relationTokenBase = normalizeIdentifier(node.via ?? propertyKey, "select relation token");
2737
+ if (node.schema && relationTokenBase.includes(".")) {
2738
+ throw new Error(
2739
+ `findMany relation "${propertyKey}" already resolves to a qualified relation token; do not also set schema`
2740
+ );
2741
+ }
2742
+ const relationSchema = node.schema?.trim();
2743
+ const relationToken = relationSchema ? `${normalizeIdentifier(relationSchema, "select relation schema")}.${relationTokenBase}` : relationTokenBase;
2487
2744
  const alias = node.as?.trim() || (relationToken !== propertyKey ? propertyKey : "");
2488
2745
  const prefix = alias ? `${alias}:` : "";
2489
2746
  return `${prefix}${relationToken}(${nested})`;
@@ -2512,6 +2769,23 @@ function compileSelectShape(select) {
2512
2769
  }
2513
2770
  return tokens.join(",");
2514
2771
  }
2772
+ function selectShapeUsesRelationSchema(select) {
2773
+ if (!isRecord5(select)) {
2774
+ return false;
2775
+ }
2776
+ for (const rawValue of Object.values(select)) {
2777
+ if (!isRelationSelectNode(rawValue)) {
2778
+ continue;
2779
+ }
2780
+ if (typeof rawValue.schema === "string" && rawValue.schema.trim().length > 0) {
2781
+ return true;
2782
+ }
2783
+ if (selectShapeUsesRelationSchema(rawValue.select)) {
2784
+ return true;
2785
+ }
2786
+ }
2787
+ return false;
2788
+ }
2515
2789
  function compileColumnWhere(column, input) {
2516
2790
  const normalizedColumn = normalizeIdentifier(column, "where column");
2517
2791
  if (!isRecord5(input)) {
@@ -2648,6 +2922,258 @@ function compileOrderBy(orderBy) {
2648
2922
  };
2649
2923
  }
2650
2924
 
2925
+ // src/gateway/structured-select.ts
2926
+ var IDENTIFIER_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
2927
+ function isIdentifierPath(value) {
2928
+ const segments = value.split(".").map((segment) => segment.trim());
2929
+ return segments.length > 1 && segments.every((segment) => IDENTIFIER_SEGMENT_PATTERN.test(segment));
2930
+ }
2931
+ function extractRelationHead(raw) {
2932
+ const trimmed = raw.trim();
2933
+ if (!trimmed) return "";
2934
+ const aliasIndex = trimmed.indexOf(":");
2935
+ const withoutAlias = aliasIndex >= 0 ? trimmed.slice(aliasIndex + 1).trim() : trimmed;
2936
+ const modifierIndex = withoutAlias.indexOf("!");
2937
+ return (modifierIndex >= 0 ? withoutAlias.slice(0, modifierIndex) : withoutAlias).trim();
2938
+ }
2939
+ function hasSchemaQualifiedRelationToken(select) {
2940
+ let singleQuoted = false;
2941
+ let doubleQuoted = false;
2942
+ let tokenStart = 0;
2943
+ for (let index = 0; index < select.length; index += 1) {
2944
+ const char = select[index];
2945
+ const next = index + 1 < select.length ? select[index + 1] : "";
2946
+ if (singleQuoted) {
2947
+ if (char === "'" && next === "'") {
2948
+ index += 1;
2949
+ continue;
2950
+ }
2951
+ if (char === "'") {
2952
+ singleQuoted = false;
2953
+ }
2954
+ continue;
2955
+ }
2956
+ if (doubleQuoted) {
2957
+ if (char === '"' && next === '"') {
2958
+ index += 1;
2959
+ continue;
2960
+ }
2961
+ if (char === '"') {
2962
+ doubleQuoted = false;
2963
+ }
2964
+ continue;
2965
+ }
2966
+ if (char === "'") {
2967
+ singleQuoted = true;
2968
+ continue;
2969
+ }
2970
+ if (char === '"') {
2971
+ doubleQuoted = true;
2972
+ continue;
2973
+ }
2974
+ if (char === "(") {
2975
+ const relationHead = extractRelationHead(select.slice(tokenStart, index));
2976
+ if (isIdentifierPath(relationHead)) {
2977
+ return true;
2978
+ }
2979
+ tokenStart = index + 1;
2980
+ continue;
2981
+ }
2982
+ if (char === "," || char === ")") {
2983
+ tokenStart = index + 1;
2984
+ }
2985
+ }
2986
+ return false;
2987
+ }
2988
+ function toStructuredSelectString(columns) {
2989
+ return Array.isArray(columns) ? columns.join(",") : columns;
2990
+ }
2991
+ function buildStructuredWhere(conditions) {
2992
+ if (!conditions?.length) return void 0;
2993
+ const where = {};
2994
+ for (const condition of conditions) {
2995
+ if (!condition.column) {
2996
+ return null;
2997
+ }
2998
+ if (condition.column_cast !== void 0 || condition.value_cast !== void 0) {
2999
+ return null;
3000
+ }
3001
+ const operand = condition.value;
3002
+ const operator = condition.operator;
3003
+ if (operator === "eq") {
3004
+ if (operand === void 0) return null;
3005
+ } else if (operator === "neq" || operator === "gt" || operator === "lt") {
3006
+ if (operand === void 0) return null;
3007
+ } else if (operator === "in") {
3008
+ if (!Array.isArray(operand)) return null;
3009
+ } else {
3010
+ return null;
3011
+ }
3012
+ const existing = where[condition.column];
3013
+ if (existing !== void 0 && (typeof existing !== "object" || existing === null || Array.isArray(existing))) {
3014
+ return null;
3015
+ }
3016
+ const next = existing ?? {};
3017
+ if (Object.prototype.hasOwnProperty.call(next, operator)) {
3018
+ return null;
3019
+ }
3020
+ next[operator] = operand;
3021
+ where[condition.column] = next;
3022
+ }
3023
+ return where;
3024
+ }
3025
+ function buildStructuredOrderBy(order) {
3026
+ if (!order?.field) return void 0;
3027
+ return {
3028
+ [order.field]: order.direction === "descending" ? "desc" : "asc"
3029
+ };
3030
+ }
3031
+ function buildStructuredSelectTransport(input) {
3032
+ const select = toStructuredSelectString(input.columns).trim();
3033
+ if (!select || select === "*") {
3034
+ return null;
3035
+ }
3036
+ if (!hasSchemaQualifiedRelationToken(select)) {
3037
+ return null;
3038
+ }
3039
+ if (input.count !== void 0 || input.head !== void 0) {
3040
+ return {
3041
+ error: "Schema-qualified nested select strings require structured select transport, which does not support count/head options in athena-js yet."
3042
+ };
3043
+ }
3044
+ const where = buildStructuredWhere(input.conditions);
3045
+ if (where === null) {
3046
+ return {
3047
+ error: "Schema-qualified nested select strings only support eq, neq, gt, lt, and in filters in athena-js structured select transport."
3048
+ };
3049
+ }
3050
+ return {
3051
+ select,
3052
+ payload: {
3053
+ table_name: input.tableName,
3054
+ select,
3055
+ where,
3056
+ orderBy: buildStructuredOrderBy(input.order),
3057
+ limit: input.limit,
3058
+ offset: input.offset,
3059
+ strip_nulls: input.stripNulls
3060
+ }
3061
+ };
3062
+ }
3063
+
3064
+ // src/query-transport.ts
3065
+ function canUseFindManyAstTransport(state) {
3066
+ return state.conditions.length === 0 && state.offset === void 0 && state.currentPage === void 0 && state.pageSize === void 0 && state.totalPages === void 0;
3067
+ }
3068
+ function toFindManyAstOrder(order) {
3069
+ if (!order) {
3070
+ return void 0;
3071
+ }
3072
+ return {
3073
+ column: order.field,
3074
+ ascending: order.direction !== "descending"
3075
+ };
3076
+ }
3077
+ function resolvePagination(input) {
3078
+ let limit = input.limit;
3079
+ let offset = input.offset;
3080
+ if (limit === void 0 && input.pageSize !== void 0) {
3081
+ limit = Math.max(0, Math.trunc(input.pageSize));
3082
+ }
3083
+ if (offset === void 0 && input.pageSize !== void 0 && input.currentPage !== void 0 && input.currentPage > 0) {
3084
+ offset = (Math.trunc(input.currentPage) - 1) * Math.max(0, Math.trunc(input.pageSize));
3085
+ }
3086
+ return { limit, offset };
3087
+ }
3088
+ function hasTypedEqualityComparison(conditions) {
3089
+ return conditions?.some(
3090
+ (condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
3091
+ ) ?? false;
3092
+ }
3093
+ function createSelectTransportPlan(input) {
3094
+ const conditions = input.state.conditions.length ? input.state.conditions.map((condition) => ({ ...condition })) : void 0;
3095
+ if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
3096
+ const query = input.buildTypedSelectQuery({
3097
+ tableName: input.tableName,
3098
+ columns: input.columns,
3099
+ conditions,
3100
+ limit: input.state.limit,
3101
+ offset: input.state.offset,
3102
+ currentPage: input.state.currentPage,
3103
+ pageSize: input.state.pageSize,
3104
+ order: input.state.order
3105
+ });
3106
+ if (query) {
3107
+ return {
3108
+ kind: "query",
3109
+ query,
3110
+ payload: { query }
3111
+ };
3112
+ }
3113
+ }
3114
+ const pagination = resolvePagination({
3115
+ limit: input.state.limit,
3116
+ offset: input.state.offset,
3117
+ currentPage: input.state.currentPage,
3118
+ pageSize: input.state.pageSize
3119
+ });
3120
+ const stripNulls = input.options?.stripNulls ?? true;
3121
+ const structuredSelectTransport = buildStructuredSelectTransport({
3122
+ tableName: input.tableName,
3123
+ columns: input.columns,
3124
+ conditions,
3125
+ limit: pagination.limit,
3126
+ offset: pagination.offset,
3127
+ order: input.state.order,
3128
+ stripNulls,
3129
+ count: input.options?.count,
3130
+ head: input.options?.head
3131
+ });
3132
+ if (structuredSelectTransport && "error" in structuredSelectTransport) {
3133
+ throw new Error(structuredSelectTransport.error);
3134
+ }
3135
+ if (structuredSelectTransport) {
3136
+ const { payload, select } = structuredSelectTransport;
3137
+ return {
3138
+ kind: "fetch",
3139
+ payload,
3140
+ debug: {
3141
+ columns: select,
3142
+ conditions,
3143
+ limit: pagination.limit,
3144
+ offset: pagination.offset,
3145
+ order: input.state.order
3146
+ }
3147
+ };
3148
+ }
3149
+ return {
3150
+ kind: "fetch",
3151
+ payload: {
3152
+ table_name: input.tableName,
3153
+ columns: input.columns,
3154
+ conditions,
3155
+ limit: input.state.limit,
3156
+ offset: input.state.offset,
3157
+ current_page: input.state.currentPage,
3158
+ page_size: input.state.pageSize,
3159
+ total_pages: input.state.totalPages,
3160
+ sort_by: input.state.order,
3161
+ strip_nulls: stripNulls,
3162
+ count: input.options?.count,
3163
+ head: input.options?.head
3164
+ },
3165
+ debug: {
3166
+ columns: input.columns,
3167
+ conditions,
3168
+ limit: input.state.limit,
3169
+ offset: input.state.offset,
3170
+ currentPage: input.state.currentPage,
3171
+ pageSize: input.state.pageSize,
3172
+ order: input.state.order
3173
+ }
3174
+ };
3175
+ }
3176
+
2651
3177
  // src/client.ts
2652
3178
  var DEFAULT_COLUMNS = "*";
2653
3179
  var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
@@ -2662,18 +3188,6 @@ var QUERY_TRACE_STACK_SKIP_PATTERNS = [
2662
3188
  "node:internal",
2663
3189
  "internal/process"
2664
3190
  ];
2665
- function canUseFindManyAstTransport(state) {
2666
- return state.conditions.length === 0 && state.offset === void 0 && state.currentPage === void 0 && state.pageSize === void 0 && state.totalPages === void 0;
2667
- }
2668
- function toFindManyAstOrder(order) {
2669
- if (!order) {
2670
- return void 0;
2671
- }
2672
- return {
2673
- column: order.field,
2674
- ascending: order.direction !== "descending"
2675
- };
2676
- }
2677
3191
  function formatResult(response) {
2678
3192
  const result = {
2679
3193
  data: response.data ?? null,
@@ -3219,17 +3733,6 @@ function conditionToDebugSqlClause(condition) {
3219
3733
  return `TRUE /* unsupported condition: ${rawCondition} */`;
3220
3734
  }
3221
3735
  }
3222
- function resolvePagination(input) {
3223
- let limit = input.limit;
3224
- let offset = input.offset;
3225
- if (limit === void 0 && input.pageSize !== void 0) {
3226
- limit = input.pageSize;
3227
- }
3228
- if (offset === void 0 && input.pageSize !== void 0 && input.currentPage !== void 0 && input.currentPage > 0) {
3229
- offset = (input.currentPage - 1) * input.pageSize;
3230
- }
3231
- return { limit, offset };
3232
- }
3233
3736
  function appendOrderLimitOffset(sqlParts, order, limit, offset) {
3234
3737
  if (order?.field) {
3235
3738
  const direction = order.direction === "descending" ? "DESC" : "ASC";
@@ -3733,64 +4236,34 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
3733
4236
  );
3734
4237
  const runSelect = async (columns = DEFAULT_COLUMNS, options, executionState = snapshotState(), callsite) => {
3735
4238
  const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
3736
- const conditions = executionState.conditions.length ? executionState.conditions.map((condition) => ({ ...condition })) : void 0;
3737
- const hasTypedEqualityComparison = conditions?.some(
3738
- (condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
3739
- ) ?? false;
3740
- if (hasTypedEqualityComparison && !options?.head && !options?.count && conditions) {
3741
- const query = buildTypedSelectQuery({
3742
- tableName: resolvedTableName,
3743
- columns,
3744
- conditions,
3745
- limit: executionState.limit,
3746
- offset: executionState.offset,
3747
- currentPage: executionState.currentPage,
3748
- pageSize: executionState.pageSize,
3749
- order: executionState.order
3750
- });
3751
- if (query) {
3752
- const payload2 = { query };
3753
- return executeWithQueryTrace(
3754
- tracer,
3755
- {
3756
- operation: "select",
3757
- endpoint: "/gateway/query",
3758
- table: resolvedTableName,
3759
- sql: query,
3760
- payload: payload2,
3761
- options
3762
- },
3763
- async () => {
3764
- const queryResponse = await client.queryGateway(payload2, options);
3765
- return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
3766
- },
3767
- callsite
3768
- );
3769
- }
3770
- }
3771
- const payload = {
3772
- table_name: resolvedTableName,
4239
+ const plan = createSelectTransportPlan({
4240
+ tableName: resolvedTableName,
3773
4241
  columns,
3774
- conditions,
3775
- limit: executionState.limit,
3776
- offset: executionState.offset,
3777
- current_page: executionState.currentPage,
3778
- page_size: executionState.pageSize,
3779
- total_pages: executionState.totalPages,
3780
- sort_by: executionState.order,
3781
- strip_nulls: options?.stripNulls ?? true,
3782
- count: options?.count,
3783
- head: options?.head
3784
- };
4242
+ state: executionState,
4243
+ options,
4244
+ buildTypedSelectQuery
4245
+ });
4246
+ if (plan.kind === "query") {
4247
+ return executeWithQueryTrace(
4248
+ tracer,
4249
+ {
4250
+ operation: "select",
4251
+ endpoint: "/gateway/query",
4252
+ table: resolvedTableName,
4253
+ sql: plan.query,
4254
+ payload: plan.payload,
4255
+ options
4256
+ },
4257
+ async () => {
4258
+ const queryResponse = await client.queryGateway(plan.payload, options);
4259
+ return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
4260
+ },
4261
+ callsite
4262
+ );
4263
+ }
3785
4264
  const sql = buildDebugSelectQuery({
3786
4265
  tableName: resolvedTableName,
3787
- columns,
3788
- conditions,
3789
- limit: executionState.limit,
3790
- offset: executionState.offset,
3791
- currentPage: executionState.currentPage,
3792
- pageSize: executionState.pageSize,
3793
- order: executionState.order
4266
+ ...plan.debug
3794
4267
  });
3795
4268
  return executeWithQueryTrace(
3796
4269
  tracer,
@@ -3799,11 +4272,11 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
3799
4272
  endpoint: "/gateway/fetch",
3800
4273
  table: resolvedTableName,
3801
4274
  sql,
3802
- payload,
4275
+ payload: plan.payload,
3803
4276
  options
3804
4277
  },
3805
4278
  async () => {
3806
- const response = await client.fetchGateway(payload, options);
4279
+ const response = await client.fetchGateway(plan.payload, options);
3807
4280
  return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
3808
4281
  },
3809
4282
  callsite
@@ -3876,7 +4349,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
3876
4349
  if (options.limit !== void 0) {
3877
4350
  executionState.limit = options.limit;
3878
4351
  }
3879
- if (experimental?.findManyAst && canUseFindManyAstTransport(baseState)) {
4352
+ if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select)) {
3880
4353
  const resolvedTableName = resolveTableNameForCall(tableName, void 0);
3881
4354
  const payload = {
3882
4355
  table_name: resolvedTableName,
@@ -4198,7 +4671,13 @@ function createClientFromConfig(config) {
4198
4671
  const formatGatewayResult = createResultFormatter(config.experimental);
4199
4672
  const queryTracer = createQueryTracer(config.experimental);
4200
4673
  const auth = createAuthClient(config.auth);
4201
- const from = (table) => createTableBuilder(table, gateway, formatGatewayResult, queryTracer, config.experimental);
4674
+ const from = (table, options) => createTableBuilder(
4675
+ resolveTableNameForCall(table, options?.schema),
4676
+ gateway,
4677
+ formatGatewayResult,
4678
+ queryTracer,
4679
+ config.experimental
4680
+ );
4202
4681
  const rpc = (fn, args, options) => {
4203
4682
  const normalizedFn = fn.trim();
4204
4683
  if (!normalizedFn) {
@@ -4221,6 +4700,7 @@ function createClientFromConfig(config) {
4221
4700
  db,
4222
4701
  rpc,
4223
4702
  query,
4703
+ verifyConnection: gateway.verifyConnection,
4224
4704
  auth: auth.auth
4225
4705
  };
4226
4706
  }
@@ -4464,8 +4944,8 @@ var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
4464
4944
  });
4465
4945
  this.db = this.baseClient.db;
4466
4946
  }
4467
- from(table) {
4468
- return this.baseClient.from(table);
4947
+ from(table, options) {
4948
+ return this.baseClient.from(table, options);
4469
4949
  }
4470
4950
  rpc(fn, args, options) {
4471
4951
  return this.baseClient.rpc(fn, args, options);
@@ -4473,6 +4953,9 @@ var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
4473
4953
  query(query, options) {
4474
4954
  return this.baseClient.query(query, options);
4475
4955
  }
4956
+ verifyConnection(options) {
4957
+ return this.baseClient.verifyConnection(options);
4958
+ }
4476
4959
  withTenantContext(context) {
4477
4960
  return new _TypedAthenaClientImpl({
4478
4961
  registry: this.registry,
@@ -4740,6 +5223,6 @@ async function runSchemaGenerator(options = {}) {
4740
5223
  return throwBrowserUnsupported("runSchemaGenerator");
4741
5224
  }
4742
5225
 
4743
- 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 };
5226
+ 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 };
4744
5227
  //# sourceMappingURL=browser.js.map
4745
5228
  //# sourceMappingURL=browser.js.map