@xylex-group/athena 3.0.2 → 3.1.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 (50) hide show
  1. package/README.md +1 -1
  2. package/dist/billing.cjs +1 -1
  3. package/dist/billing.cjs.map +1 -1
  4. package/dist/billing.js +1 -1
  5. package/dist/billing.js.map +1 -1
  6. package/dist/browser.cjs +322 -1
  7. package/dist/browser.cjs.map +1 -1
  8. package/dist/browser.d.cts +5 -5
  9. package/dist/browser.d.ts +5 -5
  10. package/dist/browser.js +301 -2
  11. package/dist/browser.js.map +1 -1
  12. package/dist/cli/index.cjs +5381 -3772
  13. package/dist/cli/index.cjs.map +1 -1
  14. package/dist/cli/index.d.cts +17 -10
  15. package/dist/cli/index.d.ts +17 -10
  16. package/dist/cli/index.js +5385 -3776
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/index.cjs +1723 -26
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +28 -6
  21. package/dist/index.d.ts +28 -6
  22. package/dist/index.js +1695 -28
  23. package/dist/index.js.map +1 -1
  24. package/dist/model-form-BbdzJ9Uh.d.ts +259 -0
  25. package/dist/model-form-BhWWsA-7.d.cts +259 -0
  26. package/dist/{module-CkUM6v58.d.ts → module-DKkJKOuJ.d.ts} +2 -2
  27. package/dist/{module-CB25egcO.d.cts → module-xFd7_Igv.d.cts} +2 -2
  28. package/dist/next/client.cjs +1 -1
  29. package/dist/next/client.cjs.map +1 -1
  30. package/dist/next/client.js +1 -1
  31. package/dist/next/client.js.map +1 -1
  32. package/dist/next/server.cjs +1 -1
  33. package/dist/next/server.cjs.map +1 -1
  34. package/dist/next/server.js +1 -1
  35. package/dist/next/server.js.map +1 -1
  36. package/dist/pipeline-DuKzYGia.d.cts +93 -0
  37. package/dist/pipeline-wer2G9xW.d.ts +93 -0
  38. package/dist/react.cjs +400 -3
  39. package/dist/react.cjs.map +1 -1
  40. package/dist/react.d.cts +67 -2
  41. package/dist/react.d.ts +67 -2
  42. package/dist/react.js +400 -4
  43. package/dist/react.js.map +1 -1
  44. package/dist/{types-BBm-kEBL.d.cts → types-1ztXDgPa.d.cts} +62 -2
  45. package/dist/{types-BaAMXCqK.d.ts → types-CccOiXPo.d.ts} +62 -2
  46. package/package.json +1 -1
  47. package/dist/model-form-Dh0sisdL.d.ts +0 -97
  48. package/dist/model-form-oOAJUVd4.d.cts +0 -97
  49. package/dist/pipeline-B8aN2EHe.d.ts +0 -8
  50. package/dist/pipeline-D4W-Cc-A.d.cts +0 -8
package/dist/react.d.cts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { u as AthenaGatewayHookConfig, v as AthenaGatewayHookResult } from './types-Bltx6iL6.cjs';
2
2
  export { w as AthenaDeletePayload, x as AthenaFetchPayload, a as AthenaGatewayCallOptions, d as AthenaGatewayErrorCode, e as AthenaGatewayErrorDetails, s as AthenaGatewayResponse, y as AthenaInsertPayload, f as AthenaJsonArray, g as AthenaJsonObject, h as AthenaJsonPrimitive, i as AthenaJsonValue, j as AthenaRpcCallOptions, k as AthenaRpcFilter, l as AthenaRpcFilterOperator, m as AthenaRpcOrder, n as AthenaRpcPayload, z as AthenaUpdatePayload } from './types-Bltx6iL6.cjs';
3
- export { A as AthenaGatewayError, M as ModelFormAdapter, a as ModelFormDefaults, b as ModelFormNullishMode, c as ModelFormValues, T as ToModelFormDefaultsOptions, d as ToModelPayloadOptions, e as createModelFormAdapter, i as isAthenaGatewayError, t as toModelFormDefaults, f as toModelPayload } from './model-form-oOAJUVd4.cjs';
3
+ import { a as AthenaReadQueryClient, c as AthenaReadQueryDefinition, e as AthenaReadQueryExecutionResult, i as AthenaReadQueryFlatRow } from './model-form-BhWWsA-7.cjs';
4
+ export { A as AthenaGatewayError, M as ModelFormAdapter, D as ModelFormDefaults, E as ModelFormNullishMode, G as ModelFormValues, T as ToModelFormDefaultsOptions, H as ToModelPayloadOptions, _ as createModelFormAdapter, a3 as isAthenaGatewayError, a6 as toModelFormDefaults, a7 as toModelPayload } from './model-form-BhWWsA-7.cjs';
4
5
  import * as react from 'react';
5
6
  import { ReactNode } from 'react';
