@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
@@ -0,0 +1,93 @@
1
+ import { b as GeneratorProviderConfig, a as LoadedGeneratorConfig, R as RunGeneratorOptions, d as RunGeneratorResult } from './types-1ztXDgPa.cjs';
2
+
3
+ type GeneratorConfigFileAction = 'created' | 'updated' | 'unchanged' | 'skipped';
4
+ type GeneratorConfigProviderMode = 'direct' | 'gateway' | 'auto';
5
+ interface EnsureGeneratorConfigFileOptions {
6
+ cwd?: string;
7
+ /** Explicit path relative to cwd or absolute. Defaults to discovered path or `athena.config.ts`. */
8
+ configPath?: string;
9
+ /** Provider mode preference when creating a new file. */
10
+ mode?: GeneratorConfigProviderMode;
11
+ /**
12
+ * Discover live schemas and auto-fill `provider.schemas`.
13
+ * Defaults to true.
14
+ */
15
+ discoverSchemas?: boolean;
16
+ /**
17
+ * When false, never write to disk (report would-be action only).
18
+ * Defaults to false.
19
+ */
20
+ dryRun?: boolean;
21
+ /**
22
+ * When true, rewrite the full modern template even if a file already exists.
23
+ * Defaults to false (intelligent surgical update only).
24
+ */
25
+ force?: boolean;
26
+ /**
27
+ * Pre-resolved provider used for schema discovery (avoids re-normalizing).
28
+ */
29
+ provider?: GeneratorProviderConfig;
30
+ /**
31
+ * Optional pre-loaded config (skips a second disk load).
32
+ */
33
+ loaded?: LoadedGeneratorConfig;
34
+ /**
35
+ * Explicit schemas to write when discovery is disabled or fails.
36
+ */
37
+ schemas?: readonly string[];
38
+ }
39
+ interface EnsureGeneratorConfigFileResult {
40
+ action: GeneratorConfigFileAction;
41
+ path: string;
42
+ absolutePath: string;
43
+ content?: string;
44
+ schemas: string[];
45
+ changes: string[];
46
+ mode: 'direct' | 'gateway';
47
+ reason?: string;
48
+ }
49
+ type DetectedMode = 'direct' | 'gateway';
50
+ /**
51
+ * Picks a provider mode from env when the caller did not force one.
52
+ * Prefers direct when a connection string is present; otherwise gateway.
53
+ */
54
+ declare function detectGeneratorProviderMode(preferred?: GeneratorConfigProviderMode): DetectedMode;
55
+ /**
56
+ * Renders a modern, typed `athena.config.ts` using `defineGeneratorConfig` + `generatorEnv`.
57
+ * Secrets stay env-backed so gateway and direct modes both work without hardcoding keys.
58
+ */
59
+ declare function renderGeneratorConfigFile(options: {
60
+ mode: DetectedMode;
61
+ schemas?: readonly string[];
62
+ }): string;
63
+ /**
64
+ * Updates only the `schemas:` value inside an existing TypeScript config source.
65
+ * Supports:
66
+ * - `schemas: ["public", "athena"]`
67
+ * - `schemas: generatorEnv.list("...", { default: ["public"] })`
68
+ *
69
+ * Returns undefined when the file cannot be updated surgically (caller may full-render).
70
+ */
71
+ declare function patchSchemasInConfigSource(source: string, schemas: readonly string[]): string | undefined;
72
+ /**
73
+ * Creates or intelligently updates `athena.config.ts`.
74
+ *
75
+ * Intelligence rules:
76
+ * - missing file → write modern direct/gateway template with env-backed secrets
77
+ * - existing file + force → full rewrite
78
+ * - existing file → only patch `provider.schemas` when auto-fill finds new values
79
+ * - skip write when content/schemas already match (no churn, safe for typecheck CI)
80
+ * - never removes user-listed schemas that discovery did not return
81
+ * - gateway mode uses the same template surface as direct (generatorEnv for url/key)
82
+ */
83
+ declare function ensureGeneratorConfigFile(options?: EnsureGeneratorConfigFileOptions): Promise<EnsureGeneratorConfigFileResult>;
84
+
85
+ /**
86
+ * End-to-end generator execution: load config, introspect, render, and optionally write files.
87
+ *
88
+ * When `writeConfig` is enabled (default), also ensures `athena.config.ts` exists and
89
+ * auto-fills discovered schemas without clobbering custom config fields.
90
+ */
91
+ declare function runSchemaGenerator(options?: RunGeneratorOptions): Promise<RunGeneratorResult>;
92
+
93
+ export { type EnsureGeneratorConfigFileOptions as E, type GeneratorConfigFileAction as G, type EnsureGeneratorConfigFileResult as a, type GeneratorConfigProviderMode as b, renderGeneratorConfigFile as c, detectGeneratorProviderMode as d, ensureGeneratorConfigFile as e, patchSchemasInConfigSource as p, runSchemaGenerator as r };
@@ -0,0 +1,93 @@
1
+ import { b as GeneratorProviderConfig, a as LoadedGeneratorConfig, R as RunGeneratorOptions, d as RunGeneratorResult } from './types-CccOiXPo.js';
2
+
3
+ type GeneratorConfigFileAction = 'created' | 'updated' | 'unchanged' | 'skipped';
4
+ type GeneratorConfigProviderMode = 'direct' | 'gateway' | 'auto';
5
+ interface EnsureGeneratorConfigFileOptions {
6
+ cwd?: string;
7
+ /** Explicit path relative to cwd or absolute. Defaults to discovered path or `athena.config.ts`. */
8
+ configPath?: string;
9
+ /** Provider mode preference when creating a new file. */
10
+ mode?: GeneratorConfigProviderMode;
11
+ /**
12
+ * Discover live schemas and auto-fill `provider.schemas`.
13
+ * Defaults to true.
14
+ */
15
+ discoverSchemas?: boolean;
16
+ /**
17
+ * When false, never write to disk (report would-be action only).
18
+ * Defaults to false.
19
+ */
20
+ dryRun?: boolean;
21
+ /**
22
+ * When true, rewrite the full modern template even if a file already exists.
23
+ * Defaults to false (intelligent surgical update only).
24
+ */
25
+ force?: boolean;
26
+ /**
27
+ * Pre-resolved provider used for schema discovery (avoids re-normalizing).
28
+ */
29
+ provider?: GeneratorProviderConfig;
30
+ /**
31
+ * Optional pre-loaded config (skips a second disk load).
32
+ */
33
+ loaded?: LoadedGeneratorConfig;
34
+ /**
35
+ * Explicit schemas to write when discovery is disabled or fails.
36
+ */
37
+ schemas?: readonly string[];
38
+ }
39
+ interface EnsureGeneratorConfigFileResult {
40
+ action: GeneratorConfigFileAction;
41
+ path: string;
42
+ absolutePath: string;
43
+ content?: string;
44
+ schemas: string[];
45
+ changes: string[];
46
+ mode: 'direct' | 'gateway';
47
+ reason?: string;
48
+ }
49
+ type DetectedMode = 'direct' | 'gateway';
50
+ /**
51
+ * Picks a provider mode from env when the caller did not force one.
52
+ * Prefers direct when a connection string is present; otherwise gateway.
53
+ */
54
+ declare function detectGeneratorProviderMode(preferred?: GeneratorConfigProviderMode): DetectedMode;
55
+ /**
56
+ * Renders a modern, typed `athena.config.ts` using `defineGeneratorConfig` + `generatorEnv`.
57
+ * Secrets stay env-backed so gateway and direct modes both work without hardcoding keys.
58
+ */
59
+ declare function renderGeneratorConfigFile(options: {
60
+ mode: DetectedMode;
61
+ schemas?: readonly string[];
62
+ }): string;
63
+ /**
64
+ * Updates only the `schemas:` value inside an existing TypeScript config source.
65
+ * Supports:
66
+ * - `schemas: ["public", "athena"]`
67
+ * - `schemas: generatorEnv.list("...", { default: ["public"] })`
68
+ *
69
+ * Returns undefined when the file cannot be updated surgically (caller may full-render).
70
+ */
71
+ declare function patchSchemasInConfigSource(source: string, schemas: readonly string[]): string | undefined;
72
+ /**
73
+ * Creates or intelligently updates `athena.config.ts`.
74
+ *
75
+ * Intelligence rules:
76
+ * - missing file → write modern direct/gateway template with env-backed secrets
77
+ * - existing file + force → full rewrite
78
+ * - existing file → only patch `provider.schemas` when auto-fill finds new values
79
+ * - skip write when content/schemas already match (no churn, safe for typecheck CI)
80
+ * - never removes user-listed schemas that discovery did not return
81
+ * - gateway mode uses the same template surface as direct (generatorEnv for url/key)
82
+ */
83
+ declare function ensureGeneratorConfigFile(options?: EnsureGeneratorConfigFileOptions): Promise<EnsureGeneratorConfigFileResult>;
84
+
85
+ /**
86
+ * End-to-end generator execution: load config, introspect, render, and optionally write files.
87
+ *
88
+ * When `writeConfig` is enabled (default), also ensures `athena.config.ts` exists and
89
+ * auto-fills discovered schemas without clobbering custom config fields.
90
+ */
91
+ declare function runSchemaGenerator(options?: RunGeneratorOptions): Promise<RunGeneratorResult>;
92
+
93
+ export { type EnsureGeneratorConfigFileOptions as E, type GeneratorConfigFileAction as G, type EnsureGeneratorConfigFileResult as a, type GeneratorConfigProviderMode as b, renderGeneratorConfigFile as c, detectGeneratorProviderMode as d, ensureGeneratorConfigFile as e, patchSchemasInConfigSource as p, runSchemaGenerator as r };
package/dist/react.cjs CHANGED
@@ -413,7 +413,7 @@ function buildAthenaRequestHeaders(input) {
413
413
 
414
414
  // package.json
415
415
  var package_default = {
416
- version: "3.0.2"
416
+ version: "3.1.0"
417
417
  };
418
418
 
419
419
  // src/sdk-version.ts
@@ -1997,6 +1997,402 @@ function useMutation(options) {
1997
1997
  lastRequest: snapshot.lastRequest
1998
1998
  };
1999
1999
  }
