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