@xylex-group/athena 3.0.3 → 3.3.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.
- package/README.md +1 -1
- package/dist/admin.cjs +55 -1
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.d.cts +32 -8
- package/dist/admin.d.ts +32 -8
- package/dist/admin.js +54 -2
- package/dist/admin.js.map +1 -1
- package/dist/athena-auth-url-C1FbVmN6.d.cts +200 -0
- package/dist/athena-auth-url-C1FbVmN6.d.ts +200 -0
- package/dist/{athena-request-headers-C7Jy-c_D.d.ts → athena-request-headers-DzimbvOA.d.ts} +48 -200
- package/dist/{athena-request-headers-DujFFyMU.d.cts → athena-request-headers-Lr_m8xCV.d.cts} +48 -200
- package/dist/billing.cjs +1 -1
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.js +1 -1
- package/dist/billing.js.map +1 -1
- package/dist/browser.cjs +912 -5
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +8 -7
- package/dist/browser.d.ts +8 -7
- package/dist/browser.js +881 -6
- package/dist/browser.js.map +1 -1
- package/dist/cli/index.cjs +7909 -7061
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +17 -10
- package/dist/cli/index.d.ts +17 -10
- package/dist/cli/index.js +7911 -7063
- package/dist/cli/index.js.map +1 -1
- package/dist/env.cjs +130 -0
- package/dist/env.cjs.map +1 -0
- package/dist/env.d.cts +70 -0
- package/dist/env.d.ts +70 -0
- package/dist/env.js +122 -0
- package/dist/env.js.map +1 -0
- package/dist/index.cjs +1570 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -8
- package/dist/index.d.ts +31 -8
- package/dist/index.js +1532 -100
- package/dist/index.js.map +1 -1
- package/dist/model-form-3Gr8rkdT.d.cts +281 -0
- package/dist/model-form-CotpEL7z.d.ts +281 -0
- package/dist/{module-CPG3ULxQ.d.cts → module-CQmOaDzP.d.cts} +4 -4
- package/dist/{module-BruTcxe0.d.ts → module-CWkUTcUc.d.ts} +4 -4
- package/dist/next/client.cjs +123 -7
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.d.cts +4 -3
- package/dist/next/client.d.ts +4 -3
- package/dist/next/client.js +123 -7
- package/dist/next/client.js.map +1 -1
- package/dist/next/server.cjs +1130 -364
- package/dist/next/server.cjs.map +1 -1
- package/dist/next/server.d.cts +121 -8
- package/dist/next/server.d.ts +121 -8
- package/dist/next/server.js +1120 -365
- package/dist/next/server.js.map +1 -1
- package/dist/pipeline-BnRKO_Pd.d.cts +93 -0
- package/dist/pipeline-sWCmlFqu.d.ts +93 -0
- package/dist/{proxy-request-headers-m4D2Tduy.d.ts → proxy-request-headers-CttlcuRb.d.ts} +1 -1
- package/dist/{proxy-request-headers-DGxdoyA0.d.cts → proxy-request-headers-pIBSn1Fw.d.cts} +1 -1
- package/dist/react.cjs +672 -16
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +123 -8
- package/dist/react.d.ts +123 -8
- package/dist/react.js +671 -17
- package/dist/react.js.map +1 -1
- package/dist/schema-handlers-BtT_IQFi.d.cts +138 -0
- package/dist/schema-handlers-VjFDhIMw.d.ts +138 -0
- package/dist/social-providers.d.cts +1 -1
- package/dist/social-providers.d.ts +1 -1
- package/dist/{types-D6tZ9aoq.d.ts → types-BDX8zS7w.d.ts} +40 -1
- package/dist/{types-AOY-GLu8.d.cts → types-BVKpQmfY.d.cts} +11 -0
- package/dist/{types-AOY-GLu8.d.ts → types-BVKpQmfY.d.ts} +11 -0
- package/dist/{types-DFr2cL1N.d.cts → types-D-Am7YSd.d.cts} +40 -1
- package/dist/utils.cjs +30 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +3 -2
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +30 -1
- package/dist/utils.js.map +1 -1
- package/dist/{v3-client-CWfZHcKL.d.cts → v3-client-G1SLeHRa.d.cts} +23 -1
- package/dist/{v3-client-DZp2NEhK.d.ts → v3-client-ao8BWQ8v.d.ts} +23 -1
- package/package.json +16 -2
- package/dist/model-form-Dh0sisdL.d.ts +0 -97
- package/dist/model-form-oOAJUVd4.d.cts +0 -97
- package/dist/pipeline-CIzV9f7b.d.cts +0 -8
- package/dist/pipeline-DNlc8Ayn.d.ts +0 -8
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
|
|
416
|
+
version: "3.3.0"
|
|
417
417
|
};
|
|
418
418
|
|
|
419
419
|
// src/sdk-version.ts
|
|
@@ -1064,7 +1064,8 @@ function stableSerialize(value, seen) {
|
|
|
1064
1064
|
if (value === void 0) return "undefined";
|
|
1065
1065
|
const valueType = typeof value;
|
|
1066
1066
|
if (valueType === "string") return `"${value}"`;
|
|
1067
|
-
if (valueType === "number")
|
|
1067
|
+
if (valueType === "number")
|
|
1068
|
+
return Number.isFinite(value) ? String(value) : "null";
|
|
1068
1069
|
if (valueType === "boolean") return value ? "true" : "false";
|
|
1069
1070
|
if (valueType === "bigint") return `${String(value)}n`;
|
|
1070
1071
|
if (valueType === "symbol") return `symbol:${String(value)}`;
|
|
@@ -1145,7 +1146,8 @@ async function runWithRetry(execute, options) {
|
|
|
1145
1146
|
}
|
|
1146
1147
|
function errorMessageFromUnknown(error) {
|
|
1147
1148
|
if (typeof error === "string" && error.trim()) return error.trim();
|
|
1148
|
-
if (error instanceof Error && error.message.trim())
|
|
1149
|
+
if (error instanceof Error && error.message.trim())
|
|
1150
|
+
return error.message.trim();
|
|
1149
1151
|
if (isRecord2(error)) {
|
|
1150
1152
|
const messageCandidate = error.message ?? error.error;
|
|
1151
1153
|
if (typeof messageCandidate === "string" && messageCandidate.trim()) {
|
|
@@ -1364,7 +1366,11 @@ var AthenaQueryClient = class {
|
|
|
1364
1366
|
const key = this.getMutationKeyToken(mutationKey);
|
|
1365
1367
|
const entry = this.ensureMutationEntry(key);
|
|
1366
1368
|
entry.activeRequestId = ++this.requestCounter;
|
|
1367
|
-
this.setMutationState(
|
|
1369
|
+
this.setMutationState(
|
|
1370
|
+
entry,
|
|
1371
|
+
createInitialMutationState(),
|
|
1372
|
+
"mutation_reset"
|
|
1373
|
+
);
|
|
1368
1374
|
}
|
|
1369
1375
|
async executeQuery(input) {
|
|
1370
1376
|
const entry = this.ensureQueryEntry(input.queryKeyToken);
|
|
@@ -1426,7 +1432,10 @@ var AthenaQueryClient = class {
|
|
|
1426
1432
|
);
|
|
1427
1433
|
}
|
|
1428
1434
|
const rawResult = await input.queryFn();
|
|
1429
|
-
const normalized = normalizeAthenaResult(
|
|
1435
|
+
const normalized = normalizeAthenaResult(
|
|
1436
|
+
rawResult,
|
|
1437
|
+
input.select
|
|
1438
|
+
);
|
|
1430
1439
|
if (normalized.error) {
|
|
1431
1440
|
throw {
|
|
1432
1441
|
__athenaNormalizedError: normalized.error,
|
|
@@ -1514,7 +1523,10 @@ var AthenaQueryClient = class {
|
|
|
1514
1523
|
this.inflightQueries.delete(input.queryKeyToken);
|
|
1515
1524
|
}
|
|
1516
1525
|
});
|
|
1517
|
-
this.inflightQueries.set(
|
|
1526
|
+
this.inflightQueries.set(
|
|
1527
|
+
input.queryKeyToken,
|
|
1528
|
+
executionPromise
|
|
1529
|
+
);
|
|
1518
1530
|
return executionPromise;
|
|
1519
1531
|
}
|
|
1520
1532
|
async executeMutation(input) {
|
|
@@ -1560,7 +1572,10 @@ var AthenaQueryClient = class {
|
|
|
1560
1572
|
);
|
|
1561
1573
|
}
|
|
1562
1574
|
const rawResult = await input.mutationFn(input.variables);
|
|
1563
|
-
const normalized = normalizeAthenaResult(
|
|
1575
|
+
const normalized = normalizeAthenaResult(
|
|
1576
|
+
rawResult,
|
|
1577
|
+
input.select
|
|
1578
|
+
);
|
|
1564
1579
|
if (normalized.error) {
|
|
1565
1580
|
throw {
|
|
1566
1581
|
__athenaNormalizedError: normalized.error,
|
|
@@ -1997,6 +2012,430 @@ function useMutation(options) {
|
|
|
1997
2012
|
lastRequest: snapshot.lastRequest
|
|
1998
2013
|
};
|
|
1999
2014
|
}
|
|
2015
|
+
|
|
2016
|
+
// src/query-debug-ast.ts
|
|
2017
|
+
var ATHENA_DEBUG_AST_KEY = "__athenaDebugAst";
|
|
2018
|
+
function getAthenaDebugAst(value) {
|
|
2019
|
+
if (!value || typeof value !== "object" && typeof value !== "function") {
|
|
2020
|
+
return null;
|
|
2021
|
+
}
|
|
2022
|
+
return value[ATHENA_DEBUG_AST_KEY] ?? null;
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
// src/query/read-query.ts
|
|
2026
|
+
function normalizeAthenaReadQueryOrderBy(orderBy) {
|
|
2027
|
+
if (!orderBy) {
|
|
2028
|
+
return [];
|
|
2029
|
+
}
|
|
2030
|
+
const list = Array.isArray(orderBy) ? orderBy : [orderBy];
|
|
2031
|
+
return list.filter(
|
|
2032
|
+
(entry) => entry && typeof entry.column === "string" && entry.column.trim().length > 0
|
|
2033
|
+
);
|
|
2034
|
+
}
|
|
2035
|
+
function isRecord3(value) {
|
|
2036
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2037
|
+
}
|
|
2038
|
+
function flattenAthenaRowValue(row, column) {
|
|
2039
|
+
if (!column.relation) {
|
|
2040
|
+
return row[column.column];
|
|
2041
|
+
}
|
|
2042
|
+
const relationValue = row[column.relation.name];
|
|
2043
|
+
if (Array.isArray(relationValue)) {
|
|
2044
|
+
return relationValue.map((entry) => isRecord3(entry) ? entry[column.column] : void 0).filter((entry) => entry !== void 0);
|
|
2045
|
+
}
|
|
2046
|
+
if (isRecord3(relationValue)) {
|
|
2047
|
+
return relationValue[column.column];
|
|
2048
|
+
}
|
|
2049
|
+
return void 0;
|
|
2050
|
+
}
|
|
2051
|
+
function resolveFlatRowKey(row, index, preferredKey) {
|
|
2052
|
+
const preferredValue = preferredKey && preferredKey in row ? row[preferredKey] : void 0;
|
|
2053
|
+
if (preferredValue !== void 0 && preferredValue !== null && `${preferredValue}`.trim().length > 0) {
|
|
2054
|
+
return String(preferredValue);
|
|
2055
|
+
}
|
|
2056
|
+
for (const [key, value] of Object.entries(row)) {
|
|
2057
|
+
if (key === "__rowKey") {
|
|
2058
|
+
continue;
|
|
2059
|
+
}
|
|
2060
|
+
if (value === void 0 || value === null) {
|
|
2061
|
+
continue;
|
|
2062
|
+
}
|
|
2063
|
+
if (Array.isArray(value)) {
|
|
2064
|
+
if (value.length > 0) {
|
|
2065
|
+
return `${key}-${value.join("-")}`;
|
|
2066
|
+
}
|
|
2067
|
+
continue;
|
|
2068
|
+
}
|
|
2069
|
+
const nextValue = String(value).trim();
|
|
2070
|
+
if (nextValue.length > 0) {
|
|
2071
|
+
return nextValue;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
return `row-${index + 1}`;
|
|
2075
|
+
}
|
|
2076
|
+
function flattenAthenaReadQueryRows(rows, columns, preferredKey) {
|
|
2077
|
+
return rows.map((entry, index) => {
|
|
2078
|
+
const sourceRow = isRecord3(entry) ? entry : {};
|
|
2079
|
+
const flatRow = columns.reduce(
|
|
2080
|
+
(currentRow, column) => {
|
|
2081
|
+
currentRow[column.key] = flattenAthenaRowValue(sourceRow, column);
|
|
2082
|
+
return currentRow;
|
|
2083
|
+
},
|
|
2084
|
+
{ __rowKey: "" }
|
|
2085
|
+
);
|
|
2086
|
+
flatRow.__rowKey = resolveFlatRowKey(flatRow, index, preferredKey);
|
|
2087
|
+
return flatRow;
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
function buildAthenaReadQuerySelectString(columns) {
|
|
2091
|
+
const baseColumns = columns.filter((column) => !column.relation).map((column) => column.column);
|
|
2092
|
+
const relationGroups = /* @__PURE__ */ new Map();
|
|
2093
|
+
for (const column of columns) {
|
|
2094
|
+
if (!column.relation) {
|
|
2095
|
+
continue;
|
|
2096
|
+
}
|
|
2097
|
+
const groupKey = [
|
|
2098
|
+
column.relation.name,
|
|
2099
|
+
column.relation.schema ?? "",
|
|
2100
|
+
column.relation.table
|
|
2101
|
+
].join(":");
|
|
2102
|
+
const existingGroup = relationGroups.get(groupKey);
|
|
2103
|
+
if (existingGroup) {
|
|
2104
|
+
if (!existingGroup.columns.includes(column.column)) {
|
|
2105
|
+
existingGroup.columns.push(column.column);
|
|
2106
|
+
}
|
|
2107
|
+
continue;
|
|
2108
|
+
}
|
|
2109
|
+
relationGroups.set(groupKey, {
|
|
2110
|
+
columns: [column.column],
|
|
2111
|
+
relation: column.relation
|
|
2112
|
+
});
|
|
2113
|
+
}
|
|
2114
|
+
const relationColumns = [...relationGroups.values()].map(
|
|
2115
|
+
({ columns: relationColumns2, relation }) => {
|
|
2116
|
+
const relationTarget = relation.schema ? `${relation.schema}.${relation.table}` : relation.table;
|
|
2117
|
+
return `${relation.name}:${relationTarget}(${relationColumns2.join(",")})`;
|
|
2118
|
+
}
|
|
2119
|
+
);
|
|
2120
|
+
return [...baseColumns, ...relationColumns].join(",");
|
|
2121
|
+
}
|
|
2122
|
+
function buildAthenaReadQueryFindManySelect(columns) {
|
|
2123
|
+
const select = {};
|
|
2124
|
+
for (const column of columns) {
|
|
2125
|
+
if (!column.relation) {
|
|
2126
|
+
select[column.column] = true;
|
|
2127
|
+
continue;
|
|
2128
|
+
}
|
|
2129
|
+
const existingRelation = select[column.relation.name];
|
|
2130
|
+
if (existingRelation && existingRelation !== true && isRecord3(existingRelation.select)) {
|
|
2131
|
+
existingRelation.select[column.column] = true;
|
|
2132
|
+
continue;
|
|
2133
|
+
}
|
|
2134
|
+
select[column.relation.name] = {
|
|
2135
|
+
...column.relation.schema ? { schema: column.relation.schema } : {},
|
|
2136
|
+
select: {
|
|
2137
|
+
[column.column]: true
|
|
2138
|
+
}
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2141
|
+
return select;
|
|
2142
|
+
}
|
|
2143
|
+
function buildAthenaReadQueryFindManyWhere(filters) {
|
|
2144
|
+
if (!filters?.length) {
|
|
2145
|
+
return;
|
|
2146
|
+
}
|
|
2147
|
+
return filters.reduce(
|
|
2148
|
+
(where, filter) => {
|
|
2149
|
+
const operator = filter.operator ?? "eq";
|
|
2150
|
+
where[filter.column] = operator === "eq" ? filter.value : { [operator]: filter.value };
|
|
2151
|
+
return where;
|
|
2152
|
+
},
|
|
2153
|
+
{}
|
|
2154
|
+
);
|
|
2155
|
+
}
|
|
2156
|
+
function buildAthenaReadQueryFindManyOrderBy(orderBy) {
|
|
2157
|
+
const normalized = normalizeAthenaReadQueryOrderBy(orderBy);
|
|
2158
|
+
if (normalized.length === 0) {
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
2161
|
+
if (normalized.length === 1) {
|
|
2162
|
+
const primary = normalized[0];
|
|
2163
|
+
if (!primary) {
|
|
2164
|
+
return;
|
|
2165
|
+
}
|
|
2166
|
+
return {
|
|
2167
|
+
ascending: primary.direction !== "desc",
|
|
2168
|
+
column: primary.column
|
|
2169
|
+
};
|
|
2170
|
+
}
|
|
2171
|
+
return Object.fromEntries(
|
|
2172
|
+
normalized.map((entry) => [
|
|
2173
|
+
entry.column,
|
|
2174
|
+
entry.direction === "desc" ? "desc" : "asc"
|
|
2175
|
+
])
|
|
2176
|
+
);
|
|
2177
|
+
}
|
|
2178
|
+
function applyAthenaReadQueryFilters(queryBuilder, filters) {
|
|
2179
|
+
if (!filters?.length) {
|
|
2180
|
+
return queryBuilder;
|
|
2181
|
+
}
|
|
2182
|
+
return filters.reduce((currentBuilder, filter) => {
|
|
2183
|
+
const operator = filter.operator ?? "eq";
|
|
2184
|
+
const builderMethod = currentBuilder[operator];
|
|
2185
|
+
if (typeof builderMethod !== "function") {
|
|
2186
|
+
return currentBuilder;
|
|
2187
|
+
}
|
|
2188
|
+
return builderMethod.call(currentBuilder, filter.column, filter.value);
|
|
2189
|
+
}, queryBuilder);
|
|
2190
|
+
}
|
|
2191
|
+
function applyAthenaReadQuerySelectOrder(queryBuilder, orderBy) {
|
|
2192
|
+
const normalized = normalizeAthenaReadQueryOrderBy(orderBy);
|
|
2193
|
+
if (normalized.length === 0) {
|
|
2194
|
+
return queryBuilder;
|
|
2195
|
+
}
|
|
2196
|
+
return normalized.reduce(
|
|
2197
|
+
(builder, entry) => builder.order(entry.column, {
|
|
2198
|
+
ascending: entry.direction !== "desc"
|
|
2199
|
+
}),
|
|
2200
|
+
queryBuilder
|
|
2201
|
+
);
|
|
2202
|
+
}
|
|
2203
|
+
function clampAthenaReadQueryTotalItems(totalItems, limit) {
|
|
2204
|
+
if (!limit || limit < 1) {
|
|
2205
|
+
return totalItems;
|
|
2206
|
+
}
|
|
2207
|
+
return Math.min(totalItems, limit);
|
|
2208
|
+
}
|
|
2209
|
+
function resolveCountValue(...candidates) {
|
|
2210
|
+
for (const candidate of candidates) {
|
|
2211
|
+
if (typeof candidate === "number" && Number.isFinite(candidate)) {
|
|
2212
|
+
return Math.max(0, Math.trunc(candidate));
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
return 0;
|
|
2216
|
+
}
|
|
2217
|
+
function resolveTotalItemsFromPage({
|
|
2218
|
+
countCandidates,
|
|
2219
|
+
limit,
|
|
2220
|
+
page,
|
|
2221
|
+
pageSize,
|
|
2222
|
+
rowCount
|
|
2223
|
+
}) {
|
|
2224
|
+
const exactCount = resolveCountValue(...countCandidates);
|
|
2225
|
+
if (exactCount > 0) {
|
|
2226
|
+
return clampAthenaReadQueryTotalItems(exactCount, limit);
|
|
2227
|
+
}
|
|
2228
|
+
if (rowCount > 0) {
|
|
2229
|
+
const base = (page - 1) * pageSize + rowCount;
|
|
2230
|
+
const synthetic = rowCount >= pageSize ? base + 1 : base;
|
|
2231
|
+
return clampAthenaReadQueryTotalItems(synthetic, limit);
|
|
2232
|
+
}
|
|
2233
|
+
return clampAthenaReadQueryTotalItems(exactCount, limit);
|
|
2234
|
+
}
|
|
2235
|
+
function resolveAthenaReadQueryPageFetch({
|
|
2236
|
+
page,
|
|
2237
|
+
pageSize,
|
|
2238
|
+
limit
|
|
2239
|
+
}) {
|
|
2240
|
+
const safePage = Math.max(1, Math.trunc(page) || 1);
|
|
2241
|
+
const safePageSize = Math.max(1, Math.trunc(pageSize) || 1);
|
|
2242
|
+
if (!limit || limit < 1) {
|
|
2243
|
+
return { page: safePage, pageSize: safePageSize, shouldFetch: true };
|
|
2244
|
+
}
|
|
2245
|
+
const totalCap = Math.trunc(limit);
|
|
2246
|
+
const offset = (safePage - 1) * safePageSize;
|
|
2247
|
+
if (offset >= totalCap) {
|
|
2248
|
+
return { page: safePage, pageSize: safePageSize, shouldFetch: false };
|
|
2249
|
+
}
|
|
2250
|
+
return {
|
|
2251
|
+
page: safePage,
|
|
2252
|
+
pageSize: Math.min(safePageSize, totalCap - offset),
|
|
2253
|
+
shouldFetch: true
|
|
2254
|
+
};
|
|
2255
|
+
}
|
|
2256
|
+
async function executeAthenaReadQuery({
|
|
2257
|
+
client,
|
|
2258
|
+
page,
|
|
2259
|
+
pageSize,
|
|
2260
|
+
query
|
|
2261
|
+
}) {
|
|
2262
|
+
const db = client.db;
|
|
2263
|
+
const baseBuilder = db.from(query.table, {
|
|
2264
|
+
schema: query.schema
|
|
2265
|
+
});
|
|
2266
|
+
const countBuilder = applyAthenaReadQueryFilters(
|
|
2267
|
+
db.from(query.table, { schema: query.schema }),
|
|
2268
|
+
query.filters
|
|
2269
|
+
);
|
|
2270
|
+
const countResult = await countBuilder.select(query.countColumn, {
|
|
2271
|
+
count: "exact",
|
|
2272
|
+
head: true
|
|
2273
|
+
});
|
|
2274
|
+
const pageFetch = resolveAthenaReadQueryPageFetch({
|
|
2275
|
+
limit: query.limit,
|
|
2276
|
+
page,
|
|
2277
|
+
pageSize
|
|
2278
|
+
});
|
|
2279
|
+
if (!pageFetch.shouldFetch) {
|
|
2280
|
+
return {
|
|
2281
|
+
rows: [],
|
|
2282
|
+
totalItems: resolveTotalItemsFromPage({
|
|
2283
|
+
countCandidates: [countResult.count],
|
|
2284
|
+
limit: query.limit,
|
|
2285
|
+
page: pageFetch.page,
|
|
2286
|
+
pageSize,
|
|
2287
|
+
rowCount: 0
|
|
2288
|
+
})
|
|
2289
|
+
};
|
|
2290
|
+
}
|
|
2291
|
+
if ((query.mode ?? "findMany") === "select") {
|
|
2292
|
+
const selectBuilder = applyAthenaReadQuerySelectOrder(
|
|
2293
|
+
applyAthenaReadQueryFilters(baseBuilder, query.filters),
|
|
2294
|
+
query.orderBy
|
|
2295
|
+
);
|
|
2296
|
+
const result2 = await selectBuilder.currentPage(pageFetch.page).pageSize(pageFetch.pageSize).select(buildAthenaReadQuerySelectString(query.columns), {
|
|
2297
|
+
count: "exact"
|
|
2298
|
+
});
|
|
2299
|
+
const rows2 = flattenAthenaReadQueryRows(
|
|
2300
|
+
Array.isArray(result2.data) ? result2.data : [],
|
|
2301
|
+
query.columns,
|
|
2302
|
+
query.rowKey
|
|
2303
|
+
);
|
|
2304
|
+
return {
|
|
2305
|
+
debugAst: getAthenaDebugAst(result2) ?? void 0,
|
|
2306
|
+
rows: rows2,
|
|
2307
|
+
totalItems: resolveTotalItemsFromPage({
|
|
2308
|
+
countCandidates: [countResult.count, result2.count],
|
|
2309
|
+
limit: query.limit,
|
|
2310
|
+
page: pageFetch.page,
|
|
2311
|
+
pageSize,
|
|
2312
|
+
rowCount: rows2.length
|
|
2313
|
+
})
|
|
2314
|
+
};
|
|
2315
|
+
}
|
|
2316
|
+
const findManyOrderBy = buildAthenaReadQueryFindManyOrderBy(query.orderBy);
|
|
2317
|
+
const findManyOptions = {
|
|
2318
|
+
...findManyOrderBy ? { orderBy: findManyOrderBy } : {},
|
|
2319
|
+
select: buildAthenaReadQueryFindManySelect(query.columns),
|
|
2320
|
+
...query.filters?.length ? { where: buildAthenaReadQueryFindManyWhere(query.filters) } : {}
|
|
2321
|
+
};
|
|
2322
|
+
const result = await baseBuilder.currentPage(pageFetch.page).pageSize(pageFetch.pageSize).findMany(findManyOptions);
|
|
2323
|
+
const rows = flattenAthenaReadQueryRows(
|
|
2324
|
+
Array.isArray(result.data) ? result.data : [],
|
|
2325
|
+
query.columns,
|
|
2326
|
+
query.rowKey
|
|
2327
|
+
);
|
|
2328
|
+
return {
|
|
2329
|
+
debugAst: getAthenaDebugAst(result) ?? void 0,
|
|
2330
|
+
rows,
|
|
2331
|
+
totalItems: resolveTotalItemsFromPage({
|
|
2332
|
+
countCandidates: [countResult.count, result.count],
|
|
2333
|
+
limit: query.limit,
|
|
2334
|
+
page: pageFetch.page,
|
|
2335
|
+
pageSize,
|
|
2336
|
+
rowCount: rows.length
|
|
2337
|
+
})
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
// src/react/use-athena-read-query.ts
|
|
2342
|
+
var DEFAULT_PAGE = 1;
|
|
2343
|
+
var DEFAULT_PAGE_SIZE = 10;
|
|
2344
|
+
function isReadQueryRunnable(query) {
|
|
2345
|
+
return query.table.trim().length > 0 && query.columns.length > 0 && query.countColumn.trim().length > 0;
|
|
2346
|
+
}
|
|
2347
|
+
function useAthenaReadQuery({
|
|
2348
|
+
client,
|
|
2349
|
+
query,
|
|
2350
|
+
page = DEFAULT_PAGE,
|
|
2351
|
+
pageSize = DEFAULT_PAGE_SIZE,
|
|
2352
|
+
enabled = true,
|
|
2353
|
+
queryKey,
|
|
2354
|
+
queryKeyPrefix,
|
|
2355
|
+
refetchOnMount,
|
|
2356
|
+
refetchOnWindowFocus,
|
|
2357
|
+
refetchOnReconnect,
|
|
2358
|
+
retry
|
|
2359
|
+
}) {
|
|
2360
|
+
const resolvedPage = page > 0 ? Math.trunc(page) : DEFAULT_PAGE;
|
|
2361
|
+
const resolvedPageSize = pageSize > 0 ? Math.trunc(pageSize) : DEFAULT_PAGE_SIZE;
|
|
2362
|
+
const queryEnabled = enabled && !!client && isReadQueryRunnable(query);
|
|
2363
|
+
const defaultQueryKey = React.useMemo(
|
|
2364
|
+
() => [
|
|
2365
|
+
"athena",
|
|
2366
|
+
"read-query",
|
|
2367
|
+
query.mode ?? "findMany",
|
|
2368
|
+
query.table,
|
|
2369
|
+
query.schema,
|
|
2370
|
+
query.columns,
|
|
2371
|
+
query.filters,
|
|
2372
|
+
query.limit,
|
|
2373
|
+
query.orderBy,
|
|
2374
|
+
query.rowKey,
|
|
2375
|
+
query.countColumn,
|
|
2376
|
+
resolvedPage,
|
|
2377
|
+
resolvedPageSize
|
|
2378
|
+
],
|
|
2379
|
+
[
|
|
2380
|
+
query.columns,
|
|
2381
|
+
query.countColumn,
|
|
2382
|
+
query.filters,
|
|
2383
|
+
query.limit,
|
|
2384
|
+
query.mode,
|
|
2385
|
+
query.orderBy,
|
|
2386
|
+
query.rowKey,
|
|
2387
|
+
query.schema,
|
|
2388
|
+
query.table,
|
|
2389
|
+
resolvedPage,
|
|
2390
|
+
resolvedPageSize
|
|
2391
|
+
]
|
|
2392
|
+
);
|
|
2393
|
+
const resolvedQueryKey = React.useMemo(() => {
|
|
2394
|
+
if (queryKey !== void 0) {
|
|
2395
|
+
return queryKey;
|
|
2396
|
+
}
|
|
2397
|
+
if (queryKeyPrefix !== void 0) {
|
|
2398
|
+
const prefix = Array.isArray(queryKeyPrefix) ? queryKeyPrefix : [queryKeyPrefix];
|
|
2399
|
+
return [...prefix, ...defaultQueryKey];
|
|
2400
|
+
}
|
|
2401
|
+
return defaultQueryKey;
|
|
2402
|
+
}, [defaultQueryKey, queryKey, queryKeyPrefix]);
|
|
2403
|
+
const result = useQuery({
|
|
2404
|
+
enabled: queryEnabled,
|
|
2405
|
+
queryKey: resolvedQueryKey,
|
|
2406
|
+
queryFn: async () => {
|
|
2407
|
+
if (!client) {
|
|
2408
|
+
throw new Error("Athena client is required to run the read query.");
|
|
2409
|
+
}
|
|
2410
|
+
return executeAthenaReadQuery({
|
|
2411
|
+
client,
|
|
2412
|
+
page: resolvedPage,
|
|
2413
|
+
pageSize: resolvedPageSize,
|
|
2414
|
+
query
|
|
2415
|
+
});
|
|
2416
|
+
},
|
|
2417
|
+
refetchOnMount,
|
|
2418
|
+
refetchOnWindowFocus,
|
|
2419
|
+
refetchOnReconnect,
|
|
2420
|
+
retry
|
|
2421
|
+
});
|
|
2422
|
+
return {
|
|
2423
|
+
data: result.data,
|
|
2424
|
+
rows: result.data?.rows ?? [],
|
|
2425
|
+
totalItems: result.data?.totalItems ?? 0,
|
|
2426
|
+
debugAst: result.data?.debugAst,
|
|
2427
|
+
page: resolvedPage,
|
|
2428
|
+
pageSize: resolvedPageSize,
|
|
2429
|
+
error: result.error,
|
|
2430
|
+
isLoading: result.isLoading,
|
|
2431
|
+
isFetching: result.isFetching,
|
|
2432
|
+
isSuccess: result.isSuccess,
|
|
2433
|
+
isError: result.isError,
|
|
2434
|
+
status: result.status,
|
|
2435
|
+
refetch: result.refetch,
|
|
2436
|
+
reset: result.reset
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2000
2439
|
function resolveGetSession(authClient) {
|
|
2001
2440
|
if ("getSession" in authClient && typeof authClient.getSession === "function") {
|
|
2002
2441
|
return authClient.getSession;
|
|
@@ -2004,7 +2443,16 @@ function resolveGetSession(authClient) {
|
|
|
2004
2443
|
if ("auth" in authClient && authClient.auth && typeof authClient.auth.getSession === "function") {
|
|
2005
2444
|
return authClient.auth.getSession;
|
|
2006
2445
|
}
|
|
2007
|
-
throw new Error(
|
|
2446
|
+
throw new Error(
|
|
2447
|
+
"useSession requires an auth-capable client (createClient(...).auth)"
|
|
2448
|
+
);
|
|
2449
|
+
}
|
|
2450
|
+
function toFallbackErrorDetails(code, message, status) {
|
|
2451
|
+
return {
|
|
2452
|
+
code,
|
|
2453
|
+
message,
|
|
2454
|
+
status
|
|
2455
|
+
};
|
|
2008
2456
|
}
|
|
2009
2457
|
function useSession(authClient, options = {}) {
|
|
2010
2458
|
const enabled = options.enabled ?? true;
|
|
@@ -2022,11 +2470,6 @@ function useSession(authClient, options = {}) {
|
|
|
2022
2470
|
React.useEffect(() => {
|
|
2023
2471
|
dataRef.current = data;
|
|
2024
2472
|
}, [data]);
|
|
2025
|
-
const toFallbackErrorDetails = (code, message, status) => ({
|
|
2026
|
-
code,
|
|
2027
|
-
message,
|
|
2028
|
-
status
|
|
2029
|
-
});
|
|
2030
2473
|
const runFetch = React.useCallback(async () => {
|
|
2031
2474
|
const requestId = ++requestIdRef.current;
|
|
2032
2475
|
const hasData = dataRef.current !== null;
|
|
@@ -2089,6 +2532,211 @@ function useSession(authClient, options = {}) {
|
|
|
2089
2532
|
refetch
|
|
2090
2533
|
};
|
|
2091
2534
|
}
|
|
2535
|
+
|
|
2536
|
+
// src/admin/index.ts
|
|
2537
|
+
function resolveAdminPermissionClient(client) {
|
|
2538
|
+
if (!client || typeof client !== "object") {
|
|
2539
|
+
return null;
|
|
2540
|
+
}
|
|
2541
|
+
const record = client;
|
|
2542
|
+
const nestedAuth = record.auth;
|
|
2543
|
+
if (nestedAuth && typeof nestedAuth === "object" && nestedAuth !== null && "admin" in nestedAuth) {
|
|
2544
|
+
return client;
|
|
2545
|
+
}
|
|
2546
|
+
if ("admin" in record) {
|
|
2547
|
+
return { auth: client };
|
|
2548
|
+
}
|
|
2549
|
+
return null;
|
|
2550
|
+
}
|
|
2551
|
+
function buildAdminAuthFetchOptions(credentials = {}) {
|
|
2552
|
+
const cookie = credentials.cookie?.trim() || void 0;
|
|
2553
|
+
const bearerToken = credentials.bearerToken?.trim() || void 0;
|
|
2554
|
+
const headers = {};
|
|
2555
|
+
if (cookie) {
|
|
2556
|
+
headers.cookie = cookie;
|
|
2557
|
+
}
|
|
2558
|
+
if (bearerToken) {
|
|
2559
|
+
headers.authorization = `Bearer ${bearerToken}`;
|
|
2560
|
+
}
|
|
2561
|
+
return {
|
|
2562
|
+
credentials: "include",
|
|
2563
|
+
...bearerToken ? { bearerToken } : {},
|
|
2564
|
+
...Object.keys(headers).length > 0 ? { headers } : {}
|
|
2565
|
+
};
|
|
2566
|
+
}
|
|
2567
|
+
function hasAdminRole(session) {
|
|
2568
|
+
const role = session?.user?.role;
|
|
2569
|
+
if (!role) {
|
|
2570
|
+
return false;
|
|
2571
|
+
}
|
|
2572
|
+
return role.split(",").map((item) => item.trim().toLowerCase()).includes("admin");
|
|
2573
|
+
}
|
|
2574
|
+
function mergeAdminFetchOptions(input) {
|
|
2575
|
+
const fromCredentials = input.credentials ? buildAdminAuthFetchOptions(input.credentials) : void 0;
|
|
2576
|
+
const explicit = input.fetchOptions;
|
|
2577
|
+
if (!fromCredentials && !explicit) {
|
|
2578
|
+
return void 0;
|
|
2579
|
+
}
|
|
2580
|
+
if (!fromCredentials) {
|
|
2581
|
+
return explicit;
|
|
2582
|
+
}
|
|
2583
|
+
if (!explicit) {
|
|
2584
|
+
return fromCredentials;
|
|
2585
|
+
}
|
|
2586
|
+
return {
|
|
2587
|
+
...fromCredentials,
|
|
2588
|
+
...explicit,
|
|
2589
|
+
headers: {
|
|
2590
|
+
...fromCredentials.headers ?? {},
|
|
2591
|
+
...explicit.headers ?? {}
|
|
2592
|
+
}
|
|
2593
|
+
};
|
|
2594
|
+
}
|
|
2595
|
+
async function hasAdminPermission(client, input) {
|
|
2596
|
+
if (!input.session?.user?.id) {
|
|
2597
|
+
return false;
|
|
2598
|
+
}
|
|
2599
|
+
if (input.allowRoleBypass !== false && hasAdminRole(input.session)) {
|
|
2600
|
+
return true;
|
|
2601
|
+
}
|
|
2602
|
+
const fetchOptions = mergeAdminFetchOptions(input);
|
|
2603
|
+
const result = await client.auth.admin.hasPermission(
|
|
2604
|
+
{
|
|
2605
|
+
permission: input.permission,
|
|
2606
|
+
permissions: input.permissions,
|
|
2607
|
+
...fetchOptions ? { fetchOptions } : {}
|
|
2608
|
+
},
|
|
2609
|
+
input.requestOptions
|
|
2610
|
+
);
|
|
2611
|
+
return Boolean(result.ok && result.data?.success);
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
// src/react/use-admin-permission.ts
|
|
2615
|
+
var DEFAULT_ADMIN_PERMISSIONS = [
|
|
2616
|
+
"admin:read"
|
|
2617
|
+
];
|
|
2618
|
+
function serializePermissions(permissions, permission) {
|
|
2619
|
+
return JSON.stringify({
|
|
2620
|
+
permission: permission ?? null,
|
|
2621
|
+
permissions: permissions ?? DEFAULT_ADMIN_PERMISSIONS
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
function useAdminPermission(client, options = {}) {
|
|
2625
|
+
const enabled = options.enabled ?? true;
|
|
2626
|
+
const sessionProvided = "session" in options;
|
|
2627
|
+
const sessionFromOptions = sessionProvided ? options.session ?? null : void 0;
|
|
2628
|
+
const permissionsKey = serializePermissions(options.permissions, options.permission);
|
|
2629
|
+
const allowRoleBypass = options.allowRoleBypass;
|
|
2630
|
+
const fetchOptions = options.fetchOptions;
|
|
2631
|
+
const requestOptions = options.requestOptions;
|
|
2632
|
+
const optionsRef = React.useRef(options);
|
|
2633
|
+
optionsRef.current = options;
|
|
2634
|
+
const sessionState = useSession(client, {
|
|
2635
|
+
...options.sessionOptions,
|
|
2636
|
+
enabled: enabled && !sessionProvided && !!client
|
|
2637
|
+
});
|
|
2638
|
+
const session = sessionProvided ? sessionFromOptions ?? null : sessionState.data;
|
|
2639
|
+
const sessionPending = !sessionProvided && sessionState.isPending;
|
|
2640
|
+
const sessionUserId = session?.user?.id ?? null;
|
|
2641
|
+
const sessionRole = session?.user?.role ?? null;
|
|
2642
|
+
const [allowed, setAllowed] = React.useState(false);
|
|
2643
|
+
const [error, setError] = React.useState(null);
|
|
2644
|
+
const [isChecking, setIsChecking] = React.useState(enabled);
|
|
2645
|
+
const requestIdRef = React.useRef(0);
|
|
2646
|
+
const mountedRef = React.useRef(true);
|
|
2647
|
+
const runCheck = React.useCallback(async () => {
|
|
2648
|
+
const requestId = ++requestIdRef.current;
|
|
2649
|
+
const current = optionsRef.current;
|
|
2650
|
+
const permissions = current.permissions ?? DEFAULT_ADMIN_PERMISSIONS;
|
|
2651
|
+
if (!enabled || !client) {
|
|
2652
|
+
if (mountedRef.current && requestId === requestIdRef.current) {
|
|
2653
|
+
setAllowed(false);
|
|
2654
|
+
setError(null);
|
|
2655
|
+
setIsChecking(false);
|
|
2656
|
+
}
|
|
2657
|
+
return false;
|
|
2658
|
+
}
|
|
2659
|
+
setIsChecking(true);
|
|
2660
|
+
try {
|
|
2661
|
+
const permissionClient = resolveAdminPermissionClient(client);
|
|
2662
|
+
if (!permissionClient) {
|
|
2663
|
+
throw new Error(
|
|
2664
|
+
"useAdminPermission requires an Athena client with auth.admin (createClient(...) or auth bindings)"
|
|
2665
|
+
);
|
|
2666
|
+
}
|
|
2667
|
+
const resolvedSession = sessionProvided ? current.session ?? null : sessionState.data;
|
|
2668
|
+
const nextAllowed = await hasAdminPermission(permissionClient, {
|
|
2669
|
+
session: resolvedSession,
|
|
2670
|
+
permissions,
|
|
2671
|
+
permission: current.permission,
|
|
2672
|
+
allowRoleBypass: current.allowRoleBypass,
|
|
2673
|
+
fetchOptions: current.fetchOptions,
|
|
2674
|
+
requestOptions: current.requestOptions
|
|
2675
|
+
});
|
|
2676
|
+
if (!mountedRef.current || requestId !== requestIdRef.current) {
|
|
2677
|
+
return nextAllowed;
|
|
2678
|
+
}
|
|
2679
|
+
setAllowed(nextAllowed);
|
|
2680
|
+
setError(null);
|
|
2681
|
+
return nextAllowed;
|
|
2682
|
+
} catch (checkError) {
|
|
2683
|
+
if (!mountedRef.current || requestId !== requestIdRef.current) {
|
|
2684
|
+
return false;
|
|
2685
|
+
}
|
|
2686
|
+
const nextError = checkError instanceof Error ? checkError : new Error("Failed to resolve admin permission");
|
|
2687
|
+
setAllowed(false);
|
|
2688
|
+
setError(nextError);
|
|
2689
|
+
return false;
|
|
2690
|
+
} finally {
|
|
2691
|
+
if (mountedRef.current && requestId === requestIdRef.current) {
|
|
2692
|
+
setIsChecking(false);
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
}, [client, enabled, sessionProvided, sessionState.data]);
|
|
2696
|
+
React.useEffect(() => {
|
|
2697
|
+
mountedRef.current = true;
|
|
2698
|
+
return () => {
|
|
2699
|
+
mountedRef.current = false;
|
|
2700
|
+
};
|
|
2701
|
+
}, []);
|
|
2702
|
+
React.useEffect(() => {
|
|
2703
|
+
if (!enabled) {
|
|
2704
|
+
setAllowed(false);
|
|
2705
|
+
setError(null);
|
|
2706
|
+
setIsChecking(false);
|
|
2707
|
+
return;
|
|
2708
|
+
}
|
|
2709
|
+
if (!sessionProvided && sessionState.isPending) {
|
|
2710
|
+
setIsChecking(true);
|
|
2711
|
+
return;
|
|
2712
|
+
}
|
|
2713
|
+
void runCheck();
|
|
2714
|
+
}, [
|
|
2715
|
+
allowRoleBypass,
|
|
2716
|
+
enabled,
|
|
2717
|
+
fetchOptions,
|
|
2718
|
+
permissionsKey,
|
|
2719
|
+
requestOptions,
|
|
2720
|
+
runCheck,
|
|
2721
|
+
sessionPending,
|
|
2722
|
+
sessionProvided,
|
|
2723
|
+
sessionRole,
|
|
2724
|
+
sessionUserId
|
|
2725
|
+
]);
|
|
2726
|
+
const refetch = React.useCallback(async () => {
|
|
2727
|
+
if (!sessionProvided) {
|
|
2728
|
+
await sessionState.refetch();
|
|
2729
|
+
}
|
|
2730
|
+
return await runCheck();
|
|
2731
|
+
}, [runCheck, sessionProvided, sessionState]);
|
|
2732
|
+
return {
|
|
2733
|
+
allowed,
|
|
2734
|
+
isPending: enabled && (sessionPending || isChecking),
|
|
2735
|
+
error,
|
|
2736
|
+
session,
|
|
2737
|
+
refetch
|
|
2738
|
+
};
|
|
2739
|
+
}
|
|
2092
2740
|
function useAthenaSessionClient(baseClient, options = {}) {
|
|
2093
2741
|
const sessionState = useSession(baseClient, options);
|
|
2094
2742
|
const scopedClient = React.useMemo(
|
|
@@ -2193,7 +2841,13 @@ function isStorageUploadInput(input) {
|
|
|
2193
2841
|
return Boolean(input) && typeof input === "object" && "files" in input && "s3_id" in input;
|
|
2194
2842
|
}
|
|
2195
2843
|
function useStorageFiles(options) {
|
|
2196
|
-
const {
|
|
2844
|
+
const {
|
|
2845
|
+
storage,
|
|
2846
|
+
input,
|
|
2847
|
+
enabled = true,
|
|
2848
|
+
callOptions,
|
|
2849
|
+
refreshIntervalMs
|
|
2850
|
+
} = options;
|
|
2197
2851
|
const [data, setData] = React__namespace.useState(null);
|
|
2198
2852
|
const [loading, setLoading] = React__namespace.useState(false);
|
|
2199
2853
|
const [error, setError] = React__namespace.useState(null);
|
|
@@ -2291,7 +2945,7 @@ function resolveNullishValue(mode) {
|
|
|
2291
2945
|
if (mode === "null") return null;
|
|
2292
2946
|
return "";
|
|
2293
2947
|
}
|
|
2294
|
-
function
|
|
2948
|
+
function isRecord4(value) {
|
|
2295
2949
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2296
2950
|
}
|
|
2297
2951
|
function isNullableColumn(model, key) {
|
|
@@ -2300,7 +2954,7 @@ function isNullableColumn(model, key) {
|
|
|
2300
2954
|
}
|
|
2301
2955
|
function toModelFormDefaults(model, values, options) {
|
|
2302
2956
|
const source = values;
|
|
2303
|
-
if (!
|
|
2957
|
+
if (!isRecord4(source)) {
|
|
2304
2958
|
return {};
|
|
2305
2959
|
}
|
|
2306
2960
|
const mode = options?.nullishMode ?? "empty-string";
|
|
@@ -2355,8 +3009,10 @@ exports.createModelFormAdapter = createModelFormAdapter;
|
|
|
2355
3009
|
exports.isAthenaGatewayError = isAthenaGatewayError;
|
|
2356
3010
|
exports.toModelFormDefaults = toModelFormDefaults;
|
|
2357
3011
|
exports.toModelPayload = toModelPayload;
|
|
3012
|
+
exports.useAdminPermission = useAdminPermission;
|
|
2358
3013
|
exports.useAthenaGateway = useAthenaGateway;
|
|
2359
3014
|
exports.useAthenaQueryClient = useAthenaQueryClient;
|
|
3015
|
+
exports.useAthenaReadQuery = useAthenaReadQuery;
|
|
2360
3016
|
exports.useAthenaSessionClient = useAthenaSessionClient;
|
|
2361
3017
|
exports.useMutation = useMutation;
|
|
2362
3018
|
exports.useQuery = useQuery;
|