2000
+
2001
+ // src/query-debug-ast.ts
2002
+ var ATHENA_DEBUG_AST_KEY = "__athenaDebugAst";
2003
+ function getAthenaDebugAst(value) {
2004
+ if (!value || typeof value !== "object" && typeof value !== "function") {
2005
+ return null;
2006
+ }
2007
+ return value[ATHENA_DEBUG_AST_KEY] ?? null;
2008
+ }
2009
+
2010
+ // src/query/read-query.ts
2011
+ function normalizeAthenaReadQueryOrderBy(orderBy) {
2012
+ if (!orderBy) {
2013
+ return [];
2014
+ }
2015
+ const list = Array.isArray(orderBy) ? orderBy : [orderBy];
2016
+ return list.filter(
2017
+ (entry) => entry && typeof entry.column === "string" && entry.column.trim().length > 0
2018
+ );
2019
+ }
2020
+ function isRecord3(value) {
2021
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2022
+ }
2023
+ function flattenAthenaRowValue(row, column) {
2024
+ if (!column.relation) {
2025
+ return row[column.column];
2026
+ }
2027
+ const relationValue = row[column.relation.name];
2028
+ if (Array.isArray(relationValue)) {
2029
+ return relationValue.map((entry) => isRecord3(entry) ? entry[column.column] : void 0).filter((entry) => entry !== void 0);
2030
+ }
2031
+ if (isRecord3(relationValue)) {
2032
+ return relationValue[column.column];
2033
+ }
2034
+ return void 0;
2035
+ }
2036
+ function resolveFlatRowKey(row, index, preferredKey) {
2037
+ const preferredValue = preferredKey && preferredKey in row ? row[preferredKey] : void 0;
2038
+ if (preferredValue !== void 0 && preferredValue !== null && `${preferredValue}`.trim().length > 0) {
2039
+ return String(preferredValue);
2040
+ }
2041
+ for (const [key, value] of Object.entries(row)) {
2042
+ if (key === "__rowKey") {
2043
+ continue;
2044
+ }
2045
+ if (value === void 0 || value === null) {
2046
+ continue;
2047
+ }
2048
+ if (Array.isArray(value)) {
2049
+ if (value.length > 0) {
2050
+ return `${key}-${value.join("-")}`;
2051
+ }
2052
+ continue;
2053
+ }
2054
+ const nextValue = String(value).trim();
2055
+ if (nextValue.length > 0) {
2056
+ return nextValue;
2057
+ }
2058
+ }
2059
+ return `row-${index + 1}`;
2060
+ }
2061
+ function flattenAthenaReadQueryRows(rows, columns, preferredKey) {
2062
+ return rows.map((entry, index) => {
2063
+ const sourceRow = isRecord3(entry) ? entry : {};
2064
+ const flatRow = columns.reduce(
2065
+ (currentRow, column) => {
2066
+ currentRow[column.key] = flattenAthenaRowValue(sourceRow, column);
2067
+ return currentRow;
2068
+ },
2069
+ { __rowKey: "" }
2070
+ );
2071
+ flatRow.__rowKey = resolveFlatRowKey(flatRow, index, preferredKey);
2072
+ return flatRow;
2073
+ });
2074
+ }
2075
+ function buildAthenaReadQuerySelectString(columns) {
2076
+ const baseColumns = columns.filter((column) => !column.relation).map((column) => column.column);
2077
+ const relationGroups = /* @__PURE__ */ new Map();
2078
+ for (const column of columns) {
2079
+ if (!column.relation) {
2080
+ continue;
2081
+ }
2082
+ const groupKey = [
2083
+ column.relation.name,
2084
+ column.relation.schema ?? "",
2085
+ column.relation.table
2086
+ ].join(":");
2087
+ const existingGroup = relationGroups.get(groupKey);
2088
+ if (existingGroup) {
2089
+ if (!existingGroup.columns.includes(column.column)) {
2090
+ existingGroup.columns.push(column.column);
2091
+ }
2092
+ continue;
2093
+ }
2094
+ relationGroups.set(groupKey, {
2095
+ columns: [column.column],
2096
+ relation: column.relation
2097
+ });
2098
+ }
2099
+ const relationColumns = [...relationGroups.values()].map(
2100
+ ({ columns: relationColumns2, relation }) => {
2101
+ const relationTarget = relation.schema ? `${relation.schema}.${relation.table}` : relation.table;
2102
+ return `${relation.name}:${relationTarget}(${relationColumns2.join(",")})`;
2103
+ }
2104
+ );
2105
+ return [...baseColumns, ...relationColumns].join(",");
2106
+ }
2107
+ function buildAthenaReadQueryFindManySelect(columns) {
2108
+ const select = {};
2109
+ for (const column of columns) {
2110
+ if (!column.relation) {
2111
+ select[column.column] = true;
2112
+ continue;
2113
+ }
2114
+ const existingRelation = select[column.relation.name];
2115
+ if (existingRelation && existingRelation !== true && isRecord3(existingRelation.select)) {
2116
+ existingRelation.select[column.column] = true;
2117
+ continue;
2118
+ }
2119
+ select[column.relation.name] = {
2120
+ ...column.relation.schema ? { schema: column.relation.schema } : {},
2121
+ select: {
2122
+ [column.column]: true
2123
+ }
2124
+ };
2125
+ }
2126
+ return select;
2127
+ }
2128
+ function buildAthenaReadQueryFindManyWhere(filters) {
2129
+ if (!filters?.length) {
2130
+ return;
2131
+ }
2132
+ return filters.reduce(
2133
+ (where, filter) => {
2134
+ const operator = filter.operator ?? "eq";
2135
+ where[filter.column] = operator === "eq" ? filter.value : { [operator]: filter.value };
2136
+ return where;
2137
+ },
2138
+ {}
2139
+ );
2140
+ }
2141
+ function buildAthenaReadQueryFindManyOrderBy(orderBy) {
2142
+ const normalized = normalizeAthenaReadQueryOrderBy(orderBy);
2143
+ if (normalized.length === 0) {
2144
+ return;
2145
+ }
2146
+ if (normalized.length === 1) {
2147
+ const primary = normalized[0];
2148
+ if (!primary) {
2149
+ return;
2150
+ }
2151
+ return {
2152
+ ascending: primary.direction !== "desc",
2153
+ column: primary.column
2154
+ };
2155
+ }
2156
+ return Object.fromEntries(
2157
+ normalized.map((entry) => [
2158
+ entry.column,
2159
+ entry.direction === "desc" ? "desc" : "asc"
2160
+ ])
2161
+ );
2162
+ }
2163
+ function applyAthenaReadQueryFilters(queryBuilder, filters) {
2164
+ if (!filters?.length) {
2165
+ return queryBuilder;
2166
+ }
2167
+ return filters.reduce((currentBuilder, filter) => {
2168
+ const operator = filter.operator ?? "eq";
2169
+ const builderMethod = currentBuilder[operator];
2170
+ if (typeof builderMethod !== "function") {
2171
+ return currentBuilder;
2172
+ }
2173
+ return builderMethod.call(currentBuilder, filter.column, filter.value);
2174
+ }, queryBuilder);
2175
+ }
2176
+ function applyAthenaReadQuerySelectOrder(queryBuilder, orderBy) {
2177
+ const normalized = normalizeAthenaReadQueryOrderBy(orderBy);
2178
+ if (normalized.length === 0) {
2179
+ return queryBuilder;
2180
+ }
2181
+ return normalized.reduce(
2182
+ (builder, entry) => builder.order(entry.column, {
2183
+ ascending: entry.direction !== "desc"
2184
+ }),
2185
+ queryBuilder
2186
+ );
2187
+ }
2188
+ function applyAthenaReadQuerySelectLimit(queryBuilder, limit) {
2189
+ if (!limit || limit < 1) {
2190
+ return queryBuilder;
2191
+ }
2192
+ return queryBuilder.limit(limit);
2193
+ }
2194
+ function clampAthenaReadQueryTotalItems(totalItems, limit) {
2195
+ if (!limit || limit < 1) {
2196
+ return totalItems;
2197
+ }
2198
+ return Math.min(totalItems, limit);
2199
+ }
2200
+ function resolveCountValue(...candidates) {
2201
+ for (const candidate of candidates) {
2202
+ if (typeof candidate === "number" && Number.isFinite(candidate)) {
2203
+ return Math.max(0, Math.trunc(candidate));
2204
+ }
2205
+ }
2206
+ return 0;
2207
+ }
2208
+ function resolveTotalItemsFromPage({
2209
+ countCandidates,
2210
+ limit,
2211
+ page,
2212
+ pageSize,
2213
+ rowCount
2214
+ }) {
2215
+ const exactCount = resolveCountValue(...countCandidates);
2216
+ if (exactCount > 0) {
2217
+ return clampAthenaReadQueryTotalItems(exactCount, limit);
2218
+ }
2219
+ if (rowCount > 0) {
2220
+ const base = (page - 1) * pageSize + rowCount;
2221
+ const synthetic = rowCount >= pageSize ? base + 1 : base;
2222
+ return clampAthenaReadQueryTotalItems(synthetic, limit);
2223
+ }
2224
+ return clampAthenaReadQueryTotalItems(exactCount, limit);
2225
+ }
2226
+ async function executeAthenaReadQuery({
2227
+ client,
2228
+ page,
2229
+ pageSize,
2230
+ query
2231
+ }) {
2232
+ const db = client.db;
2233
+ const baseBuilder = db.from(query.table, {
2234
+ schema: query.schema
2235
+ });
2236
+ const countBuilder = applyAthenaReadQueryFilters(
2237
+ db.from(query.table, { schema: query.schema }),
2238
+ query.filters
2239
+ );
2240
+ const countResult = await countBuilder.select(query.countColumn, {
2241
+ count: "exact",
2242
+ head: true
2243
+ });
2244
+ if ((query.mode ?? "findMany") === "select") {
2245
+ const selectBuilder = applyAthenaReadQuerySelectLimit(
2246
+ applyAthenaReadQuerySelectOrder(
2247
+ applyAthenaReadQueryFilters(baseBuilder, query.filters),
2248
+ query.orderBy
2249
+ ),
2250
+ query.limit
2251
+ );
2252
+ const result2 = await selectBuilder.currentPage(page).pageSize(pageSize).select(buildAthenaReadQuerySelectString(query.columns), {
2253
+ count: "exact"
2254
+ });
2255
+ const rows2 = flattenAthenaReadQueryRows(
2256
+ Array.isArray(result2.data) ? result2.data : [],
2257
+ query.columns,
2258
+ query.rowKey
2259
+ );
2260
+ return {
2261
+ debugAst: getAthenaDebugAst(result2) ?? void 0,
2262
+ rows: rows2,
2263
+ totalItems: resolveTotalItemsFromPage({
2264
+ countCandidates: [countResult.count, result2.count],
2265
+ limit: query.limit,
2266
+ page,
2267
+ pageSize,
2268
+ rowCount: rows2.length
2269
+ })
2270
+ };
2271
+ }
2272
+ const findManyOrderBy = buildAthenaReadQueryFindManyOrderBy(query.orderBy);
2273
+ const findManyOptions = {
2274
+ ...query.limit ? { limit: query.limit } : {},
2275
+ ...findManyOrderBy ? { orderBy: findManyOrderBy } : {},
2276
+ select: buildAthenaReadQueryFindManySelect(query.columns),
2277
+ ...query.filters?.length ? { where: buildAthenaReadQueryFindManyWhere(query.filters) } : {}
2278
+ };
2279
+ const result = await baseBuilder.currentPage(page).pageSize(pageSize).findMany(findManyOptions);
2280
+ const rows = flattenAthenaReadQueryRows(
2281
+ Array.isArray(result.data) ? result.data : [],
2282
+ query.columns,
2283
+ query.rowKey
2284
+ );
2285
+ return {
2286
+ debugAst: getAthenaDebugAst(result) ?? void 0,
2287
+ rows,
2288
+ totalItems: resolveTotalItemsFromPage({
2289
+ countCandidates: [countResult.count, result.count],
2290
+ limit: query.limit,
2291
+ page,
2292
+ pageSize,
2293
+ rowCount: rows.length
2294
+ })
2295
+ };
2296
+ }
2297
+
2298
+ // src/react/use-athena-read-query.ts
2299
+ var DEFAULT_PAGE = 1;
2300
+ var DEFAULT_PAGE_SIZE = 10;
2301
+ function isReadQueryRunnable(query) {
2302
+ return query.table.trim().length > 0 && query.columns.length > 0 && query.countColumn.trim().length > 0;
2303
+ }
2304
+ function useAthenaReadQuery({
2305
+ client,
2306
+ query,
2307
+ page = DEFAULT_PAGE,
2308
+ pageSize = DEFAULT_PAGE_SIZE,
2309
+ enabled = true,
2310
+ queryKey,
2311
+ queryKeyPrefix,
2312
+ refetchOnMount,
2313
+ refetchOnWindowFocus,
2314
+ refetchOnReconnect,
2315
+ retry
2316
+ }) {
2317
+ const resolvedPage = page > 0 ? Math.trunc(page) : DEFAULT_PAGE;
2318
+ const resolvedPageSize = pageSize > 0 ? Math.trunc(pageSize) : DEFAULT_PAGE_SIZE;
2319
+ const queryEnabled = enabled && !!client && isReadQueryRunnable(query);
2320
+ const defaultQueryKey = React.useMemo(
2321
+ () => [
2322
+ "athena",
2323
+ "read-query",
2324
+ query.mode ?? "findMany",
2325
+ query.table,
2326
+ query.schema,
2327
+ query.columns,
2328
+ query.filters,
2329
+ query.limit,
2330
+ query.orderBy,
2331
+ query.rowKey,
2332
+ query.countColumn,
2333
+ resolvedPage,
2334
+ resolvedPageSize
2335
+ ],
2336
+ [
2337
+ query.columns,
2338
+ query.countColumn,
2339
+ query.filters,
2340
+ query.limit,
2341
+ query.mode,
2342
+ query.orderBy,
2343
+ query.rowKey,
2344
+ query.schema,
2345
+ query.table,
2346
+ resolvedPage,
2347
+ resolvedPageSize
2348
+ ]
2349
+ );
2350
+ const resolvedQueryKey = React.useMemo(() => {
2351
+ if (queryKey !== void 0) {
2352
+ return queryKey;
2353
+ }
2354
+ if (queryKeyPrefix !== void 0) {
2355
+ const prefix = Array.isArray(queryKeyPrefix) ? queryKeyPrefix : [queryKeyPrefix];
2356
+ return [...prefix, ...defaultQueryKey];
2357
+ }
2358
+ return defaultQueryKey;
2359
+ }, [defaultQueryKey, queryKey, queryKeyPrefix]);
2360
+ const result = useQuery({
2361
+ enabled: queryEnabled,
2362
+ queryKey: resolvedQueryKey,
2363
+ queryFn: async () => {
2364
+ if (!client) {
2365
+ throw new Error("Athena client is required to run the read query.");
2366
+ }
2367
+ return executeAthenaReadQuery({
2368
+ client,
2369
+ page: resolvedPage,
2370
+ pageSize: resolvedPageSize,
2371
+ query
2372
+ });
2373
+ },
2374
+ refetchOnMount,
2375
+ refetchOnWindowFocus,
2376
+ refetchOnReconnect,
2377
+ retry
2378
+ });
2379
+ return {
2380
+ data: result.data,
2381
+ rows: result.data?.rows ?? [],
2382
+ totalItems: result.data?.totalItems ?? 0,
2383
+ debugAst: result.data?.debugAst,
2384
+ page: resolvedPage,
2385
+ pageSize: resolvedPageSize,
2386
+ error: result.error,
2387
+ isLoading: result.isLoading,
2388
+ isFetching: result.isFetching,
2389
+ isSuccess: result.isSuccess,
2390
+ isError: result.isError,
2391
+ status: result.status,
2392
+ refetch: result.refetch,
2393
+ reset: result.reset
2394
+ };
2395
+ }
2000
2396
  function resolveGetSession(authClient) {
2001
2397
  if ("getSession" in authClient && typeof authClient.getSession === "function") {
2002
2398
  return authClient.getSession;
@@ -2291,7 +2687,7 @@ function resolveNullishValue(mode) {
2291
2687
  if (mode === "null") return null;
2292
2688
  return "";
2293
2689
  }
2294
- function isRecord3(value) {
2690
+ function isRecord4(value) {
2295
2691
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2296
2692
  }
2297
2693
  function isNullableColumn(model, key) {
@@ -2300,7 +2696,7 @@ function isNullableColumn(model, key) {
2300
2696
  }
2301
2697
  function toModelFormDefaults(model, values, options) {
2302
2698
  const source = values;
2303
- if (!isRecord3(source)) {
2699
+ if (!isRecord4(source)) {
2304
2700
  return {};
2305
2701
  }
2306
2702
  const mode = options?.nullishMode ?? "empty-string";
@@ -2357,6 +2753,7 @@ exports.toModelFormDefaults = toModelFormDefaults;
2357
2753
  exports.toModelPayload = toModelPayload;
2358
2754
  exports.useAthenaGateway = useAthenaGateway;
2359
2755
  exports.useAthenaQueryClient = useAthenaQueryClient;
2756
+ exports.useAthenaReadQuery = useAthenaReadQuery;
2360
2757
  exports.useAthenaSessionClient = useAthenaSessionClient;
2361
2758
  exports.useMutation = useMutation;
2362
2759
  exports.useQuery = useQuery;