@xylex-group/athena 1.9.0 → 2.1.2
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 +86 -68
- package/bin/athena-js.js +0 -0
- package/dist/browser.cjs +3319 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +25 -0
- package/dist/browser.d.ts +25 -0
- package/dist/browser.js +3276 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli/index.cjs +1839 -275
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -2
- package/dist/cli/index.d.ts +3 -2
- package/dist/cli/index.js +1840 -276
- package/dist/cli/index.js.map +1 -1
- package/dist/client-BX0NQqOn.d.ts +435 -0
- package/dist/client-dpAp-NZK.d.cts +435 -0
- package/dist/cookies.cjs +890 -0
- package/dist/cookies.cjs.map +1 -0
- package/dist/cookies.d.cts +174 -0
- package/dist/cookies.d.ts +174 -0
- package/dist/cookies.js +869 -0
- package/dist/cookies.js.map +1 -0
- package/dist/index.cjs +2724 -1777
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -641
- package/dist/index.d.ts +8 -641
- package/dist/index.js +2725 -1779
- package/dist/index.js.map +1 -1
- package/dist/model-form-2hqmoOUX.d.ts +1284 -0
- package/dist/model-form-Cy-zaO0u.d.cts +1284 -0
- package/dist/pipeline-BOPszLsL.d.ts +8 -0
- package/dist/pipeline-E3FDbs4W.d.cts +8 -0
- package/dist/react.cjs +93 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +38 -4
- package/dist/react.d.ts +38 -4
- package/dist/react.js +93 -1
- package/dist/react.js.map +1 -1
- package/dist/{types-BnzoaNRC.d.cts → types-BaBzjwXr.d.cts} +1 -1
- package/dist/{types-BnzoaNRC.d.ts → types-BaBzjwXr.d.ts} +1 -1
- package/dist/{pipeline-CQgV-Yfo.d.ts → types-CeBPrnGj.d.ts} +2 -7
- package/dist/{pipeline-C-cN0ACi.d.cts → types-CpqL-pZx.d.cts} +2 -7
- package/package.json +36 -17
- package/dist/model-form-Bm_kqCn2.d.ts +0 -92
- package/dist/model-form-DkS48fsh.d.cts +0 -92
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { existsSync } from 'fs';
|
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
2
|
import { resolve, dirname, posix } from 'path';
|
|
4
3
|
import { pathToFileURL } from 'url';
|
|
5
4
|
import { mkdir, writeFile } from 'fs/promises';
|
|
@@ -501,1264 +500,2411 @@ function identifier(...segments) {
|
|
|
501
500
|
return new SqlIdentifierPath(expandedSegments);
|
|
502
501
|
}
|
|
503
502
|
|
|
504
|
-
// src/client.ts
|
|
505
|
-
var
|
|
506
|
-
var
|
|
507
|
-
var
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
errorDetails: response.errorDetails ?? null,
|
|
513
|
-
status: response.status,
|
|
514
|
-
raw: response.raw
|
|
515
|
-
};
|
|
516
|
-
if (response.count !== void 0) {
|
|
517
|
-
result.count = response.count;
|
|
518
|
-
}
|
|
519
|
-
return result;
|
|
503
|
+
// src/auth/client.ts
|
|
504
|
+
var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
|
|
505
|
+
var FALLBACK_SDK_VERSION2 = "1.0.0";
|
|
506
|
+
var SDK_NAME2 = "xylex-group/athena-auth";
|
|
507
|
+
var SDK_VERSION2 = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION2;
|
|
508
|
+
var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
|
|
509
|
+
function normalizeBaseUrl(baseUrl) {
|
|
510
|
+
return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
|
|
520
511
|
}
|
|
521
|
-
function
|
|
522
|
-
|
|
523
|
-
const singleData = Array.isArray(payload) ? payload.length ? payload[0] : null : payload ?? null;
|
|
524
|
-
return {
|
|
525
|
-
...response,
|
|
526
|
-
data: singleData
|
|
527
|
-
};
|
|
512
|
+
function isRecord2(value) {
|
|
513
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
528
514
|
}
|
|
529
|
-
function
|
|
530
|
-
return
|
|
531
|
-
if (!next) return acc;
|
|
532
|
-
return { ...acc, ...next };
|
|
533
|
-
}, void 0);
|
|
515
|
+
function normalizeHeaderValue2(value) {
|
|
516
|
+
return value ? value : void 0;
|
|
534
517
|
}
|
|
535
|
-
function
|
|
536
|
-
|
|
518
|
+
function parseResponseBody2(rawText, contentType) {
|
|
519
|
+
if (!rawText) {
|
|
520
|
+
return { parsed: null, parseFailed: false };
|
|
521
|
+
}
|
|
522
|
+
const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
|
|
523
|
+
const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
|
|
524
|
+
if (!looksJson) {
|
|
525
|
+
return { parsed: rawText, parseFailed: false };
|
|
526
|
+
}
|
|
527
|
+
try {
|
|
528
|
+
return { parsed: JSON.parse(rawText), parseFailed: false };
|
|
529
|
+
} catch {
|
|
530
|
+
return { parsed: rawText, parseFailed: true };
|
|
531
|
+
}
|
|
537
532
|
}
|
|
538
|
-
function
|
|
539
|
-
return
|
|
533
|
+
function resolveRequestId2(headers) {
|
|
534
|
+
return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
|
|
540
535
|
}
|
|
541
|
-
function
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
if (!promise) {
|
|
549
|
-
promise = executor(payloadColumns, payloadOptions);
|
|
536
|
+
function resolveErrorMessage2(payload, fallback) {
|
|
537
|
+
if (isRecord2(payload)) {
|
|
538
|
+
const messageCandidates = [payload.error, payload.message, payload.details];
|
|
539
|
+
for (const candidate of messageCandidates) {
|
|
540
|
+
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
541
|
+
return candidate.trim();
|
|
542
|
+
}
|
|
550
543
|
}
|
|
551
|
-
|
|
544
|
+
}
|
|
545
|
+
if (typeof payload === "string" && payload.trim().length > 0) {
|
|
546
|
+
return payload.trim();
|
|
547
|
+
}
|
|
548
|
+
return fallback;
|
|
549
|
+
}
|
|
550
|
+
function toErrorDetails(input) {
|
|
551
|
+
return {
|
|
552
|
+
code: input.code,
|
|
553
|
+
message: input.message,
|
|
554
|
+
status: input.status,
|
|
555
|
+
endpoint: input.endpoint,
|
|
556
|
+
method: input.method,
|
|
557
|
+
requestId: input.requestId,
|
|
558
|
+
hint: input.hint,
|
|
559
|
+
cause: input.cause
|
|
552
560
|
};
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
single(columns = selectedColumns, options) {
|
|
563
|
-
selectedColumns = columns;
|
|
564
|
-
selectedOptions = options ?? selectedOptions;
|
|
565
|
-
return run(columns, options).then(toSingleResult);
|
|
566
|
-
},
|
|
567
|
-
maybeSingle(columns = selectedColumns, options) {
|
|
568
|
-
return mutationQuery.single(columns, options);
|
|
569
|
-
},
|
|
570
|
-
then(onfulfilled, onrejected) {
|
|
571
|
-
return run(selectedColumns, selectedOptions).then(onfulfilled, onrejected);
|
|
572
|
-
},
|
|
573
|
-
catch(onrejected) {
|
|
574
|
-
return run(selectedColumns, selectedOptions).catch(onrejected);
|
|
575
|
-
},
|
|
576
|
-
finally(onfinally) {
|
|
577
|
-
return run(selectedColumns, selectedOptions).finally(onfinally);
|
|
561
|
+
}
|
|
562
|
+
function mergeCallOptions(base, override) {
|
|
563
|
+
if (!base && !override) return void 0;
|
|
564
|
+
return {
|
|
565
|
+
...base,
|
|
566
|
+
...override,
|
|
567
|
+
headers: {
|
|
568
|
+
...base?.headers ?? {},
|
|
569
|
+
...override?.headers ?? {}
|
|
578
570
|
}
|
|
579
571
|
};
|
|
580
|
-
return mutationQuery;
|
|
581
|
-
}
|
|
582
|
-
function getResourceId(state) {
|
|
583
|
-
const candidate = state.conditions.find(
|
|
584
|
-
(condition) => condition.operator === "eq" && (condition.column === "resource_id" || condition.column === "id")
|
|
585
|
-
);
|
|
586
|
-
return candidate?.value?.toString();
|
|
587
572
|
}
|
|
588
|
-
function
|
|
589
|
-
if (
|
|
590
|
-
return
|
|
573
|
+
function extractFetchOptions(input) {
|
|
574
|
+
if (!input) {
|
|
575
|
+
return {
|
|
576
|
+
payload: void 0,
|
|
577
|
+
fetchOptions: void 0
|
|
578
|
+
};
|
|
591
579
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
return column === "id" || /(?:^|_)uuid(?:_|$)/i.test(column) || /_id$/i.test(column);
|
|
599
|
-
}
|
|
600
|
-
function shouldUseUuidTextComparison(column, value) {
|
|
601
|
-
return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
|
|
580
|
+
const { fetchOptions, ...rest } = input;
|
|
581
|
+
const hasPayloadKeys = Object.keys(rest).length > 0;
|
|
582
|
+
return {
|
|
583
|
+
payload: hasPayloadKeys ? rest : void 0,
|
|
584
|
+
fetchOptions
|
|
585
|
+
};
|
|
602
586
|
}
|
|
603
|
-
function
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
|
|
587
|
+
function buildHeaders2(config, options) {
|
|
588
|
+
const headers = {
|
|
589
|
+
"Content-Type": "application/json",
|
|
590
|
+
"X-Athena-Sdk": SDK_HEADER_VALUE2
|
|
591
|
+
};
|
|
592
|
+
const apiKey = options?.apiKey ?? config.apiKey;
|
|
593
|
+
if (apiKey) {
|
|
594
|
+
headers.apikey = apiKey;
|
|
595
|
+
headers["x-api-key"] = apiKey;
|
|
607
596
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
597
|
+
const bearerToken = options?.bearerToken ?? config.bearerToken;
|
|
598
|
+
if (bearerToken) {
|
|
599
|
+
headers.Authorization = `Bearer ${bearerToken}`;
|
|
600
|
+
}
|
|
601
|
+
const mergedExtraHeaders = {
|
|
602
|
+
...config.headers ?? {},
|
|
603
|
+
...options?.headers ?? {}
|
|
604
|
+
};
|
|
605
|
+
Object.entries(mergedExtraHeaders).forEach(([key, value]) => {
|
|
606
|
+
const normalized = normalizeHeaderValue2(value);
|
|
607
|
+
if (normalized) {
|
|
608
|
+
headers[key] = normalized;
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
return headers;
|
|
622
612
|
}
|
|
623
|
-
function
|
|
624
|
-
if (
|
|
625
|
-
|
|
613
|
+
function appendQueryParam(searchParams, key, value) {
|
|
614
|
+
if (value === void 0 || value === null) return;
|
|
615
|
+
if (Array.isArray(value)) {
|
|
616
|
+
value.forEach((item) => {
|
|
617
|
+
searchParams.append(key, String(item));
|
|
618
|
+
});
|
|
619
|
+
return;
|
|
626
620
|
}
|
|
627
|
-
|
|
621
|
+
searchParams.append(key, String(value));
|
|
628
622
|
}
|
|
629
|
-
function
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
623
|
+
function buildRequestUrl(baseUrl, endpoint, query) {
|
|
624
|
+
const url = `${baseUrl}${endpoint}`;
|
|
625
|
+
if (!query || Object.keys(query).length === 0) return url;
|
|
626
|
+
const searchParams = new URLSearchParams();
|
|
627
|
+
Object.entries(query).forEach(([key, value]) => appendQueryParam(searchParams, key, value));
|
|
628
|
+
const queryText = searchParams.toString();
|
|
629
|
+
return queryText ? `${url}?${queryText}` : url;
|
|
630
|
+
}
|
|
631
|
+
function inferDefaultMethod(endpoint) {
|
|
632
|
+
if (endpoint.startsWith("/reset-password/")) {
|
|
633
|
+
return "GET";
|
|
634
634
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
635
|
+
switch (endpoint) {
|
|
636
|
+
case "/get-session":
|
|
637
|
+
case "/list-sessions":
|
|
638
|
+
case "/verify-email":
|
|
639
|
+
case "/change-email/verify":
|
|
640
|
+
case "/delete-user/verify":
|
|
641
|
+
case "/email-list":
|
|
642
|
+
case "/email/list":
|
|
643
|
+
case "/delete-user/callback":
|
|
644
|
+
case "/list-accounts":
|
|
645
|
+
case "/passkey/generate-register-options":
|
|
646
|
+
case "/passkey/list-user-passkeys":
|
|
647
|
+
case "/.well-known/webauthn":
|
|
648
|
+
case "/admin/list-users":
|
|
649
|
+
case "/admin/athena-client/list":
|
|
650
|
+
case "/admin/audit-log/list":
|
|
651
|
+
case "/admin/email/get":
|
|
652
|
+
case "/admin/email-failure/list":
|
|
653
|
+
case "/admin/email-failure/get":
|
|
654
|
+
case "/admin/email-template/get":
|
|
655
|
+
case "/admin/email-template/list":
|
|
656
|
+
case "/admin/email/list":
|
|
657
|
+
case "/api-key/get":
|
|
658
|
+
case "/api-key/list":
|
|
659
|
+
case "/organization/get-full-organization":
|
|
660
|
+
case "/organization/list":
|
|
661
|
+
case "/organization/get-invitation":
|
|
662
|
+
case "/organization/list-invitations":
|
|
663
|
+
case "/organization/list-user-invitations":
|
|
664
|
+
case "/organization/list-members":
|
|
665
|
+
case "/organization/get-active-member":
|
|
666
|
+
case "/health":
|
|
667
|
+
case "/ok":
|
|
668
|
+
case "/error":
|
|
669
|
+
return "GET";
|
|
670
|
+
default:
|
|
671
|
+
return "POST";
|
|
642
672
|
}
|
|
643
|
-
return `${normalizedSchema}.${tableName}`;
|
|
644
673
|
}
|
|
645
|
-
function
|
|
646
|
-
|
|
647
|
-
const
|
|
648
|
-
const
|
|
649
|
-
const
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
lte: "<=",
|
|
656
|
-
like: "LIKE",
|
|
657
|
-
ilike: "ILIKE"
|
|
674
|
+
async function callAuthEndpoint(config, context, body, query, options) {
|
|
675
|
+
const baseUrl = normalizeBaseUrl(options?.baseUrl ?? config.baseUrl);
|
|
676
|
+
const url = buildRequestUrl(baseUrl, context.endpoint, query);
|
|
677
|
+
const headers = buildHeaders2(config, options);
|
|
678
|
+
const credentials = options?.credentials ?? config.credentials ?? "include";
|
|
679
|
+
const requestInit = {
|
|
680
|
+
method: context.method,
|
|
681
|
+
headers,
|
|
682
|
+
credentials,
|
|
683
|
+
signal: options?.signal
|
|
658
684
|
};
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
685
|
+
if (context.method !== "GET") {
|
|
686
|
+
requestInit.body = JSON.stringify(body ?? {});
|
|
687
|
+
}
|
|
688
|
+
const fetcher = config.fetch ?? globalThis.fetch;
|
|
689
|
+
if (!fetcher) {
|
|
690
|
+
const details = toErrorDetails({
|
|
691
|
+
code: "UNKNOWN_ERROR",
|
|
692
|
+
message: "No fetch implementation available for auth client",
|
|
693
|
+
status: 0,
|
|
694
|
+
endpoint: context.endpoint,
|
|
695
|
+
method: context.method,
|
|
696
|
+
hint: "Use Node 18+ or provide `fetch` via createClient(..., { auth: { fetch } }) or createAuthClient({ fetch })"
|
|
697
|
+
});
|
|
698
|
+
return {
|
|
699
|
+
ok: false,
|
|
700
|
+
status: 0,
|
|
701
|
+
data: null,
|
|
702
|
+
error: details.message,
|
|
703
|
+
errorDetails: details,
|
|
704
|
+
raw: null
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
try {
|
|
708
|
+
const response = await fetcher(url, requestInit);
|
|
709
|
+
const rawText = await response.text();
|
|
710
|
+
const requestId = resolveRequestId2(response.headers);
|
|
711
|
+
const parsedBody = parseResponseBody2(rawText ?? "", response.headers.get("content-type"));
|
|
712
|
+
if (parsedBody.parseFailed) {
|
|
713
|
+
const details = toErrorDetails({
|
|
714
|
+
code: "INVALID_JSON",
|
|
715
|
+
message: "Auth server returned malformed JSON",
|
|
716
|
+
status: response.status,
|
|
717
|
+
endpoint: context.endpoint,
|
|
718
|
+
method: context.method,
|
|
719
|
+
requestId,
|
|
720
|
+
hint: "Verify the auth endpoint response body is valid JSON.",
|
|
721
|
+
cause: rawText.slice(0, 300)
|
|
722
|
+
});
|
|
723
|
+
return {
|
|
724
|
+
ok: false,
|
|
725
|
+
status: response.status,
|
|
726
|
+
data: null,
|
|
727
|
+
error: details.message,
|
|
728
|
+
errorDetails: details,
|
|
729
|
+
raw: parsedBody.parsed
|
|
730
|
+
};
|
|
677
731
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
732
|
+
const parsed = parsedBody.parsed;
|
|
733
|
+
if (!response.ok) {
|
|
734
|
+
const details = toErrorDetails({
|
|
735
|
+
code: "HTTP_ERROR",
|
|
736
|
+
message: resolveErrorMessage2(
|
|
737
|
+
parsed,
|
|
738
|
+
`Auth endpoint ${context.method} ${context.endpoint} failed with status ${response.status}`
|
|
739
|
+
),
|
|
740
|
+
status: response.status,
|
|
741
|
+
endpoint: context.endpoint,
|
|
742
|
+
method: context.method,
|
|
743
|
+
requestId
|
|
744
|
+
});
|
|
745
|
+
return {
|
|
746
|
+
ok: false,
|
|
747
|
+
status: response.status,
|
|
748
|
+
data: null,
|
|
749
|
+
error: details.message,
|
|
750
|
+
errorDetails: details,
|
|
751
|
+
raw: parsed
|
|
752
|
+
};
|
|
683
753
|
}
|
|
684
|
-
|
|
685
|
-
|
|
754
|
+
return {
|
|
755
|
+
ok: true,
|
|
756
|
+
status: response.status,
|
|
757
|
+
data: parsed ?? null,
|
|
758
|
+
error: null,
|
|
759
|
+
errorDetails: null,
|
|
760
|
+
raw: parsed
|
|
761
|
+
};
|
|
762
|
+
} catch (callError) {
|
|
763
|
+
const message = callError instanceof Error ? callError.message : String(callError);
|
|
764
|
+
const details = toErrorDetails({
|
|
765
|
+
code: "NETWORK_ERROR",
|
|
766
|
+
message: `Network error while calling ${context.method} ${context.endpoint}: ${message}`,
|
|
767
|
+
status: 0,
|
|
768
|
+
endpoint: context.endpoint,
|
|
769
|
+
method: context.method,
|
|
770
|
+
cause: message,
|
|
771
|
+
hint: "Check auth server URL, DNS, and network reachability."
|
|
772
|
+
});
|
|
773
|
+
return {
|
|
774
|
+
ok: false,
|
|
775
|
+
status: 0,
|
|
776
|
+
data: null,
|
|
777
|
+
error: details.message,
|
|
778
|
+
errorDetails: details,
|
|
779
|
+
raw: null
|
|
780
|
+
};
|
|
686
781
|
}
|
|
687
782
|
}
|
|
688
|
-
function
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
if (!clause) return null;
|
|
693
|
-
whereClauses.push(clause);
|
|
694
|
-
}
|
|
695
|
-
let limit = input.limit;
|
|
696
|
-
let offset = input.offset;
|
|
697
|
-
if (limit === void 0 && input.pageSize !== void 0) {
|
|
698
|
-
limit = input.pageSize;
|
|
699
|
-
}
|
|
700
|
-
if (offset === void 0 && input.pageSize !== void 0 && input.currentPage !== void 0 && input.currentPage > 0) {
|
|
701
|
-
offset = (input.currentPage - 1) * input.pageSize;
|
|
702
|
-
}
|
|
703
|
-
const sqlParts = [
|
|
704
|
-
`SELECT ${buildSelectColumnsClause(input.columns)} FROM ${quoteQualifiedIdentifier(input.tableName)}`
|
|
705
|
-
];
|
|
706
|
-
if (whereClauses.length > 0) {
|
|
707
|
-
sqlParts.push(`WHERE ${whereClauses.join(" AND ")}`);
|
|
708
|
-
}
|
|
709
|
-
if (input.order?.field) {
|
|
710
|
-
const direction = input.order.direction === "descending" ? "DESC" : "ASC";
|
|
711
|
-
sqlParts.push(`ORDER BY ${quoteQualifiedIdentifier(input.order.field)} ${direction}`);
|
|
712
|
-
}
|
|
713
|
-
if (limit !== void 0) {
|
|
714
|
-
sqlParts.push(`LIMIT ${Math.max(0, Math.trunc(limit))}`);
|
|
715
|
-
}
|
|
716
|
-
if (offset !== void 0) {
|
|
717
|
-
sqlParts.push(`OFFSET ${Math.max(0, Math.trunc(offset))}`);
|
|
718
|
-
}
|
|
719
|
-
return `${sqlParts.join(" ")};`;
|
|
783
|
+
function executePostWithCompatibleInput(config, context, input, options) {
|
|
784
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
785
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
786
|
+
return callAuthEndpoint(config, context, payload ?? {}, void 0, mergedOptions);
|
|
720
787
|
}
|
|
721
|
-
function
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
788
|
+
function executePostWithOptionalInput(config, context, input, options) {
|
|
789
|
+
const { fetchOptions } = extractFetchOptions(input);
|
|
790
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
791
|
+
return callAuthEndpoint(config, context, {}, void 0, mergedOptions);
|
|
792
|
+
}
|
|
793
|
+
function executeGetWithCompatibleInput(config, context, input, options) {
|
|
794
|
+
const { fetchOptions } = extractFetchOptions(input);
|
|
795
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
796
|
+
return callAuthEndpoint(config, context, void 0, void 0, mergedOptions);
|
|
797
|
+
}
|
|
798
|
+
function executeGetWithQueryCompatibleInput(config, context, input, options) {
|
|
799
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
800
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
801
|
+
const query = payload?.query;
|
|
802
|
+
return callAuthEndpoint(
|
|
803
|
+
config,
|
|
804
|
+
context,
|
|
805
|
+
void 0,
|
|
806
|
+
query,
|
|
807
|
+
mergedOptions
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
function createAuthClient(config = {}) {
|
|
811
|
+
const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
|
|
812
|
+
const resolvedConfig = {
|
|
813
|
+
...config,
|
|
814
|
+
baseUrl: normalizedBaseUrl
|
|
815
|
+
};
|
|
816
|
+
const request = (input, options) => {
|
|
817
|
+
const method = input.method ?? (input.body !== void 0 ? "POST" : inferDefaultMethod(input.endpoint));
|
|
818
|
+
const mergedOptions = mergeCallOptions(input.fetchOptions, options);
|
|
819
|
+
return callAuthEndpoint(
|
|
820
|
+
resolvedConfig,
|
|
821
|
+
{ endpoint: input.endpoint, method },
|
|
822
|
+
input.body,
|
|
823
|
+
input.query,
|
|
824
|
+
mergedOptions
|
|
825
|
+
);
|
|
826
|
+
};
|
|
827
|
+
const postGeneric = (endpoint, input, options) => {
|
|
828
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
829
|
+
return request(
|
|
830
|
+
{
|
|
831
|
+
endpoint,
|
|
832
|
+
method: "POST",
|
|
833
|
+
body: payload ?? {},
|
|
834
|
+
fetchOptions
|
|
835
|
+
},
|
|
836
|
+
options
|
|
837
|
+
);
|
|
838
|
+
};
|
|
839
|
+
const getGeneric = (endpoint, input, options) => {
|
|
840
|
+
const { fetchOptions } = extractFetchOptions(input);
|
|
841
|
+
return request(
|
|
842
|
+
{
|
|
843
|
+
endpoint,
|
|
844
|
+
method: "GET",
|
|
845
|
+
fetchOptions
|
|
846
|
+
},
|
|
847
|
+
options
|
|
848
|
+
);
|
|
849
|
+
};
|
|
850
|
+
const getWithQuery = (endpoint, input, options) => {
|
|
851
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
852
|
+
const query = payload?.query;
|
|
853
|
+
return request(
|
|
854
|
+
{
|
|
855
|
+
endpoint,
|
|
856
|
+
method: "GET",
|
|
857
|
+
query,
|
|
858
|
+
fetchOptions
|
|
859
|
+
},
|
|
860
|
+
options
|
|
861
|
+
);
|
|
862
|
+
};
|
|
863
|
+
const listUserEmailsWithFallback = async (input, options) => {
|
|
864
|
+
const primary = await getWithQuery(
|
|
865
|
+
"/email/list",
|
|
866
|
+
input,
|
|
867
|
+
options
|
|
868
|
+
);
|
|
869
|
+
if (primary.ok || primary.status !== 404 || primary.errorDetails?.code !== "HTTP_ERROR") {
|
|
870
|
+
return primary;
|
|
871
|
+
}
|
|
872
|
+
return getWithQuery(
|
|
873
|
+
"/email-list",
|
|
874
|
+
input,
|
|
875
|
+
options
|
|
876
|
+
);
|
|
877
|
+
};
|
|
878
|
+
const healthWithFallback = async (input, options) => {
|
|
879
|
+
const primary = await getGeneric("/health", input, options);
|
|
880
|
+
if (primary.ok || primary.status !== 404 || primary.errorDetails?.code !== "HTTP_ERROR") {
|
|
881
|
+
return primary;
|
|
882
|
+
}
|
|
883
|
+
const fallback = await getGeneric("/ok", input, options);
|
|
884
|
+
if (!fallback.ok) {
|
|
885
|
+
return {
|
|
886
|
+
...fallback,
|
|
887
|
+
data: null
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
const fallbackStatus = isRecord2(fallback.data) && typeof fallback.data.ok === "boolean" ? fallback.data.ok ? "ok" : "error" : "ok";
|
|
891
|
+
return {
|
|
892
|
+
...fallback,
|
|
893
|
+
data: {
|
|
894
|
+
status: fallbackStatus
|
|
729
895
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
896
|
+
};
|
|
897
|
+
};
|
|
898
|
+
const signOut = (input, options) => executePostWithOptionalInput(
|
|
899
|
+
resolvedConfig,
|
|
900
|
+
{ endpoint: "/sign-out", method: "POST" },
|
|
901
|
+
input,
|
|
902
|
+
options
|
|
903
|
+
);
|
|
904
|
+
const revokeSessions = (input, options) => executePostWithOptionalInput(
|
|
905
|
+
resolvedConfig,
|
|
906
|
+
{ endpoint: "/revoke-sessions", method: "POST" },
|
|
907
|
+
input,
|
|
908
|
+
options
|
|
909
|
+
);
|
|
910
|
+
const revokeOtherSessions = (input, options) => executePostWithOptionalInput(
|
|
911
|
+
resolvedConfig,
|
|
912
|
+
{ endpoint: "/revoke-other-sessions", method: "POST" },
|
|
913
|
+
input,
|
|
914
|
+
options
|
|
915
|
+
);
|
|
916
|
+
const revokeSession = (input, options) => executePostWithCompatibleInput(
|
|
917
|
+
resolvedConfig,
|
|
918
|
+
{ endpoint: "/revoke-session", method: "POST" },
|
|
919
|
+
input,
|
|
920
|
+
options
|
|
921
|
+
);
|
|
922
|
+
const deleteUser = (input, options) => {
|
|
923
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
924
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
925
|
+
return callAuthEndpoint(
|
|
926
|
+
resolvedConfig,
|
|
927
|
+
{ endpoint: "/delete-user", method: "POST" },
|
|
928
|
+
payload ?? {},
|
|
929
|
+
void 0,
|
|
930
|
+
mergedOptions
|
|
931
|
+
);
|
|
932
|
+
};
|
|
933
|
+
const deleteUserCallback = (input, options) => {
|
|
934
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
935
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
936
|
+
const query = payload ?? {};
|
|
937
|
+
return callAuthEndpoint(
|
|
938
|
+
resolvedConfig,
|
|
939
|
+
{ endpoint: "/delete-user/callback", method: "GET" },
|
|
940
|
+
void 0,
|
|
941
|
+
{
|
|
942
|
+
token: query.token,
|
|
943
|
+
callbackURL: query.callbackURL
|
|
944
|
+
},
|
|
945
|
+
mergedOptions
|
|
946
|
+
);
|
|
947
|
+
};
|
|
948
|
+
const resolveResetPasswordToken = (input, options) => {
|
|
949
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
950
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
951
|
+
const query = payload;
|
|
952
|
+
const token = query?.token?.trim();
|
|
953
|
+
if (!token) {
|
|
954
|
+
throw new Error("resolveResetPasswordToken requires a non-empty token");
|
|
955
|
+
}
|
|
956
|
+
const endpoint = `/reset-password/${encodeURIComponent(token)}`;
|
|
957
|
+
return callAuthEndpoint(
|
|
958
|
+
resolvedConfig,
|
|
959
|
+
{ endpoint, method: "GET" },
|
|
960
|
+
void 0,
|
|
961
|
+
query?.callbackURL ? { callbackURL: query.callbackURL } : void 0,
|
|
962
|
+
mergedOptions
|
|
963
|
+
);
|
|
964
|
+
};
|
|
965
|
+
const organization = {
|
|
966
|
+
create: (input, options) => executePostWithCompatibleInput(
|
|
967
|
+
resolvedConfig,
|
|
968
|
+
{ endpoint: "/organization/create", method: "POST" },
|
|
969
|
+
input,
|
|
970
|
+
options
|
|
971
|
+
),
|
|
972
|
+
update: (input, options) => executePostWithCompatibleInput(
|
|
973
|
+
resolvedConfig,
|
|
974
|
+
{ endpoint: "/organization/update", method: "POST" },
|
|
975
|
+
input,
|
|
976
|
+
options
|
|
977
|
+
),
|
|
978
|
+
delete: (input, options) => executePostWithCompatibleInput(
|
|
979
|
+
resolvedConfig,
|
|
980
|
+
{ endpoint: "/organization/delete", method: "POST" },
|
|
981
|
+
input,
|
|
982
|
+
options
|
|
983
|
+
),
|
|
984
|
+
setActive: (input, options) => executePostWithCompatibleInput(
|
|
985
|
+
resolvedConfig,
|
|
986
|
+
{ endpoint: "/organization/set-active", method: "POST" },
|
|
987
|
+
input,
|
|
988
|
+
options
|
|
989
|
+
),
|
|
990
|
+
list: (input, options) => getGeneric(
|
|
991
|
+
"/organization/list",
|
|
992
|
+
input,
|
|
993
|
+
options
|
|
994
|
+
),
|
|
995
|
+
getFull: (input, options) => executeGetWithQueryCompatibleInput(
|
|
996
|
+
resolvedConfig,
|
|
997
|
+
{ endpoint: "/organization/get-full-organization", method: "GET" },
|
|
998
|
+
input,
|
|
999
|
+
options
|
|
1000
|
+
),
|
|
1001
|
+
checkSlug: (input, options) => executePostWithCompatibleInput(
|
|
1002
|
+
resolvedConfig,
|
|
1003
|
+
{ endpoint: "/organization/check-slug", method: "POST" },
|
|
1004
|
+
input,
|
|
1005
|
+
options
|
|
1006
|
+
),
|
|
1007
|
+
leave: (input, options) => executePostWithCompatibleInput(
|
|
1008
|
+
resolvedConfig,
|
|
1009
|
+
{ endpoint: "/organization/leave", method: "POST" },
|
|
1010
|
+
input,
|
|
1011
|
+
options
|
|
1012
|
+
),
|
|
1013
|
+
listUserInvitations: (input, options) => executeGetWithQueryCompatibleInput(
|
|
1014
|
+
resolvedConfig,
|
|
1015
|
+
{ endpoint: "/organization/list-user-invitations", method: "GET" },
|
|
1016
|
+
input,
|
|
1017
|
+
options
|
|
1018
|
+
),
|
|
1019
|
+
hasPermission: (input, options) => postGeneric(
|
|
1020
|
+
"/organization/has-permission",
|
|
1021
|
+
input,
|
|
1022
|
+
options
|
|
1023
|
+
),
|
|
1024
|
+
invitation: {
|
|
1025
|
+
cancel: (input, options) => executePostWithCompatibleInput(
|
|
1026
|
+
resolvedConfig,
|
|
1027
|
+
{ endpoint: "/organization/cancel-invitation", method: "POST" },
|
|
1028
|
+
input,
|
|
1029
|
+
options
|
|
1030
|
+
),
|
|
1031
|
+
accept: (input, options) => executePostWithCompatibleInput(
|
|
1032
|
+
resolvedConfig,
|
|
1033
|
+
{ endpoint: "/organization/accept-invitation", method: "POST" },
|
|
1034
|
+
input,
|
|
1035
|
+
options
|
|
1036
|
+
),
|
|
1037
|
+
get: (input, options) => executeGetWithQueryCompatibleInput(
|
|
1038
|
+
resolvedConfig,
|
|
1039
|
+
{ endpoint: "/organization/get-invitation", method: "GET" },
|
|
1040
|
+
input,
|
|
1041
|
+
options
|
|
1042
|
+
),
|
|
1043
|
+
reject: (input, options) => executePostWithCompatibleInput(
|
|
1044
|
+
resolvedConfig,
|
|
1045
|
+
{ endpoint: "/organization/reject-invitation", method: "POST" },
|
|
1046
|
+
input,
|
|
1047
|
+
options
|
|
1048
|
+
),
|
|
1049
|
+
list: (input, options) => executeGetWithQueryCompatibleInput(
|
|
1050
|
+
resolvedConfig,
|
|
1051
|
+
{ endpoint: "/organization/list-invitations", method: "GET" },
|
|
1052
|
+
input,
|
|
1053
|
+
options
|
|
1054
|
+
)
|
|
752
1055
|
},
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
1056
|
+
member: {
|
|
1057
|
+
remove: (input, options) => executePostWithCompatibleInput(
|
|
1058
|
+
resolvedConfig,
|
|
1059
|
+
{ endpoint: "/organization/remove-member", method: "POST" },
|
|
1060
|
+
input,
|
|
1061
|
+
options
|
|
1062
|
+
),
|
|
1063
|
+
updateRole: (input, options) => executePostWithCompatibleInput(
|
|
1064
|
+
resolvedConfig,
|
|
1065
|
+
{ endpoint: "/organization/update-member-role", method: "POST" },
|
|
1066
|
+
input,
|
|
1067
|
+
options
|
|
1068
|
+
),
|
|
1069
|
+
invite: (input, options) => executePostWithCompatibleInput(
|
|
1070
|
+
resolvedConfig,
|
|
1071
|
+
{ endpoint: "/organization/invite-member", method: "POST" },
|
|
1072
|
+
input,
|
|
1073
|
+
options
|
|
1074
|
+
),
|
|
1075
|
+
getActive: (input, options) => executeGetWithCompatibleInput(
|
|
1076
|
+
resolvedConfig,
|
|
1077
|
+
{ endpoint: "/organization/get-active-member", method: "GET" },
|
|
1078
|
+
input,
|
|
1079
|
+
options
|
|
1080
|
+
),
|
|
1081
|
+
list: (input, options) => executeGetWithQueryCompatibleInput(
|
|
1082
|
+
resolvedConfig,
|
|
1083
|
+
{ endpoint: "/organization/list-members", method: "GET" },
|
|
1084
|
+
input,
|
|
1085
|
+
options
|
|
1086
|
+
)
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
const authResetPassword = Object.assign(
|
|
1090
|
+
(input, options) => executePostWithCompatibleInput(
|
|
1091
|
+
resolvedConfig,
|
|
1092
|
+
{ endpoint: "/reset-password", method: "POST" },
|
|
1093
|
+
input,
|
|
1094
|
+
options
|
|
1095
|
+
),
|
|
1096
|
+
{
|
|
1097
|
+
token: resolveResetPasswordToken
|
|
1098
|
+
}
|
|
1099
|
+
);
|
|
1100
|
+
const sessionRevokeBinding = (input, options) => {
|
|
1101
|
+
if (Array.isArray(input)) {
|
|
1102
|
+
if (input.length === 0) {
|
|
1103
|
+
throw new Error("session.revoke requires at least one session token");
|
|
1104
|
+
}
|
|
1105
|
+
if (input.length === 1) {
|
|
1106
|
+
return revokeSession(input[0], options);
|
|
1107
|
+
}
|
|
1108
|
+
return revokeSessions(void 0, options);
|
|
1109
|
+
}
|
|
1110
|
+
const parsed = input;
|
|
1111
|
+
const tokens = Array.isArray(parsed.tokens) ? parsed.tokens.filter((token2) => token2.trim().length > 0) : void 0;
|
|
1112
|
+
if (tokens && tokens.length > 1) {
|
|
1113
|
+
return revokeSessions(
|
|
1114
|
+
parsed.fetchOptions ? { fetchOptions: parsed.fetchOptions } : void 0,
|
|
1115
|
+
options
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
if (tokens && tokens.length === 1) {
|
|
1119
|
+
return revokeSession(
|
|
1120
|
+
{ token: tokens[0], fetchOptions: parsed.fetchOptions },
|
|
1121
|
+
options
|
|
1122
|
+
);
|
|
1123
|
+
}
|
|
1124
|
+
const token = parsed.token?.trim();
|
|
1125
|
+
if (!token) {
|
|
1126
|
+
throw new Error("session.revoke requires a non-empty token or a non-empty token list");
|
|
1127
|
+
}
|
|
1128
|
+
return revokeSession(
|
|
1129
|
+
{
|
|
1130
|
+
token,
|
|
1131
|
+
fetchOptions: parsed.fetchOptions
|
|
1132
|
+
},
|
|
1133
|
+
options
|
|
1134
|
+
);
|
|
1135
|
+
};
|
|
1136
|
+
const adminUserSessionRevokeBinding = (input, options) => {
|
|
1137
|
+
const requireUserId = (userId) => {
|
|
1138
|
+
const trimmed = String(userId ?? "").trim();
|
|
1139
|
+
if (!trimmed) {
|
|
1140
|
+
throw new Error("admin.user.session.revoke requires a non-empty userId");
|
|
1141
|
+
}
|
|
1142
|
+
return trimmed;
|
|
1143
|
+
};
|
|
1144
|
+
const requireSinglePluralUserId = (sessions2) => {
|
|
1145
|
+
const uniqueUserIds = [...new Set(sessions2.map((session) => requireUserId(session.userId)))];
|
|
1146
|
+
if (uniqueUserIds.length !== 1) {
|
|
1147
|
+
throw new Error("admin.user.session.revoke requires the same userId across plural payloads");
|
|
1148
|
+
}
|
|
1149
|
+
return { userId: uniqueUserIds[0] };
|
|
1150
|
+
};
|
|
1151
|
+
if (Array.isArray(input)) {
|
|
1152
|
+
if (input.length === 0) {
|
|
1153
|
+
throw new Error("admin.user.session.revoke requires at least one payload item");
|
|
1154
|
+
}
|
|
1155
|
+
if (input.length === 1) {
|
|
1156
|
+
return postGeneric(
|
|
1157
|
+
"/admin/revoke-user-session",
|
|
1158
|
+
{
|
|
1159
|
+
...input[0],
|
|
1160
|
+
userId: requireUserId(input[0].userId)
|
|
1161
|
+
},
|
|
1162
|
+
options
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
return postGeneric(
|
|
1166
|
+
"/admin/revoke-user-sessions",
|
|
1167
|
+
requireSinglePluralUserId(input),
|
|
1168
|
+
options
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
const parsed = input;
|
|
1172
|
+
const sessions = parsed.sessions;
|
|
1173
|
+
if (sessions && sessions.length === 0) {
|
|
1174
|
+
throw new Error("admin.user.session.revoke requires at least one payload item");
|
|
1175
|
+
}
|
|
1176
|
+
if (sessions && sessions.length === 1) {
|
|
1177
|
+
return postGeneric(
|
|
1178
|
+
"/admin/revoke-user-session",
|
|
1179
|
+
{
|
|
1180
|
+
...sessions[0],
|
|
1181
|
+
userId: requireUserId(sessions[0].userId),
|
|
1182
|
+
fetchOptions: parsed.fetchOptions
|
|
1183
|
+
},
|
|
1184
|
+
options
|
|
1185
|
+
);
|
|
1186
|
+
}
|
|
1187
|
+
if (sessions && sessions.length > 1) {
|
|
1188
|
+
return postGeneric(
|
|
1189
|
+
"/admin/revoke-user-sessions",
|
|
1190
|
+
{
|
|
1191
|
+
...requireSinglePluralUserId(sessions),
|
|
1192
|
+
fetchOptions: parsed.fetchOptions
|
|
1193
|
+
},
|
|
1194
|
+
options
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1197
|
+
const normalizedUserId = requireUserId(parsed.userId);
|
|
1198
|
+
if (!parsed.sessionToken) {
|
|
1199
|
+
return postGeneric(
|
|
1200
|
+
"/admin/revoke-user-sessions",
|
|
1201
|
+
{
|
|
1202
|
+
userId: normalizedUserId,
|
|
1203
|
+
fetchOptions: parsed.fetchOptions
|
|
1204
|
+
},
|
|
1205
|
+
options
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
return postGeneric(
|
|
1209
|
+
"/admin/revoke-user-session",
|
|
1210
|
+
{
|
|
1211
|
+
...parsed,
|
|
1212
|
+
userId: normalizedUserId
|
|
1213
|
+
},
|
|
1214
|
+
options
|
|
1215
|
+
);
|
|
1216
|
+
};
|
|
1217
|
+
const auth = {
|
|
1218
|
+
getSession: (input, options) => getGeneric("/get-session", input, options),
|
|
1219
|
+
signOut,
|
|
1220
|
+
forgetPassword: (input, options) => postGeneric("/forget-password", input, options),
|
|
1221
|
+
resetPassword: authResetPassword,
|
|
1222
|
+
setPassword: (input, options) => postGeneric("/set-password", input, options),
|
|
1223
|
+
verifyEmail: (input, options) => {
|
|
1224
|
+
const queryInput = {
|
|
1225
|
+
query: {
|
|
1226
|
+
token: input.token,
|
|
1227
|
+
callbackURL: input.callbackURL
|
|
1228
|
+
},
|
|
1229
|
+
fetchOptions: input.fetchOptions
|
|
1230
|
+
};
|
|
1231
|
+
return getWithQuery(
|
|
1232
|
+
"/verify-email",
|
|
1233
|
+
queryInput,
|
|
1234
|
+
options
|
|
1235
|
+
);
|
|
757
1236
|
},
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
1237
|
+
sendVerificationEmail: (input, options) => postGeneric("/send-verification-email", input, options),
|
|
1238
|
+
changeEmail: (input, options) => postGeneric("/change-email", input, options),
|
|
1239
|
+
changeEmailVerify: (input, options) => getWithQuery("/change-email/verify", input, options),
|
|
1240
|
+
deleteUserVerify: (input, options) => getWithQuery("/delete-user/verify", input, options),
|
|
1241
|
+
changePassword: (input, options) => postGeneric("/change-password", input, options),
|
|
1242
|
+
user: {
|
|
1243
|
+
update: (input, options) => postGeneric("/update-user", input, options),
|
|
1244
|
+
delete: (input, options) => postGeneric("/delete-user", input, options),
|
|
1245
|
+
email: {
|
|
1246
|
+
list: listUserEmailsWithFallback
|
|
1247
|
+
}
|
|
761
1248
|
},
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
1249
|
+
session: {
|
|
1250
|
+
list: (input, options) => getGeneric("/list-sessions", input, options),
|
|
1251
|
+
revoke: sessionRevokeBinding,
|
|
1252
|
+
revokeOther: revokeOtherSessions
|
|
765
1253
|
},
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
return self;
|
|
1254
|
+
social: {
|
|
1255
|
+
link: (input, options) => postGeneric("/link-social", input, options)
|
|
769
1256
|
},
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
1257
|
+
account: {
|
|
1258
|
+
list: (input, options) => getGeneric("/list-accounts", input, options),
|
|
1259
|
+
unlink: (input, options) => postGeneric("/unlink-account", input, options)
|
|
773
1260
|
},
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
return self;
|
|
1261
|
+
deleteUser: {
|
|
1262
|
+
callback: deleteUserCallback
|
|
777
1263
|
},
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
1264
|
+
refreshToken: (input, options) => postGeneric("/refresh-token", input, options),
|
|
1265
|
+
getAccessToken: (input, options) => postGeneric("/get-access-token", input, options),
|
|
1266
|
+
health: healthWithFallback,
|
|
1267
|
+
ok: (input, options) => getGeneric("/ok", input, options),
|
|
1268
|
+
error: (input, options) => getGeneric("/error", input, options),
|
|
1269
|
+
twoFactor: {
|
|
1270
|
+
getTotpUri: (input, options) => postGeneric("/two-factor/get-totp-uri", input, options),
|
|
1271
|
+
verifyTotp: (input, options) => postGeneric("/two-factor/verify-totp", input, options),
|
|
1272
|
+
sendOtp: (input, options) => postGeneric("/two-factor/send-otp", input, options),
|
|
1273
|
+
verifyOtp: (input, options) => postGeneric("/two-factor/verify-otp", input, options),
|
|
1274
|
+
verifyBackupCode: (input, options) => postGeneric("/two-factor/verify-backup-code", input, options),
|
|
1275
|
+
generateBackupCodes: (input, options) => executePostWithCompatibleInput(
|
|
1276
|
+
resolvedConfig,
|
|
1277
|
+
{ endpoint: "/two-factor/generate-backup-codes", method: "POST" },
|
|
1278
|
+
input,
|
|
1279
|
+
options
|
|
1280
|
+
),
|
|
1281
|
+
enable: (input, options) => postGeneric("/two-factor/enable", input, options),
|
|
1282
|
+
disable: (input, options) => postGeneric("/two-factor/disable", input, options)
|
|
784
1283
|
},
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
1284
|
+
passkey: {
|
|
1285
|
+
generateRegisterOptions: (input, options) => getGeneric("/passkey/generate-register-options", input, options),
|
|
1286
|
+
generateAuthenticateOptions: (input, options) => postGeneric("/passkey/generate-authenticate-options", input, options),
|
|
1287
|
+
verifyRegistration: (input, options) => postGeneric("/passkey/verify-registration", input, options),
|
|
1288
|
+
verifyAuthentication: (input, options) => postGeneric("/passkey/verify-authentication", input, options),
|
|
1289
|
+
listUserPasskeys: (input, options) => getGeneric("/passkey/list-user-passkeys", input, options),
|
|
1290
|
+
deletePasskey: (input, options) => postGeneric("/passkey/delete-passkey", input, options),
|
|
1291
|
+
updatePasskey: (input, options) => postGeneric("/passkey/update-passkey", input, options),
|
|
1292
|
+
getRelatedOrigins: (input, options) => getGeneric("/.well-known/webauthn", input, options)
|
|
788
1293
|
},
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
1294
|
+
admin: {
|
|
1295
|
+
role: {
|
|
1296
|
+
set: (input, options) => postGeneric("/admin/set-role", input, options)
|
|
1297
|
+
},
|
|
1298
|
+
user: {
|
|
1299
|
+
list: (input, options) => getWithQuery("/admin/list-users", input, options),
|
|
1300
|
+
create: (input, options) => postGeneric("/admin/create-user", input, options),
|
|
1301
|
+
unban: (input, options) => postGeneric("/admin/unban-user", input, options),
|
|
1302
|
+
ban: (input, options) => postGeneric("/admin/ban-user", input, options),
|
|
1303
|
+
impersonate: (input, options) => postGeneric("/admin/impersonate-user", input, options),
|
|
1304
|
+
stopImpersonating: (input, options) => postGeneric("/admin/stop-impersonating", input, options),
|
|
1305
|
+
remove: (input, options) => postGeneric("/admin/remove-user", input, options),
|
|
1306
|
+
setPassword: (input, options) => postGeneric("/admin/set-user-password", input, options),
|
|
1307
|
+
session: {
|
|
1308
|
+
list: (input, options) => postGeneric("/admin/list-user-sessions", input, options),
|
|
1309
|
+
revoke: adminUserSessionRevokeBinding
|
|
1310
|
+
}
|
|
1311
|
+
},
|
|
1312
|
+
hasPermission: (input, options) => postGeneric("/admin/has-permission", input, options),
|
|
1313
|
+
apiKey: {
|
|
1314
|
+
create: (input, options) => postGeneric("/admin/api-key/create", input, options)
|
|
1315
|
+
},
|
|
1316
|
+
athenaClient: {
|
|
1317
|
+
create: (input, options) => postGeneric("/admin/athena-client/create", input, options),
|
|
1318
|
+
list: (input, options) => getWithQuery("/admin/athena-client/list", input, options)
|
|
1319
|
+
},
|
|
1320
|
+
auditLog: {
|
|
1321
|
+
list: (input, options) => getWithQuery("/admin/audit-log/list", input, options)
|
|
1322
|
+
},
|
|
1323
|
+
email: {
|
|
1324
|
+
list: (input, options) => getWithQuery("/admin/email/list", input, options),
|
|
1325
|
+
get: (input, options) => getWithQuery("/admin/email/get", input, options),
|
|
1326
|
+
create: (input, options) => postGeneric("/admin/email/create", input, options),
|
|
1327
|
+
update: (input, options) => postGeneric("/admin/email/update", input, options),
|
|
1328
|
+
delete: (input, options) => postGeneric("/admin/email/delete", input, options),
|
|
1329
|
+
failure: {
|
|
1330
|
+
list: (input, options) => getWithQuery("/admin/email-failure/list", input, options),
|
|
1331
|
+
get: (input, options) => getWithQuery("/admin/email-failure/get", input, options),
|
|
1332
|
+
create: (input, options) => postGeneric("/admin/email-failure/create", input, options),
|
|
1333
|
+
update: (input, options) => postGeneric("/admin/email-failure/update", input, options),
|
|
1334
|
+
delete: (input, options) => postGeneric("/admin/email-failure/delete", input, options)
|
|
1335
|
+
},
|
|
1336
|
+
template: {
|
|
1337
|
+
list: (input, options) => getWithQuery("/admin/email-template/list", input, options),
|
|
1338
|
+
get: (input, options) => getWithQuery("/admin/email-template/get", input, options),
|
|
1339
|
+
create: (input, options) => postGeneric("/admin/email-template/create", input, options),
|
|
1340
|
+
update: (input, options) => postGeneric("/admin/email-template/update", input, options),
|
|
1341
|
+
delete: (input, options) => postGeneric("/admin/email-template/delete", input, options)
|
|
1342
|
+
}
|
|
1343
|
+
},
|
|
1344
|
+
emailTemplate: {
|
|
1345
|
+
get: (input, options) => getWithQuery("/admin/email-template/get", input, options),
|
|
1346
|
+
create: (input, options) => postGeneric("/admin/email-template/create", input, options),
|
|
1347
|
+
delete: (input, options) => postGeneric("/admin/email-template/delete", input, options),
|
|
1348
|
+
list: (input, options) => getWithQuery("/admin/email-template/list", input, options),
|
|
1349
|
+
update: (input, options) => postGeneric("/admin/email-template/update", input, options)
|
|
1350
|
+
}
|
|
792
1351
|
},
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
addCondition("like", String(column), value);
|
|
807
|
-
return self;
|
|
808
|
-
},
|
|
809
|
-
ilike(column, value) {
|
|
810
|
-
addCondition("ilike", String(column), value);
|
|
811
|
-
return self;
|
|
812
|
-
},
|
|
813
|
-
is(column, value) {
|
|
814
|
-
addCondition("is", String(column), value);
|
|
815
|
-
return self;
|
|
816
|
-
},
|
|
817
|
-
in(column, values) {
|
|
818
|
-
addCondition("in", String(column), values);
|
|
819
|
-
return self;
|
|
1352
|
+
apiKey: {
|
|
1353
|
+
create: (input, options) => postGeneric("/api-key/create", input, options),
|
|
1354
|
+
get: (input, options) => getWithQuery("/api-key/get", input, options),
|
|
1355
|
+
update: (input, options) => postGeneric("/api-key/update", input, options),
|
|
1356
|
+
delete: (input, options) => postGeneric("/api-key/delete", input, options),
|
|
1357
|
+
list: (input, options) => getWithQuery("/api-key/list", input, options),
|
|
1358
|
+
verify: (input, options) => postGeneric("/api-key/verify", input, options),
|
|
1359
|
+
deleteAllExpired: (input, options) => executePostWithOptionalInput(
|
|
1360
|
+
resolvedConfig,
|
|
1361
|
+
{ endpoint: "/api-key/delete-all-expired-api-keys", method: "POST" },
|
|
1362
|
+
input,
|
|
1363
|
+
options
|
|
1364
|
+
)
|
|
820
1365
|
},
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
1366
|
+
signIn: {
|
|
1367
|
+
email: (input, options) => postGeneric("/sign-in/email", input, options),
|
|
1368
|
+
username: (input, options) => postGeneric("/sign-in/username", input, options),
|
|
1369
|
+
social: (input, options) => postGeneric("/sign-in/social", input, options)
|
|
824
1370
|
},
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
return self;
|
|
1371
|
+
signUp: {
|
|
1372
|
+
email: (input, options) => postGeneric("/sign-up/email", input, options)
|
|
828
1373
|
},
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
1374
|
+
organization,
|
|
1375
|
+
callback: {
|
|
1376
|
+
provider: (input, options) => {
|
|
1377
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
1378
|
+
const parsed = payload;
|
|
1379
|
+
const provider = String(parsed?.provider ?? "").trim();
|
|
1380
|
+
if (!provider) {
|
|
1381
|
+
throw new Error("callback.provider requires a non-empty provider value");
|
|
1382
|
+
}
|
|
1383
|
+
const code = String(parsed?.code ?? "").trim();
|
|
1384
|
+
const state = String(parsed?.state ?? "").trim();
|
|
1385
|
+
if (!code || !state) {
|
|
1386
|
+
throw new Error("callback.provider requires non-empty code and state values");
|
|
1387
|
+
}
|
|
1388
|
+
const endpoint = `/callback/${encodeURIComponent(provider)}`;
|
|
1389
|
+
return request({
|
|
1390
|
+
endpoint,
|
|
1391
|
+
method: "GET",
|
|
1392
|
+
query: {
|
|
1393
|
+
code,
|
|
1394
|
+
state
|
|
1395
|
+
},
|
|
1396
|
+
fetchOptions
|
|
1397
|
+
}, options);
|
|
835
1398
|
}
|
|
836
|
-
return self;
|
|
837
|
-
},
|
|
838
|
-
or(expression) {
|
|
839
|
-
addCondition("or", void 0, expression);
|
|
840
|
-
return self;
|
|
841
1399
|
}
|
|
842
1400
|
};
|
|
843
|
-
}
|
|
844
|
-
function toRpcSelect(columns) {
|
|
845
|
-
if (!columns) return void 0;
|
|
846
|
-
return Array.isArray(columns) ? columns.join(",") : columns;
|
|
847
|
-
}
|
|
848
|
-
function createRpcFilterMethods(filters, self) {
|
|
849
|
-
const addFilter = (operator, column, value) => {
|
|
850
|
-
filters.push({ column, operator, value });
|
|
851
|
-
};
|
|
852
1401
|
return {
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
addFilter("lte", column, value);
|
|
875
|
-
return self;
|
|
876
|
-
},
|
|
877
|
-
like(column, value) {
|
|
878
|
-
addFilter("like", column, value);
|
|
879
|
-
return self;
|
|
1402
|
+
baseUrl: normalizedBaseUrl,
|
|
1403
|
+
request,
|
|
1404
|
+
signIn: {
|
|
1405
|
+
email: (input, options) => executePostWithCompatibleInput(
|
|
1406
|
+
resolvedConfig,
|
|
1407
|
+
{ endpoint: "/sign-in/email", method: "POST" },
|
|
1408
|
+
input,
|
|
1409
|
+
options
|
|
1410
|
+
),
|
|
1411
|
+
username: (input, options) => executePostWithCompatibleInput(
|
|
1412
|
+
resolvedConfig,
|
|
1413
|
+
{ endpoint: "/sign-in/username", method: "POST" },
|
|
1414
|
+
input,
|
|
1415
|
+
options
|
|
1416
|
+
),
|
|
1417
|
+
social: (input, options) => executePostWithCompatibleInput(
|
|
1418
|
+
resolvedConfig,
|
|
1419
|
+
{ endpoint: "/sign-in/social", method: "POST" },
|
|
1420
|
+
input,
|
|
1421
|
+
options
|
|
1422
|
+
)
|
|
880
1423
|
},
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
1424
|
+
signUp: {
|
|
1425
|
+
email: (input, options) => executePostWithCompatibleInput(
|
|
1426
|
+
resolvedConfig,
|
|
1427
|
+
{ endpoint: "/sign-up/email", method: "POST" },
|
|
1428
|
+
input,
|
|
1429
|
+
options
|
|
1430
|
+
)
|
|
884
1431
|
},
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
1432
|
+
signOut,
|
|
1433
|
+
logout: signOut,
|
|
1434
|
+
getSession: (input, options) => executeGetWithCompatibleInput(
|
|
1435
|
+
resolvedConfig,
|
|
1436
|
+
{ endpoint: "/get-session", method: "GET" },
|
|
1437
|
+
input,
|
|
1438
|
+
options
|
|
1439
|
+
),
|
|
1440
|
+
listSessions: (input, options) => executeGetWithCompatibleInput(
|
|
1441
|
+
resolvedConfig,
|
|
1442
|
+
{ endpoint: "/list-sessions", method: "GET" },
|
|
1443
|
+
input,
|
|
1444
|
+
options
|
|
1445
|
+
),
|
|
1446
|
+
revokeSession,
|
|
1447
|
+
clearSession: revokeSession,
|
|
1448
|
+
revokeSessions,
|
|
1449
|
+
clearSessions: revokeSessions,
|
|
1450
|
+
revokeOtherSessions,
|
|
1451
|
+
clearOtherSessions: revokeOtherSessions,
|
|
1452
|
+
forgetPassword: (input, options) => executePostWithCompatibleInput(
|
|
1453
|
+
resolvedConfig,
|
|
1454
|
+
{ endpoint: "/forget-password", method: "POST" },
|
|
1455
|
+
input,
|
|
1456
|
+
options
|
|
1457
|
+
),
|
|
1458
|
+
resetPassword: (input, options) => executePostWithCompatibleInput(
|
|
1459
|
+
resolvedConfig,
|
|
1460
|
+
{ endpoint: "/reset-password", method: "POST" },
|
|
1461
|
+
input,
|
|
1462
|
+
options
|
|
1463
|
+
),
|
|
1464
|
+
resolveResetPasswordToken,
|
|
1465
|
+
verifyEmail: (input, options) => {
|
|
1466
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
1467
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
1468
|
+
const query = payload;
|
|
1469
|
+
return callAuthEndpoint(
|
|
1470
|
+
resolvedConfig,
|
|
1471
|
+
{ endpoint: "/verify-email", method: "GET" },
|
|
1472
|
+
void 0,
|
|
1473
|
+
query ? {
|
|
1474
|
+
token: query.token,
|
|
1475
|
+
callbackURL: query.callbackURL
|
|
1476
|
+
} : void 0,
|
|
1477
|
+
mergedOptions
|
|
1478
|
+
);
|
|
888
1479
|
},
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
1480
|
+
sendVerificationEmail: (input, options) => executePostWithCompatibleInput(
|
|
1481
|
+
resolvedConfig,
|
|
1482
|
+
{ endpoint: "/send-verification-email", method: "POST" },
|
|
1483
|
+
input,
|
|
1484
|
+
options
|
|
1485
|
+
),
|
|
1486
|
+
changeEmail: (input, options) => executePostWithCompatibleInput(
|
|
1487
|
+
resolvedConfig,
|
|
1488
|
+
{ endpoint: "/change-email", method: "POST" },
|
|
1489
|
+
input,
|
|
1490
|
+
options
|
|
1491
|
+
),
|
|
1492
|
+
changePassword: (input, options) => executePostWithCompatibleInput(
|
|
1493
|
+
resolvedConfig,
|
|
1494
|
+
{ endpoint: "/change-password", method: "POST" },
|
|
1495
|
+
input,
|
|
1496
|
+
options
|
|
1497
|
+
),
|
|
1498
|
+
updateUser: (input, options) => executePostWithCompatibleInput(
|
|
1499
|
+
resolvedConfig,
|
|
1500
|
+
{ endpoint: "/update-user", method: "POST" },
|
|
1501
|
+
input,
|
|
1502
|
+
options
|
|
1503
|
+
),
|
|
1504
|
+
deleteUser,
|
|
1505
|
+
deleteUserCallback,
|
|
1506
|
+
linkSocial: (input, options) => executePostWithCompatibleInput(
|
|
1507
|
+
resolvedConfig,
|
|
1508
|
+
{ endpoint: "/link-social", method: "POST" },
|
|
1509
|
+
input,
|
|
1510
|
+
options
|
|
1511
|
+
),
|
|
1512
|
+
listAccounts: (input, options) => executeGetWithCompatibleInput(
|
|
1513
|
+
resolvedConfig,
|
|
1514
|
+
{ endpoint: "/list-accounts", method: "GET" },
|
|
1515
|
+
input,
|
|
1516
|
+
options
|
|
1517
|
+
),
|
|
1518
|
+
unlinkAccount: (input, options) => executePostWithCompatibleInput(
|
|
1519
|
+
resolvedConfig,
|
|
1520
|
+
{ endpoint: "/unlink-account", method: "POST" },
|
|
1521
|
+
input,
|
|
1522
|
+
options
|
|
1523
|
+
),
|
|
1524
|
+
refreshToken: (input, options) => executePostWithCompatibleInput(
|
|
1525
|
+
resolvedConfig,
|
|
1526
|
+
{ endpoint: "/refresh-token", method: "POST" },
|
|
1527
|
+
input,
|
|
1528
|
+
options
|
|
1529
|
+
),
|
|
1530
|
+
getAccessToken: (input, options) => executePostWithCompatibleInput(
|
|
1531
|
+
resolvedConfig,
|
|
1532
|
+
{ endpoint: "/get-access-token", method: "POST" },
|
|
1533
|
+
input,
|
|
1534
|
+
options
|
|
1535
|
+
),
|
|
1536
|
+
organization,
|
|
1537
|
+
auth
|
|
893
1538
|
};
|
|
894
1539
|
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
async single(columns, options) {
|
|
936
|
-
const result = await run(columns, options);
|
|
937
|
-
return toSingleResult(result);
|
|
938
|
-
},
|
|
939
|
-
maybeSingle(columns, options) {
|
|
940
|
-
return builder.single(columns, options);
|
|
941
|
-
},
|
|
942
|
-
order(column, options) {
|
|
943
|
-
state.order = { column, ascending: options?.ascending ?? true };
|
|
944
|
-
return builder;
|
|
945
|
-
},
|
|
946
|
-
limit(count) {
|
|
947
|
-
state.limit = count;
|
|
948
|
-
return builder;
|
|
949
|
-
},
|
|
950
|
-
offset(count) {
|
|
951
|
-
state.offset = count;
|
|
952
|
-
return builder;
|
|
953
|
-
},
|
|
954
|
-
range(from, to) {
|
|
955
|
-
state.offset = from;
|
|
956
|
-
state.limit = to - from + 1;
|
|
957
|
-
return builder;
|
|
958
|
-
},
|
|
959
|
-
then(onfulfilled, onrejected) {
|
|
960
|
-
return run(selectedColumns, selectedOptions).then(onfulfilled, onrejected);
|
|
961
|
-
},
|
|
962
|
-
catch(onrejected) {
|
|
963
|
-
return run(selectedColumns, selectedOptions).catch(onrejected);
|
|
964
|
-
},
|
|
965
|
-
finally(onfinally) {
|
|
966
|
-
return run(selectedColumns, selectedOptions).finally(onfinally);
|
|
967
|
-
}
|
|
968
|
-
});
|
|
969
|
-
return builder;
|
|
1540
|
+
|
|
1541
|
+
// src/auxiliaries.ts
|
|
1542
|
+
var AthenaErrorKind = {
|
|
1543
|
+
UniqueViolation: "unique_violation",
|
|
1544
|
+
NotFound: "not_found",
|
|
1545
|
+
Validation: "validation",
|
|
1546
|
+
Auth: "auth",
|
|
1547
|
+
RateLimit: "rate_limit",
|
|
1548
|
+
Transient: "transient",
|
|
1549
|
+
Unknown: "unknown"
|
|
1550
|
+
};
|
|
1551
|
+
var AthenaErrorCode = {
|
|
1552
|
+
UniqueViolation: "UNIQUE_VIOLATION",
|
|
1553
|
+
NotFound: "NOT_FOUND",
|
|
1554
|
+
ValidationFailed: "VALIDATION_FAILED",
|
|
1555
|
+
AuthUnauthorized: "AUTH_UNAUTHORIZED",
|
|
1556
|
+
AuthForbidden: "AUTH_FORBIDDEN",
|
|
1557
|
+
RateLimited: "RATE_LIMITED",
|
|
1558
|
+
NetworkUnavailable: "NETWORK_UNAVAILABLE",
|
|
1559
|
+
TransientFailure: "TRANSIENT_FAILURE",
|
|
1560
|
+
HttpFailure: "HTTP_FAILURE",
|
|
1561
|
+
Unknown: "UNKNOWN"
|
|
1562
|
+
};
|
|
1563
|
+
var AthenaErrorCategory = {
|
|
1564
|
+
Transport: "transport",
|
|
1565
|
+
Client: "client",
|
|
1566
|
+
Server: "server",
|
|
1567
|
+
Database: "database",
|
|
1568
|
+
Unknown: "unknown"
|
|
1569
|
+
};
|
|
1570
|
+
function parseBooleanFlag(rawValue, fallback) {
|
|
1571
|
+
if (!rawValue) return fallback;
|
|
1572
|
+
const normalized = rawValue.trim().toLowerCase();
|
|
1573
|
+
if (normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on") {
|
|
1574
|
+
return true;
|
|
1575
|
+
}
|
|
1576
|
+
if (normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off") {
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
return fallback;
|
|
970
1580
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1581
|
+
var AthenaError = class extends Error {
|
|
1582
|
+
code;
|
|
1583
|
+
kind;
|
|
1584
|
+
category;
|
|
1585
|
+
status;
|
|
1586
|
+
retryable;
|
|
1587
|
+
requestId;
|
|
1588
|
+
context;
|
|
1589
|
+
raw;
|
|
1590
|
+
constructor(input) {
|
|
1591
|
+
super(input.message);
|
|
1592
|
+
this.name = "AthenaError";
|
|
1593
|
+
this.code = input.code;
|
|
1594
|
+
this.kind = input.kind;
|
|
1595
|
+
this.category = input.category;
|
|
1596
|
+
this.status = input.status;
|
|
1597
|
+
this.retryable = input.retryable ?? false;
|
|
1598
|
+
this.requestId = input.requestId;
|
|
1599
|
+
this.context = input.context;
|
|
1600
|
+
this.raw = input.raw;
|
|
1601
|
+
}
|
|
1602
|
+
};
|
|
1603
|
+
function isRecord3(value) {
|
|
1604
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1605
|
+
}
|
|
1606
|
+
function isAthenaErrorKind(value) {
|
|
1607
|
+
return value === "unique_violation" || value === "not_found" || value === "validation" || value === "auth" || value === "rate_limit" || value === "transient" || value === "unknown";
|
|
1608
|
+
}
|
|
1609
|
+
function isAthenaErrorCode(value) {
|
|
1610
|
+
return value === "UNIQUE_VIOLATION" || value === "NOT_FOUND" || value === "VALIDATION_FAILED" || value === "AUTH_UNAUTHORIZED" || value === "AUTH_FORBIDDEN" || value === "RATE_LIMITED" || value === "NETWORK_UNAVAILABLE" || value === "TRANSIENT_FAILURE" || value === "HTTP_FAILURE" || value === "UNKNOWN";
|
|
1611
|
+
}
|
|
1612
|
+
function isAthenaErrorCategory(value) {
|
|
1613
|
+
return value === "transport" || value === "client" || value === "server" || value === "database" || value === "unknown";
|
|
1614
|
+
}
|
|
1615
|
+
function isNormalizedAthenaError(value) {
|
|
1616
|
+
return isRecord3(value) && isAthenaErrorKind(value.kind) && isAthenaErrorCode(value.code) && isAthenaErrorCategory(value.category) && typeof value.retryable === "boolean" && typeof value.message === "string" && "raw" in value;
|
|
1617
|
+
}
|
|
1618
|
+
function withContextOverrides(normalized, context) {
|
|
1619
|
+
if (!context?.table && !context?.operation) {
|
|
1620
|
+
return normalized;
|
|
1621
|
+
}
|
|
1622
|
+
return {
|
|
1623
|
+
...normalized,
|
|
1624
|
+
table: context.table ?? normalized.table,
|
|
1625
|
+
operation: context.operation ?? normalized.operation
|
|
974
1626
|
};
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1627
|
+
}
|
|
1628
|
+
function resolveAttachedNormalizedError(resultOrError) {
|
|
1629
|
+
if (!isRecord3(resultOrError)) return void 0;
|
|
1630
|
+
if (!("__athenaNormalizedError" in resultOrError)) return void 0;
|
|
1631
|
+
const candidate = resultOrError.__athenaNormalizedError;
|
|
1632
|
+
return isNormalizedAthenaError(candidate) ? candidate : void 0;
|
|
1633
|
+
}
|
|
1634
|
+
function safeStringify(value) {
|
|
1635
|
+
try {
|
|
1636
|
+
const serialized = JSON.stringify(value);
|
|
1637
|
+
return serialized ?? String(value);
|
|
1638
|
+
} catch {
|
|
1639
|
+
return "[unserializable]";
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
function contextHint(context) {
|
|
1643
|
+
if (!context?.identity) return void 0;
|
|
1644
|
+
const identity = typeof context.identity === "string" ? context.identity : safeStringify(context.identity);
|
|
1645
|
+
return `Identity: ${identity}`;
|
|
1646
|
+
}
|
|
1647
|
+
function isAthenaResultLike(value) {
|
|
1648
|
+
return isRecord3(value) && "status" in value && "error" in value && "data" in value && typeof value.status === "number";
|
|
1649
|
+
}
|
|
1650
|
+
function operationFromDetails(details) {
|
|
1651
|
+
if (!details?.endpoint) return void 0;
|
|
1652
|
+
if (details.endpoint === "/gateway/fetch" || details.endpoint === "/gateway/query") return "select";
|
|
1653
|
+
if (details.endpoint === "/gateway/insert") return "insert";
|
|
1654
|
+
if (details.endpoint === "/gateway/update") return "update";
|
|
1655
|
+
if (details.endpoint === "/gateway/delete") return "delete";
|
|
1656
|
+
if (details.endpoint === "/gateway/rpc" || details.endpoint.startsWith("/rpc/")) return "rpc";
|
|
1657
|
+
return void 0;
|
|
1658
|
+
}
|
|
1659
|
+
function matchRegex(input, patterns) {
|
|
1660
|
+
for (const pattern of patterns) {
|
|
1661
|
+
const match = pattern.exec(input);
|
|
1662
|
+
if (match?.[1]) return match[1];
|
|
1663
|
+
}
|
|
1664
|
+
return void 0;
|
|
1665
|
+
}
|
|
1666
|
+
function extractConstraint(message) {
|
|
1667
|
+
return matchRegex(message, [
|
|
1668
|
+
/unique constraint\s+["'`]([^"'`]+)["'`]/i,
|
|
1669
|
+
/constraint\s+["'`]([^"'`]+)["'`]/i
|
|
1670
|
+
]);
|
|
1671
|
+
}
|
|
1672
|
+
function extractTable(message) {
|
|
1673
|
+
return matchRegex(message, [
|
|
1674
|
+
/(?:table|relation)\s+["'`]([^"'`]+)["'`]/i,
|
|
1675
|
+
/on\s+table\s+([a-zA-Z0-9_.]+)/i
|
|
1676
|
+
]);
|
|
1677
|
+
}
|
|
1678
|
+
function classifyKind(status, code, message) {
|
|
1679
|
+
const lower = message.toLowerCase();
|
|
1680
|
+
const hasUniquePattern = lower.includes("unique constraint") || lower.includes("duplicate key") || lower.includes("already exists") || lower.includes("duplicate");
|
|
1681
|
+
const hasNotFoundPattern = lower.includes("not found") || lower.includes("no rows");
|
|
1682
|
+
const hasValidationPattern = lower.includes("validation") || lower.includes("invalid") || lower.includes("malformed");
|
|
1683
|
+
const hasAuthPattern = lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("auth");
|
|
1684
|
+
const hasRateLimitPattern = lower.includes("rate limit") || lower.includes("too many requests");
|
|
1685
|
+
const hasTransientPattern = lower.includes("timeout") || lower.includes("temporar") || lower.includes("connection reset") || lower.includes("socket") || lower.includes("deadlock");
|
|
1686
|
+
if (status === 409 || hasUniquePattern) return "unique_violation";
|
|
1687
|
+
if (status === 404 || hasNotFoundPattern) return "not_found";
|
|
1688
|
+
if (status === 401 || status === 403 || hasAuthPattern) return "auth";
|
|
1689
|
+
if (status === 429 || hasRateLimitPattern) return "rate_limit";
|
|
1690
|
+
if (status === 400 || status === 422 || hasValidationPattern) return "validation";
|
|
1691
|
+
if (code === "NETWORK_ERROR" || status === 0 || status !== void 0 && status >= 500 || hasTransientPattern) {
|
|
1692
|
+
return "transient";
|
|
1693
|
+
}
|
|
1694
|
+
return "unknown";
|
|
1695
|
+
}
|
|
1696
|
+
function toAthenaErrorCode(kind, status, gatewayCode) {
|
|
1697
|
+
if (gatewayCode === "NETWORK_ERROR" || kind === "transient" && status === 0) {
|
|
1698
|
+
return AthenaErrorCode.NetworkUnavailable;
|
|
1699
|
+
}
|
|
1700
|
+
switch (kind) {
|
|
1701
|
+
case "unique_violation":
|
|
1702
|
+
return AthenaErrorCode.UniqueViolation;
|
|
1703
|
+
case "not_found":
|
|
1704
|
+
return AthenaErrorCode.NotFound;
|
|
1705
|
+
case "validation":
|
|
1706
|
+
return AthenaErrorCode.ValidationFailed;
|
|
1707
|
+
case "rate_limit":
|
|
1708
|
+
return AthenaErrorCode.RateLimited;
|
|
1709
|
+
case "auth":
|
|
1710
|
+
if (status === 403) {
|
|
1711
|
+
return AthenaErrorCode.AuthForbidden;
|
|
999
1712
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1713
|
+
return AthenaErrorCode.AuthUnauthorized;
|
|
1714
|
+
case "transient":
|
|
1715
|
+
return status !== void 0 && status >= 500 ? AthenaErrorCode.HttpFailure : AthenaErrorCode.TransientFailure;
|
|
1716
|
+
case "unknown":
|
|
1717
|
+
default:
|
|
1718
|
+
return status !== void 0 && status >= 400 ? AthenaErrorCode.HttpFailure : AthenaErrorCode.Unknown;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
function toAthenaErrorCategory(kind, status) {
|
|
1722
|
+
if (kind === "transient" && (status === 0 || status === void 0)) {
|
|
1723
|
+
return AthenaErrorCategory.Transport;
|
|
1724
|
+
}
|
|
1725
|
+
if (kind === "unique_violation") return AthenaErrorCategory.Database;
|
|
1726
|
+
if (kind === "validation" || kind === "auth" || kind === "not_found") return AthenaErrorCategory.Client;
|
|
1727
|
+
if (kind === "rate_limit" || kind === "transient") return AthenaErrorCategory.Server;
|
|
1728
|
+
return AthenaErrorCategory.Unknown;
|
|
1729
|
+
}
|
|
1730
|
+
function isRetryable(kind, status) {
|
|
1731
|
+
if (kind === "rate_limit" || kind === "transient") return true;
|
|
1732
|
+
return status !== void 0 && status >= 500;
|
|
1733
|
+
}
|
|
1734
|
+
function toGatewayCode(kind, status) {
|
|
1735
|
+
if (kind === "transient" && (status === 0 || status === void 0)) return "NETWORK_ERROR";
|
|
1736
|
+
if (kind === "validation") return "INVALID_JSON";
|
|
1737
|
+
if (status !== void 0 && status >= 400) return "HTTP_ERROR";
|
|
1738
|
+
return "UNKNOWN_ERROR";
|
|
1739
|
+
}
|
|
1740
|
+
function toAthenaGatewayError(source, fallbackMessage, context) {
|
|
1741
|
+
if (isAthenaGatewayError(source)) {
|
|
1742
|
+
return source;
|
|
1743
|
+
}
|
|
1744
|
+
if (isAthenaResultLike(source) && source.errorDetails) {
|
|
1745
|
+
return new AthenaGatewayError({
|
|
1746
|
+
code: source.errorDetails.code,
|
|
1747
|
+
message: source.error ?? source.errorDetails.message,
|
|
1748
|
+
status: source.status,
|
|
1749
|
+
endpoint: source.errorDetails.endpoint,
|
|
1750
|
+
method: source.errorDetails.method,
|
|
1751
|
+
requestId: source.errorDetails.requestId,
|
|
1752
|
+
hint: source.errorDetails.hint,
|
|
1753
|
+
cause: source.errorDetails.cause
|
|
1754
|
+
});
|
|
1755
|
+
}
|
|
1756
|
+
const normalized = normalizeAthenaError(source, context);
|
|
1757
|
+
const message = isAthenaResultLike(source) && source.error == null && source.errorDetails == null ? fallbackMessage : normalized.message || fallbackMessage;
|
|
1758
|
+
return new AthenaGatewayError({
|
|
1759
|
+
code: toGatewayCode(normalized.kind, normalized.status),
|
|
1760
|
+
message,
|
|
1761
|
+
status: normalized.status ?? 0,
|
|
1762
|
+
hint: normalized.constraint != null ? `Constraint: ${normalized.constraint}` : contextHint(context),
|
|
1763
|
+
cause: typeof normalized.raw === "string" ? normalized.raw : safeStringify(normalized.raw)
|
|
1764
|
+
});
|
|
1765
|
+
}
|
|
1766
|
+
function isOk(result) {
|
|
1767
|
+
return result.error == null && result.status >= 200 && result.status < 300;
|
|
1768
|
+
}
|
|
1769
|
+
function normalizeAthenaError(resultOrError, context) {
|
|
1770
|
+
const attached = resolveAttachedNormalizedError(resultOrError);
|
|
1771
|
+
if (attached) {
|
|
1772
|
+
return withContextOverrides(attached, context);
|
|
1773
|
+
}
|
|
1774
|
+
if (isAthenaResultLike(resultOrError)) {
|
|
1775
|
+
const details = resultOrError.errorDetails;
|
|
1776
|
+
const message2 = resultOrError.error ?? details?.message ?? `Athena ${context?.operation ?? operationFromDetails(details) ?? "request"} failed`;
|
|
1777
|
+
const operation = context?.operation ?? operationFromDetails(details);
|
|
1778
|
+
const table = context?.table ?? extractTable(message2);
|
|
1779
|
+
const constraint = extractConstraint(message2);
|
|
1780
|
+
const kind2 = classifyKind(resultOrError.status, details?.code, message2);
|
|
1781
|
+
const code = toAthenaErrorCode(kind2, resultOrError.status, details?.code);
|
|
1782
|
+
const category = toAthenaErrorCategory(kind2, resultOrError.status);
|
|
1783
|
+
return {
|
|
1784
|
+
kind: kind2,
|
|
1785
|
+
code,
|
|
1786
|
+
category,
|
|
1787
|
+
retryable: isRetryable(kind2, resultOrError.status),
|
|
1788
|
+
status: resultOrError.status,
|
|
1789
|
+
constraint,
|
|
1790
|
+
table,
|
|
1791
|
+
operation,
|
|
1792
|
+
message: message2,
|
|
1793
|
+
raw: resultOrError.raw
|
|
1794
|
+
};
|
|
1795
|
+
}
|
|
1796
|
+
if (isAthenaGatewayError(resultOrError)) {
|
|
1797
|
+
const details = resultOrError.toDetails();
|
|
1798
|
+
const operation = context?.operation ?? operationFromDetails(details);
|
|
1799
|
+
const table = context?.table ?? extractTable(resultOrError.message);
|
|
1800
|
+
const constraint = extractConstraint(resultOrError.message);
|
|
1801
|
+
const kind2 = classifyKind(resultOrError.status, resultOrError.code, resultOrError.message);
|
|
1802
|
+
const code = toAthenaErrorCode(kind2, resultOrError.status, resultOrError.code);
|
|
1803
|
+
const category = toAthenaErrorCategory(kind2, resultOrError.status);
|
|
1804
|
+
return {
|
|
1805
|
+
kind: kind2,
|
|
1806
|
+
code,
|
|
1807
|
+
category,
|
|
1808
|
+
retryable: isRetryable(kind2, resultOrError.status),
|
|
1809
|
+
status: resultOrError.status,
|
|
1810
|
+
constraint,
|
|
1811
|
+
table,
|
|
1812
|
+
operation,
|
|
1813
|
+
message: resultOrError.message,
|
|
1814
|
+
raw: resultOrError
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
if (resultOrError instanceof Error) {
|
|
1818
|
+
const maybeStatus = isRecord3(resultOrError) && typeof resultOrError.status === "number" ? resultOrError.status : void 0;
|
|
1819
|
+
const kind2 = classifyKind(maybeStatus, void 0, resultOrError.message);
|
|
1820
|
+
return {
|
|
1821
|
+
kind: kind2,
|
|
1822
|
+
code: toAthenaErrorCode(kind2, maybeStatus),
|
|
1823
|
+
category: toAthenaErrorCategory(kind2, maybeStatus),
|
|
1824
|
+
retryable: isRetryable(kind2, maybeStatus),
|
|
1825
|
+
status: maybeStatus,
|
|
1826
|
+
constraint: extractConstraint(resultOrError.message),
|
|
1827
|
+
table: context?.table ?? extractTable(resultOrError.message),
|
|
1828
|
+
operation: context?.operation,
|
|
1829
|
+
message: resultOrError.message,
|
|
1830
|
+
raw: resultOrError
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
const message = typeof resultOrError === "string" ? resultOrError : "Unknown Athena error";
|
|
1834
|
+
const kind = classifyKind(void 0, void 0, message);
|
|
1835
|
+
return {
|
|
1836
|
+
kind,
|
|
1837
|
+
code: toAthenaErrorCode(kind, void 0),
|
|
1838
|
+
category: toAthenaErrorCategory(kind, void 0),
|
|
1839
|
+
retryable: isRetryable(kind, void 0),
|
|
1840
|
+
status: void 0,
|
|
1841
|
+
constraint: extractConstraint(message),
|
|
1842
|
+
table: context?.table ?? extractTable(message),
|
|
1843
|
+
operation: context?.operation,
|
|
1844
|
+
message,
|
|
1845
|
+
raw: resultOrError
|
|
1002
1846
|
};
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
);
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1847
|
+
}
|
|
1848
|
+
function unwrapRows(result, options) {
|
|
1849
|
+
if (!isOk(result)) {
|
|
1850
|
+
throw toAthenaGatewayError(result, "Athena request failed", options?.context);
|
|
1851
|
+
}
|
|
1852
|
+
if (result.data == null) return [];
|
|
1853
|
+
return Array.isArray(result.data) ? result.data : [result.data];
|
|
1854
|
+
}
|
|
1855
|
+
function unwrap(result, options) {
|
|
1856
|
+
if (!isOk(result)) {
|
|
1857
|
+
throw toAthenaGatewayError(result, "Athena request failed", options?.context);
|
|
1858
|
+
}
|
|
1859
|
+
if (result.data == null && !options?.allowNull) {
|
|
1860
|
+
throw toAthenaGatewayError(result, "Expected data but received null", options?.context);
|
|
1861
|
+
}
|
|
1862
|
+
return result.data;
|
|
1863
|
+
}
|
|
1864
|
+
function unwrapOne(result, options) {
|
|
1865
|
+
const rows = unwrapRows(result, options);
|
|
1866
|
+
if (!rows.length) {
|
|
1867
|
+
if (options?.allowNull) return null;
|
|
1868
|
+
throw toAthenaGatewayError(result, "Expected one row but received none", options?.context);
|
|
1869
|
+
}
|
|
1870
|
+
if (options?.requireExactlyOne && rows.length !== 1) {
|
|
1871
|
+
throw toAthenaGatewayError(
|
|
1872
|
+
result,
|
|
1873
|
+
`Expected exactly one row but received ${rows.length}`,
|
|
1874
|
+
options.context
|
|
1875
|
+
);
|
|
1876
|
+
}
|
|
1877
|
+
return rows[0];
|
|
1878
|
+
}
|
|
1879
|
+
function requireSuccess(result, context) {
|
|
1880
|
+
if (!isOk(result)) {
|
|
1881
|
+
throw toAthenaGatewayError(
|
|
1882
|
+
result,
|
|
1883
|
+
`Athena ${context?.operation ?? "request"} failed`,
|
|
1884
|
+
context
|
|
1885
|
+
);
|
|
1886
|
+
}
|
|
1887
|
+
return result;
|
|
1888
|
+
}
|
|
1889
|
+
function requireAffected(result, options, context) {
|
|
1890
|
+
requireSuccess(result, context);
|
|
1891
|
+
const minimum = options?.min ?? 1;
|
|
1892
|
+
const count = result.count;
|
|
1893
|
+
if (count == null) {
|
|
1894
|
+
throw new AthenaGatewayError({
|
|
1895
|
+
code: "UNKNOWN_ERROR",
|
|
1896
|
+
status: result.status,
|
|
1897
|
+
message: "Expected affected row count but response.count is missing",
|
|
1898
|
+
hint: 'Set call option { count: "exact" } for mutation postcondition checks.',
|
|
1899
|
+
cause: safeStringify(result.raw)
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
if (count < minimum) {
|
|
1903
|
+
throw new AthenaGatewayError({
|
|
1904
|
+
code: "UNKNOWN_ERROR",
|
|
1905
|
+
status: result.status,
|
|
1906
|
+
message: `Expected at least ${minimum} affected rows but received ${count}`,
|
|
1907
|
+
hint: contextHint(context),
|
|
1908
|
+
cause: safeStringify(result.raw)
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
return count;
|
|
1912
|
+
}
|
|
1913
|
+
function applyBounds(value, options) {
|
|
1914
|
+
if (options?.min !== void 0 && value < options.min) return null;
|
|
1915
|
+
if (options?.max !== void 0 && value > options.max) return null;
|
|
1916
|
+
return value;
|
|
1917
|
+
}
|
|
1918
|
+
function parseIntegerString(value) {
|
|
1919
|
+
const normalized = value.trim();
|
|
1920
|
+
if (!/^[-+]?\d+$/.test(normalized)) return null;
|
|
1921
|
+
const parsed = Number(normalized);
|
|
1922
|
+
if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) return null;
|
|
1923
|
+
return parsed;
|
|
1924
|
+
}
|
|
1925
|
+
function coerceInt(value, options) {
|
|
1926
|
+
if (value == null) return null;
|
|
1927
|
+
if (typeof value === "number") {
|
|
1928
|
+
if (!Number.isFinite(value) || !Number.isInteger(value)) return null;
|
|
1929
|
+
return applyBounds(value, options);
|
|
1930
|
+
}
|
|
1931
|
+
if (typeof value === "string") {
|
|
1932
|
+
const parsed = parseIntegerString(value);
|
|
1933
|
+
if (parsed == null) return null;
|
|
1934
|
+
return applyBounds(parsed, options);
|
|
1935
|
+
}
|
|
1936
|
+
if (typeof value === "bigint") {
|
|
1937
|
+
if (options?.strictBigInt) {
|
|
1938
|
+
if (value > BigInt(Number.MAX_SAFE_INTEGER) || value < BigInt(Number.MIN_SAFE_INTEGER)) {
|
|
1939
|
+
return null;
|
|
1029
1940
|
}
|
|
1030
1941
|
}
|
|
1031
|
-
const
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1942
|
+
const parsed = Number(value);
|
|
1943
|
+
if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) return null;
|
|
1944
|
+
return applyBounds(parsed, options);
|
|
1945
|
+
}
|
|
1946
|
+
return null;
|
|
1947
|
+
}
|
|
1948
|
+
function assertInt(value, label = "value", options) {
|
|
1949
|
+
const parsed = coerceInt(value, options);
|
|
1950
|
+
if (parsed == null) {
|
|
1951
|
+
throw new TypeError(`${label} must be a finite integer`);
|
|
1952
|
+
}
|
|
1953
|
+
return parsed;
|
|
1954
|
+
}
|
|
1955
|
+
function defaultShouldRetry(error) {
|
|
1956
|
+
const normalized = normalizeAthenaError(error);
|
|
1957
|
+
return normalized.kind === "transient" || normalized.kind === "rate_limit";
|
|
1958
|
+
}
|
|
1959
|
+
function computeDelayMs(attempt, error, config) {
|
|
1960
|
+
const baseDelay = config.baseDelayMs;
|
|
1961
|
+
const rawDelay = typeof config.backoff === "function" ? config.backoff(attempt, error) : config.backoff === "linear" ? baseDelay * attempt : baseDelay * Math.pow(2, attempt - 1);
|
|
1962
|
+
const safeDelay = Number.isFinite(rawDelay) ? Math.max(0, rawDelay) : 0;
|
|
1963
|
+
const clamped = Math.min(config.maxDelayMs, safeDelay);
|
|
1964
|
+
const jitterFactor = typeof config.jitter === "number" ? Math.max(0, Math.min(1, config.jitter)) : config.jitter ? 0.2 : 0;
|
|
1965
|
+
if (!jitterFactor) return clamped;
|
|
1966
|
+
const deviation = clamped * jitterFactor;
|
|
1967
|
+
const offset = (Math.random() * 2 - 1) * deviation;
|
|
1968
|
+
return Math.max(0, clamped + offset);
|
|
1969
|
+
}
|
|
1970
|
+
function sleep(ms) {
|
|
1971
|
+
if (ms <= 0) return Promise.resolve();
|
|
1972
|
+
return new Promise((resolve3) => {
|
|
1973
|
+
setTimeout(resolve3, ms);
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
async function withRetry(config, fn) {
|
|
1977
|
+
const retries = Math.max(0, Math.trunc(config.retries));
|
|
1978
|
+
const shouldRetry = config.shouldRetry ?? defaultShouldRetry;
|
|
1979
|
+
const resolvedConfig = {
|
|
1980
|
+
baseDelayMs: config.baseDelayMs ?? 100,
|
|
1981
|
+
maxDelayMs: config.maxDelayMs ?? 1e4,
|
|
1982
|
+
backoff: config.backoff ?? "exponential",
|
|
1983
|
+
jitter: config.jitter ?? false
|
|
1047
1984
|
};
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
return toSingleResult(r);
|
|
1055
|
-
},
|
|
1056
|
-
maybeSingle(cols, opts) {
|
|
1057
|
-
return chain.single(cols, opts);
|
|
1058
|
-
},
|
|
1059
|
-
then(onfulfilled, onrejected) {
|
|
1060
|
-
return runSelect(columns, options).then(onfulfilled, onrejected);
|
|
1061
|
-
},
|
|
1062
|
-
catch(onrejected) {
|
|
1063
|
-
return runSelect(columns, options).catch(onrejected);
|
|
1064
|
-
},
|
|
1065
|
-
finally(onfinally) {
|
|
1066
|
-
return runSelect(columns, options).finally(onfinally);
|
|
1985
|
+
for (let attempts = 0; attempts <= retries; attempts += 1) {
|
|
1986
|
+
try {
|
|
1987
|
+
return await fn();
|
|
1988
|
+
} catch (error) {
|
|
1989
|
+
if (attempts >= retries) {
|
|
1990
|
+
throw error;
|
|
1067
1991
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1992
|
+
const currentAttempt = attempts + 1;
|
|
1993
|
+
const retry = await shouldRetry(error, currentAttempt);
|
|
1994
|
+
if (!retry) {
|
|
1995
|
+
throw error;
|
|
1996
|
+
}
|
|
1997
|
+
const delay = computeDelayMs(currentAttempt, error, resolvedConfig);
|
|
1998
|
+
await sleep(delay);
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
throw new Error("withRetry reached an unexpected state");
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
// src/db/module.ts
|
|
2005
|
+
function createDbModule(input) {
|
|
2006
|
+
const db = {
|
|
2007
|
+
from(table) {
|
|
2008
|
+
return input.from(table);
|
|
1081
2009
|
},
|
|
1082
|
-
select(columns
|
|
1083
|
-
return
|
|
2010
|
+
select(table, columns, options) {
|
|
2011
|
+
return input.from(table).select(columns, options);
|
|
1084
2012
|
},
|
|
1085
|
-
insert(values, options) {
|
|
1086
|
-
|
|
1087
|
-
const executeInsertMany = async (columns, selectOptions) => {
|
|
1088
|
-
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1089
|
-
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1090
|
-
const payload = {
|
|
1091
|
-
table_name: resolvedTableName,
|
|
1092
|
-
insert_body: asAthenaJsonObjectArray(values)
|
|
1093
|
-
};
|
|
1094
|
-
if (columns) payload.columns = columns;
|
|
1095
|
-
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
1096
|
-
if (mergedOptions?.head) payload.head = mergedOptions.head;
|
|
1097
|
-
if (mergedOptions?.defaultToNull !== void 0) {
|
|
1098
|
-
payload.default_to_null = mergedOptions.defaultToNull;
|
|
1099
|
-
}
|
|
1100
|
-
const response = await client.insertGateway(payload, mergedOptions);
|
|
1101
|
-
return formatResult(response);
|
|
1102
|
-
};
|
|
1103
|
-
return createMutationQuery(executeInsertMany);
|
|
1104
|
-
}
|
|
1105
|
-
const executeInsertOne = async (columns, selectOptions) => {
|
|
1106
|
-
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1107
|
-
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1108
|
-
const payload = {
|
|
1109
|
-
table_name: resolvedTableName,
|
|
1110
|
-
insert_body: asAthenaJsonObject(values)
|
|
1111
|
-
};
|
|
1112
|
-
if (columns) payload.columns = columns;
|
|
1113
|
-
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
1114
|
-
if (mergedOptions?.head) payload.head = mergedOptions.head;
|
|
1115
|
-
if (mergedOptions?.defaultToNull !== void 0) {
|
|
1116
|
-
payload.default_to_null = mergedOptions.defaultToNull;
|
|
1117
|
-
}
|
|
1118
|
-
const response = await client.insertGateway(payload, mergedOptions);
|
|
1119
|
-
return formatResult(response);
|
|
1120
|
-
};
|
|
1121
|
-
return createMutationQuery(executeInsertOne);
|
|
2013
|
+
insert(table, values, options) {
|
|
2014
|
+
return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
|
|
1122
2015
|
},
|
|
1123
|
-
upsert(values, options) {
|
|
1124
|
-
|
|
1125
|
-
const executeUpsertMany = async (columns, selectOptions) => {
|
|
1126
|
-
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1127
|
-
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1128
|
-
const payload = {
|
|
1129
|
-
table_name: resolvedTableName,
|
|
1130
|
-
insert_body: asAthenaJsonObjectArray(values),
|
|
1131
|
-
update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
|
|
1132
|
-
};
|
|
1133
|
-
if (columns) payload.columns = columns;
|
|
1134
|
-
if (options?.onConflict) payload.on_conflict = options.onConflict;
|
|
1135
|
-
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
1136
|
-
if (mergedOptions?.head) payload.head = mergedOptions.head;
|
|
1137
|
-
if (mergedOptions?.defaultToNull !== void 0) {
|
|
1138
|
-
payload.default_to_null = mergedOptions.defaultToNull;
|
|
1139
|
-
}
|
|
1140
|
-
const response = await client.insertGateway(payload, mergedOptions);
|
|
1141
|
-
return formatResult(response);
|
|
1142
|
-
};
|
|
1143
|
-
return createMutationQuery(executeUpsertMany);
|
|
1144
|
-
}
|
|
1145
|
-
const executeUpsertOne = async (columns, selectOptions) => {
|
|
1146
|
-
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1147
|
-
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1148
|
-
const payload = {
|
|
1149
|
-
table_name: resolvedTableName,
|
|
1150
|
-
insert_body: asAthenaJsonObject(values),
|
|
1151
|
-
update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
|
|
1152
|
-
};
|
|
1153
|
-
if (columns) payload.columns = columns;
|
|
1154
|
-
if (options?.onConflict) payload.on_conflict = options.onConflict;
|
|
1155
|
-
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
1156
|
-
if (mergedOptions?.head) payload.head = mergedOptions.head;
|
|
1157
|
-
if (mergedOptions?.defaultToNull !== void 0) {
|
|
1158
|
-
payload.default_to_null = mergedOptions.defaultToNull;
|
|
1159
|
-
}
|
|
1160
|
-
const response = await client.insertGateway(payload, mergedOptions);
|
|
1161
|
-
return formatResult(response);
|
|
1162
|
-
};
|
|
1163
|
-
return createMutationQuery(executeUpsertOne);
|
|
2016
|
+
upsert(table, values, options) {
|
|
2017
|
+
return Array.isArray(values) ? input.from(table).upsert(values, options) : input.from(table).upsert(values, options);
|
|
1164
2018
|
},
|
|
1165
|
-
update(values, options) {
|
|
1166
|
-
|
|
1167
|
-
const filters = state.conditions.length ? [...state.conditions] : void 0;
|
|
1168
|
-
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1169
|
-
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1170
|
-
const payload = {
|
|
1171
|
-
table_name: resolvedTableName,
|
|
1172
|
-
set: asAthenaJsonObject(values),
|
|
1173
|
-
conditions: filters,
|
|
1174
|
-
strip_nulls: mergedOptions?.stripNulls ?? true
|
|
1175
|
-
};
|
|
1176
|
-
if (state.order) payload.sort_by = state.order;
|
|
1177
|
-
if (state.currentPage !== void 0) payload.current_page = state.currentPage;
|
|
1178
|
-
if (state.pageSize !== void 0) payload.page_size = state.pageSize;
|
|
1179
|
-
if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
|
|
1180
|
-
if (columns) payload.columns = columns;
|
|
1181
|
-
const response = await client.updateGateway(payload, mergedOptions);
|
|
1182
|
-
return formatResult(response);
|
|
1183
|
-
};
|
|
1184
|
-
const mutation = createMutationQuery(executeUpdate, null);
|
|
1185
|
-
const updateChain = {};
|
|
1186
|
-
const filterMethods2 = createFilterMethods(state, addCondition, updateChain);
|
|
1187
|
-
Object.assign(updateChain, filterMethods2, mutation);
|
|
1188
|
-
return updateChain;
|
|
2019
|
+
update(table, values, options) {
|
|
2020
|
+
return input.from(table).update(values, options);
|
|
1189
2021
|
},
|
|
1190
|
-
delete(options) {
|
|
1191
|
-
|
|
1192
|
-
const resourceId = options?.resourceId ?? getResourceId(state);
|
|
1193
|
-
if (!resourceId && !filters?.length) {
|
|
1194
|
-
throw new Error('delete requires a resource_id either via eq("resource_id", ...) or options.resourceId');
|
|
1195
|
-
}
|
|
1196
|
-
const executeDelete = async (columns, selectOptions) => {
|
|
1197
|
-
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1198
|
-
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1199
|
-
const payload = {
|
|
1200
|
-
table_name: resolvedTableName,
|
|
1201
|
-
resource_id: resourceId,
|
|
1202
|
-
conditions: filters
|
|
1203
|
-
};
|
|
1204
|
-
if (state.order) payload.sort_by = state.order;
|
|
1205
|
-
if (state.currentPage !== void 0) payload.current_page = state.currentPage;
|
|
1206
|
-
if (state.pageSize !== void 0) payload.page_size = state.pageSize;
|
|
1207
|
-
if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
|
|
1208
|
-
if (columns) payload.columns = columns;
|
|
1209
|
-
const response = await client.deleteGateway(payload, mergedOptions);
|
|
1210
|
-
return formatResult(response);
|
|
1211
|
-
};
|
|
1212
|
-
return createMutationQuery(executeDelete, null);
|
|
2022
|
+
delete(table, options) {
|
|
2023
|
+
return input.from(table).delete(options);
|
|
1213
2024
|
},
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
return toSingleResult(response);
|
|
2025
|
+
rpc(fn, args, options) {
|
|
2026
|
+
return input.rpc(fn, args, options);
|
|
1217
2027
|
},
|
|
1218
|
-
|
|
1219
|
-
return
|
|
2028
|
+
query(query, options) {
|
|
2029
|
+
return input.query(query, options);
|
|
1220
2030
|
}
|
|
2031
|
+
};
|
|
2032
|
+
return db;
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
// src/client.ts
|
|
2036
|
+
var DEFAULT_COLUMNS = "*";
|
|
2037
|
+
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
2038
|
+
var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
|
|
2039
|
+
var ATHENA_NORMALIZED_ERROR_KEY = "__athenaNormalizedError";
|
|
2040
|
+
function formatResult(response) {
|
|
2041
|
+
const result = {
|
|
2042
|
+
data: response.data ?? null,
|
|
2043
|
+
error: response.error ?? null,
|
|
2044
|
+
errorDetails: response.errorDetails ?? null,
|
|
2045
|
+
status: response.status,
|
|
2046
|
+
raw: response.raw
|
|
2047
|
+
};
|
|
2048
|
+
if (response.count !== void 0) {
|
|
2049
|
+
result.count = response.count;
|
|
2050
|
+
}
|
|
2051
|
+
return result;
|
|
2052
|
+
}
|
|
2053
|
+
function attachNormalizedError(result, normalizedError) {
|
|
2054
|
+
Object.defineProperty(result, ATHENA_NORMALIZED_ERROR_KEY, {
|
|
2055
|
+
value: normalizedError,
|
|
2056
|
+
enumerable: false,
|
|
2057
|
+
configurable: true,
|
|
2058
|
+
writable: false
|
|
1221
2059
|
});
|
|
1222
|
-
return builder;
|
|
1223
2060
|
}
|
|
1224
|
-
function
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
2061
|
+
function createResultFormatter(experimental) {
|
|
2062
|
+
if (!experimental?.enableErrorNormalization) {
|
|
2063
|
+
return formatResult;
|
|
2064
|
+
}
|
|
2065
|
+
return (response, context) => {
|
|
2066
|
+
const result = formatResult(response);
|
|
2067
|
+
if (result.error == null) {
|
|
2068
|
+
return result;
|
|
1229
2069
|
}
|
|
1230
|
-
const
|
|
1231
|
-
|
|
2070
|
+
const normalizedError = normalizeAthenaError(result, context);
|
|
2071
|
+
attachNormalizedError(result, normalizedError);
|
|
2072
|
+
return result;
|
|
1232
2073
|
};
|
|
1233
2074
|
}
|
|
1234
|
-
function
|
|
1235
|
-
const
|
|
1236
|
-
|
|
1237
|
-
apiKey: config.apiKey,
|
|
1238
|
-
client: config.client,
|
|
1239
|
-
backend: config.backend,
|
|
1240
|
-
headers: config.headers
|
|
1241
|
-
});
|
|
2075
|
+
function toSingleResult(response) {
|
|
2076
|
+
const payload = response.data;
|
|
2077
|
+
const singleData = Array.isArray(payload) ? payload.length ? payload[0] : null : payload ?? null;
|
|
1242
2078
|
return {
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
},
|
|
1246
|
-
rpc(fn, args, options) {
|
|
1247
|
-
const normalizedFn = fn.trim();
|
|
1248
|
-
if (!normalizedFn) {
|
|
1249
|
-
throw new Error("rpc requires a function name");
|
|
1250
|
-
}
|
|
1251
|
-
return createRpcBuilder(
|
|
1252
|
-
normalizedFn,
|
|
1253
|
-
args,
|
|
1254
|
-
options,
|
|
1255
|
-
gateway
|
|
1256
|
-
);
|
|
1257
|
-
},
|
|
1258
|
-
query: createQueryBuilder(gateway)
|
|
2079
|
+
...response,
|
|
2080
|
+
data: singleData
|
|
1259
2081
|
};
|
|
1260
2082
|
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
2083
|
+
function mergeOptions(...options) {
|
|
2084
|
+
return options.reduce((acc, next) => {
|
|
2085
|
+
if (!next) return acc;
|
|
2086
|
+
return { ...acc, ...next };
|
|
2087
|
+
}, void 0);
|
|
1265
2088
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
backend(backend) {
|
|
1282
|
-
this.backendConfig = toBackendConfig(backend);
|
|
1283
|
-
return this;
|
|
1284
|
-
}
|
|
1285
|
-
client(clientName) {
|
|
1286
|
-
this.clientName = clientName;
|
|
1287
|
-
return this;
|
|
1288
|
-
}
|
|
1289
|
-
headers(headers) {
|
|
1290
|
-
this.defaultHeaders = headers;
|
|
1291
|
-
return this;
|
|
1292
|
-
}
|
|
1293
|
-
healthTracking(enabled) {
|
|
1294
|
-
this.isHealthTrackingEnabled = enabled;
|
|
1295
|
-
return this;
|
|
1296
|
-
}
|
|
1297
|
-
build() {
|
|
1298
|
-
if (!this.baseUrl || !this.apiKey) {
|
|
1299
|
-
throw new Error("AthenaClient requires url and key; call .url() and .key() before .build()");
|
|
2089
|
+
function asAthenaJsonObject(value) {
|
|
2090
|
+
return value;
|
|
2091
|
+
}
|
|
2092
|
+
function asAthenaJsonObjectArray(values) {
|
|
2093
|
+
return values;
|
|
2094
|
+
}
|
|
2095
|
+
function createMutationQuery(executor, defaultColumns = DEFAULT_COLUMNS) {
|
|
2096
|
+
let selectedColumns = defaultColumns === null ? void 0 : defaultColumns;
|
|
2097
|
+
let selectedOptions;
|
|
2098
|
+
let promise = null;
|
|
2099
|
+
const run = (columns, options) => {
|
|
2100
|
+
const payloadColumns = columns ?? selectedColumns;
|
|
2101
|
+
const payloadOptions = options ?? selectedOptions;
|
|
2102
|
+
if (!promise) {
|
|
2103
|
+
promise = executor(payloadColumns, payloadOptions);
|
|
1300
2104
|
}
|
|
1301
|
-
return
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
2105
|
+
return promise;
|
|
2106
|
+
};
|
|
2107
|
+
const mutationQuery = {
|
|
2108
|
+
select(columns = selectedColumns, options) {
|
|
2109
|
+
selectedColumns = columns;
|
|
2110
|
+
selectedOptions = options ?? selectedOptions;
|
|
2111
|
+
return run(columns, options);
|
|
2112
|
+
},
|
|
2113
|
+
returning(columns = selectedColumns, options) {
|
|
2114
|
+
return mutationQuery.select(columns, options);
|
|
2115
|
+
},
|
|
2116
|
+
single(columns = selectedColumns, options) {
|
|
2117
|
+
selectedColumns = columns;
|
|
2118
|
+
selectedOptions = options ?? selectedOptions;
|
|
2119
|
+
return run(columns, options).then(toSingleResult);
|
|
2120
|
+
},
|
|
2121
|
+
maybeSingle(columns = selectedColumns, options) {
|
|
2122
|
+
return mutationQuery.single(columns, options);
|
|
2123
|
+
},
|
|
2124
|
+
then(onfulfilled, onrejected) {
|
|
2125
|
+
return run(selectedColumns, selectedOptions).then(onfulfilled, onrejected);
|
|
2126
|
+
},
|
|
2127
|
+
catch(onrejected) {
|
|
2128
|
+
return run(selectedColumns, selectedOptions).catch(onrejected);
|
|
2129
|
+
},
|
|
2130
|
+
finally(onfinally) {
|
|
2131
|
+
return run(selectedColumns, selectedOptions).finally(onfinally);
|
|
1324
2132
|
}
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
};
|
|
1328
|
-
function createClient(url, apiKey, options) {
|
|
1329
|
-
const b = AthenaClient.builder().url(url).key(apiKey).backend(toBackendConfig(options?.backend));
|
|
1330
|
-
if (options?.client) b.client(options.client);
|
|
1331
|
-
if (options?.headers && Object.keys(options.headers).length > 0) b.headers(options.headers);
|
|
1332
|
-
return b.build();
|
|
2133
|
+
};
|
|
2134
|
+
return mutationQuery;
|
|
1333
2135
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
// src/auxiliaries.ts
|
|
1344
|
-
var AthenaErrorKind = {
|
|
1345
|
-
UniqueViolation: "unique_violation",
|
|
1346
|
-
NotFound: "not_found",
|
|
1347
|
-
Validation: "validation",
|
|
1348
|
-
Auth: "auth",
|
|
1349
|
-
RateLimit: "rate_limit",
|
|
1350
|
-
Transient: "transient",
|
|
1351
|
-
Unknown: "unknown"
|
|
1352
|
-
};
|
|
1353
|
-
var AthenaErrorCode = {
|
|
1354
|
-
UniqueViolation: "UNIQUE_VIOLATION",
|
|
1355
|
-
NotFound: "NOT_FOUND",
|
|
1356
|
-
ValidationFailed: "VALIDATION_FAILED",
|
|
1357
|
-
AuthUnauthorized: "AUTH_UNAUTHORIZED",
|
|
1358
|
-
AuthForbidden: "AUTH_FORBIDDEN",
|
|
1359
|
-
RateLimited: "RATE_LIMITED",
|
|
1360
|
-
NetworkUnavailable: "NETWORK_UNAVAILABLE",
|
|
1361
|
-
TransientFailure: "TRANSIENT_FAILURE",
|
|
1362
|
-
HttpFailure: "HTTP_FAILURE",
|
|
1363
|
-
Unknown: "UNKNOWN"
|
|
1364
|
-
};
|
|
1365
|
-
var AthenaErrorCategory = {
|
|
1366
|
-
Transport: "transport",
|
|
1367
|
-
Client: "client",
|
|
1368
|
-
Server: "server",
|
|
1369
|
-
Database: "database",
|
|
1370
|
-
Unknown: "unknown"
|
|
1371
|
-
};
|
|
1372
|
-
var AthenaError = class extends Error {
|
|
1373
|
-
code;
|
|
1374
|
-
kind;
|
|
1375
|
-
category;
|
|
1376
|
-
status;
|
|
1377
|
-
retryable;
|
|
1378
|
-
requestId;
|
|
1379
|
-
context;
|
|
1380
|
-
raw;
|
|
1381
|
-
constructor(input) {
|
|
1382
|
-
super(input.message);
|
|
1383
|
-
this.name = "AthenaError";
|
|
1384
|
-
this.code = input.code;
|
|
1385
|
-
this.kind = input.kind;
|
|
1386
|
-
this.category = input.category;
|
|
1387
|
-
this.status = input.status;
|
|
1388
|
-
this.retryable = input.retryable ?? false;
|
|
1389
|
-
this.requestId = input.requestId;
|
|
1390
|
-
this.context = input.context;
|
|
1391
|
-
this.raw = input.raw;
|
|
2136
|
+
function getResourceId(state) {
|
|
2137
|
+
const candidate = state.conditions.find(
|
|
2138
|
+
(condition) => condition.operator === "eq" && (condition.column === "resource_id" || condition.column === "id")
|
|
2139
|
+
);
|
|
2140
|
+
return candidate?.value?.toString();
|
|
2141
|
+
}
|
|
2142
|
+
function stringifyFilterValue(value) {
|
|
2143
|
+
if (Array.isArray(value)) {
|
|
2144
|
+
return value.join(",");
|
|
1392
2145
|
}
|
|
1393
|
-
|
|
1394
|
-
function isRecord2(value) {
|
|
1395
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2146
|
+
return String(value);
|
|
1396
2147
|
}
|
|
1397
|
-
function
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
2148
|
+
function isUuidString(value) {
|
|
2149
|
+
return UUID_PATTERN.test(value.trim());
|
|
2150
|
+
}
|
|
2151
|
+
function isUuidIdentifierColumn(column) {
|
|
2152
|
+
return column === "id" || /(?:^|_)uuid(?:_|$)/i.test(column) || /_id$/i.test(column);
|
|
2153
|
+
}
|
|
2154
|
+
function shouldUseUuidTextComparison(column, value) {
|
|
2155
|
+
return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
|
|
2156
|
+
}
|
|
2157
|
+
function normalizeCast(cast) {
|
|
2158
|
+
const normalized = cast.trim().toLowerCase();
|
|
2159
|
+
if (!SAFE_CAST_PATTERN.test(normalized)) {
|
|
2160
|
+
throw new Error(`Invalid cast type "${cast}"`);
|
|
1403
2161
|
}
|
|
2162
|
+
return normalized;
|
|
1404
2163
|
}
|
|
1405
|
-
function
|
|
1406
|
-
|
|
1407
|
-
const identity = typeof context.identity === "string" ? context.identity : safeStringify(context.identity);
|
|
1408
|
-
return `Identity: ${identity}`;
|
|
2164
|
+
function escapeSqlStringLiteral(value) {
|
|
2165
|
+
return value.replace(/'/g, "''");
|
|
1409
2166
|
}
|
|
1410
|
-
function
|
|
1411
|
-
|
|
2167
|
+
function toSqlLiteral(value) {
|
|
2168
|
+
if (value === null) return "NULL";
|
|
2169
|
+
if (typeof value === "number") return Number.isFinite(value) ? String(value) : "NULL";
|
|
2170
|
+
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
2171
|
+
return `'${escapeSqlStringLiteral(value)}'`;
|
|
1412
2172
|
}
|
|
1413
|
-
function
|
|
1414
|
-
if (!
|
|
1415
|
-
|
|
1416
|
-
if (details.endpoint === "/gateway/insert") return "insert";
|
|
1417
|
-
if (details.endpoint === "/gateway/update") return "update";
|
|
1418
|
-
if (details.endpoint === "/gateway/delete") return "delete";
|
|
1419
|
-
if (details.endpoint === "/gateway/rpc" || details.endpoint.startsWith("/rpc/")) return "rpc";
|
|
1420
|
-
return void 0;
|
|
2173
|
+
function withCast(expression, cast) {
|
|
2174
|
+
if (!cast) return expression;
|
|
2175
|
+
return `${expression}::${normalizeCast(cast)}`;
|
|
1421
2176
|
}
|
|
1422
|
-
function
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
if (match?.[1]) return match[1];
|
|
2177
|
+
function buildSelectColumnsClause(columns) {
|
|
2178
|
+
if (Array.isArray(columns)) {
|
|
2179
|
+
return columns.map((column) => quoteQualifiedIdentifier(column)).join(", ");
|
|
1426
2180
|
}
|
|
1427
|
-
return
|
|
1428
|
-
}
|
|
1429
|
-
function extractConstraint(message) {
|
|
1430
|
-
return matchRegex(message, [
|
|
1431
|
-
/unique constraint\s+["'`]([^"'`]+)["'`]/i,
|
|
1432
|
-
/constraint\s+["'`]([^"'`]+)["'`]/i
|
|
1433
|
-
]);
|
|
2181
|
+
return quoteSelectColumnsExpression(columns);
|
|
1434
2182
|
}
|
|
1435
|
-
function
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
2183
|
+
function resolveTableNameForCall(tableName, schema) {
|
|
2184
|
+
if (!schema) return tableName;
|
|
2185
|
+
const normalizedSchema = schema.trim();
|
|
2186
|
+
if (!normalizedSchema) {
|
|
2187
|
+
throw new Error("schema option must be a non-empty string");
|
|
2188
|
+
}
|
|
2189
|
+
if (tableName.includes(".")) {
|
|
2190
|
+
if (tableName.startsWith(`${normalizedSchema}.`)) {
|
|
2191
|
+
return tableName;
|
|
2192
|
+
}
|
|
2193
|
+
throw new Error(
|
|
2194
|
+
`schema option "${normalizedSchema}" conflicts with schema-qualified table "${tableName}"`
|
|
2195
|
+
);
|
|
2196
|
+
}
|
|
2197
|
+
return `${normalizedSchema}.${tableName}`;
|
|
1440
2198
|
}
|
|
1441
|
-
function
|
|
1442
|
-
|
|
1443
|
-
const
|
|
1444
|
-
const
|
|
1445
|
-
const
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
2199
|
+
function conditionToSqlClause(condition) {
|
|
2200
|
+
if (!condition.column) return null;
|
|
2201
|
+
const column = withCast(quoteQualifiedIdentifier(condition.column), condition.column_cast);
|
|
2202
|
+
const value = condition.value;
|
|
2203
|
+
const sqlOperator = {
|
|
2204
|
+
eq: "=",
|
|
2205
|
+
neq: "!=",
|
|
2206
|
+
gt: ">",
|
|
2207
|
+
gte: ">=",
|
|
2208
|
+
lt: "<",
|
|
2209
|
+
lte: "<=",
|
|
2210
|
+
like: "LIKE",
|
|
2211
|
+
ilike: "ILIKE"
|
|
2212
|
+
};
|
|
2213
|
+
switch (condition.operator) {
|
|
2214
|
+
case "eq":
|
|
2215
|
+
case "neq":
|
|
2216
|
+
case "gt":
|
|
2217
|
+
case "gte":
|
|
2218
|
+
case "lt":
|
|
2219
|
+
case "lte":
|
|
2220
|
+
case "like":
|
|
2221
|
+
case "ilike": {
|
|
2222
|
+
if (Array.isArray(value) || value === void 0) return null;
|
|
2223
|
+
const rhs = withCast(toSqlLiteral(value), condition.value_cast);
|
|
2224
|
+
return `${column} ${sqlOperator[condition.operator]} ${rhs}`;
|
|
2225
|
+
}
|
|
2226
|
+
case "is": {
|
|
2227
|
+
if (value === null) return `${column} IS NULL`;
|
|
2228
|
+
if (value === true) return `${column} IS TRUE`;
|
|
2229
|
+
if (value === false) return `${column} IS FALSE`;
|
|
2230
|
+
return null;
|
|
2231
|
+
}
|
|
2232
|
+
case "in": {
|
|
2233
|
+
if (!Array.isArray(value)) return null;
|
|
2234
|
+
if (value.length === 0) return "FALSE";
|
|
2235
|
+
const values = value.map((item) => withCast(toSqlLiteral(item), condition.value_cast));
|
|
2236
|
+
return `${column} IN (${values.join(", ")})`;
|
|
2237
|
+
}
|
|
2238
|
+
default:
|
|
2239
|
+
return null;
|
|
1456
2240
|
}
|
|
1457
|
-
return "unknown";
|
|
1458
2241
|
}
|
|
1459
|
-
function
|
|
1460
|
-
|
|
1461
|
-
|
|
2242
|
+
function buildTypedSelectQuery(input) {
|
|
2243
|
+
const whereClauses = [];
|
|
2244
|
+
for (const condition of input.conditions) {
|
|
2245
|
+
const clause = conditionToSqlClause(condition);
|
|
2246
|
+
if (!clause) return null;
|
|
2247
|
+
whereClauses.push(clause);
|
|
1462
2248
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
2249
|
+
let limit = input.limit;
|
|
2250
|
+
let offset = input.offset;
|
|
2251
|
+
if (limit === void 0 && input.pageSize !== void 0) {
|
|
2252
|
+
limit = input.pageSize;
|
|
2253
|
+
}
|
|
2254
|
+
if (offset === void 0 && input.pageSize !== void 0 && input.currentPage !== void 0 && input.currentPage > 0) {
|
|
2255
|
+
offset = (input.currentPage - 1) * input.pageSize;
|
|
2256
|
+
}
|
|
2257
|
+
const sqlParts = [
|
|
2258
|
+
`SELECT ${buildSelectColumnsClause(input.columns)} FROM ${quoteQualifiedIdentifier(input.tableName)}`
|
|
2259
|
+
];
|
|
2260
|
+
if (whereClauses.length > 0) {
|
|
2261
|
+
sqlParts.push(`WHERE ${whereClauses.join(" AND ")}`);
|
|
2262
|
+
}
|
|
2263
|
+
if (input.order?.field) {
|
|
2264
|
+
const direction = input.order.direction === "descending" ? "DESC" : "ASC";
|
|
2265
|
+
sqlParts.push(`ORDER BY ${quoteQualifiedIdentifier(input.order.field)} ${direction}`);
|
|
2266
|
+
}
|
|
2267
|
+
if (limit !== void 0) {
|
|
2268
|
+
sqlParts.push(`LIMIT ${Math.max(0, Math.trunc(limit))}`);
|
|
1482
2269
|
}
|
|
2270
|
+
if (offset !== void 0) {
|
|
2271
|
+
sqlParts.push(`OFFSET ${Math.max(0, Math.trunc(offset))}`);
|
|
2272
|
+
}
|
|
2273
|
+
return `${sqlParts.join(" ")};`;
|
|
2274
|
+
}
|
|
2275
|
+
function createFilterMethods(state, addCondition, self) {
|
|
2276
|
+
return {
|
|
2277
|
+
eq(column, value) {
|
|
2278
|
+
const columnName = String(column);
|
|
2279
|
+
if (shouldUseUuidTextComparison(columnName, value)) {
|
|
2280
|
+
addCondition("eq", columnName, value, { columnCast: "text" });
|
|
2281
|
+
} else {
|
|
2282
|
+
addCondition("eq", columnName, value);
|
|
2283
|
+
}
|
|
2284
|
+
return self;
|
|
2285
|
+
},
|
|
2286
|
+
eqCast(column, value, cast) {
|
|
2287
|
+
addCondition("eq", String(column), value, { valueCast: cast });
|
|
2288
|
+
return self;
|
|
2289
|
+
},
|
|
2290
|
+
eqUuid(column, value) {
|
|
2291
|
+
addCondition("eq", String(column), value, { valueCast: "uuid" });
|
|
2292
|
+
return self;
|
|
2293
|
+
},
|
|
2294
|
+
match(filters) {
|
|
2295
|
+
Object.entries(filters).forEach(([column, value]) => {
|
|
2296
|
+
if (value === void 0) {
|
|
2297
|
+
return;
|
|
2298
|
+
}
|
|
2299
|
+
if (shouldUseUuidTextComparison(column, value)) {
|
|
2300
|
+
addCondition("eq", column, value, { columnCast: "text" });
|
|
2301
|
+
} else {
|
|
2302
|
+
addCondition("eq", column, value);
|
|
2303
|
+
}
|
|
2304
|
+
});
|
|
2305
|
+
return self;
|
|
2306
|
+
},
|
|
2307
|
+
range(from, to) {
|
|
2308
|
+
state.offset = from;
|
|
2309
|
+
state.limit = to - from + 1;
|
|
2310
|
+
return self;
|
|
2311
|
+
},
|
|
2312
|
+
limit(count) {
|
|
2313
|
+
state.limit = count;
|
|
2314
|
+
return self;
|
|
2315
|
+
},
|
|
2316
|
+
offset(count) {
|
|
2317
|
+
state.offset = count;
|
|
2318
|
+
return self;
|
|
2319
|
+
},
|
|
2320
|
+
currentPage(value) {
|
|
2321
|
+
state.currentPage = value;
|
|
2322
|
+
return self;
|
|
2323
|
+
},
|
|
2324
|
+
pageSize(value) {
|
|
2325
|
+
state.pageSize = value;
|
|
2326
|
+
return self;
|
|
2327
|
+
},
|
|
2328
|
+
totalPages(value) {
|
|
2329
|
+
state.totalPages = value;
|
|
2330
|
+
return self;
|
|
2331
|
+
},
|
|
2332
|
+
order(column, options) {
|
|
2333
|
+
state.order = {
|
|
2334
|
+
field: String(column),
|
|
2335
|
+
direction: options?.ascending === false ? "descending" : "ascending"
|
|
2336
|
+
};
|
|
2337
|
+
return self;
|
|
2338
|
+
},
|
|
2339
|
+
gt(column, value) {
|
|
2340
|
+
addCondition("gt", String(column), value);
|
|
2341
|
+
return self;
|
|
2342
|
+
},
|
|
2343
|
+
gte(column, value) {
|
|
2344
|
+
addCondition("gte", String(column), value);
|
|
2345
|
+
return self;
|
|
2346
|
+
},
|
|
2347
|
+
lt(column, value) {
|
|
2348
|
+
addCondition("lt", String(column), value);
|
|
2349
|
+
return self;
|
|
2350
|
+
},
|
|
2351
|
+
lte(column, value) {
|
|
2352
|
+
addCondition("lte", String(column), value);
|
|
2353
|
+
return self;
|
|
2354
|
+
},
|
|
2355
|
+
neq(column, value) {
|
|
2356
|
+
addCondition("neq", String(column), value);
|
|
2357
|
+
return self;
|
|
2358
|
+
},
|
|
2359
|
+
like(column, value) {
|
|
2360
|
+
addCondition("like", String(column), value);
|
|
2361
|
+
return self;
|
|
2362
|
+
},
|
|
2363
|
+
ilike(column, value) {
|
|
2364
|
+
addCondition("ilike", String(column), value);
|
|
2365
|
+
return self;
|
|
2366
|
+
},
|
|
2367
|
+
is(column, value) {
|
|
2368
|
+
addCondition("is", String(column), value);
|
|
2369
|
+
return self;
|
|
2370
|
+
},
|
|
2371
|
+
in(column, values) {
|
|
2372
|
+
addCondition("in", String(column), values);
|
|
2373
|
+
return self;
|
|
2374
|
+
},
|
|
2375
|
+
contains(column, values) {
|
|
2376
|
+
addCondition("contains", String(column), values);
|
|
2377
|
+
return self;
|
|
2378
|
+
},
|
|
2379
|
+
containedBy(column, values) {
|
|
2380
|
+
addCondition("containedBy", String(column), values);
|
|
2381
|
+
return self;
|
|
2382
|
+
},
|
|
2383
|
+
not(columnOrExpression, operator, value) {
|
|
2384
|
+
const expression = String(columnOrExpression);
|
|
2385
|
+
if (operator != null && value !== void 0) {
|
|
2386
|
+
addCondition("not", void 0, `${expression}.${operator}.${stringifyFilterValue(value)}`);
|
|
2387
|
+
} else {
|
|
2388
|
+
addCondition("not", void 0, expression);
|
|
2389
|
+
}
|
|
2390
|
+
return self;
|
|
2391
|
+
},
|
|
2392
|
+
or(expression) {
|
|
2393
|
+
addCondition("or", void 0, expression);
|
|
2394
|
+
return self;
|
|
2395
|
+
}
|
|
2396
|
+
};
|
|
1483
2397
|
}
|
|
1484
|
-
function
|
|
1485
|
-
if (
|
|
1486
|
-
|
|
1487
|
-
}
|
|
1488
|
-
if (kind === "unique_violation") return AthenaErrorCategory.Database;
|
|
1489
|
-
if (kind === "validation" || kind === "auth" || kind === "not_found") return AthenaErrorCategory.Client;
|
|
1490
|
-
if (kind === "rate_limit" || kind === "transient") return AthenaErrorCategory.Server;
|
|
1491
|
-
return AthenaErrorCategory.Unknown;
|
|
2398
|
+
function toRpcSelect(columns) {
|
|
2399
|
+
if (!columns) return void 0;
|
|
2400
|
+
return Array.isArray(columns) ? columns.join(",") : columns;
|
|
1492
2401
|
}
|
|
1493
|
-
function
|
|
1494
|
-
|
|
1495
|
-
|
|
2402
|
+
function createRpcFilterMethods(filters, self) {
|
|
2403
|
+
const addFilter = (operator, column, value) => {
|
|
2404
|
+
filters.push({ column, operator, value });
|
|
2405
|
+
};
|
|
2406
|
+
return {
|
|
2407
|
+
eq(column, value) {
|
|
2408
|
+
addFilter("eq", column, value);
|
|
2409
|
+
return self;
|
|
2410
|
+
},
|
|
2411
|
+
neq(column, value) {
|
|
2412
|
+
addFilter("neq", column, value);
|
|
2413
|
+
return self;
|
|
2414
|
+
},
|
|
2415
|
+
gt(column, value) {
|
|
2416
|
+
addFilter("gt", column, value);
|
|
2417
|
+
return self;
|
|
2418
|
+
},
|
|
2419
|
+
gte(column, value) {
|
|
2420
|
+
addFilter("gte", column, value);
|
|
2421
|
+
return self;
|
|
2422
|
+
},
|
|
2423
|
+
lt(column, value) {
|
|
2424
|
+
addFilter("lt", column, value);
|
|
2425
|
+
return self;
|
|
2426
|
+
},
|
|
2427
|
+
lte(column, value) {
|
|
2428
|
+
addFilter("lte", column, value);
|
|
2429
|
+
return self;
|
|
2430
|
+
},
|
|
2431
|
+
like(column, value) {
|
|
2432
|
+
addFilter("like", column, value);
|
|
2433
|
+
return self;
|
|
2434
|
+
},
|
|
2435
|
+
ilike(column, value) {
|
|
2436
|
+
addFilter("ilike", column, value);
|
|
2437
|
+
return self;
|
|
2438
|
+
},
|
|
2439
|
+
is(column, value) {
|
|
2440
|
+
addFilter("is", column, value);
|
|
2441
|
+
return self;
|
|
2442
|
+
},
|
|
2443
|
+
in(column, values) {
|
|
2444
|
+
addFilter("in", column, values);
|
|
2445
|
+
return self;
|
|
2446
|
+
}
|
|
2447
|
+
};
|
|
1496
2448
|
}
|
|
1497
|
-
function
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
2449
|
+
function createRpcBuilder(functionName, args, baseOptions, client, formatGatewayResult) {
|
|
2450
|
+
const state = {
|
|
2451
|
+
filters: []
|
|
2452
|
+
};
|
|
2453
|
+
let selectedColumns;
|
|
2454
|
+
let selectedOptions;
|
|
2455
|
+
let promise = null;
|
|
2456
|
+
const executeRpc = async (columns, options) => {
|
|
2457
|
+
const mergedOptions = mergeOptions(baseOptions, options);
|
|
2458
|
+
const payload = {
|
|
2459
|
+
function: functionName,
|
|
2460
|
+
args,
|
|
2461
|
+
schema: mergedOptions?.schema,
|
|
2462
|
+
select: toRpcSelect(columns),
|
|
2463
|
+
filters: state.filters.length ? [...state.filters] : void 0,
|
|
2464
|
+
count: mergedOptions?.count,
|
|
2465
|
+
head: mergedOptions?.head,
|
|
2466
|
+
limit: state.limit,
|
|
2467
|
+
offset: state.offset,
|
|
2468
|
+
order: state.order
|
|
2469
|
+
};
|
|
2470
|
+
const response = await client.rpcGateway(payload, mergedOptions);
|
|
2471
|
+
return formatGatewayResult(response, { operation: "rpc" });
|
|
2472
|
+
};
|
|
2473
|
+
const run = (columns, options) => {
|
|
2474
|
+
const payloadColumns = columns ?? selectedColumns;
|
|
2475
|
+
const payloadOptions = options ?? selectedOptions;
|
|
2476
|
+
if (!promise) {
|
|
2477
|
+
promise = executeRpc(payloadColumns, payloadOptions);
|
|
2478
|
+
}
|
|
2479
|
+
return promise;
|
|
2480
|
+
};
|
|
2481
|
+
const builder = {};
|
|
2482
|
+
const filterMethods = createRpcFilterMethods(state.filters, builder);
|
|
2483
|
+
Object.assign(builder, filterMethods, {
|
|
2484
|
+
select(columns = selectedColumns, options) {
|
|
2485
|
+
selectedColumns = columns;
|
|
2486
|
+
selectedOptions = options ?? selectedOptions;
|
|
2487
|
+
return run(columns, options);
|
|
2488
|
+
},
|
|
2489
|
+
async single(columns, options) {
|
|
2490
|
+
const result = await run(columns, options);
|
|
2491
|
+
return toSingleResult(result);
|
|
2492
|
+
},
|
|
2493
|
+
maybeSingle(columns, options) {
|
|
2494
|
+
return builder.single(columns, options);
|
|
2495
|
+
},
|
|
2496
|
+
order(column, options) {
|
|
2497
|
+
state.order = { column, ascending: options?.ascending ?? true };
|
|
2498
|
+
return builder;
|
|
2499
|
+
},
|
|
2500
|
+
limit(count) {
|
|
2501
|
+
state.limit = count;
|
|
2502
|
+
return builder;
|
|
2503
|
+
},
|
|
2504
|
+
offset(count) {
|
|
2505
|
+
state.offset = count;
|
|
2506
|
+
return builder;
|
|
2507
|
+
},
|
|
2508
|
+
range(from, to) {
|
|
2509
|
+
state.offset = from;
|
|
2510
|
+
state.limit = to - from + 1;
|
|
2511
|
+
return builder;
|
|
2512
|
+
},
|
|
2513
|
+
then(onfulfilled, onrejected) {
|
|
2514
|
+
return run(selectedColumns, selectedOptions).then(onfulfilled, onrejected);
|
|
2515
|
+
},
|
|
2516
|
+
catch(onrejected) {
|
|
2517
|
+
return run(selectedColumns, selectedOptions).catch(onrejected);
|
|
2518
|
+
},
|
|
2519
|
+
finally(onfinally) {
|
|
2520
|
+
return run(selectedColumns, selectedOptions).finally(onfinally);
|
|
2521
|
+
}
|
|
2522
|
+
});
|
|
2523
|
+
return builder;
|
|
1502
2524
|
}
|
|
1503
|
-
function
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
2525
|
+
function createTableBuilder(tableName, client, formatGatewayResult) {
|
|
2526
|
+
const state = {
|
|
2527
|
+
conditions: []
|
|
2528
|
+
};
|
|
2529
|
+
const addCondition = (operator, column, value, hints) => {
|
|
2530
|
+
const condition = { operator };
|
|
2531
|
+
if (column) {
|
|
2532
|
+
condition.column = column;
|
|
2533
|
+
if (operator === "eq") {
|
|
2534
|
+
condition.eq_column = column;
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
if (value !== void 0) {
|
|
2538
|
+
condition.value = value;
|
|
2539
|
+
if (operator === "eq") {
|
|
2540
|
+
condition.eq_value = value;
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
if (hints?.valueCast) {
|
|
2544
|
+
condition.value_cast = hints.valueCast;
|
|
2545
|
+
if (operator === "eq") {
|
|
2546
|
+
condition.eq_value_cast = hints.valueCast;
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
if (hints?.columnCast) {
|
|
2550
|
+
condition.column_cast = hints.columnCast;
|
|
2551
|
+
if (operator === "eq") {
|
|
2552
|
+
condition.eq_column_cast = hints.columnCast;
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
state.conditions.push(condition);
|
|
2556
|
+
};
|
|
2557
|
+
const builder = {};
|
|
2558
|
+
const filterMethods = createFilterMethods(
|
|
2559
|
+
state,
|
|
2560
|
+
addCondition,
|
|
2561
|
+
builder
|
|
2562
|
+
);
|
|
2563
|
+
const runSelect = async (columns = DEFAULT_COLUMNS, options) => {
|
|
2564
|
+
const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
|
|
2565
|
+
const conditions = state.conditions.length ? state.conditions.map((condition) => ({ ...condition })) : void 0;
|
|
2566
|
+
const hasTypedEqualityComparison = conditions?.some(
|
|
2567
|
+
(condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
|
|
2568
|
+
) ?? false;
|
|
2569
|
+
if (hasTypedEqualityComparison && !options?.head && !options?.count && conditions) {
|
|
2570
|
+
const query = buildTypedSelectQuery({
|
|
2571
|
+
tableName: resolvedTableName,
|
|
2572
|
+
columns,
|
|
2573
|
+
conditions,
|
|
2574
|
+
limit: state.limit,
|
|
2575
|
+
offset: state.offset,
|
|
2576
|
+
currentPage: state.currentPage,
|
|
2577
|
+
pageSize: state.pageSize,
|
|
2578
|
+
order: state.order
|
|
2579
|
+
});
|
|
2580
|
+
if (query) {
|
|
2581
|
+
const queryResponse = await client.queryGateway({ query }, options);
|
|
2582
|
+
return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
const payload = {
|
|
2586
|
+
table_name: resolvedTableName,
|
|
2587
|
+
columns,
|
|
2588
|
+
conditions,
|
|
2589
|
+
limit: state.limit,
|
|
2590
|
+
offset: state.offset,
|
|
2591
|
+
current_page: state.currentPage,
|
|
2592
|
+
page_size: state.pageSize,
|
|
2593
|
+
total_pages: state.totalPages,
|
|
2594
|
+
sort_by: state.order,
|
|
2595
|
+
strip_nulls: options?.stripNulls ?? true,
|
|
2596
|
+
count: options?.count,
|
|
2597
|
+
head: options?.head
|
|
2598
|
+
};
|
|
2599
|
+
const response = await client.fetchGateway(payload, options);
|
|
2600
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
|
|
2601
|
+
};
|
|
2602
|
+
const createSelectChain = (columns, options) => {
|
|
2603
|
+
const chain = {};
|
|
2604
|
+
const filterMethods2 = createFilterMethods(state, addCondition, chain);
|
|
2605
|
+
Object.assign(chain, filterMethods2, {
|
|
2606
|
+
async single(cols, opts) {
|
|
2607
|
+
const r = await runSelect(cols ?? columns, opts ?? options);
|
|
2608
|
+
return toSingleResult(r);
|
|
2609
|
+
},
|
|
2610
|
+
maybeSingle(cols, opts) {
|
|
2611
|
+
return chain.single(cols, opts);
|
|
2612
|
+
},
|
|
2613
|
+
then(onfulfilled, onrejected) {
|
|
2614
|
+
return runSelect(columns, options).then(onfulfilled, onrejected);
|
|
2615
|
+
},
|
|
2616
|
+
catch(onrejected) {
|
|
2617
|
+
return runSelect(columns, options).catch(onrejected);
|
|
2618
|
+
},
|
|
2619
|
+
finally(onfinally) {
|
|
2620
|
+
return runSelect(columns, options).finally(onfinally);
|
|
2621
|
+
}
|
|
1517
2622
|
});
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
2623
|
+
return chain;
|
|
2624
|
+
};
|
|
2625
|
+
Object.assign(builder, filterMethods, {
|
|
2626
|
+
reset() {
|
|
2627
|
+
state.conditions = [];
|
|
2628
|
+
state.limit = void 0;
|
|
2629
|
+
state.offset = void 0;
|
|
2630
|
+
state.order = void 0;
|
|
2631
|
+
state.currentPage = void 0;
|
|
2632
|
+
state.pageSize = void 0;
|
|
2633
|
+
state.totalPages = void 0;
|
|
2634
|
+
return builder;
|
|
2635
|
+
},
|
|
2636
|
+
select(columns = DEFAULT_COLUMNS, options) {
|
|
2637
|
+
return createSelectChain(columns, options);
|
|
2638
|
+
},
|
|
2639
|
+
insert(values, options) {
|
|
2640
|
+
if (Array.isArray(values)) {
|
|
2641
|
+
const executeInsertMany = async (columns, selectOptions) => {
|
|
2642
|
+
const mergedOptions = mergeOptions(options, selectOptions);
|
|
2643
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
2644
|
+
const payload = {
|
|
2645
|
+
table_name: resolvedTableName,
|
|
2646
|
+
insert_body: asAthenaJsonObjectArray(values)
|
|
2647
|
+
};
|
|
2648
|
+
if (columns) payload.columns = columns;
|
|
2649
|
+
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
2650
|
+
if (mergedOptions?.head) payload.head = mergedOptions.head;
|
|
2651
|
+
if (mergedOptions?.defaultToNull !== void 0) {
|
|
2652
|
+
payload.default_to_null = mergedOptions.defaultToNull;
|
|
2653
|
+
}
|
|
2654
|
+
const response = await client.insertGateway(payload, mergedOptions);
|
|
2655
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "insert" });
|
|
2656
|
+
};
|
|
2657
|
+
return createMutationQuery(executeInsertMany);
|
|
2658
|
+
}
|
|
2659
|
+
const executeInsertOne = async (columns, selectOptions) => {
|
|
2660
|
+
const mergedOptions = mergeOptions(options, selectOptions);
|
|
2661
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
2662
|
+
const payload = {
|
|
2663
|
+
table_name: resolvedTableName,
|
|
2664
|
+
insert_body: asAthenaJsonObject(values)
|
|
2665
|
+
};
|
|
2666
|
+
if (columns) payload.columns = columns;
|
|
2667
|
+
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
2668
|
+
if (mergedOptions?.head) payload.head = mergedOptions.head;
|
|
2669
|
+
if (mergedOptions?.defaultToNull !== void 0) {
|
|
2670
|
+
payload.default_to_null = mergedOptions.defaultToNull;
|
|
2671
|
+
}
|
|
2672
|
+
const response = await client.insertGateway(payload, mergedOptions);
|
|
2673
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "insert" });
|
|
2674
|
+
};
|
|
2675
|
+
return createMutationQuery(executeInsertOne);
|
|
2676
|
+
},
|
|
2677
|
+
upsert(values, options) {
|
|
2678
|
+
if (Array.isArray(values)) {
|
|
2679
|
+
const executeUpsertMany = async (columns, selectOptions) => {
|
|
2680
|
+
const mergedOptions = mergeOptions(options, selectOptions);
|
|
2681
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
2682
|
+
const payload = {
|
|
2683
|
+
table_name: resolvedTableName,
|
|
2684
|
+
insert_body: asAthenaJsonObjectArray(values),
|
|
2685
|
+
update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
|
|
2686
|
+
};
|
|
2687
|
+
if (columns) payload.columns = columns;
|
|
2688
|
+
if (options?.onConflict) payload.on_conflict = options.onConflict;
|
|
2689
|
+
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
2690
|
+
if (mergedOptions?.head) payload.head = mergedOptions.head;
|
|
2691
|
+
if (mergedOptions?.defaultToNull !== void 0) {
|
|
2692
|
+
payload.default_to_null = mergedOptions.defaultToNull;
|
|
2693
|
+
}
|
|
2694
|
+
const response = await client.insertGateway(payload, mergedOptions);
|
|
2695
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "insert" });
|
|
2696
|
+
};
|
|
2697
|
+
return createMutationQuery(executeUpsertMany);
|
|
2698
|
+
}
|
|
2699
|
+
const executeUpsertOne = async (columns, selectOptions) => {
|
|
2700
|
+
const mergedOptions = mergeOptions(options, selectOptions);
|
|
2701
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
2702
|
+
const payload = {
|
|
2703
|
+
table_name: resolvedTableName,
|
|
2704
|
+
insert_body: asAthenaJsonObject(values),
|
|
2705
|
+
update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
|
|
2706
|
+
};
|
|
2707
|
+
if (columns) payload.columns = columns;
|
|
2708
|
+
if (options?.onConflict) payload.on_conflict = options.onConflict;
|
|
2709
|
+
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
2710
|
+
if (mergedOptions?.head) payload.head = mergedOptions.head;
|
|
2711
|
+
if (mergedOptions?.defaultToNull !== void 0) {
|
|
2712
|
+
payload.default_to_null = mergedOptions.defaultToNull;
|
|
2713
|
+
}
|
|
2714
|
+
const response = await client.insertGateway(payload, mergedOptions);
|
|
2715
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "insert" });
|
|
2716
|
+
};
|
|
2717
|
+
return createMutationQuery(executeUpsertOne);
|
|
2718
|
+
},
|
|
2719
|
+
update(values, options) {
|
|
2720
|
+
const executeUpdate = async (columns, selectOptions) => {
|
|
2721
|
+
const filters = state.conditions.length ? [...state.conditions] : void 0;
|
|
2722
|
+
const mergedOptions = mergeOptions(options, selectOptions);
|
|
2723
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
2724
|
+
const payload = {
|
|
2725
|
+
table_name: resolvedTableName,
|
|
2726
|
+
set: asAthenaJsonObject(values),
|
|
2727
|
+
conditions: filters,
|
|
2728
|
+
strip_nulls: mergedOptions?.stripNulls ?? true
|
|
2729
|
+
};
|
|
2730
|
+
if (state.order) payload.sort_by = state.order;
|
|
2731
|
+
if (state.currentPage !== void 0) payload.current_page = state.currentPage;
|
|
2732
|
+
if (state.pageSize !== void 0) payload.page_size = state.pageSize;
|
|
2733
|
+
if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
|
|
2734
|
+
if (columns) payload.columns = columns;
|
|
2735
|
+
const response = await client.updateGateway(payload, mergedOptions);
|
|
2736
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "update" });
|
|
2737
|
+
};
|
|
2738
|
+
const mutation = createMutationQuery(executeUpdate, null);
|
|
2739
|
+
const updateChain = {};
|
|
2740
|
+
const filterMethods2 = createFilterMethods(state, addCondition, updateChain);
|
|
2741
|
+
Object.assign(updateChain, filterMethods2, mutation);
|
|
2742
|
+
return updateChain;
|
|
2743
|
+
},
|
|
2744
|
+
delete(options) {
|
|
2745
|
+
const filters = state.conditions.length ? [...state.conditions] : void 0;
|
|
2746
|
+
const resourceId = options?.resourceId ?? getResourceId(state);
|
|
2747
|
+
if (!resourceId && !filters?.length) {
|
|
2748
|
+
throw new Error('delete requires a resource_id either via eq("resource_id", ...) or options.resourceId');
|
|
2749
|
+
}
|
|
2750
|
+
const executeDelete = async (columns, selectOptions) => {
|
|
2751
|
+
const mergedOptions = mergeOptions(options, selectOptions);
|
|
2752
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
2753
|
+
const payload = {
|
|
2754
|
+
table_name: resolvedTableName,
|
|
2755
|
+
resource_id: resourceId,
|
|
2756
|
+
conditions: filters
|
|
2757
|
+
};
|
|
2758
|
+
if (state.order) payload.sort_by = state.order;
|
|
2759
|
+
if (state.currentPage !== void 0) payload.current_page = state.currentPage;
|
|
2760
|
+
if (state.pageSize !== void 0) payload.page_size = state.pageSize;
|
|
2761
|
+
if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
|
|
2762
|
+
if (columns) payload.columns = columns;
|
|
2763
|
+
const response = await client.deleteGateway(payload, mergedOptions);
|
|
2764
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "delete" });
|
|
2765
|
+
};
|
|
2766
|
+
return createMutationQuery(executeDelete, null);
|
|
2767
|
+
},
|
|
2768
|
+
async single(columns, options) {
|
|
2769
|
+
const response = await builder.select(columns, options);
|
|
2770
|
+
return toSingleResult(response);
|
|
2771
|
+
},
|
|
2772
|
+
async maybeSingle(columns, options) {
|
|
2773
|
+
return builder.single(columns, options);
|
|
2774
|
+
}
|
|
1527
2775
|
});
|
|
2776
|
+
return builder;
|
|
1528
2777
|
}
|
|
1529
|
-
function
|
|
1530
|
-
return
|
|
2778
|
+
function createQueryBuilder(client, formatGatewayResult) {
|
|
2779
|
+
return async function query(query, options) {
|
|
2780
|
+
const normalizedQuery = query.trim();
|
|
2781
|
+
if (!normalizedQuery) {
|
|
2782
|
+
throw new Error("query requires a non-empty string");
|
|
2783
|
+
}
|
|
2784
|
+
const response = await client.queryGateway({ query: normalizedQuery }, options);
|
|
2785
|
+
return formatGatewayResult(response, { operation: "query" });
|
|
2786
|
+
};
|
|
1531
2787
|
}
|
|
1532
|
-
function
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
const table = context?.table ?? extractTable(resultOrError.message);
|
|
1559
|
-
const constraint = extractConstraint(resultOrError.message);
|
|
1560
|
-
const kind2 = classifyKind(resultOrError.status, resultOrError.code, resultOrError.message);
|
|
1561
|
-
const code = toAthenaErrorCode(kind2, resultOrError.status, resultOrError.code);
|
|
1562
|
-
const category = toAthenaErrorCategory(kind2, resultOrError.status);
|
|
1563
|
-
return {
|
|
1564
|
-
kind: kind2,
|
|
1565
|
-
code,
|
|
1566
|
-
category,
|
|
1567
|
-
retryable: isRetryable(kind2, resultOrError.status),
|
|
1568
|
-
status: resultOrError.status,
|
|
1569
|
-
constraint,
|
|
1570
|
-
table,
|
|
1571
|
-
operation,
|
|
1572
|
-
message: resultOrError.message,
|
|
1573
|
-
raw: resultOrError
|
|
1574
|
-
};
|
|
1575
|
-
}
|
|
1576
|
-
if (resultOrError instanceof Error) {
|
|
1577
|
-
const maybeStatus = isRecord2(resultOrError) && typeof resultOrError.status === "number" ? resultOrError.status : void 0;
|
|
1578
|
-
const kind2 = classifyKind(maybeStatus, void 0, resultOrError.message);
|
|
1579
|
-
return {
|
|
1580
|
-
kind: kind2,
|
|
1581
|
-
code: toAthenaErrorCode(kind2, maybeStatus),
|
|
1582
|
-
category: toAthenaErrorCategory(kind2, maybeStatus),
|
|
1583
|
-
retryable: isRetryable(kind2, maybeStatus),
|
|
1584
|
-
status: maybeStatus,
|
|
1585
|
-
constraint: extractConstraint(resultOrError.message),
|
|
1586
|
-
table: context?.table ?? extractTable(resultOrError.message),
|
|
1587
|
-
operation: context?.operation,
|
|
1588
|
-
message: resultOrError.message,
|
|
1589
|
-
raw: resultOrError
|
|
1590
|
-
};
|
|
1591
|
-
}
|
|
1592
|
-
const message = typeof resultOrError === "string" ? resultOrError : "Unknown Athena error";
|
|
1593
|
-
const kind = classifyKind(void 0, void 0, message);
|
|
2788
|
+
function createClientFromConfig(config) {
|
|
2789
|
+
const gateway = createAthenaGatewayClient({
|
|
2790
|
+
baseUrl: config.baseUrl,
|
|
2791
|
+
apiKey: config.apiKey,
|
|
2792
|
+
client: config.client,
|
|
2793
|
+
backend: config.backend,
|
|
2794
|
+
headers: config.headers
|
|
2795
|
+
});
|
|
2796
|
+
const formatGatewayResult = createResultFormatter(config.experimental);
|
|
2797
|
+
const auth = createAuthClient(config.auth);
|
|
2798
|
+
const from = (table) => createTableBuilder(table, gateway, formatGatewayResult);
|
|
2799
|
+
const rpc = (fn, args, options) => {
|
|
2800
|
+
const normalizedFn = fn.trim();
|
|
2801
|
+
if (!normalizedFn) {
|
|
2802
|
+
throw new Error("rpc requires a function name");
|
|
2803
|
+
}
|
|
2804
|
+
return createRpcBuilder(
|
|
2805
|
+
normalizedFn,
|
|
2806
|
+
args,
|
|
2807
|
+
options,
|
|
2808
|
+
gateway,
|
|
2809
|
+
formatGatewayResult
|
|
2810
|
+
);
|
|
2811
|
+
};
|
|
2812
|
+
const query = createQueryBuilder(gateway, formatGatewayResult);
|
|
2813
|
+
const db = createDbModule({ from, rpc, query });
|
|
1594
2814
|
return {
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
constraint: extractConstraint(message),
|
|
1601
|
-
table: context?.table ?? extractTable(message),
|
|
1602
|
-
operation: context?.operation,
|
|
1603
|
-
message,
|
|
1604
|
-
raw: resultOrError
|
|
2815
|
+
from,
|
|
2816
|
+
db,
|
|
2817
|
+
rpc,
|
|
2818
|
+
query,
|
|
2819
|
+
auth: auth.auth
|
|
1605
2820
|
};
|
|
1606
2821
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
}
|
|
1611
|
-
if (result.data == null) return [];
|
|
1612
|
-
return Array.isArray(result.data) ? result.data : [result.data];
|
|
2822
|
+
var DEFAULT_BACKEND = { type: "athena" };
|
|
2823
|
+
function toBackendConfig(b) {
|
|
2824
|
+
if (!b) return DEFAULT_BACKEND;
|
|
2825
|
+
return typeof b === "string" ? { type: b } : b;
|
|
1613
2826
|
}
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
2827
|
+
var AthenaClientBuilderImpl = class {
|
|
2828
|
+
baseUrl;
|
|
2829
|
+
apiKey;
|
|
2830
|
+
backendConfig = DEFAULT_BACKEND;
|
|
2831
|
+
clientName;
|
|
2832
|
+
defaultHeaders;
|
|
2833
|
+
isHealthTrackingEnabled = false;
|
|
2834
|
+
url(url) {
|
|
2835
|
+
this.baseUrl = url;
|
|
2836
|
+
return this;
|
|
1617
2837
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
2838
|
+
key(apiKey) {
|
|
2839
|
+
this.apiKey = apiKey;
|
|
2840
|
+
return this;
|
|
1620
2841
|
}
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
const rows = unwrapRows(result, options);
|
|
1625
|
-
if (!rows.length) {
|
|
1626
|
-
if (options?.allowNull) return null;
|
|
1627
|
-
throw toAthenaGatewayError(result, "Expected one row but received none", options?.context);
|
|
2842
|
+
backend(backend) {
|
|
2843
|
+
this.backendConfig = toBackendConfig(backend);
|
|
2844
|
+
return this;
|
|
1628
2845
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
`Expected exactly one row but received ${rows.length}`,
|
|
1633
|
-
options.context
|
|
1634
|
-
);
|
|
2846
|
+
client(clientName) {
|
|
2847
|
+
this.clientName = clientName;
|
|
2848
|
+
return this;
|
|
1635
2849
|
}
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
if (!isOk(result)) {
|
|
1640
|
-
throw toAthenaGatewayError(
|
|
1641
|
-
result,
|
|
1642
|
-
`Athena ${context?.operation ?? "request"} failed`,
|
|
1643
|
-
context
|
|
1644
|
-
);
|
|
2850
|
+
headers(headers) {
|
|
2851
|
+
this.defaultHeaders = headers;
|
|
2852
|
+
return this;
|
|
1645
2853
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
requireSuccess(result, context);
|
|
1650
|
-
const minimum = options?.min ?? 1;
|
|
1651
|
-
const count = result.count;
|
|
1652
|
-
if (count == null) {
|
|
1653
|
-
throw new AthenaGatewayError({
|
|
1654
|
-
code: "UNKNOWN_ERROR",
|
|
1655
|
-
status: result.status,
|
|
1656
|
-
message: "Expected affected row count but response.count is missing",
|
|
1657
|
-
hint: 'Set call option { count: "exact" } for mutation postcondition checks.',
|
|
1658
|
-
cause: safeStringify(result.raw)
|
|
1659
|
-
});
|
|
2854
|
+
healthTracking(enabled) {
|
|
2855
|
+
this.isHealthTrackingEnabled = enabled;
|
|
2856
|
+
return this;
|
|
1660
2857
|
}
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
2858
|
+
build() {
|
|
2859
|
+
if (!this.baseUrl || !this.apiKey) {
|
|
2860
|
+
throw new Error("AthenaClient requires url and key; call .url() and .key() before .build()");
|
|
2861
|
+
}
|
|
2862
|
+
return createClientFromConfig({
|
|
2863
|
+
baseUrl: this.baseUrl,
|
|
2864
|
+
apiKey: this.apiKey,
|
|
2865
|
+
client: this.clientName,
|
|
2866
|
+
backend: this.backendConfig,
|
|
2867
|
+
headers: this.defaultHeaders,
|
|
2868
|
+
healthTracking: this.isHealthTrackingEnabled
|
|
1668
2869
|
});
|
|
1669
2870
|
}
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
return value;
|
|
1676
|
-
}
|
|
1677
|
-
function parseIntegerString(value) {
|
|
1678
|
-
const normalized = value.trim();
|
|
1679
|
-
if (!/^[-+]?\d+$/.test(normalized)) return null;
|
|
1680
|
-
const parsed = Number(normalized);
|
|
1681
|
-
if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) return null;
|
|
1682
|
-
return parsed;
|
|
1683
|
-
}
|
|
1684
|
-
function coerceInt(value, options) {
|
|
1685
|
-
if (value == null) return null;
|
|
1686
|
-
if (typeof value === "number") {
|
|
1687
|
-
if (!Number.isFinite(value) || !Number.isInteger(value)) return null;
|
|
1688
|
-
return applyBounds(value, options);
|
|
1689
|
-
}
|
|
1690
|
-
if (typeof value === "string") {
|
|
1691
|
-
const parsed = parseIntegerString(value);
|
|
1692
|
-
if (parsed == null) return null;
|
|
1693
|
-
return applyBounds(parsed, options);
|
|
2871
|
+
};
|
|
2872
|
+
var AthenaClient = class _AthenaClient {
|
|
2873
|
+
/** Create a fluent builder for a strongly-typed Athena SDK client. */
|
|
2874
|
+
static builder() {
|
|
2875
|
+
return new AthenaClientBuilderImpl();
|
|
1694
2876
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
2877
|
+
/** Build a client from process environment variables. */
|
|
2878
|
+
static fromEnvironment() {
|
|
2879
|
+
const url = process.env.ATHENA_URL ?? process.env.ATHENA_GATEWAY_URL;
|
|
2880
|
+
const key = process.env.ATHENA_API_KEY ?? process.env.ATHENA_GATEWAY_API_KEY;
|
|
2881
|
+
if (!url || !key) {
|
|
2882
|
+
throw new Error(
|
|
2883
|
+
"ATHENA_URL and ATHENA_API_KEY (or ATHENA_GATEWAY_URL and ATHENA_GATEWAY_API_KEY) are required"
|
|
2884
|
+
);
|
|
1700
2885
|
}
|
|
1701
|
-
|
|
1702
|
-
if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) return null;
|
|
1703
|
-
return applyBounds(parsed, options);
|
|
1704
|
-
}
|
|
1705
|
-
return null;
|
|
1706
|
-
}
|
|
1707
|
-
function assertInt(value, label = "value", options) {
|
|
1708
|
-
const parsed = coerceInt(value, options);
|
|
1709
|
-
if (parsed == null) {
|
|
1710
|
-
throw new TypeError(`${label} must be a finite integer`);
|
|
2886
|
+
return _AthenaClient.builder().url(url).key(key).build();
|
|
1711
2887
|
}
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
const clamped = Math.min(config.maxDelayMs, safeDelay);
|
|
1723
|
-
const jitterFactor = typeof config.jitter === "number" ? Math.max(0, Math.min(1, config.jitter)) : config.jitter ? 0.2 : 0;
|
|
1724
|
-
if (!jitterFactor) return clamped;
|
|
1725
|
-
const deviation = clamped * jitterFactor;
|
|
1726
|
-
const offset = (Math.random() * 2 - 1) * deviation;
|
|
1727
|
-
return Math.max(0, clamped + offset);
|
|
1728
|
-
}
|
|
1729
|
-
function sleep(ms) {
|
|
1730
|
-
if (ms <= 0) return Promise.resolve();
|
|
1731
|
-
return new Promise((resolve3) => {
|
|
1732
|
-
setTimeout(resolve3, ms);
|
|
2888
|
+
};
|
|
2889
|
+
function createClient(url, apiKey, options) {
|
|
2890
|
+
return createClientFromConfig({
|
|
2891
|
+
baseUrl: url,
|
|
2892
|
+
apiKey,
|
|
2893
|
+
client: options?.client,
|
|
2894
|
+
backend: toBackendConfig(options?.backend),
|
|
2895
|
+
headers: options?.headers,
|
|
2896
|
+
auth: options?.auth,
|
|
2897
|
+
experimental: options?.experimental
|
|
1733
2898
|
});
|
|
1734
2899
|
}
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
};
|
|
1744
|
-
for (let attempts = 0; attempts <= retries; attempts += 1) {
|
|
1745
|
-
try {
|
|
1746
|
-
return await fn();
|
|
1747
|
-
} catch (error) {
|
|
1748
|
-
if (attempts >= retries) {
|
|
1749
|
-
throw error;
|
|
1750
|
-
}
|
|
1751
|
-
const currentAttempt = attempts + 1;
|
|
1752
|
-
const retry = await shouldRetry(error, currentAttempt);
|
|
1753
|
-
if (!retry) {
|
|
1754
|
-
throw error;
|
|
1755
|
-
}
|
|
1756
|
-
const delay = computeDelayMs(currentAttempt, error, resolvedConfig);
|
|
1757
|
-
await sleep(delay);
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
|
-
throw new Error("withRetry reached an unexpected state");
|
|
1761
|
-
}
|
|
2900
|
+
|
|
2901
|
+
// src/gateway/types.ts
|
|
2902
|
+
var Backend = {
|
|
2903
|
+
Athena: { type: "athena" },
|
|
2904
|
+
Postgrest: { type: "postgrest" },
|
|
2905
|
+
PostgreSQL: { type: "postgresql" },
|
|
2906
|
+
ScyllaDB: { type: "scylladb" }
|
|
2907
|
+
};
|
|
1762
2908
|
|
|
1763
2909
|
// src/schema/definitions.ts
|
|
1764
2910
|
function defineModel(input) {
|
|
@@ -1825,6 +2971,7 @@ var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
|
|
|
1825
2971
|
registry;
|
|
1826
2972
|
tenantKeyMap;
|
|
1827
2973
|
tenantContext;
|
|
2974
|
+
db;
|
|
1828
2975
|
baseClient;
|
|
1829
2976
|
registryNavigator;
|
|
1830
2977
|
tenantHeaderMapper;
|
|
@@ -1851,6 +2998,7 @@ var TypedAthenaClientImpl = class _TypedAthenaClientImpl {
|
|
|
1851
2998
|
client: this.clientOptions.client,
|
|
1852
2999
|
headers: this.tenantHeaderMapper.apply(this.clientOptions.headers, tenantContext)
|
|
1853
3000
|
});
|
|
3001
|
+
this.db = this.baseClient.db;
|
|
1854
3002
|
}
|
|
1855
3003
|
from(table) {
|
|
1856
3004
|
return this.baseClient.from(table);
|
|
@@ -2240,6 +3388,21 @@ var PostgresCatalogSnapshotAssembler = class {
|
|
|
2240
3388
|
};
|
|
2241
3389
|
|
|
2242
3390
|
// src/schema/postgres-provider.ts
|
|
3391
|
+
var pgPoolConstructorPromise;
|
|
3392
|
+
async function loadPgPoolConstructor() {
|
|
3393
|
+
if (!pgPoolConstructorPromise) {
|
|
3394
|
+
pgPoolConstructorPromise = import('pg').then((module) => {
|
|
3395
|
+
const poolConstructor = module.Pool ?? module.default?.Pool;
|
|
3396
|
+
if (!poolConstructor) {
|
|
3397
|
+
throw new Error(
|
|
3398
|
+
'@xylex-group/athena: Unable to load the PostgreSQL driver. Ensure "pg" is installed and this API runs in a Node.js server runtime.'
|
|
3399
|
+
);
|
|
3400
|
+
}
|
|
3401
|
+
return poolConstructor;
|
|
3402
|
+
});
|
|
3403
|
+
}
|
|
3404
|
+
return pgPoolConstructorPromise;
|
|
3405
|
+
}
|
|
2243
3406
|
var PgCatalogClient = class {
|
|
2244
3407
|
constructor(pool) {
|
|
2245
3408
|
this.pool = pool;
|
|
@@ -2279,7 +3442,8 @@ var PostgresIntrospectionProvider = class {
|
|
|
2279
3442
|
}
|
|
2280
3443
|
async inspect(options) {
|
|
2281
3444
|
const schemas = options?.schemas && options.schemas.length > 0 ? normalizePostgresCatalogSchemas(options.schemas) : this.schemas;
|
|
2282
|
-
const
|
|
3445
|
+
const PoolConstructor = await loadPgPoolConstructor();
|
|
3446
|
+
const pool = new PoolConstructor({
|
|
2283
3447
|
connectionString: this.connectionString
|
|
2284
3448
|
});
|
|
2285
3449
|
const catalogClient = new PgCatalogClient(pool);
|
|
@@ -2316,7 +3480,7 @@ function resolveNullishValue(mode) {
|
|
|
2316
3480
|
if (mode === "null") return null;
|
|
2317
3481
|
return "";
|
|
2318
3482
|
}
|
|
2319
|
-
function
|
|
3483
|
+
function isRecord4(value) {
|
|
2320
3484
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2321
3485
|
}
|
|
2322
3486
|
function isNullableColumn(model, key) {
|
|
@@ -2325,7 +3489,7 @@ function isNullableColumn(model, key) {
|
|
|
2325
3489
|
}
|
|
2326
3490
|
function toModelFormDefaults(model, values, options) {
|
|
2327
3491
|
const source = values;
|
|
2328
|
-
if (!
|
|
3492
|
+
if (!isRecord4(source)) {
|
|
2329
3493
|
return {};
|
|
2330
3494
|
}
|
|
2331
3495
|
const mode = options?.nullishMode ?? "empty-string";
|
|
@@ -2401,6 +3565,7 @@ function resolveProviderSchemas(providerConfig) {
|
|
|
2401
3565
|
}
|
|
2402
3566
|
|
|
2403
3567
|
// src/generator/config.ts
|
|
3568
|
+
var POSTGRES_PROTOCOLS = /* @__PURE__ */ new Set(["postgres:", "postgresql:"]);
|
|
2404
3569
|
var DEFAULT_CONFIG_CANDIDATES = [
|
|
2405
3570
|
"athena.config.ts",
|
|
2406
3571
|
"athena.config.js",
|
|
@@ -2430,6 +3595,184 @@ var DEFAULT_EXPERIMENTAL_FLAGS = {
|
|
|
2430
3595
|
postgresGatewayIntrospection: false,
|
|
2431
3596
|
scyllaProviderContracts: true
|
|
2432
3597
|
};
|
|
3598
|
+
var PROJECT_ENV_FILENAMES = [".env", ".env.local"];
|
|
3599
|
+
var DIRECT_CONNECTION_STRING_ENV_KEYS = [
|
|
3600
|
+
"ATHENA_GENERATOR_PG_URL",
|
|
3601
|
+
"DATABASE_URL",
|
|
3602
|
+
"PG_URL",
|
|
3603
|
+
"POSTGRES_URL",
|
|
3604
|
+
"POSTGRESQL_URL"
|
|
3605
|
+
];
|
|
3606
|
+
var POSTGRES_DATABASE_ENV_KEYS = ["ATHENA_GENERATOR_DB", "ATHENA_DATABASE", "PGDATABASE"];
|
|
3607
|
+
var POSTGRES_PASSWORD_ENV_KEYS = ["ATHENA_GENERATOR_PG_PASSWORD", "PGPASSWORD"];
|
|
3608
|
+
var GATEWAY_URL_ENV_KEYS = ["ATHENA_URL", "ATHENA_GATEWAY_URL", "ATHENA_GENERATOR_URL"];
|
|
3609
|
+
var GATEWAY_API_KEY_ENV_KEYS = [
|
|
3610
|
+
"ATHENA_API_KEY",
|
|
3611
|
+
"ATHENA_GATEWAY_API_KEY",
|
|
3612
|
+
"ATHENA_GENERATOR_API_KEY"
|
|
3613
|
+
];
|
|
3614
|
+
function normalizeRawEnvValue(rawValue) {
|
|
3615
|
+
if (rawValue.startsWith('"') && rawValue.endsWith('"') && rawValue.length >= 2) {
|
|
3616
|
+
const inner = rawValue.slice(1, -1);
|
|
3617
|
+
return inner.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
3618
|
+
}
|
|
3619
|
+
if (rawValue.startsWith("'") && rawValue.endsWith("'") && rawValue.length >= 2) {
|
|
3620
|
+
return rawValue.slice(1, -1);
|
|
3621
|
+
}
|
|
3622
|
+
const commentIndex = rawValue.search(/\s+#/);
|
|
3623
|
+
const withoutComment = commentIndex >= 0 ? rawValue.slice(0, commentIndex) : rawValue;
|
|
3624
|
+
return withoutComment.trim();
|
|
3625
|
+
}
|
|
3626
|
+
function parseEnvLine(line) {
|
|
3627
|
+
const trimmed = line.trim();
|
|
3628
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
3629
|
+
return void 0;
|
|
3630
|
+
}
|
|
3631
|
+
const match = trimmed.match(/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
|
|
3632
|
+
if (!match) {
|
|
3633
|
+
return void 0;
|
|
3634
|
+
}
|
|
3635
|
+
const [, key, rawValue] = match;
|
|
3636
|
+
return [key, normalizeRawEnvValue(rawValue.trim())];
|
|
3637
|
+
}
|
|
3638
|
+
function readProjectEnvEntries(cwd) {
|
|
3639
|
+
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
3640
|
+
const filenames = [
|
|
3641
|
+
...PROJECT_ENV_FILENAMES,
|
|
3642
|
+
...nodeEnv ? [`.env.${nodeEnv}`, `.env.${nodeEnv}.local`] : []
|
|
3643
|
+
];
|
|
3644
|
+
const entries = /* @__PURE__ */ new Map();
|
|
3645
|
+
for (const filename of filenames) {
|
|
3646
|
+
const absolutePath = resolve(cwd, filename);
|
|
3647
|
+
if (!existsSync(absolutePath)) {
|
|
3648
|
+
continue;
|
|
3649
|
+
}
|
|
3650
|
+
const content = readFileSync(absolutePath, "utf8");
|
|
3651
|
+
const lines = content.split(/\r?\n/g);
|
|
3652
|
+
for (const line of lines) {
|
|
3653
|
+
const parsed = parseEnvLine(line);
|
|
3654
|
+
if (!parsed) {
|
|
3655
|
+
continue;
|
|
3656
|
+
}
|
|
3657
|
+
const [key, value] = parsed;
|
|
3658
|
+
entries.set(key, value);
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
return entries;
|
|
3662
|
+
}
|
|
3663
|
+
function applyProjectEnv(cwd) {
|
|
3664
|
+
const envEntries = readProjectEnvEntries(cwd);
|
|
3665
|
+
if (envEntries.size === 0) {
|
|
3666
|
+
return () => {
|
|
3667
|
+
};
|
|
3668
|
+
}
|
|
3669
|
+
const initialKeys = new Set(
|
|
3670
|
+
Object.keys(process.env).filter((key) => process.env[key] !== void 0)
|
|
3671
|
+
);
|
|
3672
|
+
const staged = /* @__PURE__ */ new Map();
|
|
3673
|
+
for (const [key, value] of envEntries.entries()) {
|
|
3674
|
+
if (initialKeys.has(key)) {
|
|
3675
|
+
continue;
|
|
3676
|
+
}
|
|
3677
|
+
staged.set(key, value);
|
|
3678
|
+
}
|
|
3679
|
+
for (const [key, value] of staged.entries()) {
|
|
3680
|
+
process.env[key] = value;
|
|
3681
|
+
}
|
|
3682
|
+
return () => {
|
|
3683
|
+
for (const key of staged.keys()) {
|
|
3684
|
+
delete process.env[key];
|
|
3685
|
+
}
|
|
3686
|
+
};
|
|
3687
|
+
}
|
|
3688
|
+
function readEnvStringValue(key) {
|
|
3689
|
+
const value = process.env[key];
|
|
3690
|
+
if (typeof value !== "string") {
|
|
3691
|
+
return void 0;
|
|
3692
|
+
}
|
|
3693
|
+
const trimmed = value.trim();
|
|
3694
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
3695
|
+
}
|
|
3696
|
+
function resolveFallbackValue(fallbackKeys) {
|
|
3697
|
+
for (const key of fallbackKeys) {
|
|
3698
|
+
const value = readEnvStringValue(key);
|
|
3699
|
+
if (value) {
|
|
3700
|
+
return value;
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
return void 0;
|
|
3704
|
+
}
|
|
3705
|
+
function normalizeOptionalString(value, fallbackKeys) {
|
|
3706
|
+
if (typeof value === "string") {
|
|
3707
|
+
const trimmed = value.trim();
|
|
3708
|
+
if (trimmed.length > 0) {
|
|
3709
|
+
return trimmed;
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
return resolveFallbackValue(fallbackKeys);
|
|
3713
|
+
}
|
|
3714
|
+
function normalizeRequiredString(value, fieldLabel, fallbackKeys) {
|
|
3715
|
+
const resolved = normalizeOptionalString(value, fallbackKeys);
|
|
3716
|
+
if (resolved) {
|
|
3717
|
+
return resolved;
|
|
3718
|
+
}
|
|
3719
|
+
throw new Error(
|
|
3720
|
+
`Generator config is missing ${fieldLabel}. Set ${fieldLabel} directly or provide one of: ${fallbackKeys.join(", ")}.`
|
|
3721
|
+
);
|
|
3722
|
+
}
|
|
3723
|
+
function applyPostgresPasswordFallback(connectionString) {
|
|
3724
|
+
let parsedUrl;
|
|
3725
|
+
try {
|
|
3726
|
+
parsedUrl = new URL(connectionString);
|
|
3727
|
+
} catch {
|
|
3728
|
+
return connectionString;
|
|
3729
|
+
}
|
|
3730
|
+
if (!POSTGRES_PROTOCOLS.has(parsedUrl.protocol)) {
|
|
3731
|
+
return connectionString;
|
|
3732
|
+
}
|
|
3733
|
+
if (!parsedUrl.username || parsedUrl.password) {
|
|
3734
|
+
return connectionString;
|
|
3735
|
+
}
|
|
3736
|
+
const fallbackPassword = resolveFallbackValue(POSTGRES_PASSWORD_ENV_KEYS);
|
|
3737
|
+
if (!fallbackPassword) {
|
|
3738
|
+
return connectionString;
|
|
3739
|
+
}
|
|
3740
|
+
parsedUrl.password = fallbackPassword;
|
|
3741
|
+
return parsedUrl.toString();
|
|
3742
|
+
}
|
|
3743
|
+
function normalizeBooleanFlag(rawValue, fallback) {
|
|
3744
|
+
if (typeof rawValue === "boolean") {
|
|
3745
|
+
return rawValue;
|
|
3746
|
+
}
|
|
3747
|
+
if (typeof rawValue === "string") {
|
|
3748
|
+
return parseBooleanFlag(rawValue, fallback);
|
|
3749
|
+
}
|
|
3750
|
+
return fallback;
|
|
3751
|
+
}
|
|
3752
|
+
function normalizeFeatureFlags(input) {
|
|
3753
|
+
return {
|
|
3754
|
+
emitRelations: normalizeBooleanFlag(
|
|
3755
|
+
input?.emitRelations,
|
|
3756
|
+
DEFAULT_FEATURES.emitRelations
|
|
3757
|
+
),
|
|
3758
|
+
emitRegistry: normalizeBooleanFlag(
|
|
3759
|
+
input?.emitRegistry,
|
|
3760
|
+
DEFAULT_FEATURES.emitRegistry
|
|
3761
|
+
)
|
|
3762
|
+
};
|
|
3763
|
+
}
|
|
3764
|
+
function normalizeExperimentalFlags(input) {
|
|
3765
|
+
return {
|
|
3766
|
+
postgresGatewayIntrospection: normalizeBooleanFlag(
|
|
3767
|
+
input?.postgresGatewayIntrospection,
|
|
3768
|
+
DEFAULT_EXPERIMENTAL_FLAGS.postgresGatewayIntrospection
|
|
3769
|
+
),
|
|
3770
|
+
scyllaProviderContracts: normalizeBooleanFlag(
|
|
3771
|
+
input?.scyllaProviderContracts,
|
|
3772
|
+
DEFAULT_EXPERIMENTAL_FLAGS.scyllaProviderContracts
|
|
3773
|
+
)
|
|
3774
|
+
};
|
|
3775
|
+
}
|
|
2433
3776
|
function normalizeOutputConfig(output) {
|
|
2434
3777
|
return {
|
|
2435
3778
|
targets: {
|
|
@@ -2442,9 +3785,41 @@ function normalizeOutputConfig(output) {
|
|
|
2442
3785
|
};
|
|
2443
3786
|
}
|
|
2444
3787
|
function normalizeProviderConfig(provider) {
|
|
2445
|
-
if (provider.kind === "postgres") {
|
|
3788
|
+
if (provider.kind === "postgres" && provider.mode === "direct") {
|
|
3789
|
+
const connectionString = normalizeRequiredString(
|
|
3790
|
+
provider.connectionString,
|
|
3791
|
+
"provider.connectionString",
|
|
3792
|
+
DIRECT_CONNECTION_STRING_ENV_KEYS
|
|
3793
|
+
);
|
|
3794
|
+
const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS);
|
|
3795
|
+
return {
|
|
3796
|
+
...provider,
|
|
3797
|
+
connectionString: applyPostgresPasswordFallback(connectionString),
|
|
3798
|
+
database,
|
|
3799
|
+
schemas: normalizeSchemaSelection(provider.schemas)
|
|
3800
|
+
};
|
|
3801
|
+
}
|
|
3802
|
+
if (provider.kind === "postgres" && provider.mode === "gateway") {
|
|
3803
|
+
const gatewayUrl = normalizeRequiredString(
|
|
3804
|
+
provider.gatewayUrl,
|
|
3805
|
+
"provider.gatewayUrl",
|
|
3806
|
+
GATEWAY_URL_ENV_KEYS
|
|
3807
|
+
);
|
|
3808
|
+
const apiKey = normalizeRequiredString(
|
|
3809
|
+
provider.apiKey,
|
|
3810
|
+
"provider.apiKey",
|
|
3811
|
+
GATEWAY_API_KEY_ENV_KEYS
|
|
3812
|
+
);
|
|
3813
|
+
const database = normalizeRequiredString(
|
|
3814
|
+
provider.database,
|
|
3815
|
+
"provider.database",
|
|
3816
|
+
POSTGRES_DATABASE_ENV_KEYS
|
|
3817
|
+
);
|
|
2446
3818
|
return {
|
|
2447
3819
|
...provider,
|
|
3820
|
+
gatewayUrl,
|
|
3821
|
+
apiKey,
|
|
3822
|
+
database,
|
|
2448
3823
|
schemas: normalizeSchemaSelection(provider.schemas)
|
|
2449
3824
|
};
|
|
2450
3825
|
}
|
|
@@ -2465,14 +3840,8 @@ function normalizeGeneratorConfig(input) {
|
|
|
2465
3840
|
...DEFAULT_NAMING,
|
|
2466
3841
|
...input.naming ?? {}
|
|
2467
3842
|
},
|
|
2468
|
-
features:
|
|
2469
|
-
|
|
2470
|
-
...input.features ?? {}
|
|
2471
|
-
},
|
|
2472
|
-
experimental: {
|
|
2473
|
-
...DEFAULT_EXPERIMENTAL_FLAGS,
|
|
2474
|
-
...input.experimental ?? {}
|
|
2475
|
-
}
|
|
3843
|
+
features: normalizeFeatureFlags(input.features),
|
|
3844
|
+
experimental: normalizeExperimentalFlags(input.experimental)
|
|
2476
3845
|
};
|
|
2477
3846
|
}
|
|
2478
3847
|
function defineGeneratorConfig(config) {
|
|
@@ -2512,6 +3881,11 @@ function extractConfigExport(module) {
|
|
|
2512
3881
|
if (moduleExports && typeof moduleExports === "object") {
|
|
2513
3882
|
queue.push(moduleExports);
|
|
2514
3883
|
}
|
|
3884
|
+
for (const value of Object.values(record)) {
|
|
3885
|
+
if (value && typeof value === "object") {
|
|
3886
|
+
queue.push(value);
|
|
3887
|
+
}
|
|
3888
|
+
}
|
|
2515
3889
|
}
|
|
2516
3890
|
throw new Error(
|
|
2517
3891
|
"Generator config file must export a config object as default export or `config`."
|
|
@@ -2526,19 +3900,24 @@ function importConfigModule(moduleSpecifier) {
|
|
|
2526
3900
|
}
|
|
2527
3901
|
async function loadGeneratorConfig(options = {}) {
|
|
2528
3902
|
const cwd = options.cwd ?? process.cwd();
|
|
3903
|
+
const restoreProjectEnv = applyProjectEnv(cwd);
|
|
2529
3904
|
const resolvedPath = options.configPath ? resolve(cwd, options.configPath) : findGeneratorConfigPath(cwd);
|
|
2530
3905
|
if (!resolvedPath) {
|
|
2531
3906
|
throw new Error(
|
|
2532
3907
|
`No generator config found in ${cwd}. Expected one of: ${DEFAULT_CONFIG_CANDIDATES.join(", ")}`
|
|
2533
3908
|
);
|
|
2534
3909
|
}
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
3910
|
+
try {
|
|
3911
|
+
const moduleUrl = pathToFileURL(resolvedPath);
|
|
3912
|
+
const module = await importConfigModule(`${moduleUrl.href}?cacheBust=${Date.now()}`);
|
|
3913
|
+
const rawConfig = extractConfigExport(module);
|
|
3914
|
+
return {
|
|
3915
|
+
configPath: resolvedPath,
|
|
3916
|
+
config: normalizeGeneratorConfig(rawConfig)
|
|
3917
|
+
};
|
|
3918
|
+
} finally {
|
|
3919
|
+
restoreProjectEnv();
|
|
3920
|
+
}
|
|
2542
3921
|
}
|
|
2543
3922
|
|
|
2544
3923
|
// src/generator/naming.ts
|
|
@@ -2682,9 +4061,13 @@ function resolvePlaceholderMap(baseTokens, outputConfig) {
|
|
|
2682
4061
|
const resolved = {
|
|
2683
4062
|
...baseTokens
|
|
2684
4063
|
};
|
|
4064
|
+
const reservedTokenKeys = new Set(Object.keys(baseTokens));
|
|
2685
4065
|
const entries = Object.entries(outputConfig.placeholderMap ?? {});
|
|
2686
4066
|
for (let index = 0; index < entries.length; index += 1) {
|
|
2687
4067
|
const [key, value] = entries[index];
|
|
4068
|
+
if (reservedTokenKeys.has(key)) {
|
|
4069
|
+
continue;
|
|
4070
|
+
}
|
|
2688
4071
|
let current = value;
|
|
2689
4072
|
for (let depth = 0; depth < 8; depth += 1) {
|
|
2690
4073
|
const next = renderTemplate(current, resolved);
|
|
@@ -2964,13 +4347,65 @@ function assertNoDuplicatePaths(files) {
|
|
|
2964
4347
|
[
|
|
2965
4348
|
`Generator output collision detected for path: ${file.path}`,
|
|
2966
4349
|
`Collision: ${existing.kind} and ${file.kind}.`,
|
|
2967
|
-
"
|
|
4350
|
+
"Use explicit placeholders such as {model}, {model_kebab}, {schema}, or {schema_kebab} in output targets so each artifact resolves to a unique path."
|
|
2968
4351
|
].join(" ")
|
|
2969
4352
|
);
|
|
2970
4353
|
}
|
|
2971
4354
|
seen.set(file.path, file);
|
|
2972
4355
|
}
|
|
2973
4356
|
}
|
|
4357
|
+
function addSchemaSegmentToPath(pathValue, schemaName) {
|
|
4358
|
+
const normalizedPath = normalizePath(pathValue);
|
|
4359
|
+
const parsedPath = posix.parse(normalizedPath);
|
|
4360
|
+
const schemaSegment = applyNamingStyle(schemaName, "kebab");
|
|
4361
|
+
if (!schemaSegment) {
|
|
4362
|
+
return normalizedPath;
|
|
4363
|
+
}
|
|
4364
|
+
const dir = parsedPath.dir.length > 0 ? `${parsedPath.dir}/${schemaSegment}` : schemaSegment;
|
|
4365
|
+
return normalizePath(posix.join(dir, parsedPath.base));
|
|
4366
|
+
}
|
|
4367
|
+
function scopeDuplicateDescriptorPathsBySchema(descriptors) {
|
|
4368
|
+
const nextDescriptors = descriptors.map((descriptor) => ({ ...descriptor }));
|
|
4369
|
+
const duplicates = /* @__PURE__ */ new Map();
|
|
4370
|
+
for (let index = 0; index < nextDescriptors.length; index += 1) {
|
|
4371
|
+
const descriptor = nextDescriptors[index];
|
|
4372
|
+
const indexes = duplicates.get(descriptor.filePath) ?? [];
|
|
4373
|
+
indexes.push(index);
|
|
4374
|
+
duplicates.set(descriptor.filePath, indexes);
|
|
4375
|
+
}
|
|
4376
|
+
let appliedSchemaScoping = false;
|
|
4377
|
+
for (const indexes of duplicates.values()) {
|
|
4378
|
+
if (indexes.length <= 1) {
|
|
4379
|
+
continue;
|
|
4380
|
+
}
|
|
4381
|
+
const schemaNames = new Set(indexes.map((index) => nextDescriptors[index].schemaName));
|
|
4382
|
+
if (schemaNames.size <= 1) {
|
|
4383
|
+
continue;
|
|
4384
|
+
}
|
|
4385
|
+
for (const index of indexes) {
|
|
4386
|
+
const descriptor = nextDescriptors[index];
|
|
4387
|
+
descriptor.filePath = addSchemaSegmentToPath(descriptor.filePath, descriptor.schemaName);
|
|
4388
|
+
}
|
|
4389
|
+
appliedSchemaScoping = true;
|
|
4390
|
+
}
|
|
4391
|
+
if (!appliedSchemaScoping) {
|
|
4392
|
+
return nextDescriptors;
|
|
4393
|
+
}
|
|
4394
|
+
const normalizedPaths = /* @__PURE__ */ new Set();
|
|
4395
|
+
for (const descriptor of nextDescriptors) {
|
|
4396
|
+
if (normalizedPaths.has(descriptor.filePath)) {
|
|
4397
|
+
throw new Error(
|
|
4398
|
+
[
|
|
4399
|
+
`Generator output collision detected for path: ${descriptor.filePath}`,
|
|
4400
|
+
"Automatic schema path scoping was applied but collisions remain.",
|
|
4401
|
+
"Add explicit placeholders such as {model}, {model_kebab}, {schema}, or {schema_kebab} to your output targets."
|
|
4402
|
+
].join(" ")
|
|
4403
|
+
);
|
|
4404
|
+
}
|
|
4405
|
+
normalizedPaths.add(descriptor.filePath);
|
|
4406
|
+
}
|
|
4407
|
+
return nextDescriptors;
|
|
4408
|
+
}
|
|
2974
4409
|
var ArtifactComposer = class {
|
|
2975
4410
|
constructor(snapshot, config) {
|
|
2976
4411
|
this.snapshot = snapshot;
|
|
@@ -3009,7 +4444,8 @@ var ArtifactComposer = class {
|
|
|
3009
4444
|
});
|
|
3010
4445
|
}
|
|
3011
4446
|
}
|
|
3012
|
-
const
|
|
4447
|
+
const scopedModelDescriptors = scopeDuplicateDescriptorPathsBySchema(modelDescriptors);
|
|
4448
|
+
let schemaDescriptors = Object.keys(this.snapshot.schemas).sort().map((schemaName) => {
|
|
3013
4449
|
const schemaPath = normalizePath(
|
|
3014
4450
|
renderOutputPath(this.config.output.targets.schema, {
|
|
3015
4451
|
provider: providerName,
|
|
@@ -3027,9 +4463,10 @@ var ArtifactComposer = class {
|
|
|
3027
4463
|
this.config.naming.schemaConst,
|
|
3028
4464
|
"schema"
|
|
3029
4465
|
),
|
|
3030
|
-
models:
|
|
4466
|
+
models: scopedModelDescriptors.filter((model) => model.schemaName === schemaName)
|
|
3031
4467
|
};
|
|
3032
4468
|
});
|
|
4469
|
+
schemaDescriptors = scopeDuplicateDescriptorPathsBySchema(schemaDescriptors);
|
|
3033
4470
|
const databasePath = normalizePath(
|
|
3034
4471
|
renderOutputPath(this.config.output.targets.database, {
|
|
3035
4472
|
provider: providerName,
|
|
@@ -3049,7 +4486,7 @@ var ArtifactComposer = class {
|
|
|
3049
4486
|
schemas: schemaDescriptors
|
|
3050
4487
|
};
|
|
3051
4488
|
const files = [];
|
|
3052
|
-
for (const modelDescriptor of
|
|
4489
|
+
for (const modelDescriptor of scopedModelDescriptors) {
|
|
3053
4490
|
files.push(renderModelArtifact(this.snapshot, modelDescriptor, this.config));
|
|
3054
4491
|
}
|
|
3055
4492
|
for (const schemaDescriptor of schemaDescriptors) {
|
|
@@ -3082,636 +4519,145 @@ var ArtifactComposer = class {
|
|
|
3082
4519
|
files
|
|
3083
4520
|
};
|
|
3084
4521
|
}
|
|
3085
|
-
};
|
|
3086
|
-
function generateArtifactsFromSnapshot(snapshot, config) {
|
|
3087
|
-
const normalizedConfig = "naming" in config && "features" in config && "experimental" in config ? config : normalizeGeneratorConfig(config);
|
|
3088
|
-
return new ArtifactComposer(snapshot, normalizedConfig).compose();
|
|
3089
|
-
}
|
|
3090
|
-
|
|
3091
|
-
// src/generator/providers.ts
|
|
3092
|
-
var AthenaGatewayCatalogClient = class {
|
|
3093
|
-
constructor(client) {
|
|
3094
|
-
this.client = client;
|
|
3095
|
-
}
|
|
3096
|
-
async queryRows(query) {
|
|
3097
|
-
const result = await this.client.query(query);
|
|
3098
|
-
if (result.error || result.status < 200 || result.status >= 300) {
|
|
3099
|
-
throw new Error(result.error ?? `Gateway query failed with status ${result.status}`);
|
|
3100
|
-
}
|
|
3101
|
-
return result.data ?? [];
|
|
3102
|
-
}
|
|
3103
|
-
async queryColumns(query) {
|
|
3104
|
-
return this.queryRows(query);
|
|
3105
|
-
}
|
|
3106
|
-
async queryEnums(query) {
|
|
3107
|
-
const rows = await this.queryRows(query);
|
|
3108
|
-
const enumMap = /* @__PURE__ */ new Map();
|
|
3109
|
-
for (const row of rows) {
|
|
3110
|
-
const existing = enumMap.get(row.type_oid) ?? [];
|
|
3111
|
-
existing.push(row.enum_label);
|
|
3112
|
-
enumMap.set(row.type_oid, existing);
|
|
3113
|
-
}
|
|
3114
|
-
return enumMap;
|
|
3115
|
-
}
|
|
3116
|
-
async queryPrimaryKeys(query) {
|
|
3117
|
-
return this.queryRows(query);
|
|
3118
|
-
}
|
|
3119
|
-
async queryForeignKeys(query) {
|
|
3120
|
-
return this.queryRows(query);
|
|
3121
|
-
}
|
|
3122
|
-
};
|
|
3123
|
-
var AthenaGatewayPostgresIntrospectionProvider = class {
|
|
3124
|
-
constructor(config) {
|
|
3125
|
-
this.config = config;
|
|
3126
|
-
this.client = createClient(this.config.gatewayUrl, this.config.apiKey, {
|
|
3127
|
-
backend: {
|
|
3128
|
-
type: this.config.backend ?? "postgresql"
|
|
3129
|
-
}
|
|
3130
|
-
});
|
|
3131
|
-
this.schemas = normalizeSchemaSelection(this.config.schemas);
|
|
3132
|
-
}
|
|
3133
|
-
backend = "postgresql";
|
|
3134
|
-
client;
|
|
3135
|
-
schemas;
|
|
3136
|
-
async inspect(options) {
|
|
3137
|
-
const schemas = options?.schemas && options.schemas.length > 0 ? normalizeSchemaSelection(options.schemas) : this.schemas;
|
|
3138
|
-
const catalogClient = new AthenaGatewayCatalogClient(this.client);
|
|
3139
|
-
const queries = buildGatewayCatalogQueries(schemas);
|
|
3140
|
-
const [columnRows, enumMap, primaryKeyRows, foreignKeyRows] = await Promise.all([
|
|
3141
|
-
catalogClient.queryColumns(queries.columns),
|
|
3142
|
-
catalogClient.queryEnums(queries.enums),
|
|
3143
|
-
catalogClient.queryPrimaryKeys(queries.primaryKeys),
|
|
3144
|
-
catalogClient.queryForeignKeys(queries.foreignKeys)
|
|
3145
|
-
]);
|
|
3146
|
-
const assembler = new PostgresCatalogSnapshotAssembler();
|
|
3147
|
-
assembler.addColumnRows(columnRows, enumMap);
|
|
3148
|
-
assembler.addPrimaryKeyRows(primaryKeyRows);
|
|
3149
|
-
assembler.addForeignKeyRows(foreignKeyRows);
|
|
3150
|
-
assembler.addManyToManyRows(foreignKeyRows);
|
|
3151
|
-
return {
|
|
3152
|
-
backend: "postgresql",
|
|
3153
|
-
database: this.config.database,
|
|
3154
|
-
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3155
|
-
schemas: assembler.toSchemas()
|
|
3156
|
-
};
|
|
3157
|
-
}
|
|
3158
|
-
};
|
|
3159
|
-
var ScyllaIntrospectionProvider = class {
|
|
3160
|
-
constructor(config) {
|
|
3161
|
-
this.config = config;
|
|
3162
|
-
}
|
|
3163
|
-
backend = "scylladb";
|
|
3164
|
-
async inspect() {
|
|
3165
|
-
throw new Error(
|
|
3166
|
-
`Scylla introspection provider is not implemented yet for keyspace ${this.config.keyspace}.`
|
|
3167
|
-
);
|
|
3168
|
-
}
|
|
3169
|
-
};
|
|
3170
|
-
function createPostgresProvider(config) {
|
|
3171
|
-
return createPostgresIntrospectionProvider({
|
|
3172
|
-
connectionString: config.connectionString,
|
|
3173
|
-
database: config.database,
|
|
3174
|
-
schemas: normalizeSchemaSelection(config.schemas)
|
|
3175
|
-
});
|
|
3176
|
-
}
|
|
3177
|
-
function resolveGeneratorProvider(providerConfig, experimentalFlags) {
|
|
3178
|
-
if (providerConfig.kind === "postgres" && providerConfig.mode === "direct") {
|
|
3179
|
-
return createPostgresProvider(providerConfig);
|
|
3180
|
-
}
|
|
3181
|
-
if (providerConfig.kind === "postgres" && providerConfig.mode === "gateway") {
|
|
3182
|
-
return new AthenaGatewayPostgresIntrospectionProvider(providerConfig);
|
|
3183
|
-
}
|
|
3184
|
-
if (providerConfig.kind === "scylla") {
|
|
3185
|
-
if (!experimentalFlags.scyllaProviderContracts) {
|
|
3186
|
-
throw new Error(
|
|
3187
|
-
"Scylla provider contracts are disabled. Set experimental.scyllaProviderContracts=true to enable placeholders."
|
|
3188
|
-
);
|
|
3189
|
-
}
|
|
3190
|
-
return new ScyllaIntrospectionProvider(providerConfig);
|
|
3191
|
-
}
|
|
3192
|
-
throw new Error(`Unsupported generator provider kind: ${providerConfig.kind ?? "unknown"}`);
|
|
3193
|
-
}
|
|
3194
|
-
async function writeArtifacts(files, cwd) {
|
|
3195
|
-
const writtenFiles = [];
|
|
3196
|
-
for (const file of files) {
|
|
3197
|
-
const absolutePath = resolve(cwd, file.path);
|
|
3198
|
-
await mkdir(dirname(absolutePath), { recursive: true });
|
|
3199
|
-
await writeFile(absolutePath, file.content, "utf8");
|
|
3200
|
-
writtenFiles.push(file.path);
|
|
3201
|
-
}
|
|
3202
|
-
return writtenFiles;
|
|
3203
|
-
}
|
|
3204
|
-
async function runSchemaGenerator(options = {}) {
|
|
3205
|
-
const cwd = options.cwd ?? process.cwd();
|
|
3206
|
-
const configOptions = {
|
|
3207
|
-
cwd,
|
|
3208
|
-
configPath: options.configPath
|
|
3209
|
-
};
|
|
3210
|
-
const { configPath, config } = await loadGeneratorConfig(configOptions);
|
|
3211
|
-
const provider = options.provider ?? resolveGeneratorProvider(config.provider, config.experimental);
|
|
3212
|
-
const snapshot = await provider.inspect({
|
|
3213
|
-
schemas: resolveProviderSchemas(config.provider)
|
|
3214
|
-
});
|
|
3215
|
-
const generated = generateArtifactsFromSnapshot(snapshot, config);
|
|
3216
|
-
const writtenFiles = options.dryRun ? [] : await writeArtifacts(generated.files, cwd);
|
|
3217
|
-
return {
|
|
3218
|
-
...generated,
|
|
3219
|
-
configPath,
|
|
3220
|
-
writtenFiles
|
|
3221
|
-
};
|
|
3222
|
-
}
|
|
3223
|
-
|
|
3224
|
-
// src/auth/client.ts
|
|
3225
|
-
var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
|
|
3226
|
-
var FALLBACK_SDK_VERSION2 = "1.0.0";
|
|
3227
|
-
var SDK_NAME2 = "xylex-group/athena-auth";
|
|
3228
|
-
var SDK_VERSION2 = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION2;
|
|
3229
|
-
var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
|
|
3230
|
-
function normalizeBaseUrl(baseUrl) {
|
|
3231
|
-
return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
|
|
3232
|
-
}
|
|
3233
|
-
function isRecord4(value) {
|
|
3234
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3235
|
-
}
|
|
3236
|
-
function normalizeHeaderValue2(value) {
|
|
3237
|
-
return value ? value : void 0;
|
|
3238
|
-
}
|
|
3239
|
-
function parseResponseBody2(rawText, contentType) {
|
|
3240
|
-
if (!rawText) {
|
|
3241
|
-
return { parsed: null, parseFailed: false };
|
|
3242
|
-
}
|
|
3243
|
-
const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
|
|
3244
|
-
const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
|
|
3245
|
-
if (!looksJson) {
|
|
3246
|
-
return { parsed: rawText, parseFailed: false };
|
|
3247
|
-
}
|
|
3248
|
-
try {
|
|
3249
|
-
return { parsed: JSON.parse(rawText), parseFailed: false };
|
|
3250
|
-
} catch {
|
|
3251
|
-
return { parsed: rawText, parseFailed: true };
|
|
3252
|
-
}
|
|
3253
|
-
}
|
|
3254
|
-
function resolveRequestId2(headers) {
|
|
3255
|
-
return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
|
|
3256
|
-
}
|
|
3257
|
-
function resolveErrorMessage2(payload, fallback) {
|
|
3258
|
-
if (isRecord4(payload)) {
|
|
3259
|
-
const messageCandidates = [payload.error, payload.message, payload.details];
|
|
3260
|
-
for (const candidate of messageCandidates) {
|
|
3261
|
-
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
3262
|
-
return candidate.trim();
|
|
3263
|
-
}
|
|
3264
|
-
}
|
|
3265
|
-
}
|
|
3266
|
-
if (typeof payload === "string" && payload.trim().length > 0) {
|
|
3267
|
-
return payload.trim();
|
|
3268
|
-
}
|
|
3269
|
-
return fallback;
|
|
3270
|
-
}
|
|
3271
|
-
function toErrorDetails(input) {
|
|
3272
|
-
return {
|
|
3273
|
-
code: input.code,
|
|
3274
|
-
message: input.message,
|
|
3275
|
-
status: input.status,
|
|
3276
|
-
endpoint: input.endpoint,
|
|
3277
|
-
method: input.method,
|
|
3278
|
-
requestId: input.requestId,
|
|
3279
|
-
hint: input.hint,
|
|
3280
|
-
cause: input.cause
|
|
3281
|
-
};
|
|
3282
|
-
}
|
|
3283
|
-
function mergeCallOptions(base, override) {
|
|
3284
|
-
if (!base && !override) return void 0;
|
|
3285
|
-
return {
|
|
3286
|
-
...base,
|
|
3287
|
-
...override,
|
|
3288
|
-
headers: {
|
|
3289
|
-
...base?.headers ?? {},
|
|
3290
|
-
...override?.headers ?? {}
|
|
3291
|
-
}
|
|
3292
|
-
};
|
|
3293
|
-
}
|
|
3294
|
-
function extractFetchOptions(input) {
|
|
3295
|
-
if (!input) {
|
|
3296
|
-
return {
|
|
3297
|
-
payload: void 0,
|
|
3298
|
-
fetchOptions: void 0
|
|
3299
|
-
};
|
|
3300
|
-
}
|
|
3301
|
-
const { fetchOptions, ...rest } = input;
|
|
3302
|
-
const hasPayloadKeys = Object.keys(rest).length > 0;
|
|
3303
|
-
return {
|
|
3304
|
-
payload: hasPayloadKeys ? rest : void 0,
|
|
3305
|
-
fetchOptions
|
|
3306
|
-
};
|
|
4522
|
+
};
|
|
4523
|
+
function generateArtifactsFromSnapshot(snapshot, config) {
|
|
4524
|
+
const normalizedConfig = "naming" in config && "features" in config && "experimental" in config ? config : normalizeGeneratorConfig(config);
|
|
4525
|
+
return new ArtifactComposer(snapshot, normalizedConfig).compose();
|
|
3307
4526
|
}
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
const apiKey = options?.apiKey ?? config.apiKey;
|
|
3314
|
-
if (apiKey) {
|
|
3315
|
-
headers.apikey = apiKey;
|
|
3316
|
-
headers["x-api-key"] = apiKey;
|
|
3317
|
-
}
|
|
3318
|
-
const bearerToken = options?.bearerToken ?? config.bearerToken;
|
|
3319
|
-
if (bearerToken) {
|
|
3320
|
-
headers.Authorization = `Bearer ${bearerToken}`;
|
|
4527
|
+
|
|
4528
|
+
// src/generator/providers.ts
|
|
4529
|
+
var AthenaGatewayCatalogClient = class {
|
|
4530
|
+
constructor(client) {
|
|
4531
|
+
this.client = client;
|
|
3321
4532
|
}
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
Object.entries(mergedExtraHeaders).forEach(([key, value]) => {
|
|
3327
|
-
const normalized = normalizeHeaderValue2(value);
|
|
3328
|
-
if (normalized) {
|
|
3329
|
-
headers[key] = normalized;
|
|
4533
|
+
async queryRows(query) {
|
|
4534
|
+
const result = await this.client.query(query);
|
|
4535
|
+
if (result.error || result.status < 200 || result.status >= 300) {
|
|
4536
|
+
throw new Error(result.error ?? `Gateway query failed with status ${result.status}`);
|
|
3330
4537
|
}
|
|
3331
|
-
|
|
3332
|
-
return headers;
|
|
3333
|
-
}
|
|
3334
|
-
function appendQueryParam(searchParams, key, value) {
|
|
3335
|
-
if (value === void 0 || value === null) return;
|
|
3336
|
-
if (Array.isArray(value)) {
|
|
3337
|
-
value.forEach((item) => {
|
|
3338
|
-
searchParams.append(key, String(item));
|
|
3339
|
-
});
|
|
3340
|
-
return;
|
|
4538
|
+
return result.data ?? [];
|
|
3341
4539
|
}
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
function buildRequestUrl(baseUrl, endpoint, query) {
|
|
3345
|
-
const url = `${baseUrl}${endpoint}`;
|
|
3346
|
-
if (!query || Object.keys(query).length === 0) return url;
|
|
3347
|
-
const searchParams = new URLSearchParams();
|
|
3348
|
-
Object.entries(query).forEach(([key, value]) => appendQueryParam(searchParams, key, value));
|
|
3349
|
-
const queryText = searchParams.toString();
|
|
3350
|
-
return queryText ? `${url}?${queryText}` : url;
|
|
3351
|
-
}
|
|
3352
|
-
function inferDefaultMethod(endpoint) {
|
|
3353
|
-
if (endpoint.startsWith("/reset-password/")) {
|
|
3354
|
-
return "GET";
|
|
4540
|
+
async queryColumns(query) {
|
|
4541
|
+
return this.queryRows(query);
|
|
3355
4542
|
}
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
default:
|
|
3366
|
-
return "POST";
|
|
4543
|
+
async queryEnums(query) {
|
|
4544
|
+
const rows = await this.queryRows(query);
|
|
4545
|
+
const enumMap = /* @__PURE__ */ new Map();
|
|
4546
|
+
for (const row of rows) {
|
|
4547
|
+
const existing = enumMap.get(row.type_oid) ?? [];
|
|
4548
|
+
existing.push(row.enum_label);
|
|
4549
|
+
enumMap.set(row.type_oid, existing);
|
|
4550
|
+
}
|
|
4551
|
+
return enumMap;
|
|
3367
4552
|
}
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
const baseUrl = normalizeBaseUrl(options?.baseUrl ?? config.baseUrl);
|
|
3371
|
-
const url = buildRequestUrl(baseUrl, context.endpoint, query);
|
|
3372
|
-
const headers = buildHeaders2(config, options);
|
|
3373
|
-
const credentials = options?.credentials ?? config.credentials ?? "include";
|
|
3374
|
-
const requestInit = {
|
|
3375
|
-
method: context.method,
|
|
3376
|
-
headers,
|
|
3377
|
-
credentials,
|
|
3378
|
-
signal: options?.signal
|
|
3379
|
-
};
|
|
3380
|
-
if (context.method !== "GET") {
|
|
3381
|
-
requestInit.body = JSON.stringify(body ?? {});
|
|
4553
|
+
async queryPrimaryKeys(query) {
|
|
4554
|
+
return this.queryRows(query);
|
|
3382
4555
|
}
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
4556
|
+
async queryForeignKeys(query) {
|
|
4557
|
+
return this.queryRows(query);
|
|
4558
|
+
}
|
|
4559
|
+
};
|
|
4560
|
+
var AthenaGatewayPostgresIntrospectionProvider = class {
|
|
4561
|
+
constructor(config) {
|
|
4562
|
+
this.config = config;
|
|
4563
|
+
this.client = createClient(this.config.gatewayUrl, this.config.apiKey, {
|
|
4564
|
+
backend: {
|
|
4565
|
+
type: this.config.backend ?? "postgresql"
|
|
4566
|
+
}
|
|
3392
4567
|
});
|
|
4568
|
+
this.schemas = normalizeSchemaSelection(this.config.schemas);
|
|
4569
|
+
}
|
|
4570
|
+
backend = "postgresql";
|
|
4571
|
+
client;
|
|
4572
|
+
schemas;
|
|
4573
|
+
async inspect(options) {
|
|
4574
|
+
const schemas = options?.schemas && options.schemas.length > 0 ? normalizeSchemaSelection(options.schemas) : this.schemas;
|
|
4575
|
+
const catalogClient = new AthenaGatewayCatalogClient(this.client);
|
|
4576
|
+
const queries = buildGatewayCatalogQueries(schemas);
|
|
4577
|
+
const [columnRows, enumMap, primaryKeyRows, foreignKeyRows] = await Promise.all([
|
|
4578
|
+
catalogClient.queryColumns(queries.columns),
|
|
4579
|
+
catalogClient.queryEnums(queries.enums),
|
|
4580
|
+
catalogClient.queryPrimaryKeys(queries.primaryKeys),
|
|
4581
|
+
catalogClient.queryForeignKeys(queries.foreignKeys)
|
|
4582
|
+
]);
|
|
4583
|
+
const assembler = new PostgresCatalogSnapshotAssembler();
|
|
4584
|
+
assembler.addColumnRows(columnRows, enumMap);
|
|
4585
|
+
assembler.addPrimaryKeyRows(primaryKeyRows);
|
|
4586
|
+
assembler.addForeignKeyRows(foreignKeyRows);
|
|
4587
|
+
assembler.addManyToManyRows(foreignKeyRows);
|
|
3393
4588
|
return {
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
errorDetails: details,
|
|
3399
|
-
raw: null
|
|
4589
|
+
backend: "postgresql",
|
|
4590
|
+
database: this.config.database,
|
|
4591
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4592
|
+
schemas: assembler.toSchemas()
|
|
3400
4593
|
};
|
|
3401
4594
|
}
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
`Auth endpoint ${context.method} ${context.endpoint} failed with status ${response.status}`
|
|
3434
|
-
),
|
|
3435
|
-
status: response.status,
|
|
3436
|
-
endpoint: context.endpoint,
|
|
3437
|
-
method: context.method,
|
|
3438
|
-
requestId
|
|
3439
|
-
});
|
|
3440
|
-
return {
|
|
3441
|
-
ok: false,
|
|
3442
|
-
status: response.status,
|
|
3443
|
-
data: null,
|
|
3444
|
-
error: details.message,
|
|
3445
|
-
errorDetails: details,
|
|
3446
|
-
raw: parsed
|
|
3447
|
-
};
|
|
4595
|
+
};
|
|
4596
|
+
var ScyllaIntrospectionProvider = class {
|
|
4597
|
+
constructor(config) {
|
|
4598
|
+
this.config = config;
|
|
4599
|
+
}
|
|
4600
|
+
backend = "scylladb";
|
|
4601
|
+
async inspect() {
|
|
4602
|
+
throw new Error(
|
|
4603
|
+
`Scylla introspection provider is not implemented yet for keyspace ${this.config.keyspace}.`
|
|
4604
|
+
);
|
|
4605
|
+
}
|
|
4606
|
+
};
|
|
4607
|
+
function createPostgresProvider(config) {
|
|
4608
|
+
return createPostgresIntrospectionProvider({
|
|
4609
|
+
connectionString: config.connectionString,
|
|
4610
|
+
database: config.database,
|
|
4611
|
+
schemas: normalizeSchemaSelection(config.schemas)
|
|
4612
|
+
});
|
|
4613
|
+
}
|
|
4614
|
+
function resolveGeneratorProvider(providerConfig, experimentalFlags) {
|
|
4615
|
+
if (providerConfig.kind === "postgres" && providerConfig.mode === "direct") {
|
|
4616
|
+
return createPostgresProvider(providerConfig);
|
|
4617
|
+
}
|
|
4618
|
+
if (providerConfig.kind === "postgres" && providerConfig.mode === "gateway") {
|
|
4619
|
+
return new AthenaGatewayPostgresIntrospectionProvider(providerConfig);
|
|
4620
|
+
}
|
|
4621
|
+
if (providerConfig.kind === "scylla") {
|
|
4622
|
+
if (!experimentalFlags.scyllaProviderContracts) {
|
|
4623
|
+
throw new Error(
|
|
4624
|
+
"Scylla provider contracts are disabled. Set experimental.scyllaProviderContracts=true to enable placeholders."
|
|
4625
|
+
);
|
|
3448
4626
|
}
|
|
3449
|
-
return
|
|
3450
|
-
ok: true,
|
|
3451
|
-
status: response.status,
|
|
3452
|
-
data: parsed ?? null,
|
|
3453
|
-
error: null,
|
|
3454
|
-
errorDetails: null,
|
|
3455
|
-
raw: parsed
|
|
3456
|
-
};
|
|
3457
|
-
} catch (callError) {
|
|
3458
|
-
const message = callError instanceof Error ? callError.message : String(callError);
|
|
3459
|
-
const details = toErrorDetails({
|
|
3460
|
-
code: "NETWORK_ERROR",
|
|
3461
|
-
message: `Network error while calling ${context.method} ${context.endpoint}: ${message}`,
|
|
3462
|
-
status: 0,
|
|
3463
|
-
endpoint: context.endpoint,
|
|
3464
|
-
method: context.method,
|
|
3465
|
-
cause: message,
|
|
3466
|
-
hint: "Check auth server URL, DNS, and network reachability."
|
|
3467
|
-
});
|
|
3468
|
-
return {
|
|
3469
|
-
ok: false,
|
|
3470
|
-
status: 0,
|
|
3471
|
-
data: null,
|
|
3472
|
-
error: details.message,
|
|
3473
|
-
errorDetails: details,
|
|
3474
|
-
raw: null
|
|
3475
|
-
};
|
|
4627
|
+
return new ScyllaIntrospectionProvider(providerConfig);
|
|
3476
4628
|
}
|
|
4629
|
+
throw new Error(`Unsupported generator provider kind: ${providerConfig.kind ?? "unknown"}`);
|
|
3477
4630
|
}
|
|
3478
|
-
function
|
|
3479
|
-
const
|
|
3480
|
-
const
|
|
3481
|
-
|
|
3482
|
-
}
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
return
|
|
3487
|
-
}
|
|
3488
|
-
function executeGetWithCompatibleInput(config, context, input, options) {
|
|
3489
|
-
const { fetchOptions } = extractFetchOptions(input);
|
|
3490
|
-
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
3491
|
-
return callAuthEndpoint(config, context, void 0, void 0, mergedOptions);
|
|
4631
|
+
async function writeArtifacts(files, cwd) {
|
|
4632
|
+
const writtenFiles = [];
|
|
4633
|
+
for (const file of files) {
|
|
4634
|
+
const absolutePath = resolve(cwd, file.path);
|
|
4635
|
+
await mkdir(dirname(absolutePath), { recursive: true });
|
|
4636
|
+
await writeFile(absolutePath, file.content, "utf8");
|
|
4637
|
+
writtenFiles.push(file.path);
|
|
4638
|
+
}
|
|
4639
|
+
return writtenFiles;
|
|
3492
4640
|
}
|
|
3493
|
-
function
|
|
3494
|
-
const
|
|
3495
|
-
const
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
};
|
|
3499
|
-
const request = (input, options) => {
|
|
3500
|
-
const method = input.method ?? (input.body !== void 0 ? "POST" : inferDefaultMethod(input.endpoint));
|
|
3501
|
-
const mergedOptions = mergeCallOptions(input.fetchOptions, options);
|
|
3502
|
-
return callAuthEndpoint(
|
|
3503
|
-
resolvedConfig,
|
|
3504
|
-
{ endpoint: input.endpoint, method },
|
|
3505
|
-
input.body,
|
|
3506
|
-
input.query,
|
|
3507
|
-
mergedOptions
|
|
3508
|
-
);
|
|
3509
|
-
};
|
|
3510
|
-
const signOut = (input, options) => executePostWithOptionalInput(
|
|
3511
|
-
resolvedConfig,
|
|
3512
|
-
{ endpoint: "/sign-out", method: "POST" },
|
|
3513
|
-
input,
|
|
3514
|
-
options
|
|
3515
|
-
);
|
|
3516
|
-
const revokeSessions = (input, options) => executePostWithOptionalInput(
|
|
3517
|
-
resolvedConfig,
|
|
3518
|
-
{ endpoint: "/revoke-sessions", method: "POST" },
|
|
3519
|
-
input,
|
|
3520
|
-
options
|
|
3521
|
-
);
|
|
3522
|
-
const revokeOtherSessions = (input, options) => executePostWithOptionalInput(
|
|
3523
|
-
resolvedConfig,
|
|
3524
|
-
{ endpoint: "/revoke-other-sessions", method: "POST" },
|
|
3525
|
-
input,
|
|
3526
|
-
options
|
|
3527
|
-
);
|
|
3528
|
-
const revokeSession = (input, options) => executePostWithCompatibleInput(
|
|
3529
|
-
resolvedConfig,
|
|
3530
|
-
{ endpoint: "/revoke-session", method: "POST" },
|
|
3531
|
-
input,
|
|
3532
|
-
options
|
|
3533
|
-
);
|
|
3534
|
-
const deleteUser = (input, options) => {
|
|
3535
|
-
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
3536
|
-
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
3537
|
-
return callAuthEndpoint(
|
|
3538
|
-
resolvedConfig,
|
|
3539
|
-
{ endpoint: "/delete-user", method: "POST" },
|
|
3540
|
-
payload ?? {},
|
|
3541
|
-
void 0,
|
|
3542
|
-
mergedOptions
|
|
3543
|
-
);
|
|
3544
|
-
};
|
|
3545
|
-
const deleteUserCallback = (input, options) => {
|
|
3546
|
-
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
3547
|
-
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
3548
|
-
const query = payload ?? {};
|
|
3549
|
-
return callAuthEndpoint(
|
|
3550
|
-
resolvedConfig,
|
|
3551
|
-
{ endpoint: "/delete-user/callback", method: "GET" },
|
|
3552
|
-
void 0,
|
|
3553
|
-
{
|
|
3554
|
-
token: query.token,
|
|
3555
|
-
callbackURL: query.callbackURL
|
|
3556
|
-
},
|
|
3557
|
-
mergedOptions
|
|
3558
|
-
);
|
|
3559
|
-
};
|
|
3560
|
-
const resolveResetPasswordToken = (input, options) => {
|
|
3561
|
-
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
3562
|
-
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
3563
|
-
const query = payload;
|
|
3564
|
-
const token = query?.token?.trim();
|
|
3565
|
-
if (!token) {
|
|
3566
|
-
throw new Error("resolveResetPasswordToken requires a non-empty token");
|
|
3567
|
-
}
|
|
3568
|
-
const endpoint = `/reset-password/${encodeURIComponent(token)}`;
|
|
3569
|
-
return callAuthEndpoint(
|
|
3570
|
-
resolvedConfig,
|
|
3571
|
-
{ endpoint, method: "GET" },
|
|
3572
|
-
void 0,
|
|
3573
|
-
query?.callbackURL ? { callbackURL: query.callbackURL } : void 0,
|
|
3574
|
-
mergedOptions
|
|
3575
|
-
);
|
|
4641
|
+
async function runSchemaGenerator(options = {}) {
|
|
4642
|
+
const cwd = options.cwd ?? process.cwd();
|
|
4643
|
+
const configOptions = {
|
|
4644
|
+
cwd,
|
|
4645
|
+
configPath: options.configPath
|
|
3576
4646
|
};
|
|
4647
|
+
const { configPath, config } = await loadGeneratorConfig(configOptions);
|
|
4648
|
+
const provider = options.provider ?? resolveGeneratorProvider(config.provider, config.experimental);
|
|
4649
|
+
const snapshot = await provider.inspect({
|
|
4650
|
+
schemas: resolveProviderSchemas(config.provider)
|
|
4651
|
+
});
|
|
4652
|
+
const generated = generateArtifactsFromSnapshot(snapshot, config);
|
|
4653
|
+
const writtenFiles = options.dryRun ? [] : await writeArtifacts(generated.files, cwd);
|
|
3577
4654
|
return {
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
email: (input, options) => executePostWithCompatibleInput(
|
|
3582
|
-
resolvedConfig,
|
|
3583
|
-
{ endpoint: "/sign-in/email", method: "POST" },
|
|
3584
|
-
input,
|
|
3585
|
-
options
|
|
3586
|
-
),
|
|
3587
|
-
username: (input, options) => executePostWithCompatibleInput(
|
|
3588
|
-
resolvedConfig,
|
|
3589
|
-
{ endpoint: "/sign-in/username", method: "POST" },
|
|
3590
|
-
input,
|
|
3591
|
-
options
|
|
3592
|
-
),
|
|
3593
|
-
social: (input, options) => executePostWithCompatibleInput(
|
|
3594
|
-
resolvedConfig,
|
|
3595
|
-
{ endpoint: "/sign-in/social", method: "POST" },
|
|
3596
|
-
input,
|
|
3597
|
-
options
|
|
3598
|
-
)
|
|
3599
|
-
},
|
|
3600
|
-
signUp: {
|
|
3601
|
-
email: (input, options) => executePostWithCompatibleInput(
|
|
3602
|
-
resolvedConfig,
|
|
3603
|
-
{ endpoint: "/sign-up/email", method: "POST" },
|
|
3604
|
-
input,
|
|
3605
|
-
options
|
|
3606
|
-
)
|
|
3607
|
-
},
|
|
3608
|
-
signOut,
|
|
3609
|
-
logout: signOut,
|
|
3610
|
-
getSession: (input, options) => executeGetWithCompatibleInput(
|
|
3611
|
-
resolvedConfig,
|
|
3612
|
-
{ endpoint: "/get-session", method: "GET" },
|
|
3613
|
-
input,
|
|
3614
|
-
options
|
|
3615
|
-
),
|
|
3616
|
-
listSessions: (input, options) => executeGetWithCompatibleInput(
|
|
3617
|
-
resolvedConfig,
|
|
3618
|
-
{ endpoint: "/list-sessions", method: "GET" },
|
|
3619
|
-
input,
|
|
3620
|
-
options
|
|
3621
|
-
),
|
|
3622
|
-
revokeSession,
|
|
3623
|
-
clearSession: revokeSession,
|
|
3624
|
-
revokeSessions,
|
|
3625
|
-
clearSessions: revokeSessions,
|
|
3626
|
-
revokeOtherSessions,
|
|
3627
|
-
clearOtherSessions: revokeOtherSessions,
|
|
3628
|
-
forgetPassword: (input, options) => executePostWithCompatibleInput(
|
|
3629
|
-
resolvedConfig,
|
|
3630
|
-
{ endpoint: "/forget-password", method: "POST" },
|
|
3631
|
-
input,
|
|
3632
|
-
options
|
|
3633
|
-
),
|
|
3634
|
-
resetPassword: (input, options) => executePostWithCompatibleInput(
|
|
3635
|
-
resolvedConfig,
|
|
3636
|
-
{ endpoint: "/reset-password", method: "POST" },
|
|
3637
|
-
input,
|
|
3638
|
-
options
|
|
3639
|
-
),
|
|
3640
|
-
resolveResetPasswordToken,
|
|
3641
|
-
verifyEmail: (input, options) => {
|
|
3642
|
-
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
3643
|
-
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
3644
|
-
const query = payload;
|
|
3645
|
-
return callAuthEndpoint(
|
|
3646
|
-
resolvedConfig,
|
|
3647
|
-
{ endpoint: "/verify-email", method: "GET" },
|
|
3648
|
-
void 0,
|
|
3649
|
-
query ? {
|
|
3650
|
-
token: query.token,
|
|
3651
|
-
callbackURL: query.callbackURL
|
|
3652
|
-
} : void 0,
|
|
3653
|
-
mergedOptions
|
|
3654
|
-
);
|
|
3655
|
-
},
|
|
3656
|
-
sendVerificationEmail: (input, options) => executePostWithCompatibleInput(
|
|
3657
|
-
resolvedConfig,
|
|
3658
|
-
{ endpoint: "/send-verification-email", method: "POST" },
|
|
3659
|
-
input,
|
|
3660
|
-
options
|
|
3661
|
-
),
|
|
3662
|
-
changeEmail: (input, options) => executePostWithCompatibleInput(
|
|
3663
|
-
resolvedConfig,
|
|
3664
|
-
{ endpoint: "/change-email", method: "POST" },
|
|
3665
|
-
input,
|
|
3666
|
-
options
|
|
3667
|
-
),
|
|
3668
|
-
changePassword: (input, options) => executePostWithCompatibleInput(
|
|
3669
|
-
resolvedConfig,
|
|
3670
|
-
{ endpoint: "/change-password", method: "POST" },
|
|
3671
|
-
input,
|
|
3672
|
-
options
|
|
3673
|
-
),
|
|
3674
|
-
updateUser: (input, options) => executePostWithCompatibleInput(
|
|
3675
|
-
resolvedConfig,
|
|
3676
|
-
{ endpoint: "/update-user", method: "POST" },
|
|
3677
|
-
input,
|
|
3678
|
-
options
|
|
3679
|
-
),
|
|
3680
|
-
deleteUser,
|
|
3681
|
-
deleteUserCallback,
|
|
3682
|
-
linkSocial: (input, options) => executePostWithCompatibleInput(
|
|
3683
|
-
resolvedConfig,
|
|
3684
|
-
{ endpoint: "/link-social", method: "POST" },
|
|
3685
|
-
input,
|
|
3686
|
-
options
|
|
3687
|
-
),
|
|
3688
|
-
listAccounts: (input, options) => executeGetWithCompatibleInput(
|
|
3689
|
-
resolvedConfig,
|
|
3690
|
-
{ endpoint: "/list-accounts", method: "GET" },
|
|
3691
|
-
input,
|
|
3692
|
-
options
|
|
3693
|
-
),
|
|
3694
|
-
unlinkAccount: (input, options) => executePostWithCompatibleInput(
|
|
3695
|
-
resolvedConfig,
|
|
3696
|
-
{ endpoint: "/unlink-account", method: "POST" },
|
|
3697
|
-
input,
|
|
3698
|
-
options
|
|
3699
|
-
),
|
|
3700
|
-
refreshToken: (input, options) => executePostWithCompatibleInput(
|
|
3701
|
-
resolvedConfig,
|
|
3702
|
-
{ endpoint: "/refresh-token", method: "POST" },
|
|
3703
|
-
input,
|
|
3704
|
-
options
|
|
3705
|
-
),
|
|
3706
|
-
getAccessToken: (input, options) => executePostWithCompatibleInput(
|
|
3707
|
-
resolvedConfig,
|
|
3708
|
-
{ endpoint: "/get-access-token", method: "POST" },
|
|
3709
|
-
input,
|
|
3710
|
-
options
|
|
3711
|
-
)
|
|
4655
|
+
...generated,
|
|
4656
|
+
configPath,
|
|
4657
|
+
writtenFiles
|
|
3712
4658
|
};
|
|
3713
4659
|
}
|
|
3714
4660
|
|
|
3715
|
-
export { AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, coerceInt, createAuthClient, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createTypedClient, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeGeneratorConfig, normalizeSchemaSelection, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, toModelFormDefaults, toModelPayload, unwrap, unwrapOne, unwrapRows, withRetry };
|
|
4661
|
+
export { AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, coerceInt, createAuthClient, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createTypedClient, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeGeneratorConfig, normalizeSchemaSelection, parseBooleanFlag, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, toModelFormDefaults, toModelPayload, unwrap, unwrapOne, unwrapRows, withRetry };
|
|
3716
4662
|
//# sourceMappingURL=index.js.map
|
|
3717
4663
|
//# sourceMappingURL=index.js.map
|