6
7
  import { aE as AthenaAuthFetchCompatibleInput, E as AthenaAuthCallOptions, ad as AthenaAuthSessionResponse, R as AthenaAuthErrorDetails, aa as AthenaAuthResult } from './types-AOY-GLu8.cjs';
@@ -240,6 +241,70 @@ declare function useQuery<TQueryFnData, TData = TQueryFnData>(options: UseQueryO
240
241
 
241
242
  declare function useMutation<TVariables, TMutationFnData, TData = TMutationFnData>(options: UseMutationOptions<TVariables, TMutationFnData, TData>): UseMutationResult<TVariables, TData>;
242
243
 
244
+ interface UseAthenaReadQueryOptions {
245
+ /**
246
+ * v3 Athena client (`createClient(...)` or a `withContext` / session-scoped view).
247
+ * Required for fetches when `enabled` is true.
248
+ */
249
+ client?: AthenaReadQueryClient | null;
250
+ /** Portable definition (expression columns + aliases). */
251
+ query: AthenaReadQueryDefinition;
252
+ /** 1-based page (default 1). */
253
+ page?: number;
254
+ /** Page size (default 10). */
255
+ pageSize?: number;
256
+ enabled?: boolean;
257
+ /** Full cache key; when set, overrides the default key composition. */
258
+ queryKey?: QueryKey;
259
+ /** Prepended to the default key when `queryKey` is omitted. */
260
+ queryKeyPrefix?: QueryKey;
261
+ refetchOnMount?: boolean;
262
+ refetchOnWindowFocus?: boolean;
263
+ refetchOnReconnect?: boolean;
264
+ retry?: number | false;
265
+ }
266
+ interface UseAthenaReadQueryResult {
267
+ data: AthenaReadQueryExecutionResult | undefined;
268
+ rows: AthenaReadQueryFlatRow[];
269
+ totalItems: number;
270
+ debugAst: AthenaReadQueryExecutionResult['debugAst'];
271
+ page: number;
272
+ pageSize: number;
273
+ error: AthenaQueryError | null;
274
+ isLoading: boolean;
275
+ isFetching: boolean;
276
+ isSuccess: boolean;
277
+ isError: boolean;
278
+ status: QueryStatus;
279
+ refetch: () => Promise<unknown>;
280
+ reset: () => void;
281
+ }
282
+ /**
283
+ * Athena-native React hook for {@link AthenaReadQueryDefinition} page reads.
284
+ *
285
+ * Uses `@xylex-group/athena/react` `useQuery` + `AthenaQueryClient` (not TanStack).
286
+ * Does **not** construct clients, open a data proxy, or manage table UI pagination.
287
+ *
288
+ * For HeroUI tables / TanStack / `dataProxy`, use auth-ui `useAthenaQuery` instead.
289
+ *
290
+ * @example
291
+ * ```tsx
292
+ * const athena = createClient({ url, key })
293
+ * // under AthenaQueryClientProvider
294
+ * const { rows, totalItems, isLoading } = useAthenaReadQuery({
295
+ * client: athena,
296
+ * page: 1,
297
+ * pageSize: 20,
298
+ * query: {
299
+ * table: 'orders',
300
+ * countColumn: 'id',
301
+ * columns: [{ column: 'id', key: 'id' }],
302
+ * },
303
+ * })
304
+ * ```
305
+ */
306
+ declare function useAthenaReadQuery({ client, query, page, pageSize, enabled, queryKey, queryKeyPrefix, refetchOnMount, refetchOnWindowFocus, refetchOnReconnect, retry, }: UseAthenaReadQueryOptions): UseAthenaReadQueryResult;
307
+
243
308
  interface UseSessionOptions {
244
309
  enabled?: boolean;
245
310
  refetchOnMount?: boolean;
@@ -364,4 +429,4 @@ interface UseStorageFileDeleteResult {
364
429
  }
365
430
  declare function useStorageFileDelete(options: UseStorageFileDeleteOptions): UseStorageFileDeleteResult;
366
431
 
367
- export { type AthenaCacheMode, type AthenaCachePolicy, AthenaGatewayHookConfig, AthenaGatewayHookResult, type AthenaMutationDefaults, type AthenaMutationEvent, type AthenaMutationRequestLog, type AthenaMutationResultData, type AthenaMutationState, AthenaQueryClient, type AthenaQueryClientConfig, AthenaQueryClientProvider, type AthenaQueryDefaults, type AthenaQueryError, type AthenaQueryEvent, type AthenaQueryRequestLog, type AthenaQueryResult, type AthenaQueryState, type AthenaResponseLike, type AthenaRetryCount, type AthenaRetryDelay, type AthenaRuntimeBaseEvent, type AthenaRuntimeEvent, type AthenaRuntimeEventType, type AthenaStateAdapter, type AthenaUnsubscribe, type QueryKey, type QueryStatus, type UseAthenaSessionClientOptions, type UseAthenaSessionClientResult, type UseMutationOptions, type UseMutationResult, type UseQueryOptions, type UseQueryResult, type UseSessionAuthClient, type UseSessionOptions, type UseSessionResult, type UseStorageFileDeleteOptions, type UseStorageFileDeleteResult, type UseStorageFilesOptions, type UseStorageFilesResult, type UseStorageUploadInput, type UseStorageUploadOptions, type UseStorageUploadResult, attachStateAdapter, createAthenaQueryClient, useAthenaGateway, useAthenaQueryClient, useAthenaSessionClient, useMutation, useQuery, useSession, useStorageFileDelete, useStorageFiles, useStorageUpload };
432
+ export { type AthenaCacheMode, type AthenaCachePolicy, AthenaGatewayHookConfig, AthenaGatewayHookResult, type AthenaMutationDefaults, type AthenaMutationEvent, type AthenaMutationRequestLog, type AthenaMutationResultData, type AthenaMutationState, AthenaQueryClient, type AthenaQueryClientConfig, AthenaQueryClientProvider, type AthenaQueryDefaults, type AthenaQueryError, type AthenaQueryEvent, type AthenaQueryRequestLog, type AthenaQueryResult, type AthenaQueryState, type AthenaResponseLike, type AthenaRetryCount, type AthenaRetryDelay, type AthenaRuntimeBaseEvent, type AthenaRuntimeEvent, type AthenaRuntimeEventType, type AthenaStateAdapter, type AthenaUnsubscribe, type QueryKey, type QueryStatus, type UseAthenaReadQueryOptions, type UseAthenaReadQueryResult, type UseAthenaSessionClientOptions, type UseAthenaSessionClientResult, type UseMutationOptions, type UseMutationResult, type UseQueryOptions, type UseQueryResult, type UseSessionAuthClient, type UseSessionOptions, type UseSessionResult, type UseStorageFileDeleteOptions, type UseStorageFileDeleteResult, type UseStorageFilesOptions, type UseStorageFilesResult, type UseStorageUploadInput, type UseStorageUploadOptions, type UseStorageUploadResult, attachStateAdapter, createAthenaQueryClient, useAthenaGateway, useAthenaQueryClient, useAthenaReadQuery, useAthenaSessionClient, useMutation, useQuery, useSession, useStorageFileDelete, useStorageFiles, useStorageUpload };
package/dist/react.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { u as AthenaGatewayHookConfig, v as AthenaGatewayHookResult } from './types-Bltx6iL6.js';
2
2
  export { w as AthenaDeletePayload, x as AthenaFetchPayload, a as AthenaGatewayCallOptions, d as AthenaGatewayErrorCode, e as AthenaGatewayErrorDetails, s as AthenaGatewayResponse, y as AthenaInsertPayload, f as AthenaJsonArray, g as AthenaJsonObject, h as AthenaJsonPrimitive, i as AthenaJsonValue, j as AthenaRpcCallOptions, k as AthenaRpcFilter, l as AthenaRpcFilterOperator, m as AthenaRpcOrder, n as AthenaRpcPayload, z as AthenaUpdatePayload } from './types-Bltx6iL6.js';
3
- export { A as AthenaGatewayError, M as ModelFormAdapter, a as ModelFormDefaults, b as ModelFormNullishMode, c as ModelFormValues, T as ToModelFormDefaultsOptions, d as ToModelPayloadOptions, e as createModelFormAdapter, i as isAthenaGatewayError, t as toModelFormDefaults, f as toModelPayload } from './model-form-Dh0sisdL.js';
3
+ import { a as AthenaReadQueryClient, c as AthenaReadQueryDefinition, e as AthenaReadQueryExecutionResult, i as AthenaReadQueryFlatRow } from './model-form-BbdzJ9Uh.js';
4
+ export { A as AthenaGatewayError, M as ModelFormAdapter, D as ModelFormDefaults, E as ModelFormNullishMode, G as ModelFormValues, T as ToModelFormDefaultsOptions, H as ToModelPayloadOptions, _ as createModelFormAdapter, a3 as isAthenaGatewayError, a6 as toModelFormDefaults, a7 as toModelPayload } from './model-form-BbdzJ9Uh.js';
4
5
  import * as react from 'react';
5
6
  import { ReactNode } from 'react';
6
7
  import { aE as AthenaAuthFetchCompatibleInput, E as AthenaAuthCallOptions, ad as AthenaAuthSessionResponse, R as AthenaAuthErrorDetails, aa as AthenaAuthResult } from './types-AOY-GLu8.js';
@@ -240,6 +241,70 @@ declare function useQuery<TQueryFnData, TData = TQueryFnData>(options: UseQueryO
240
241
 
241
242
  declare function useMutation<TVariables, TMutationFnData, TData = TMutationFnData>(options: UseMutationOptions<TVariables, TMutationFnData, TData>): UseMutationResult<TVariables, TData>;
242
243
 
244
+ interface UseAthenaReadQueryOptions {
245
+ /**
246
+ * v3 Athena client (`createClient(...)` or a `withContext` / session-scoped view).
247
+ * Required for fetches when `enabled` is true.
248
+ */
249
+ client?: AthenaReadQueryClient | null;
250
+ /** Portable definition (expression columns + aliases). */
251
+ query: AthenaReadQueryDefinition;
252
+ /** 1-based page (default 1). */
253
+ page?: number;
254
+ /** Page size (default 10). */
255
+ pageSize?: number;
256
+ enabled?: boolean;
257
+ /** Full cache key; when set, overrides the default key composition. */
258
+ queryKey?: QueryKey;
259
+ /** Prepended to the default key when `queryKey` is omitted. */
260
+ queryKeyPrefix?: QueryKey;
261
+ refetchOnMount?: boolean;
262
+ refetchOnWindowFocus?: boolean;
263
+ refetchOnReconnect?: boolean;
264
+ retry?: number | false;
265
+ }
266
+ interface UseAthenaReadQueryResult {
267
+ data: AthenaReadQueryExecutionResult | undefined;
268
+ rows: AthenaReadQueryFlatRow[];
269
+ totalItems: number;
270
+ debugAst: AthenaReadQueryExecutionResult['debugAst'];
271
+ page: number;
272
+ pageSize: number;
273
+ error: AthenaQueryError | null;
274
+ isLoading: boolean;
275
+ isFetching: boolean;
276
+ isSuccess: boolean;
277
+ isError: boolean;
278
+ status: QueryStatus;
279
+ refetch: () => Promise<unknown>;
280
+ reset: () => void;
281
+ }
282
+ /**
283
+ * Athena-native React hook for {@link AthenaReadQueryDefinition} page reads.
284
+ *
285
+ * Uses `@xylex-group/athena/react` `useQuery` + `AthenaQueryClient` (not TanStack).
286
+ * Does **not** construct clients, open a data proxy, or manage table UI pagination.
287
+ *
288
+ * For HeroUI tables / TanStack / `dataProxy`, use auth-ui `useAthenaQuery` instead.
289
+ *
290
+ * @example
291
+ * ```tsx
292
+ * const athena = createClient({ url, key })
293
+ * // under AthenaQueryClientProvider
294
+ * const { rows, totalItems, isLoading } = useAthenaReadQuery({
295
+ * client: athena,
296
+ * page: 1,
297
+ * pageSize: 20,
298
+ * query: {
299
+ * table: 'orders',
300
+ * countColumn: 'id',
301
+ * columns: [{ column: 'id', key: 'id' }],
302
+ * },
303
+ * })
304
+ * ```
305
+ */
306
+ declare function useAthenaReadQuery({ client, query, page, pageSize, enabled, queryKey, queryKeyPrefix, refetchOnMount, refetchOnWindowFocus, refetchOnReconnect, retry, }: UseAthenaReadQueryOptions): UseAthenaReadQueryResult;
307
+
243
308
  interface UseSessionOptions {
244
309
  enabled?: boolean;
245
310
  refetchOnMount?: boolean;
@@ -364,4 +429,4 @@ interface UseStorageFileDeleteResult {
364
429
  }
365
430
  declare function useStorageFileDelete(options: UseStorageFileDeleteOptions): UseStorageFileDeleteResult;
366
431
 
367
- export { type AthenaCacheMode, type AthenaCachePolicy, AthenaGatewayHookConfig, AthenaGatewayHookResult, type AthenaMutationDefaults, type AthenaMutationEvent, type AthenaMutationRequestLog, type AthenaMutationResultData, type AthenaMutationState, AthenaQueryClient, type AthenaQueryClientConfig, AthenaQueryClientProvider, type AthenaQueryDefaults, type AthenaQueryError, type AthenaQueryEvent, type AthenaQueryRequestLog, type AthenaQueryResult, type AthenaQueryState, type AthenaResponseLike, type AthenaRetryCount, type AthenaRetryDelay, type AthenaRuntimeBaseEvent, type AthenaRuntimeEvent, type AthenaRuntimeEventType, type AthenaStateAdapter, type AthenaUnsubscribe, type QueryKey, type QueryStatus, type UseAthenaSessionClientOptions, type UseAthenaSessionClientResult, type UseMutationOptions, type UseMutationResult, type UseQueryOptions, type UseQueryResult, type UseSessionAuthClient, type UseSessionOptions, type UseSessionResult, type UseStorageFileDeleteOptions, type UseStorageFileDeleteResult, type UseStorageFilesOptions, type UseStorageFilesResult, type UseStorageUploadInput, type UseStorageUploadOptions, type UseStorageUploadResult, attachStateAdapter, createAthenaQueryClient, useAthenaGateway, useAthenaQueryClient, useAthenaSessionClient, useMutation, useQuery, useSession, useStorageFileDelete, useStorageFiles, useStorageUpload };
432
+ export { type AthenaCacheMode, type AthenaCachePolicy, AthenaGatewayHookConfig, AthenaGatewayHookResult, type AthenaMutationDefaults, type AthenaMutationEvent, type AthenaMutationRequestLog, type AthenaMutationResultData, type AthenaMutationState, AthenaQueryClient, type AthenaQueryClientConfig, AthenaQueryClientProvider, type AthenaQueryDefaults, type AthenaQueryError, type AthenaQueryEvent, type AthenaQueryRequestLog, type AthenaQueryResult, type AthenaQueryState, type AthenaResponseLike, type AthenaRetryCount, type AthenaRetryDelay, type AthenaRuntimeBaseEvent, type AthenaRuntimeEvent, type AthenaRuntimeEventType, type AthenaStateAdapter, type AthenaUnsubscribe, type QueryKey, type QueryStatus, type UseAthenaReadQueryOptions, type UseAthenaReadQueryResult, type UseAthenaSessionClientOptions, type UseAthenaSessionClientResult, type UseMutationOptions, type UseMutationResult, type UseQueryOptions, type UseQueryResult, type UseSessionAuthClient, type UseSessionOptions, type UseSessionResult, type UseStorageFileDeleteOptions, type UseStorageFileDeleteResult, type UseStorageFilesOptions, type UseStorageFilesResult, type UseStorageUploadInput, type UseStorageUploadOptions, type UseStorageUploadResult, attachStateAdapter, createAthenaQueryClient, useAthenaGateway, useAthenaQueryClient, useAthenaReadQuery, useAthenaSessionClient, useMutation, useQuery, useSession, useStorageFileDelete, useStorageFiles, useStorageUpload };
package/dist/react.js CHANGED
@@ -392,7 +392,7 @@ function buildAthenaRequestHeaders(input) {
392
392
 
393
393
  // package.json
394
394
  var package_default = {
395
- version: "3.0.2"
395
+ version: "3.1.0"
396
396
  };
397
397
 
398
398
  // src/sdk-version.ts
@@ -1976,6 +1976,402 @@ function useMutation(options) {
1976
1976
  lastRequest: snapshot.lastRequest
1977
1977
  };
1978
1978
  }
1979
+
1980
+ // src/query-debug-ast.ts
1981
+ var ATHENA_DEBUG_AST_KEY = "__athenaDebugAst";
1982
+ function getAthenaDebugAst(value) {
1983
+ if (!value || typeof value !== "object" && typeof value !== "function") {
1984
+ return null;
1985
+ }
1986
+ return value[ATHENA_DEBUG_AST_KEY] ?? null;
1987
+ }
1988
+
1989
+ // src/query/read-query.ts
1990
+ function normalizeAthenaReadQueryOrderBy(orderBy) {
1991
+ if (!orderBy) {
1992
+ return [];
1993
+ }
1994
+ const list = Array.isArray(orderBy) ? orderBy : [orderBy];
1995
+ return list.filter(
1996
+ (entry) => entry && typeof entry.column === "string" && entry.column.trim().length > 0
1997
+ );
1998
+ }
1999
+ function isRecord3(value) {
2000
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2001
+ }
2002
+ function flattenAthenaRowValue(row, column) {
2003
+ if (!column.relation) {
2004
+ return row[column.column];
2005
+ }
2006
+ const relationValue = row[column.relation.name];
2007
+ if (Array.isArray(relationValue)) {
2008
+ return relationValue.map((entry) => isRecord3(entry) ? entry[column.column] : void 0).filter((entry) => entry !== void 0);
2009
+ }
2010
+ if (isRecord3(relationValue)) {
2011
+ return relationValue[column.column];
2012
+ }
2013
+ return void 0;
2014
+ }
2015
+ function resolveFlatRowKey(row, index, preferredKey) {
2016
+ const preferredValue = preferredKey && preferredKey in row ? row[preferredKey] : void 0;
2017
+ if (preferredValue !== void 0 && preferredValue !== null && `${preferredValue}`.trim().length > 0) {
2018
+ return String(preferredValue);
2019
+ }
2020
+ for (const [key, value] of Object.entries(row)) {
2021
+ if (key === "__rowKey") {
2022
+ continue;
2023
+ }
2024
+ if (value === void 0 || value === null) {
2025
+ continue;
2026
+ }
2027
+ if (Array.isArray(value)) {
2028
+ if (value.length > 0) {
2029
+ return `${key}-${value.join("-")}`;
2030
+ }
2031
+ continue;
2032
+ }
2033
+ const nextValue = String(value).trim();
2034
+ if (nextValue.length > 0) {
2035
+ return nextValue;
2036
+ }
2037
+ }
2038
+ return `row-${index + 1}`;
2039
+ }
2040
+ function flattenAthenaReadQueryRows(rows, columns, preferredKey) {
2041
+ return rows.map((entry, index) => {
2042
+ const sourceRow = isRecord3(entry) ? entry : {};
2043
+ const flatRow = columns.reduce(
2044
+ (currentRow, column) => {
2045
+ currentRow[column.key] = flattenAthenaRowValue(sourceRow, column);
2046
+ return currentRow;
2047
+ },
2048
+ { __rowKey: "" }
2049
+ );
2050
+ flatRow.__rowKey = resolveFlatRowKey(flatRow, index, preferredKey);
2051
+ return flatRow;
2052
+ });
2053
+ }
2054
+ function buildAthenaReadQuerySelectString(columns) {
2055
+ const baseColumns = columns.filter((column) => !column.relation).map((column) => column.column);
2056
+ const relationGroups = /* @__PURE__ */ new Map();
2057
+ for (const column of columns) {
2058
+ if (!column.relation) {
2059
+ continue;
2060
+ }
2061
+ const groupKey = [
2062
+ column.relation.name,
2063
+ column.relation.schema ?? "",
2064
+ column.relation.table
2065
+ ].join(":");
2066
+ const existingGroup = relationGroups.get(groupKey);
2067
+ if (existingGroup) {
2068
+ if (!existingGroup.columns.includes(column.column)) {
2069
+ existingGroup.columns.push(column.column);
2070
+ }
2071
+ continue;
2072
+ }
2073
+ relationGroups.set(groupKey, {
2074
+ columns: [column.column],
2075
+ relation: column.relation
2076
+ });
2077
+ }
2078
+ const relationColumns = [...relationGroups.values()].map(
2079
+ ({ columns: relationColumns2, relation }) => {
2080
+ const relationTarget = relation.schema ? `${relation.schema}.${relation.table}` : relation.table;
2081
+ return `${relation.name}:${relationTarget}(${relationColumns2.join(",")})`;
2082
+ }
2083
+ );
2084
+ return [...baseColumns, ...relationColumns].join(",");
2085
+ }
2086
+ function buildAthenaReadQueryFindManySelect(columns) {
2087
+ const select = {};
2088
+ for (const column of columns) {
2089
+ if (!column.relation) {
2090
+ select[column.column] = true;
2091
+ continue;
2092
+ }
2093
+ const existingRelation = select[column.relation.name];
2094
+ if (existingRelation && existingRelation !== true && isRecord3(existingRelation.select)) {
2095
+ existingRelation.select[column.column] = true;
2096
+ continue;
2097
+ }
2098
+ select[column.relation.name] = {
2099
+ ...column.relation.schema ? { schema: column.relation.schema } : {},
2100
+ select: {
2101
+ [column.column]: true
2102
+ }
2103
+ };
2104
+ }
2105
+ return select;
2106
+ }
2107
+ function buildAthenaReadQueryFindManyWhere(filters) {
2108
+ if (!filters?.length) {
2109
+ return;
2110
+ }
2111
+ return filters.reduce(
2112
+ (where, filter) => {
2113
+ const operator = filter.operator ?? "eq";
2114
+ where[filter.column] = operator === "eq" ? filter.value : { [operator]: filter.value };
2115
+ return where;
2116
+ },
2117
+ {}
2118
+ );
2119
+ }
2120
+ function buildAthenaReadQueryFindManyOrderBy(orderBy) {
2121
+ const normalized = normalizeAthenaReadQueryOrderBy(orderBy);
2122
+ if (normalized.length === 0) {
2123
+ return;
2124
+ }
2125
+ if (normalized.length === 1) {
2126
+ const primary = normalized[0];
2127
+ if (!primary) {
2128
+ return;
2129
+ }
2130
+ return {
2131
+ ascending: primary.direction !== "desc",
2132
+ column: primary.column
2133
+ };
2134
+ }
2135
+ return Object.fromEntries(
2136
+ normalized.map((entry) => [
2137
+ entry.column,
2138
+ entry.direction === "desc" ? "desc" : "asc"
2139
+ ])
2140
+ );
2141
+ }
2142
+ function applyAthenaReadQueryFilters(queryBuilder, filters) {
2143
+ if (!filters?.length) {
2144
+ return queryBuilder;
2145
+ }
2146
+ return filters.reduce((currentBuilder, filter) => {
2147
+ const operator = filter.operator ?? "eq";
2148
+ const builderMethod = currentBuilder[operator];
2149
+ if (typeof builderMethod !== "function") {
2150
+ return currentBuilder;
2151
+ }
2152
+ return builderMethod.call(currentBuilder, filter.column, filter.value);
2153
+ }, queryBuilder);
2154
+ }
2155
+ function applyAthenaReadQuerySelectOrder(queryBuilder, orderBy) {
2156
+ const normalized = normalizeAthenaReadQueryOrderBy(orderBy);
2157
+ if (normalized.length === 0) {
2158
+ return queryBuilder;
2159
+ }
2160
+ return normalized.reduce(
2161
+ (builder, entry) => builder.order(entry.column, {
2162
+ ascending: entry.direction !== "desc"
2163
+ }),
2164
+ queryBuilder
2165
+ );
2166
+ }
2167
+ function applyAthenaReadQuerySelectLimit(queryBuilder, limit) {
2168
+ if (!limit || limit < 1) {
2169
+ return queryBuilder;
2170
+ }
2171
+ return queryBuilder.limit(limit);
2172
+ }
2173
+ function clampAthenaReadQueryTotalItems(totalItems, limit) {
2174
+ if (!limit || limit < 1) {
2175
+ return totalItems;
2176
+ }
2177
+ return Math.min(totalItems, limit);
2178
+ }
2179
+ function resolveCountValue(...candidates) {
2180
+ for (const candidate of candidates) {
2181
+ if (typeof candidate === "number" && Number.isFinite(candidate)) {
2182
+ return Math.max(0, Math.trunc(candidate));
2183
+ }
2184
+ }
2185
+ return 0;
2186
+ }
2187
+ function resolveTotalItemsFromPage({
2188
+ countCandidates,
2189
+ limit,
2190
+ page,
2191
+ pageSize,
2192
+ rowCount
2193
+ }) {
2194
+ const exactCount = resolveCountValue(...countCandidates);
2195
+ if (exactCount > 0) {
2196
+ return clampAthenaReadQueryTotalItems(exactCount, limit);
2197
+ }
2198
+ if (rowCount > 0) {
2199
+ const base = (page - 1) * pageSize + rowCount;
2200
+ const synthetic = rowCount >= pageSize ? base + 1 : base;
2201
+ return clampAthenaReadQueryTotalItems(synthetic, limit);
2202
+ }
2203
+ return clampAthenaReadQueryTotalItems(exactCount, limit);
2204
+ }
2205
+ async function executeAthenaReadQuery({
2206
+ client,
2207
+ page,
2208
+ pageSize,
2209
+ query
2210
+ }) {
2211
+ const db = client.db;
2212
+ const baseBuilder = db.from(query.table, {
2213
+ schema: query.schema
2214
+ });
2215
+ const countBuilder = applyAthenaReadQueryFilters(
2216
+ db.from(query.table, { schema: query.schema }),
2217
+ query.filters
2218
+ );
2219
+ const countResult = await countBuilder.select(query.countColumn, {
2220
+ count: "exact",
2221
+ head: true
2222
+ });
2223
+ if ((query.mode ?? "findMany") === "select") {
2224
+ const selectBuilder = applyAthenaReadQuerySelectLimit(
2225
+ applyAthenaReadQuerySelectOrder(
2226
+ applyAthenaReadQueryFilters(baseBuilder, query.filters),
2227
+ query.orderBy
2228
+ ),
2229
+ query.limit
2230
+ );
2231
+ const result2 = await selectBuilder.currentPage(page).pageSize(pageSize).select(buildAthenaReadQuerySelectString(query.columns), {
2232
+ count: "exact"
2233
+ });
2234
+ const rows2 = flattenAthenaReadQueryRows(
2235
+ Array.isArray(result2.data) ? result2.data : [],
2236
+ query.columns,
2237
+ query.rowKey
2238
+ );
2239
+ return {
2240
+ debugAst: getAthenaDebugAst(result2) ?? void 0,
2241
+ rows: rows2,
2242
+ totalItems: resolveTotalItemsFromPage({
2243
+ countCandidates: [countResult.count, result2.count],
2244
+ limit: query.limit,
2245
+ page,
2246
+ pageSize,
2247
+ rowCount: rows2.length
2248
+ })
2249
+ };
2250
+ }
2251
+ const findManyOrderBy = buildAthenaReadQueryFindManyOrderBy(query.orderBy);
2252
+ const findManyOptions = {
2253
+ ...query.limit ? { limit: query.limit } : {},
2254
+ ...findManyOrderBy ? { orderBy: findManyOrderBy } : {},
2255
+ select: buildAthenaReadQueryFindManySelect(query.columns),
2256
+ ...query.filters?.length ? { where: buildAthenaReadQueryFindManyWhere(query.filters) } : {}
2257
+ };
2258
+ const result = await baseBuilder.currentPage(page).pageSize(pageSize).findMany(findManyOptions);
2259
+ const rows = flattenAthenaReadQueryRows(
2260
+ Array.isArray(result.data) ? result.data : [],
2261
+ query.columns,
2262
+ query.rowKey
2263
+ );
2264
+ return {
2265
+ debugAst: getAthenaDebugAst(result) ?? void 0,
2266
+ rows,
2267
+ totalItems: resolveTotalItemsFromPage({
2268
+ countCandidates: [countResult.count, result.count],
2269
+ limit: query.limit,
2270
+ page,
2271
+ pageSize,
2272
+ rowCount: rows.length
2273
+ })
2274
+ };
2275
+ }
2276
+
2277
+ // src/react/use-athena-read-query.ts
2278
+ var DEFAULT_PAGE = 1;
2279
+ var DEFAULT_PAGE_SIZE = 10;
2280
+ function isReadQueryRunnable(query) {
2281
+ return query.table.trim().length > 0 && query.columns.length > 0 && query.countColumn.trim().length > 0;
2282
+ }
2283
+ function useAthenaReadQuery({
2284
+ client,
2285
+ query,
2286
+ page = DEFAULT_PAGE,
2287
+ pageSize = DEFAULT_PAGE_SIZE,
2288
+ enabled = true,
2289
+ queryKey,
2290
+ queryKeyPrefix,
2291
+ refetchOnMount,
2292
+ refetchOnWindowFocus,
2293
+ refetchOnReconnect,
2294
+ retry
2295
+ }) {
2296
+ const resolvedPage = page > 0 ? Math.trunc(page) : DEFAULT_PAGE;
2297
+ const resolvedPageSize = pageSize > 0 ? Math.trunc(pageSize) : DEFAULT_PAGE_SIZE;
2298
+ const queryEnabled = enabled && !!client && isReadQueryRunnable(query);
2299
+ const defaultQueryKey = useMemo(
2300
+ () => [
2301
+ "athena",
2302
+ "read-query",
2303
+ query.mode ?? "findMany",
2304
+ query.table,
2305
+ query.schema,
2306
+ query.columns,
2307
+ query.filters,
2308
+ query.limit,
2309
+ query.orderBy,
2310
+ query.rowKey,
2311
+ query.countColumn,
2312
+ resolvedPage,
2313
+ resolvedPageSize
2314
+ ],
2315
+ [
2316
+ query.columns,
2317
+ query.countColumn,
2318
+ query.filters,
2319
+ query.limit,
2320
+ query.mode,
2321
+ query.orderBy,
2322
+ query.rowKey,
2323
+ query.schema,
2324
+ query.table,
2325
+ resolvedPage,
2326
+ resolvedPageSize
2327
+ ]
2328
+ );
2329
+ const resolvedQueryKey = useMemo(() => {
2330
+ if (queryKey !== void 0) {
2331
+ return queryKey;
2332
+ }
2333
+ if (queryKeyPrefix !== void 0) {
2334
+ const prefix = Array.isArray(queryKeyPrefix) ? queryKeyPrefix : [queryKeyPrefix];
2335
+ return [...prefix, ...defaultQueryKey];
2336
+ }
2337
+ return defaultQueryKey;
2338
+ }, [defaultQueryKey, queryKey, queryKeyPrefix]);
2339
+ const result = useQuery({
2340
+ enabled: queryEnabled,
2341
+ queryKey: resolvedQueryKey,
2342
+ queryFn: async () => {
2343
+ if (!client) {
2344
+ throw new Error("Athena client is required to run the read query.");
2345
+ }
2346
+ return executeAthenaReadQuery({
2347
+ client,
2348
+ page: resolvedPage,
2349
+ pageSize: resolvedPageSize,
2350
+ query
2351
+ });
2352
+ },
2353
+ refetchOnMount,
2354
+ refetchOnWindowFocus,
2355
+ refetchOnReconnect,
2356
+ retry
2357
+ });
2358
+ return {
2359
+ data: result.data,
2360
+ rows: result.data?.rows ?? [],
2361
+ totalItems: result.data?.totalItems ?? 0,
2362
+ debugAst: result.data?.debugAst,
2363
+ page: resolvedPage,
2364
+ pageSize: resolvedPageSize,
2365
+ error: result.error,
2366
+ isLoading: result.isLoading,
2367
+ isFetching: result.isFetching,
2368
+ isSuccess: result.isSuccess,
2369
+ isError: result.isError,
2370
+ status: result.status,
2371
+ refetch: result.refetch,
2372
+ reset: result.reset
2373
+ };
2374
+ }
1979
2375
  function resolveGetSession(authClient) {
1980
2376
  if ("getSession" in authClient && typeof authClient.getSession === "function") {
1981
2377
  return authClient.getSession;
@@ -2270,7 +2666,7 @@ function resolveNullishValue(mode) {
2270
2666
  if (mode === "null") return null;
2271
2667
  return "";
2272
2668
  }
2273
- function isRecord3(value) {
2669
+ function isRecord4(value) {
2274
2670
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2275
2671
  }
2276
2672
  function isNullableColumn(model, key) {
@@ -2279,7 +2675,7 @@ function isNullableColumn(model, key) {
2279
2675
  }
2280
2676
  function toModelFormDefaults(model, values, options) {
2281
2677
  const source = values;
2282
- if (!isRecord3(source)) {
2678
+ if (!isRecord4(source)) {
2283
2679
  return {};
2284
2680
  }
2285
2681
  const mode = options?.nullishMode ?? "empty-string";
@@ -2325,6 +2721,6 @@ function createModelFormAdapter(model) {
2325
2721
  };
2326
2722
  }
2327
2723
 
2328
- export { AthenaGatewayError, AthenaQueryClient, AthenaQueryClientProvider, attachStateAdapter, createAthenaQueryClient, createModelFormAdapter, isAthenaGatewayError, toModelFormDefaults, toModelPayload, useAthenaGateway, useAthenaQueryClient, useAthenaSessionClient, useMutation, useQuery, useSession, useStorageFileDelete, useStorageFiles, useStorageUpload };
2724
+ export { AthenaGatewayError, AthenaQueryClient, AthenaQueryClientProvider, attachStateAdapter, createAthenaQueryClient, createModelFormAdapter, isAthenaGatewayError, toModelFormDefaults, toModelPayload, useAthenaGateway, useAthenaQueryClient, useAthenaReadQuery, useAthenaSessionClient, useMutation, useQuery, useSession, useStorageFileDelete, useStorageFiles, useStorageUpload };
2329
2725
  //# sourceMappingURL=react.js.map
2330
2726
  //# sourceMappingURL=react.js.map