@xylex-group/athena 2.3.0 → 2.4.1
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 +195 -106
- package/dist/browser.cjs +870 -154
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +7 -7
- package/dist/browser.d.ts +7 -7
- package/dist/browser.js +869 -155
- package/dist/browser.js.map +1 -1
- package/dist/cli/index.cjs +905 -144
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -3
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +905 -144
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +870 -154
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +869 -155
- package/dist/index.js.map +1 -1
- package/dist/{model-form-hoE2jHIi.d.cts → model-form-4LPnOPAF.d.cts} +9 -5
- package/dist/{model-form-BpDXlbxb.d.ts → model-form-CO4-LmNC.d.ts} +9 -5
- package/dist/{pipeline-BNIw8pDQ.d.ts → pipeline-CR4V15jF.d.ts} +1 -1
- package/dist/{pipeline-DNIpEsN8.d.cts → pipeline-DZeExYMA.d.cts} +1 -1
- package/dist/{react-email-qPA1wjFV.d.ts → react-email-6mOyxBo4.d.cts} +60 -13
- package/dist/{react-email-BvyCZnfW.d.cts → react-email-Buhcpglm.d.ts} +60 -13
- package/dist/react.cjs +333 -16
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +4 -4
- package/dist/react.d.ts +4 -4
- package/dist/react.js +333 -16
- package/dist/react.js.map +1 -1
- package/dist/{types-A5e97acl.d.cts → types-09Q4D86N.d.cts} +23 -2
- package/dist/{types-A5e97acl.d.ts → types-09Q4D86N.d.ts} +23 -2
- package/dist/{types-bDlr4u7p.d.cts → types-D1JvL21V.d.cts} +1 -1
- package/dist/{types-BnD22-vb.d.ts → types-DU3gNdFv.d.ts} +1 -1
- package/dist/utils.cjs +131 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +42 -1
- package/dist/utils.d.ts +42 -1
- package/dist/utils.js +117 -1
- package/dist/utils.js.map +1 -1
- package/package.json +40 -40
package/dist/cli/index.js
CHANGED
|
@@ -497,6 +497,7 @@ function classifyKind(status, code, message) {
|
|
|
497
497
|
if (status === 404 || hasNotFoundPattern) return "not_found";
|
|
498
498
|
if (status === 401 || status === 403 || hasAuthPattern) return "auth";
|
|
499
499
|
if (status === 429 || hasRateLimitPattern) return "rate_limit";
|
|
500
|
+
if (code === "INVALID_URL") return "validation";
|
|
500
501
|
if (status === 400 || status === 422 || hasValidationPattern) return "validation";
|
|
501
502
|
if (code === "NETWORK_ERROR" || status === 0 || status !== void 0 && status >= 500 || hasTransientPattern) {
|
|
502
503
|
return "transient";
|
|
@@ -504,6 +505,9 @@ function classifyKind(status, code, message) {
|
|
|
504
505
|
return "unknown";
|
|
505
506
|
}
|
|
506
507
|
function toAthenaErrorCode(kind, status, gatewayCode) {
|
|
508
|
+
if (gatewayCode === "INVALID_URL") {
|
|
509
|
+
return AthenaErrorCode.ValidationFailed;
|
|
510
|
+
}
|
|
507
511
|
if (gatewayCode === "NETWORK_ERROR" || kind === "transient" && status === 0) {
|
|
508
512
|
return AthenaErrorCode.NetworkUnavailable;
|
|
509
513
|
}
|
|
@@ -657,6 +661,54 @@ function normalizeAthenaError(resultOrError, context) {
|
|
|
657
661
|
raw: resultOrError
|
|
658
662
|
};
|
|
659
663
|
}
|
|
664
|
+
function defaultShouldRetry(error) {
|
|
665
|
+
const normalized = normalizeAthenaError(error);
|
|
666
|
+
return normalized.kind === "transient" || normalized.kind === "rate_limit";
|
|
667
|
+
}
|
|
668
|
+
function computeDelayMs(attempt, error, config) {
|
|
669
|
+
const baseDelay = config.baseDelayMs;
|
|
670
|
+
const rawDelay = typeof config.backoff === "function" ? config.backoff(attempt, error) : config.backoff === "linear" ? baseDelay * attempt : baseDelay * Math.pow(2, attempt - 1);
|
|
671
|
+
const safeDelay = Number.isFinite(rawDelay) ? Math.max(0, rawDelay) : 0;
|
|
672
|
+
const clamped = Math.min(config.maxDelayMs, safeDelay);
|
|
673
|
+
const jitterFactor = typeof config.jitter === "number" ? Math.max(0, Math.min(1, config.jitter)) : config.jitter ? 0.2 : 0;
|
|
674
|
+
if (!jitterFactor) return clamped;
|
|
675
|
+
const deviation = clamped * jitterFactor;
|
|
676
|
+
const offset = (Math.random() * 2 - 1) * deviation;
|
|
677
|
+
return Math.max(0, clamped + offset);
|
|
678
|
+
}
|
|
679
|
+
function sleep(ms) {
|
|
680
|
+
if (ms <= 0) return Promise.resolve();
|
|
681
|
+
return new Promise((resolve3) => {
|
|
682
|
+
setTimeout(resolve3, ms);
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
async function withRetry(config, fn) {
|
|
686
|
+
const retries = Math.max(0, Math.trunc(config.retries));
|
|
687
|
+
const shouldRetry = config.shouldRetry ?? defaultShouldRetry;
|
|
688
|
+
const resolvedConfig = {
|
|
689
|
+
baseDelayMs: config.baseDelayMs ?? 100,
|
|
690
|
+
maxDelayMs: config.maxDelayMs ?? 1e4,
|
|
691
|
+
backoff: config.backoff ?? "exponential",
|
|
692
|
+
jitter: config.jitter ?? false
|
|
693
|
+
};
|
|
694
|
+
for (let attempts = 0; attempts <= retries; attempts += 1) {
|
|
695
|
+
try {
|
|
696
|
+
return await fn();
|
|
697
|
+
} catch (error) {
|
|
698
|
+
if (attempts >= retries) {
|
|
699
|
+
throw error;
|
|
700
|
+
}
|
|
701
|
+
const currentAttempt = attempts + 1;
|
|
702
|
+
const retry = await shouldRetry(error, currentAttempt);
|
|
703
|
+
if (!retry) {
|
|
704
|
+
throw error;
|
|
705
|
+
}
|
|
706
|
+
const delay = computeDelayMs(currentAttempt, error, resolvedConfig);
|
|
707
|
+
await sleep(delay);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
throw new Error("withRetry reached an unexpected state");
|
|
711
|
+
}
|
|
660
712
|
|
|
661
713
|
// src/generator/schema-selection.ts
|
|
662
714
|
var DEFAULT_POSTGRES_SCHEMAS = ["public"];
|
|
@@ -1357,13 +1409,114 @@ function generateArtifactsFromSnapshot(snapshot, config) {
|
|
|
1357
1409
|
return new ArtifactComposer(snapshot, normalizedConfig).compose();
|
|
1358
1410
|
}
|
|
1359
1411
|
|
|
1412
|
+
// src/gateway/url.ts
|
|
1413
|
+
var ATHENA_DEFAULT_BASE_URL = "https://athena-db.com";
|
|
1414
|
+
function describeReceivedValue(value) {
|
|
1415
|
+
if (value === void 0) return "undefined";
|
|
1416
|
+
if (value === null) return "null";
|
|
1417
|
+
if (typeof value === "string") {
|
|
1418
|
+
return value.trim().length > 0 ? JSON.stringify(value) : "an empty string";
|
|
1419
|
+
}
|
|
1420
|
+
return `${typeof value} ${JSON.stringify(value)}`;
|
|
1421
|
+
}
|
|
1422
|
+
function invalidBaseUrlError(message, hint) {
|
|
1423
|
+
return new AthenaGatewayError({
|
|
1424
|
+
code: "INVALID_URL",
|
|
1425
|
+
message,
|
|
1426
|
+
status: 0,
|
|
1427
|
+
hint
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
function normalizeAthenaGatewayBaseUrl(input, options = {}) {
|
|
1431
|
+
const label = options.label ?? "Athena gateway base URL";
|
|
1432
|
+
const candidate = input ?? options.defaultBaseUrl;
|
|
1433
|
+
if (candidate === void 0 || candidate === null) {
|
|
1434
|
+
throw invalidBaseUrlError(
|
|
1435
|
+
`${label} must be a non-empty absolute http(s) URL. Received ${describeReceivedValue(input)}.`,
|
|
1436
|
+
'Set ATHENA_URL (or pass createClient(url, ...)) to a full URL such as "https://mirror3.athena-db.com".'
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
1439
|
+
const trimmed = candidate.trim();
|
|
1440
|
+
if (!trimmed) {
|
|
1441
|
+
throw invalidBaseUrlError(
|
|
1442
|
+
`${label} must be a non-empty absolute http(s) URL. Received ${describeReceivedValue(candidate)}.`,
|
|
1443
|
+
'Set ATHENA_URL (or pass createClient(url, ...)) to a full URL such as "https://mirror3.athena-db.com".'
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1446
|
+
let parsed;
|
|
1447
|
+
try {
|
|
1448
|
+
parsed = new URL(trimmed);
|
|
1449
|
+
} catch {
|
|
1450
|
+
throw invalidBaseUrlError(
|
|
1451
|
+
`${label} must be a valid absolute http(s) URL. Received ${describeReceivedValue(candidate)}.`,
|
|
1452
|
+
'Use a full URL including the protocol, for example "https://mirror3.athena-db.com".'
|
|
1453
|
+
);
|
|
1454
|
+
}
|
|
1455
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
1456
|
+
throw invalidBaseUrlError(
|
|
1457
|
+
`${label} must use http or https. Received ${JSON.stringify(trimmed)}.`,
|
|
1458
|
+
'Use an Athena gateway URL such as "https://mirror3.athena-db.com".'
|
|
1459
|
+
);
|
|
1460
|
+
}
|
|
1461
|
+
if (parsed.search || parsed.hash) {
|
|
1462
|
+
throw invalidBaseUrlError(
|
|
1463
|
+
`${label} must not include query parameters or hash fragments. Received ${JSON.stringify(trimmed)}.`,
|
|
1464
|
+
'Pass only the base URL. Endpoint paths such as "/gateway/fetch" are appended by the SDK.'
|
|
1465
|
+
);
|
|
1466
|
+
}
|
|
1467
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
1468
|
+
}
|
|
1469
|
+
function buildAthenaGatewayUrl(baseUrl, path) {
|
|
1470
|
+
if (!path.startsWith("/")) {
|
|
1471
|
+
throw invalidBaseUrlError(
|
|
1472
|
+
`Athena gateway path must start with "/". Received ${JSON.stringify(path)}.`,
|
|
1473
|
+
'Use a leading slash such as "/gateway/fetch" or "/".'
|
|
1474
|
+
);
|
|
1475
|
+
}
|
|
1476
|
+
return `${baseUrl}${path}`;
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
// src/cookies/cookie-utils.ts
|
|
1480
|
+
var SECURE_COOKIE_PREFIX = "__Secure-";
|
|
1481
|
+
function parseCookies(cookieHeader) {
|
|
1482
|
+
const cookies = cookieHeader.split("; ");
|
|
1483
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
1484
|
+
cookies.forEach((cookie) => {
|
|
1485
|
+
const [name, value] = cookie.split(/=(.*)/s);
|
|
1486
|
+
cookieMap.set(name, value);
|
|
1487
|
+
});
|
|
1488
|
+
return cookieMap;
|
|
1489
|
+
}
|
|
1490
|
+
var getSessionCookie = (request, config) => {
|
|
1491
|
+
const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
|
|
1492
|
+
if (!cookies) {
|
|
1493
|
+
return null;
|
|
1494
|
+
}
|
|
1495
|
+
const { cookieName = "session_token", cookiePrefix = "athena-auth" } = {};
|
|
1496
|
+
const parsedCookie = parseCookies(cookies);
|
|
1497
|
+
const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
|
|
1498
|
+
const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
|
|
1499
|
+
if (sessionToken) {
|
|
1500
|
+
return sessionToken;
|
|
1501
|
+
}
|
|
1502
|
+
return null;
|
|
1503
|
+
};
|
|
1504
|
+
|
|
1505
|
+
// package.json
|
|
1506
|
+
var package_default = {
|
|
1507
|
+
version: "2.4.1"
|
|
1508
|
+
};
|
|
1509
|
+
|
|
1510
|
+
// src/sdk-version.ts
|
|
1511
|
+
var PACKAGE_VERSION = package_default.version;
|
|
1512
|
+
function buildSdkHeaderValue(sdkName) {
|
|
1513
|
+
return `${sdkName} ${PACKAGE_VERSION}`;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1360
1516
|
// src/gateway/client.ts
|
|
1361
|
-
var DEFAULT_BASE_URL = "https://athena-db.com";
|
|
1362
1517
|
var DEFAULT_CLIENT = "railway_direct";
|
|
1363
|
-
var FALLBACK_SDK_VERSION = "1.3.0";
|
|
1364
1518
|
var SDK_NAME = "xylex-group/athena";
|
|
1365
|
-
var
|
|
1366
|
-
var SDK_HEADER_VALUE = `${SDK_NAME} ${SDK_VERSION}`;
|
|
1519
|
+
var SDK_HEADER_VALUE = buildSdkHeaderValue(SDK_NAME);
|
|
1367
1520
|
function parseResponseBody(rawText, contentType) {
|
|
1368
1521
|
if (!rawText) {
|
|
1369
1522
|
return { parsed: null, parseFailed: false };
|
|
@@ -1382,6 +1535,37 @@ function parseResponseBody(rawText, contentType) {
|
|
|
1382
1535
|
function normalizeHeaderValue(value) {
|
|
1383
1536
|
return value ? value : void 0;
|
|
1384
1537
|
}
|
|
1538
|
+
function resolveHeaderValue(headers, candidates) {
|
|
1539
|
+
for (const candidate of candidates) {
|
|
1540
|
+
const direct = normalizeHeaderValue(headers[candidate]);
|
|
1541
|
+
if (direct) return direct;
|
|
1542
|
+
}
|
|
1543
|
+
const loweredCandidates = new Set(candidates.map((candidate) => candidate.toLowerCase()));
|
|
1544
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
1545
|
+
if (!loweredCandidates.has(key.toLowerCase())) {
|
|
1546
|
+
continue;
|
|
1547
|
+
}
|
|
1548
|
+
const normalized = normalizeHeaderValue(value);
|
|
1549
|
+
if (normalized) return normalized;
|
|
1550
|
+
}
|
|
1551
|
+
return void 0;
|
|
1552
|
+
}
|
|
1553
|
+
function resolveBearerTokenFromAuthorizationHeader(headers) {
|
|
1554
|
+
const authorization = resolveHeaderValue(headers, ["Authorization"]);
|
|
1555
|
+
if (!authorization) {
|
|
1556
|
+
return void 0;
|
|
1557
|
+
}
|
|
1558
|
+
const match = authorization.match(/^Bearer\s+(.+)$/i);
|
|
1559
|
+
const token = match?.[1]?.trim();
|
|
1560
|
+
return token ? token : void 0;
|
|
1561
|
+
}
|
|
1562
|
+
function resolveSessionTokenFromCookieHeader(headers) {
|
|
1563
|
+
const cookie = resolveHeaderValue(headers, ["Cookie"]);
|
|
1564
|
+
if (!cookie) {
|
|
1565
|
+
return void 0;
|
|
1566
|
+
}
|
|
1567
|
+
return getSessionCookie(new Headers({ cookie })) ?? void 0;
|
|
1568
|
+
}
|
|
1385
1569
|
function isRecord2(value) {
|
|
1386
1570
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1387
1571
|
}
|
|
@@ -1499,7 +1683,7 @@ function buildRpcGetEndpoint(payload) {
|
|
|
1499
1683
|
status: 0
|
|
1500
1684
|
});
|
|
1501
1685
|
}
|
|
1502
|
-
query.
|
|
1686
|
+
query.append(filter.column, toRpcFilterQueryValue(filter));
|
|
1503
1687
|
}
|
|
1504
1688
|
}
|
|
1505
1689
|
const endpoint = `/rpc/${encodeURIComponent(functionName)}`;
|
|
@@ -1545,6 +1729,20 @@ function buildHeaders(config, options) {
|
|
|
1545
1729
|
headers["apikey"] = finalApiKey;
|
|
1546
1730
|
headers["x-api-key"] = headers["x-api-key"] ?? finalApiKey;
|
|
1547
1731
|
}
|
|
1732
|
+
const explicitSessionToken = resolveHeaderValue(extraHeaders, [
|
|
1733
|
+
"X-Athena-Auth-Session-Token"
|
|
1734
|
+
]);
|
|
1735
|
+
const derivedSessionToken = explicitSessionToken ?? resolveSessionTokenFromCookieHeader(extraHeaders);
|
|
1736
|
+
if (derivedSessionToken) {
|
|
1737
|
+
headers["X-Athena-Auth-Session-Token"] = derivedSessionToken;
|
|
1738
|
+
}
|
|
1739
|
+
const explicitBearerToken = resolveHeaderValue(extraHeaders, [
|
|
1740
|
+
"X-Athena-Auth-Bearer-Token"
|
|
1741
|
+
]);
|
|
1742
|
+
const derivedBearerToken = explicitBearerToken ?? resolveBearerTokenFromAuthorizationHeader(extraHeaders);
|
|
1743
|
+
if (derivedBearerToken) {
|
|
1744
|
+
headers["X-Athena-Auth-Bearer-Token"] = derivedBearerToken;
|
|
1745
|
+
}
|
|
1548
1746
|
const athenaClientKeys = ["x-athena-client", "X-Athena-Client"];
|
|
1549
1747
|
Object.entries(extraHeaders).forEach(([key, value]) => {
|
|
1550
1748
|
if (athenaClientKeys.includes(key)) return;
|
|
@@ -1555,9 +1753,168 @@ function buildHeaders(config, options) {
|
|
|
1555
1753
|
});
|
|
1556
1754
|
return headers;
|
|
1557
1755
|
}
|
|
1756
|
+
function toInvalidUrlResponse(error, endpoint, method) {
|
|
1757
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1758
|
+
const gatewayError = error instanceof AthenaGatewayError ? error : new AthenaGatewayError({
|
|
1759
|
+
code: "INVALID_URL",
|
|
1760
|
+
message,
|
|
1761
|
+
status: 0,
|
|
1762
|
+
endpoint,
|
|
1763
|
+
method,
|
|
1764
|
+
cause: message,
|
|
1765
|
+
hint: "Set ATHENA_URL to a full http(s) URL before running queries."
|
|
1766
|
+
});
|
|
1767
|
+
return {
|
|
1768
|
+
ok: false,
|
|
1769
|
+
status: 0,
|
|
1770
|
+
statusText: null,
|
|
1771
|
+
data: null,
|
|
1772
|
+
error: gatewayError.message,
|
|
1773
|
+
errorDetails: detailsFromError(
|
|
1774
|
+
new AthenaGatewayError({
|
|
1775
|
+
code: gatewayError.code,
|
|
1776
|
+
message: gatewayError.message,
|
|
1777
|
+
status: gatewayError.status,
|
|
1778
|
+
endpoint,
|
|
1779
|
+
method,
|
|
1780
|
+
requestId: gatewayError.requestId,
|
|
1781
|
+
hint: gatewayError.hint,
|
|
1782
|
+
cause: gatewayError.causeDetail
|
|
1783
|
+
})
|
|
1784
|
+
),
|
|
1785
|
+
raw: null
|
|
1786
|
+
};
|
|
1787
|
+
}
|
|
1788
|
+
function resolveGatewayBaseUrl(input) {
|
|
1789
|
+
return normalizeAthenaGatewayBaseUrl(input, {
|
|
1790
|
+
defaultBaseUrl: ATHENA_DEFAULT_BASE_URL
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
function resolveProbePath(path) {
|
|
1794
|
+
if (!path) return "/";
|
|
1795
|
+
if (!path.startsWith("/")) {
|
|
1796
|
+
throw new AthenaGatewayError({
|
|
1797
|
+
code: "INVALID_URL",
|
|
1798
|
+
message: `Athena gateway probe path must start with "/". Received ${JSON.stringify(path)}.`,
|
|
1799
|
+
status: 0,
|
|
1800
|
+
hint: 'Use a leading slash such as "/" or "/health".'
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
return path;
|
|
1804
|
+
}
|
|
1805
|
+
function mergeConnectionHeaders(baseHeaders, headers) {
|
|
1806
|
+
const merged = {
|
|
1807
|
+
...baseHeaders,
|
|
1808
|
+
...headers ?? {}
|
|
1809
|
+
};
|
|
1810
|
+
if (!merged["X-Athena-Sdk"] && !merged["x-athena-sdk"]) {
|
|
1811
|
+
merged["X-Athena-Sdk"] = SDK_HEADER_VALUE;
|
|
1812
|
+
}
|
|
1813
|
+
return merged;
|
|
1814
|
+
}
|
|
1815
|
+
async function performConnectionCheck(baseUrl, requestHeaders, options) {
|
|
1816
|
+
const path = resolveProbePath(options?.path);
|
|
1817
|
+
const url = buildAthenaGatewayUrl(baseUrl, path);
|
|
1818
|
+
try {
|
|
1819
|
+
const response = await fetch(url, {
|
|
1820
|
+
method: "GET",
|
|
1821
|
+
headers: mergeConnectionHeaders(requestHeaders, options?.headers),
|
|
1822
|
+
signal: options?.signal
|
|
1823
|
+
});
|
|
1824
|
+
const rawText = await response.text();
|
|
1825
|
+
const requestId = resolveRequestId(response.headers);
|
|
1826
|
+
const parsedBody = parseResponseBody(
|
|
1827
|
+
rawText ?? "",
|
|
1828
|
+
response.headers.get("content-type")
|
|
1829
|
+
);
|
|
1830
|
+
if (parsedBody.parseFailed) {
|
|
1831
|
+
const invalidJsonError = new AthenaGatewayError({
|
|
1832
|
+
code: "INVALID_JSON",
|
|
1833
|
+
message: "Gateway probe returned malformed JSON",
|
|
1834
|
+
status: response.status,
|
|
1835
|
+
method: "GET",
|
|
1836
|
+
requestId,
|
|
1837
|
+
hint: "Verify the gateway response body is valid JSON.",
|
|
1838
|
+
cause: rawText.slice(0, 300)
|
|
1839
|
+
});
|
|
1840
|
+
return {
|
|
1841
|
+
ok: false,
|
|
1842
|
+
reachable: true,
|
|
1843
|
+
status: response.status,
|
|
1844
|
+
statusText: resolveStatusText(response, parsedBody.parsed),
|
|
1845
|
+
baseUrl,
|
|
1846
|
+
url,
|
|
1847
|
+
error: invalidJsonError.message,
|
|
1848
|
+
errorDetails: detailsFromError(invalidJsonError),
|
|
1849
|
+
raw: parsedBody.parsed
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1852
|
+
const parsed = parsedBody.parsed;
|
|
1853
|
+
if (!response.ok) {
|
|
1854
|
+
const httpError = new AthenaGatewayError({
|
|
1855
|
+
code: "HTTP_ERROR",
|
|
1856
|
+
message: resolveErrorMessage(
|
|
1857
|
+
parsed,
|
|
1858
|
+
`Athena gateway GET ${path} failed with status ${response.status}`
|
|
1859
|
+
),
|
|
1860
|
+
status: response.status,
|
|
1861
|
+
method: "GET",
|
|
1862
|
+
requestId,
|
|
1863
|
+
hint: resolveErrorHint(parsed)
|
|
1864
|
+
});
|
|
1865
|
+
return {
|
|
1866
|
+
ok: false,
|
|
1867
|
+
reachable: true,
|
|
1868
|
+
status: response.status,
|
|
1869
|
+
statusText: resolveStatusText(response, parsed),
|
|
1870
|
+
baseUrl,
|
|
1871
|
+
url,
|
|
1872
|
+
error: httpError.message,
|
|
1873
|
+
errorDetails: detailsFromError(httpError),
|
|
1874
|
+
raw: parsed
|
|
1875
|
+
};
|
|
1876
|
+
}
|
|
1877
|
+
return {
|
|
1878
|
+
ok: true,
|
|
1879
|
+
reachable: true,
|
|
1880
|
+
status: response.status,
|
|
1881
|
+
statusText: resolveStatusText(response, parsed),
|
|
1882
|
+
baseUrl,
|
|
1883
|
+
url,
|
|
1884
|
+
error: void 0,
|
|
1885
|
+
errorDetails: null,
|
|
1886
|
+
raw: parsed
|
|
1887
|
+
};
|
|
1888
|
+
} catch (callError) {
|
|
1889
|
+
const message = callError instanceof Error ? callError.message : String(callError);
|
|
1890
|
+
const networkError = new AthenaGatewayError({
|
|
1891
|
+
code: "NETWORK_ERROR",
|
|
1892
|
+
message: `Network error while probing Athena gateway ${url}: ${message}`,
|
|
1893
|
+
method: "GET",
|
|
1894
|
+
cause: message,
|
|
1895
|
+
hint: "Check gateway URL, DNS, and network reachability."
|
|
1896
|
+
});
|
|
1897
|
+
return {
|
|
1898
|
+
ok: false,
|
|
1899
|
+
reachable: false,
|
|
1900
|
+
status: 0,
|
|
1901
|
+
statusText: null,
|
|
1902
|
+
baseUrl,
|
|
1903
|
+
url,
|
|
1904
|
+
error: networkError.message,
|
|
1905
|
+
errorDetails: detailsFromError(networkError),
|
|
1906
|
+
raw: null
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1558
1910
|
async function callAthena(config, endpoint, method, payload, options) {
|
|
1559
|
-
|
|
1560
|
-
|
|
1911
|
+
let baseUrl;
|
|
1912
|
+
try {
|
|
1913
|
+
baseUrl = resolveGatewayBaseUrl(options?.baseUrl ?? config.baseUrl);
|
|
1914
|
+
} catch (error) {
|
|
1915
|
+
return toInvalidUrlResponse(error, endpoint, method);
|
|
1916
|
+
}
|
|
1917
|
+
const url = buildAthenaGatewayUrl(baseUrl, endpoint);
|
|
1561
1918
|
const headers = buildHeaders(config, options);
|
|
1562
1919
|
try {
|
|
1563
1920
|
const requestInit = {
|
|
@@ -1654,32 +2011,44 @@ async function callAthena(config, endpoint, method, payload, options) {
|
|
|
1654
2011
|
}
|
|
1655
2012
|
}
|
|
1656
2013
|
function createAthenaGatewayClient(config = {}) {
|
|
2014
|
+
const normalizedBaseUrl = resolveGatewayBaseUrl(config.baseUrl);
|
|
2015
|
+
const normalizedConfig = {
|
|
2016
|
+
...config,
|
|
2017
|
+
baseUrl: normalizedBaseUrl
|
|
2018
|
+
};
|
|
1657
2019
|
return {
|
|
1658
|
-
baseUrl:
|
|
2020
|
+
baseUrl: normalizedBaseUrl,
|
|
1659
2021
|
buildHeaders(options) {
|
|
1660
|
-
return buildHeaders(
|
|
2022
|
+
return buildHeaders(normalizedConfig, options);
|
|
2023
|
+
},
|
|
2024
|
+
verifyConnection(options) {
|
|
2025
|
+
return performConnectionCheck(
|
|
2026
|
+
normalizedBaseUrl,
|
|
2027
|
+
buildHeaders(normalizedConfig),
|
|
2028
|
+
options
|
|
2029
|
+
);
|
|
1661
2030
|
},
|
|
1662
2031
|
fetchGateway(payload, options) {
|
|
1663
|
-
return callAthena(
|
|
2032
|
+
return callAthena(normalizedConfig, "/gateway/fetch", "POST", payload, options);
|
|
1664
2033
|
},
|
|
1665
2034
|
insertGateway(payload, options) {
|
|
1666
|
-
return callAthena(
|
|
2035
|
+
return callAthena(normalizedConfig, "/gateway/insert", "PUT", payload, options);
|
|
1667
2036
|
},
|
|
1668
2037
|
updateGateway(payload, options) {
|
|
1669
|
-
return callAthena(
|
|
2038
|
+
return callAthena(normalizedConfig, "/gateway/update", "POST", payload, options);
|
|
1670
2039
|
},
|
|
1671
2040
|
deleteGateway(payload, options) {
|
|
1672
|
-
return callAthena(
|
|
2041
|
+
return callAthena(normalizedConfig, "/gateway/delete", "DELETE", payload, options);
|
|
1673
2042
|
},
|
|
1674
2043
|
rpcGateway(payload, options) {
|
|
1675
2044
|
if (options?.get) {
|
|
1676
2045
|
const endpoint = buildRpcGetEndpoint(payload);
|
|
1677
|
-
return callAthena(
|
|
2046
|
+
return callAthena(normalizedConfig, endpoint, "GET", null, options);
|
|
1678
2047
|
}
|
|
1679
|
-
return callAthena(
|
|
2048
|
+
return callAthena(normalizedConfig, "/gateway/rpc", "POST", payload, options);
|
|
1680
2049
|
},
|
|
1681
2050
|
queryGateway(payload, options) {
|
|
1682
|
-
return callAthena(
|
|
2051
|
+
return callAthena(normalizedConfig, "/gateway/query", "POST", payload, options);
|
|
1683
2052
|
}
|
|
1684
2053
|
};
|
|
1685
2054
|
}
|
|
@@ -2008,10 +2377,8 @@ async function resolveReactEmailPayloadFields(input, fields, options) {
|
|
|
2008
2377
|
|
|
2009
2378
|
// src/auth/client.ts
|
|
2010
2379
|
var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
|
|
2011
|
-
var FALLBACK_SDK_VERSION2 = "1.0.0";
|
|
2012
2380
|
var SDK_NAME2 = "xylex-group/athena-auth";
|
|
2013
|
-
var
|
|
2014
|
-
var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
|
|
2381
|
+
var SDK_HEADER_VALUE2 = buildSdkHeaderValue(SDK_NAME2);
|
|
2015
2382
|
function normalizeBaseUrl(baseUrl) {
|
|
2016
2383
|
return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
|
|
2017
2384
|
}
|
|
@@ -3084,8 +3451,8 @@ function createAuthClient(config = {}) {
|
|
|
3084
3451
|
// src/db/module.ts
|
|
3085
3452
|
function createDbModule(input) {
|
|
3086
3453
|
const db = {
|
|
3087
|
-
from(table) {
|
|
3088
|
-
return input.from(table);
|
|
3454
|
+
from(table, options) {
|
|
3455
|
+
return input.from(table, options);
|
|
3089
3456
|
},
|
|
3090
3457
|
select(table, columns, options) {
|
|
3091
3458
|
return input.from(table).select(columns, options);
|
|
@@ -3190,7 +3557,19 @@ function buildGatewayCondition(operator, column, value) {
|
|
|
3190
3557
|
function compileRelationToken(key, node) {
|
|
3191
3558
|
const nested = compileSelectShape(node.select);
|
|
3192
3559
|
const propertyKey = normalizeIdentifier(key, "select relation key");
|
|
3193
|
-
|
|
3560
|
+
if (node.schema && node.via) {
|
|
3561
|
+
throw new Error(
|
|
3562
|
+
`findMany relation "${propertyKey}" cannot combine schema and via yet; use schema with the relation key, or use via without schema`
|
|
3563
|
+
);
|
|
3564
|
+
}
|
|
3565
|
+
const relationTokenBase = normalizeIdentifier(node.via ?? propertyKey, "select relation token");
|
|
3566
|
+
if (node.schema && relationTokenBase.includes(".")) {
|
|
3567
|
+
throw new Error(
|
|
3568
|
+
`findMany relation "${propertyKey}" already resolves to a qualified relation token; do not also set schema`
|
|
3569
|
+
);
|
|
3570
|
+
}
|
|
3571
|
+
const relationSchema = node.schema?.trim();
|
|
3572
|
+
const relationToken = relationSchema ? `${normalizeIdentifier(relationSchema, "select relation schema")}.${relationTokenBase}` : relationTokenBase;
|
|
3194
3573
|
const alias = node.as?.trim() || (relationToken !== propertyKey ? propertyKey : "");
|
|
3195
3574
|
const prefix = alias ? `${alias}:` : "";
|
|
3196
3575
|
return `${prefix}${relationToken}(${nested})`;
|
|
@@ -3219,6 +3598,23 @@ function compileSelectShape(select) {
|
|
|
3219
3598
|
}
|
|
3220
3599
|
return tokens.join(",");
|
|
3221
3600
|
}
|
|
3601
|
+
function selectShapeUsesRelationSchema(select) {
|
|
3602
|
+
if (!isRecord5(select)) {
|
|
3603
|
+
return false;
|
|
3604
|
+
}
|
|
3605
|
+
for (const rawValue of Object.values(select)) {
|
|
3606
|
+
if (!isRelationSelectNode(rawValue)) {
|
|
3607
|
+
continue;
|
|
3608
|
+
}
|
|
3609
|
+
if (typeof rawValue.schema === "string" && rawValue.schema.trim().length > 0) {
|
|
3610
|
+
return true;
|
|
3611
|
+
}
|
|
3612
|
+
if (selectShapeUsesRelationSchema(rawValue.select)) {
|
|
3613
|
+
return true;
|
|
3614
|
+
}
|
|
3615
|
+
}
|
|
3616
|
+
return false;
|
|
3617
|
+
}
|
|
3222
3618
|
function compileColumnWhere(column, input) {
|
|
3223
3619
|
const normalizedColumn = normalizeIdentifier(column, "where column");
|
|
3224
3620
|
if (!isRecord5(input)) {
|
|
@@ -3355,6 +3751,356 @@ function compileOrderBy(orderBy) {
|
|
|
3355
3751
|
};
|
|
3356
3752
|
}
|
|
3357
3753
|
|
|
3754
|
+
// src/gateway/structured-select.ts
|
|
3755
|
+
var IDENTIFIER_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
3756
|
+
function isIdentifierPath(value) {
|
|
3757
|
+
const segments = value.split(".").map((segment) => segment.trim());
|
|
3758
|
+
return segments.length > 1 && segments.every((segment) => IDENTIFIER_SEGMENT_PATTERN.test(segment));
|
|
3759
|
+
}
|
|
3760
|
+
function extractRelationHead(raw) {
|
|
3761
|
+
const trimmed = raw.trim();
|
|
3762
|
+
if (!trimmed) return "";
|
|
3763
|
+
const aliasIndex = trimmed.indexOf(":");
|
|
3764
|
+
const withoutAlias = aliasIndex >= 0 ? trimmed.slice(aliasIndex + 1).trim() : trimmed;
|
|
3765
|
+
const modifierIndex = withoutAlias.indexOf("!");
|
|
3766
|
+
return (modifierIndex >= 0 ? withoutAlias.slice(0, modifierIndex) : withoutAlias).trim();
|
|
3767
|
+
}
|
|
3768
|
+
function hasSchemaQualifiedRelationToken(select) {
|
|
3769
|
+
let singleQuoted = false;
|
|
3770
|
+
let doubleQuoted = false;
|
|
3771
|
+
let tokenStart = 0;
|
|
3772
|
+
for (let index = 0; index < select.length; index += 1) {
|
|
3773
|
+
const char = select[index];
|
|
3774
|
+
const next = index + 1 < select.length ? select[index + 1] : "";
|
|
3775
|
+
if (singleQuoted) {
|
|
3776
|
+
if (char === "'" && next === "'") {
|
|
3777
|
+
index += 1;
|
|
3778
|
+
continue;
|
|
3779
|
+
}
|
|
3780
|
+
if (char === "'") {
|
|
3781
|
+
singleQuoted = false;
|
|
3782
|
+
}
|
|
3783
|
+
continue;
|
|
3784
|
+
}
|
|
3785
|
+
if (doubleQuoted) {
|
|
3786
|
+
if (char === '"' && next === '"') {
|
|
3787
|
+
index += 1;
|
|
3788
|
+
continue;
|
|
3789
|
+
}
|
|
3790
|
+
if (char === '"') {
|
|
3791
|
+
doubleQuoted = false;
|
|
3792
|
+
}
|
|
3793
|
+
continue;
|
|
3794
|
+
}
|
|
3795
|
+
if (char === "'") {
|
|
3796
|
+
singleQuoted = true;
|
|
3797
|
+
continue;
|
|
3798
|
+
}
|
|
3799
|
+
if (char === '"') {
|
|
3800
|
+
doubleQuoted = true;
|
|
3801
|
+
continue;
|
|
3802
|
+
}
|
|
3803
|
+
if (char === "(") {
|
|
3804
|
+
const relationHead = extractRelationHead(select.slice(tokenStart, index));
|
|
3805
|
+
if (isIdentifierPath(relationHead)) {
|
|
3806
|
+
return true;
|
|
3807
|
+
}
|
|
3808
|
+
tokenStart = index + 1;
|
|
3809
|
+
continue;
|
|
3810
|
+
}
|
|
3811
|
+
if (char === "," || char === ")") {
|
|
3812
|
+
tokenStart = index + 1;
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
return false;
|
|
3816
|
+
}
|
|
3817
|
+
function toStructuredSelectString(columns) {
|
|
3818
|
+
return Array.isArray(columns) ? columns.join(",") : columns;
|
|
3819
|
+
}
|
|
3820
|
+
function buildStructuredWhere(conditions) {
|
|
3821
|
+
if (!conditions?.length) return void 0;
|
|
3822
|
+
const where = {};
|
|
3823
|
+
for (const condition of conditions) {
|
|
3824
|
+
if (!condition.column) {
|
|
3825
|
+
return null;
|
|
3826
|
+
}
|
|
3827
|
+
if (condition.value_cast !== void 0) {
|
|
3828
|
+
return null;
|
|
3829
|
+
}
|
|
3830
|
+
const operand = condition.value;
|
|
3831
|
+
const operator = condition.operator;
|
|
3832
|
+
if (operator === "eq") {
|
|
3833
|
+
if (operand === void 0) return null;
|
|
3834
|
+
} else if (operator === "neq" || operator === "gt" || operator === "lt") {
|
|
3835
|
+
if (operand === void 0) return null;
|
|
3836
|
+
} else if (operator === "in") {
|
|
3837
|
+
if (!Array.isArray(operand)) return null;
|
|
3838
|
+
} else {
|
|
3839
|
+
return null;
|
|
3840
|
+
}
|
|
3841
|
+
const existing = where[condition.column];
|
|
3842
|
+
if (existing !== void 0 && (typeof existing !== "object" || existing === null || Array.isArray(existing))) {
|
|
3843
|
+
return null;
|
|
3844
|
+
}
|
|
3845
|
+
const next = existing ?? {};
|
|
3846
|
+
if (Object.prototype.hasOwnProperty.call(next, operator)) {
|
|
3847
|
+
return null;
|
|
3848
|
+
}
|
|
3849
|
+
next[operator] = operand;
|
|
3850
|
+
where[condition.column] = next;
|
|
3851
|
+
}
|
|
3852
|
+
return where;
|
|
3853
|
+
}
|
|
3854
|
+
function buildStructuredOrderBy(order) {
|
|
3855
|
+
if (!order?.field) return void 0;
|
|
3856
|
+
return {
|
|
3857
|
+
[order.field]: order.direction === "descending" ? "desc" : "asc"
|
|
3858
|
+
};
|
|
3859
|
+
}
|
|
3860
|
+
function buildStructuredSelectTransport(input) {
|
|
3861
|
+
const select = toStructuredSelectString(input.columns).trim();
|
|
3862
|
+
if (!select || select === "*") {
|
|
3863
|
+
return null;
|
|
3864
|
+
}
|
|
3865
|
+
if (!hasSchemaQualifiedRelationToken(select)) {
|
|
3866
|
+
return null;
|
|
3867
|
+
}
|
|
3868
|
+
if (input.count !== void 0 || input.head !== void 0) {
|
|
3869
|
+
return {
|
|
3870
|
+
error: "Schema-qualified nested select strings require structured select transport, which does not support count/head options in athena-js yet."
|
|
3871
|
+
};
|
|
3872
|
+
}
|
|
3873
|
+
const where = buildStructuredWhere(input.conditions);
|
|
3874
|
+
if (where === null) {
|
|
3875
|
+
return {
|
|
3876
|
+
error: "Schema-qualified nested select strings only support eq, neq, gt, lt, and in filters in athena-js structured select transport."
|
|
3877
|
+
};
|
|
3878
|
+
}
|
|
3879
|
+
return {
|
|
3880
|
+
select,
|
|
3881
|
+
payload: {
|
|
3882
|
+
table_name: input.tableName,
|
|
3883
|
+
select,
|
|
3884
|
+
where,
|
|
3885
|
+
orderBy: buildStructuredOrderBy(input.order),
|
|
3886
|
+
limit: input.limit,
|
|
3887
|
+
offset: input.offset,
|
|
3888
|
+
strip_nulls: input.stripNulls
|
|
3889
|
+
}
|
|
3890
|
+
};
|
|
3891
|
+
}
|
|
3892
|
+
|
|
3893
|
+
// src/query-transport.ts
|
|
3894
|
+
function canUseFindManyAstTransport(state) {
|
|
3895
|
+
return state.conditions.length === 0 && state.offset === void 0 && state.currentPage === void 0 && state.pageSize === void 0 && state.totalPages === void 0;
|
|
3896
|
+
}
|
|
3897
|
+
function toFindManyAstOrder(order) {
|
|
3898
|
+
if (!order) {
|
|
3899
|
+
return void 0;
|
|
3900
|
+
}
|
|
3901
|
+
return {
|
|
3902
|
+
column: order.field,
|
|
3903
|
+
ascending: order.direction !== "descending"
|
|
3904
|
+
};
|
|
3905
|
+
}
|
|
3906
|
+
function isRecord6(value) {
|
|
3907
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3908
|
+
}
|
|
3909
|
+
function normalizeFindManyAstColumnPredicate(value) {
|
|
3910
|
+
if (!isRecord6(value)) {
|
|
3911
|
+
return {
|
|
3912
|
+
eq: value
|
|
3913
|
+
};
|
|
3914
|
+
}
|
|
3915
|
+
const normalized = {};
|
|
3916
|
+
for (const [key, operand] of Object.entries(value)) {
|
|
3917
|
+
if (operand !== void 0) {
|
|
3918
|
+
normalized[key] = operand;
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
return normalized;
|
|
3922
|
+
}
|
|
3923
|
+
function normalizeFindManyAstBooleanOperand(clause) {
|
|
3924
|
+
const normalized = {};
|
|
3925
|
+
for (const [column, value] of Object.entries(clause)) {
|
|
3926
|
+
if (value === void 0) {
|
|
3927
|
+
continue;
|
|
3928
|
+
}
|
|
3929
|
+
normalized[column] = normalizeFindManyAstColumnPredicate(value);
|
|
3930
|
+
}
|
|
3931
|
+
return normalized;
|
|
3932
|
+
}
|
|
3933
|
+
function normalizeFindManyAstWhere(where) {
|
|
3934
|
+
if (!where || !isRecord6(where)) {
|
|
3935
|
+
return where;
|
|
3936
|
+
}
|
|
3937
|
+
const normalized = {};
|
|
3938
|
+
for (const [key, value] of Object.entries(where)) {
|
|
3939
|
+
if (value === void 0) {
|
|
3940
|
+
continue;
|
|
3941
|
+
}
|
|
3942
|
+
if (key === "or" && Array.isArray(value)) {
|
|
3943
|
+
normalized.or = value.map(
|
|
3944
|
+
(clause) => normalizeFindManyAstBooleanOperand(clause)
|
|
3945
|
+
);
|
|
3946
|
+
continue;
|
|
3947
|
+
}
|
|
3948
|
+
if (key === "not" && isRecord6(value)) {
|
|
3949
|
+
normalized.not = normalizeFindManyAstBooleanOperand(
|
|
3950
|
+
value
|
|
3951
|
+
);
|
|
3952
|
+
continue;
|
|
3953
|
+
}
|
|
3954
|
+
normalized[key] = normalizeFindManyAstColumnPredicate(value);
|
|
3955
|
+
}
|
|
3956
|
+
return normalized;
|
|
3957
|
+
}
|
|
3958
|
+
function predicateRequiresUuidQueryFallback(column, value) {
|
|
3959
|
+
if (!isRecord6(value)) {
|
|
3960
|
+
return shouldUseUuidTextComparison(column, value);
|
|
3961
|
+
}
|
|
3962
|
+
const eqValue = value.eq;
|
|
3963
|
+
return eqValue !== void 0 && shouldUseUuidTextComparison(column, eqValue);
|
|
3964
|
+
}
|
|
3965
|
+
function booleanOperandRequiresUuidQueryFallback(clause) {
|
|
3966
|
+
for (const [column, value] of Object.entries(clause)) {
|
|
3967
|
+
if (value === void 0) {
|
|
3968
|
+
continue;
|
|
3969
|
+
}
|
|
3970
|
+
if (predicateRequiresUuidQueryFallback(column, value)) {
|
|
3971
|
+
return true;
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
return false;
|
|
3975
|
+
}
|
|
3976
|
+
function findManyAstWhereRequiresLegacyTransport(where) {
|
|
3977
|
+
if (!where || !isRecord6(where)) {
|
|
3978
|
+
return false;
|
|
3979
|
+
}
|
|
3980
|
+
for (const [key, value] of Object.entries(where)) {
|
|
3981
|
+
if (value === void 0) {
|
|
3982
|
+
continue;
|
|
3983
|
+
}
|
|
3984
|
+
if (key === "or" && Array.isArray(value)) {
|
|
3985
|
+
if (value.some(
|
|
3986
|
+
(clause) => booleanOperandRequiresUuidQueryFallback(clause)
|
|
3987
|
+
)) {
|
|
3988
|
+
return true;
|
|
3989
|
+
}
|
|
3990
|
+
continue;
|
|
3991
|
+
}
|
|
3992
|
+
if (key === "not" && isRecord6(value)) {
|
|
3993
|
+
if (booleanOperandRequiresUuidQueryFallback(value)) {
|
|
3994
|
+
return true;
|
|
3995
|
+
}
|
|
3996
|
+
continue;
|
|
3997
|
+
}
|
|
3998
|
+
if (predicateRequiresUuidQueryFallback(key, value)) {
|
|
3999
|
+
return true;
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
4002
|
+
return false;
|
|
4003
|
+
}
|
|
4004
|
+
function resolvePagination(input) {
|
|
4005
|
+
let limit = input.limit;
|
|
4006
|
+
let offset = input.offset;
|
|
4007
|
+
if (limit === void 0 && input.pageSize !== void 0) {
|
|
4008
|
+
limit = Math.max(0, Math.trunc(input.pageSize));
|
|
4009
|
+
}
|
|
4010
|
+
if (offset === void 0 && input.pageSize !== void 0 && input.currentPage !== void 0 && input.currentPage > 0) {
|
|
4011
|
+
offset = (Math.trunc(input.currentPage) - 1) * Math.max(0, Math.trunc(input.pageSize));
|
|
4012
|
+
}
|
|
4013
|
+
return { limit, offset };
|
|
4014
|
+
}
|
|
4015
|
+
function hasTypedEqualityComparison(conditions) {
|
|
4016
|
+
return conditions?.some(
|
|
4017
|
+
(condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
|
|
4018
|
+
) ?? false;
|
|
4019
|
+
}
|
|
4020
|
+
function createSelectTransportPlan(input) {
|
|
4021
|
+
const conditions = input.state.conditions.length ? input.state.conditions.map((condition) => ({ ...condition })) : void 0;
|
|
4022
|
+
const pagination = resolvePagination({
|
|
4023
|
+
limit: input.state.limit,
|
|
4024
|
+
offset: input.state.offset,
|
|
4025
|
+
currentPage: input.state.currentPage,
|
|
4026
|
+
pageSize: input.state.pageSize
|
|
4027
|
+
});
|
|
4028
|
+
const stripNulls = input.options?.stripNulls ?? true;
|
|
4029
|
+
const structuredSelectTransport = buildStructuredSelectTransport({
|
|
4030
|
+
tableName: input.tableName,
|
|
4031
|
+
columns: input.columns,
|
|
4032
|
+
conditions,
|
|
4033
|
+
limit: pagination.limit,
|
|
4034
|
+
offset: pagination.offset,
|
|
4035
|
+
order: input.state.order,
|
|
4036
|
+
stripNulls,
|
|
4037
|
+
count: input.options?.count,
|
|
4038
|
+
head: input.options?.head
|
|
4039
|
+
});
|
|
4040
|
+
if (structuredSelectTransport && "error" in structuredSelectTransport) {
|
|
4041
|
+
throw new Error(structuredSelectTransport.error);
|
|
4042
|
+
}
|
|
4043
|
+
if (structuredSelectTransport) {
|
|
4044
|
+
const { payload, select } = structuredSelectTransport;
|
|
4045
|
+
return {
|
|
4046
|
+
kind: "fetch",
|
|
4047
|
+
payload,
|
|
4048
|
+
debug: {
|
|
4049
|
+
columns: select,
|
|
4050
|
+
conditions,
|
|
4051
|
+
limit: pagination.limit,
|
|
4052
|
+
offset: pagination.offset,
|
|
4053
|
+
order: input.state.order
|
|
4054
|
+
}
|
|
4055
|
+
};
|
|
4056
|
+
}
|
|
4057
|
+
if (hasTypedEqualityComparison(conditions) && !input.options?.head && !input.options?.count && conditions) {
|
|
4058
|
+
const query = input.buildTypedSelectQuery({
|
|
4059
|
+
tableName: input.tableName,
|
|
4060
|
+
columns: input.columns,
|
|
4061
|
+
conditions,
|
|
4062
|
+
limit: input.state.limit,
|
|
4063
|
+
offset: input.state.offset,
|
|
4064
|
+
currentPage: input.state.currentPage,
|
|
4065
|
+
pageSize: input.state.pageSize,
|
|
4066
|
+
order: input.state.order
|
|
4067
|
+
});
|
|
4068
|
+
if (query) {
|
|
4069
|
+
return {
|
|
4070
|
+
kind: "query",
|
|
4071
|
+
query,
|
|
4072
|
+
payload: { query }
|
|
4073
|
+
};
|
|
4074
|
+
}
|
|
4075
|
+
}
|
|
4076
|
+
return {
|
|
4077
|
+
kind: "fetch",
|
|
4078
|
+
payload: {
|
|
4079
|
+
table_name: input.tableName,
|
|
4080
|
+
columns: input.columns,
|
|
4081
|
+
conditions,
|
|
4082
|
+
limit: input.state.limit,
|
|
4083
|
+
offset: input.state.offset,
|
|
4084
|
+
current_page: input.state.currentPage,
|
|
4085
|
+
page_size: input.state.pageSize,
|
|
4086
|
+
total_pages: input.state.totalPages,
|
|
4087
|
+
sort_by: input.state.order,
|
|
4088
|
+
strip_nulls: stripNulls,
|
|
4089
|
+
count: input.options?.count,
|
|
4090
|
+
head: input.options?.head
|
|
4091
|
+
},
|
|
4092
|
+
debug: {
|
|
4093
|
+
columns: input.columns,
|
|
4094
|
+
conditions,
|
|
4095
|
+
limit: input.state.limit,
|
|
4096
|
+
offset: input.state.offset,
|
|
4097
|
+
currentPage: input.state.currentPage,
|
|
4098
|
+
pageSize: input.state.pageSize,
|
|
4099
|
+
order: input.state.order
|
|
4100
|
+
}
|
|
4101
|
+
};
|
|
4102
|
+
}
|
|
4103
|
+
|
|
3358
4104
|
// src/client.ts
|
|
3359
4105
|
var DEFAULT_COLUMNS = "*";
|
|
3360
4106
|
var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
|
|
@@ -3369,18 +4115,6 @@ var QUERY_TRACE_STACK_SKIP_PATTERNS = [
|
|
|
3369
4115
|
"node:internal",
|
|
3370
4116
|
"internal/process"
|
|
3371
4117
|
];
|
|
3372
|
-
function canUseFindManyAstTransport(state) {
|
|
3373
|
-
return state.conditions.length === 0 && state.offset === void 0 && state.currentPage === void 0 && state.pageSize === void 0 && state.totalPages === void 0;
|
|
3374
|
-
}
|
|
3375
|
-
function toFindManyAstOrder(order) {
|
|
3376
|
-
if (!order) {
|
|
3377
|
-
return void 0;
|
|
3378
|
-
}
|
|
3379
|
-
return {
|
|
3380
|
-
column: order.field,
|
|
3381
|
-
ascending: order.direction !== "descending"
|
|
3382
|
-
};
|
|
3383
|
-
}
|
|
3384
4118
|
function formatResult(response) {
|
|
3385
4119
|
const result = {
|
|
3386
4120
|
data: response.data ?? null,
|
|
@@ -3395,6 +4129,13 @@ function formatResult(response) {
|
|
|
3395
4129
|
}
|
|
3396
4130
|
return result;
|
|
3397
4131
|
}
|
|
4132
|
+
var EXPERIMENTAL_READ_RETRY_CONFIG = {
|
|
4133
|
+
retries: 2,
|
|
4134
|
+
baseDelayMs: 100,
|
|
4135
|
+
maxDelayMs: 1e3,
|
|
4136
|
+
backoff: "exponential",
|
|
4137
|
+
jitter: true
|
|
4138
|
+
};
|
|
3398
4139
|
function attachNormalizedError(result, normalizedError) {
|
|
3399
4140
|
Object.defineProperty(result, ATHENA_NORMALIZED_ERROR_KEY, {
|
|
3400
4141
|
value: normalizedError,
|
|
@@ -3421,7 +4162,36 @@ function createResultFormatter(experimental) {
|
|
|
3421
4162
|
return result;
|
|
3422
4163
|
};
|
|
3423
4164
|
}
|
|
3424
|
-
function
|
|
4165
|
+
async function executeExperimentalRead(experimental, runner) {
|
|
4166
|
+
if (!experimental?.retryReads) {
|
|
4167
|
+
return runner();
|
|
4168
|
+
}
|
|
4169
|
+
let lastRetryableResult;
|
|
4170
|
+
let lastRetrySignal = null;
|
|
4171
|
+
try {
|
|
4172
|
+
return await withRetry(
|
|
4173
|
+
{
|
|
4174
|
+
...EXPERIMENTAL_READ_RETRY_CONFIG,
|
|
4175
|
+
shouldRetry: (error) => error === lastRetrySignal || normalizeAthenaError(error).retryable
|
|
4176
|
+
},
|
|
4177
|
+
async () => {
|
|
4178
|
+
const result = await runner();
|
|
4179
|
+
if (result.error?.retryable) {
|
|
4180
|
+
lastRetryableResult = result;
|
|
4181
|
+
lastRetrySignal = result.error;
|
|
4182
|
+
throw lastRetrySignal;
|
|
4183
|
+
}
|
|
4184
|
+
return result;
|
|
4185
|
+
}
|
|
4186
|
+
);
|
|
4187
|
+
} catch (error) {
|
|
4188
|
+
if (lastRetryableResult && error === lastRetrySignal) {
|
|
4189
|
+
return lastRetryableResult;
|
|
4190
|
+
}
|
|
4191
|
+
throw error;
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
function isRecord7(value) {
|
|
3425
4195
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3426
4196
|
}
|
|
3427
4197
|
function firstNonEmptyString2(...values) {
|
|
@@ -3433,8 +4203,8 @@ function firstNonEmptyString2(...values) {
|
|
|
3433
4203
|
return void 0;
|
|
3434
4204
|
}
|
|
3435
4205
|
function resolveStructuredErrorPayload2(raw) {
|
|
3436
|
-
if (!
|
|
3437
|
-
return
|
|
4206
|
+
if (!isRecord7(raw)) return null;
|
|
4207
|
+
return isRecord7(raw.error) ? raw.error : raw;
|
|
3438
4208
|
}
|
|
3439
4209
|
function resolveStructuredErrorDetails(payload, message) {
|
|
3440
4210
|
if (!payload || !("details" in payload)) {
|
|
@@ -3450,7 +4220,7 @@ function resolveStructuredErrorDetails(payload, message) {
|
|
|
3450
4220
|
return details;
|
|
3451
4221
|
}
|
|
3452
4222
|
function createResultError(response, result, normalized) {
|
|
3453
|
-
const rawRecord =
|
|
4223
|
+
const rawRecord = isRecord7(response.raw) ? response.raw : null;
|
|
3454
4224
|
const payload = resolveStructuredErrorPayload2(response.raw);
|
|
3455
4225
|
const message = firstNonEmptyString2(
|
|
3456
4226
|
response.error,
|
|
@@ -3645,7 +4415,14 @@ function toSingleResult(response) {
|
|
|
3645
4415
|
function mergeOptions(...options) {
|
|
3646
4416
|
return options.reduce((acc, next) => {
|
|
3647
4417
|
if (!next) return acc;
|
|
3648
|
-
|
|
4418
|
+
const merged = { ...acc ?? {}, ...next };
|
|
4419
|
+
if (acc?.headers || next.headers) {
|
|
4420
|
+
merged.headers = {
|
|
4421
|
+
...acc?.headers ?? {},
|
|
4422
|
+
...next.headers ?? {}
|
|
4423
|
+
};
|
|
4424
|
+
}
|
|
4425
|
+
return merged;
|
|
3649
4426
|
}, void 0);
|
|
3650
4427
|
}
|
|
3651
4428
|
function asAthenaJsonObject(value) {
|
|
@@ -3926,17 +4703,6 @@ function conditionToDebugSqlClause(condition) {
|
|
|
3926
4703
|
return `TRUE /* unsupported condition: ${rawCondition} */`;
|
|
3927
4704
|
}
|
|
3928
4705
|
}
|
|
3929
|
-
function resolvePagination(input) {
|
|
3930
|
-
let limit = input.limit;
|
|
3931
|
-
let offset = input.offset;
|
|
3932
|
-
if (limit === void 0 && input.pageSize !== void 0) {
|
|
3933
|
-
limit = input.pageSize;
|
|
3934
|
-
}
|
|
3935
|
-
if (offset === void 0 && input.pageSize !== void 0 && input.currentPage !== void 0 && input.currentPage > 0) {
|
|
3936
|
-
offset = (input.currentPage - 1) * input.pageSize;
|
|
3937
|
-
}
|
|
3938
|
-
return { limit, offset };
|
|
3939
|
-
}
|
|
3940
4706
|
function appendOrderLimitOffset(sqlParts, order, limit, offset) {
|
|
3941
4707
|
if (order?.field) {
|
|
3942
4708
|
const direction = order.direction === "descending" ? "DESC" : "ASC";
|
|
@@ -4440,80 +5206,56 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
4440
5206
|
);
|
|
4441
5207
|
const runSelect = async (columns = DEFAULT_COLUMNS, options, executionState = snapshotState(), callsite) => {
|
|
4442
5208
|
const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
|
|
4443
|
-
const
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
currentPage: executionState.currentPage,
|
|
4455
|
-
pageSize: executionState.pageSize,
|
|
4456
|
-
order: executionState.order
|
|
4457
|
-
});
|
|
4458
|
-
if (query) {
|
|
4459
|
-
const payload2 = { query };
|
|
4460
|
-
return executeWithQueryTrace(
|
|
5209
|
+
const plan = createSelectTransportPlan({
|
|
5210
|
+
tableName: resolvedTableName,
|
|
5211
|
+
columns,
|
|
5212
|
+
state: executionState,
|
|
5213
|
+
options,
|
|
5214
|
+
buildTypedSelectQuery
|
|
5215
|
+
});
|
|
5216
|
+
if (plan.kind === "query") {
|
|
5217
|
+
return executeExperimentalRead(
|
|
5218
|
+
experimental,
|
|
5219
|
+
() => executeWithQueryTrace(
|
|
4461
5220
|
tracer,
|
|
4462
5221
|
{
|
|
4463
5222
|
operation: "select",
|
|
4464
5223
|
endpoint: "/gateway/query",
|
|
4465
5224
|
table: resolvedTableName,
|
|
4466
|
-
sql: query,
|
|
4467
|
-
payload:
|
|
5225
|
+
sql: plan.query,
|
|
5226
|
+
payload: plan.payload,
|
|
4468
5227
|
options
|
|
4469
5228
|
},
|
|
4470
5229
|
async () => {
|
|
4471
|
-
const queryResponse = await client.queryGateway(
|
|
5230
|
+
const queryResponse = await client.queryGateway(plan.payload, options);
|
|
4472
5231
|
return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
|
|
4473
5232
|
},
|
|
4474
5233
|
callsite
|
|
4475
|
-
)
|
|
4476
|
-
|
|
5234
|
+
)
|
|
5235
|
+
);
|
|
4477
5236
|
}
|
|
4478
|
-
const payload = {
|
|
4479
|
-
table_name: resolvedTableName,
|
|
4480
|
-
columns,
|
|
4481
|
-
conditions,
|
|
4482
|
-
limit: executionState.limit,
|
|
4483
|
-
offset: executionState.offset,
|
|
4484
|
-
current_page: executionState.currentPage,
|
|
4485
|
-
page_size: executionState.pageSize,
|
|
4486
|
-
total_pages: executionState.totalPages,
|
|
4487
|
-
sort_by: executionState.order,
|
|
4488
|
-
strip_nulls: options?.stripNulls ?? true,
|
|
4489
|
-
count: options?.count,
|
|
4490
|
-
head: options?.head
|
|
4491
|
-
};
|
|
4492
5237
|
const sql = buildDebugSelectQuery({
|
|
4493
5238
|
tableName: resolvedTableName,
|
|
4494
|
-
|
|
4495
|
-
conditions,
|
|
4496
|
-
limit: executionState.limit,
|
|
4497
|
-
offset: executionState.offset,
|
|
4498
|
-
currentPage: executionState.currentPage,
|
|
4499
|
-
pageSize: executionState.pageSize,
|
|
4500
|
-
order: executionState.order
|
|
5239
|
+
...plan.debug
|
|
4501
5240
|
});
|
|
4502
|
-
return
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
5241
|
+
return executeExperimentalRead(
|
|
5242
|
+
experimental,
|
|
5243
|
+
() => executeWithQueryTrace(
|
|
5244
|
+
tracer,
|
|
5245
|
+
{
|
|
5246
|
+
operation: "select",
|
|
5247
|
+
endpoint: "/gateway/fetch",
|
|
5248
|
+
table: resolvedTableName,
|
|
5249
|
+
sql,
|
|
5250
|
+
payload: plan.payload,
|
|
5251
|
+
options
|
|
5252
|
+
},
|
|
5253
|
+
async () => {
|
|
5254
|
+
const response = await client.fetchGateway(plan.payload, options);
|
|
5255
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
|
|
5256
|
+
},
|
|
5257
|
+
callsite
|
|
5258
|
+
)
|
|
4517
5259
|
);
|
|
4518
5260
|
};
|
|
4519
5261
|
const createSelectChain = (columns, options, initialCallsite) => {
|
|
@@ -4583,14 +5325,14 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
4583
5325
|
if (options.limit !== void 0) {
|
|
4584
5326
|
executionState.limit = options.limit;
|
|
4585
5327
|
}
|
|
4586
|
-
if (experimental?.findManyAst && canUseFindManyAstTransport(baseState)) {
|
|
5328
|
+
if (experimental?.findManyAst && canUseFindManyAstTransport(baseState) && !selectShapeUsesRelationSchema(options.select) && !findManyAstWhereRequiresLegacyTransport(options.where)) {
|
|
4587
5329
|
const resolvedTableName = resolveTableNameForCall(tableName, void 0);
|
|
4588
5330
|
const payload = {
|
|
4589
5331
|
table_name: resolvedTableName,
|
|
4590
5332
|
select: options.select
|
|
4591
5333
|
};
|
|
4592
5334
|
if (options.where !== void 0) {
|
|
4593
|
-
payload.where = options.where;
|
|
5335
|
+
payload.where = normalizeFindManyAstWhere(options.where);
|
|
4594
5336
|
}
|
|
4595
5337
|
const astOrder = toFindManyAstOrder(executionState.order);
|
|
4596
5338
|
if (astOrder !== void 0) {
|
|
@@ -4606,22 +5348,25 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
4606
5348
|
limit: executionState.limit,
|
|
4607
5349
|
order: executionState.order
|
|
4608
5350
|
});
|
|
4609
|
-
return
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
async () => {
|
|
4619
|
-
const response = await client.fetchGateway(
|
|
5351
|
+
return executeExperimentalRead(
|
|
5352
|
+
experimental,
|
|
5353
|
+
() => executeWithQueryTrace(
|
|
5354
|
+
tracer,
|
|
5355
|
+
{
|
|
5356
|
+
operation: "select",
|
|
5357
|
+
endpoint: "/gateway/fetch",
|
|
5358
|
+
table: resolvedTableName,
|
|
5359
|
+
sql,
|
|
4620
5360
|
payload
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
5361
|
+
},
|
|
5362
|
+
async () => {
|
|
5363
|
+
const response = await client.fetchGateway(
|
|
5364
|
+
payload
|
|
5365
|
+
);
|
|
5366
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
|
|
5367
|
+
},
|
|
5368
|
+
callsite
|
|
5369
|
+
)
|
|
4625
5370
|
);
|
|
4626
5371
|
}
|
|
4627
5372
|
return runSelect(
|
|
@@ -4869,7 +5614,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
4869
5614
|
});
|
|
4870
5615
|
return builder;
|
|
4871
5616
|
}
|
|
4872
|
-
function createQueryBuilder(client, formatGatewayResult, tracer) {
|
|
5617
|
+
function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
|
|
4873
5618
|
return async function query(query, options) {
|
|
4874
5619
|
const normalizedQuery = query.trim();
|
|
4875
5620
|
if (!normalizedQuery) {
|
|
@@ -4877,35 +5622,50 @@ function createQueryBuilder(client, formatGatewayResult, tracer) {
|
|
|
4877
5622
|
}
|
|
4878
5623
|
const payload = { query: normalizedQuery };
|
|
4879
5624
|
const callsite = captureTraceCallsite(tracer);
|
|
4880
|
-
return
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
5625
|
+
return executeExperimentalRead(
|
|
5626
|
+
experimental,
|
|
5627
|
+
() => executeWithQueryTrace(
|
|
5628
|
+
tracer,
|
|
5629
|
+
{
|
|
5630
|
+
operation: "query",
|
|
5631
|
+
endpoint: "/gateway/query",
|
|
5632
|
+
sql: normalizedQuery,
|
|
5633
|
+
payload,
|
|
5634
|
+
options
|
|
5635
|
+
},
|
|
5636
|
+
async () => {
|
|
5637
|
+
const response = await client.queryGateway(payload, options);
|
|
5638
|
+
return formatGatewayResult(response, { operation: "query" });
|
|
5639
|
+
},
|
|
5640
|
+
callsite
|
|
5641
|
+
)
|
|
4894
5642
|
);
|
|
4895
5643
|
};
|
|
4896
5644
|
}
|
|
4897
5645
|
function createClientFromConfig(config) {
|
|
5646
|
+
const gatewayHeaders = {
|
|
5647
|
+
...config.headers ?? {}
|
|
5648
|
+
};
|
|
5649
|
+
if (config.auth?.bearerToken && gatewayHeaders["X-Athena-Auth-Bearer-Token"] === void 0 && gatewayHeaders["x-athena-auth-bearer-token"] === void 0) {
|
|
5650
|
+
gatewayHeaders["X-Athena-Auth-Bearer-Token"] = config.auth.bearerToken;
|
|
5651
|
+
}
|
|
4898
5652
|
const gateway = createAthenaGatewayClient({
|
|
4899
5653
|
baseUrl: config.baseUrl,
|
|
4900
5654
|
apiKey: config.apiKey,
|
|
4901
5655
|
client: config.client,
|
|
4902
5656
|
backend: config.backend,
|
|
4903
|
-
headers:
|
|
5657
|
+
headers: gatewayHeaders
|
|
4904
5658
|
});
|
|
4905
5659
|
const formatGatewayResult = createResultFormatter();
|
|
4906
5660
|
const queryTracer = createQueryTracer(config.experimental);
|
|
4907
5661
|
const auth = createAuthClient(config.auth);
|
|
4908
|
-
const from = (table) => createTableBuilder(
|
|
5662
|
+
const from = (table, options) => createTableBuilder(
|
|
5663
|
+
resolveTableNameForCall(table, options?.schema),
|
|
5664
|
+
gateway,
|
|
5665
|
+
formatGatewayResult,
|
|
5666
|
+
queryTracer,
|
|
5667
|
+
config.experimental
|
|
5668
|
+
);
|
|
4909
5669
|
const rpc = (fn, args, options) => {
|
|
4910
5670
|
const normalizedFn = fn.trim();
|
|
4911
5671
|
if (!normalizedFn) {
|
|
@@ -4921,13 +5681,14 @@ function createClientFromConfig(config) {
|
|
|
4921
5681
|
captureTraceCallsite(queryTracer)
|
|
4922
5682
|
);
|
|
4923
5683
|
};
|
|
4924
|
-
const query = createQueryBuilder(gateway, formatGatewayResult, queryTracer);
|
|
5684
|
+
const query = createQueryBuilder(gateway, formatGatewayResult, config.experimental, queryTracer);
|
|
4925
5685
|
const db = createDbModule({ from, rpc, query });
|
|
4926
5686
|
return {
|
|
4927
5687
|
from,
|
|
4928
5688
|
db,
|
|
4929
5689
|
rpc,
|
|
4930
5690
|
query,
|
|
5691
|
+
verifyConnection: gateway.verifyConnection,
|
|
4931
5692
|
auth: auth.auth
|
|
4932
5693
|
};
|
|
4933
5694
|
}
|