@xano/sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +788 -0
- package/LICENSE +21 -0
- package/README.md +541 -0
- package/dist/.build-fingerprint +1 -0
- package/dist/agent-file-refresh-ZEMK33AX.js +38 -0
- package/dist/answer-shape-K67TAAPY.js +33 -0
- package/dist/backend-dir-2U53CIAL.js +39 -0
- package/dist/backend-slot-7QXW2QYC.js +28 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +255 -0
- package/dist/branch-NCRNWQBQ.js +61 -0
- package/dist/branch-commands-ACIRCEQJ.js +79 -0
- package/dist/bundle.d.ts +223 -0
- package/dist/bundle.js +153 -0
- package/dist/capture-WAXPD7DR.js +41 -0
- package/dist/chunk-27GWNP2I.js +23 -0
- package/dist/chunk-2CMJZDCL.js +177 -0
- package/dist/chunk-2EZ3ZJZZ.js +302 -0
- package/dist/chunk-2GNFDZA2.js +390 -0
- package/dist/chunk-2MNLRIOX.js +11 -0
- package/dist/chunk-2TFRR6JV.js +104 -0
- package/dist/chunk-2ZUEE4EK.js +408 -0
- package/dist/chunk-36JUQZVQ.js +22 -0
- package/dist/chunk-3DRXWLJ5.js +83 -0
- package/dist/chunk-3JDU4VRL.js +137 -0
- package/dist/chunk-3KZCLN4Z.js +241 -0
- package/dist/chunk-3LDULPRE.js +168 -0
- package/dist/chunk-3M4LFYNQ.js +111 -0
- package/dist/chunk-3XI5CTUE.js +22 -0
- package/dist/chunk-3YW23UFH.js +50 -0
- package/dist/chunk-45UIT5T2.js +862 -0
- package/dist/chunk-4BW2SG2N.js +46 -0
- package/dist/chunk-4KHEMC32.js +79 -0
- package/dist/chunk-4POWHT2K.js +321 -0
- package/dist/chunk-4Q2GN7NW.js +192 -0
- package/dist/chunk-5A2PLKZB.js +70 -0
- package/dist/chunk-5FBYXK5P.js +159 -0
- package/dist/chunk-5HVXPTU4.js +323 -0
- package/dist/chunk-5QU2P5CA.js +304 -0
- package/dist/chunk-5V5XU32D.js +191 -0
- package/dist/chunk-5ZSO4T2G.js +10 -0
- package/dist/chunk-622HUCZT.js +10 -0
- package/dist/chunk-65HWOMGV.js +177 -0
- package/dist/chunk-6ELFRN3P.js +365 -0
- package/dist/chunk-6HO3NCSJ.js +1055 -0
- package/dist/chunk-6IUMKYWI.js +457 -0
- package/dist/chunk-6KEB3C3U.js +65 -0
- package/dist/chunk-6MR5TI5V.js +987 -0
- package/dist/chunk-6NNTNXN7.js +157 -0
- package/dist/chunk-6PBR37LN.js +97 -0
- package/dist/chunk-6QXLMMT3.js +155 -0
- package/dist/chunk-6ZGJCBZS.js +224 -0
- package/dist/chunk-73IVBKMA.js +250 -0
- package/dist/chunk-7G3CTU7I.js +286 -0
- package/dist/chunk-A3UDOZB6.js +222 -0
- package/dist/chunk-A6E77GDW.js +85 -0
- package/dist/chunk-AHJWCYQO.js +660 -0
- package/dist/chunk-AKNCFVKZ.js +36 -0
- package/dist/chunk-AM4FKL4J.js +237 -0
- package/dist/chunk-AN6BL47T.js +26 -0
- package/dist/chunk-AOSYVMUS.js +147 -0
- package/dist/chunk-APWXY5SL.js +182 -0
- package/dist/chunk-AWEIIR2U.js +218 -0
- package/dist/chunk-AWQ7BQTQ.js +73 -0
- package/dist/chunk-BAUZOWGX.js +393 -0
- package/dist/chunk-BHACRS6R.js +940 -0
- package/dist/chunk-BWPNT55T.js +680 -0
- package/dist/chunk-C6RIMRU4.js +187 -0
- package/dist/chunk-CGVQZXYG.js +263 -0
- package/dist/chunk-CIMQZRRE.js +162 -0
- package/dist/chunk-CJHQKJU4.js +113 -0
- package/dist/chunk-CTMO46PK.js +1897 -0
- package/dist/chunk-D53J55C5.js +106 -0
- package/dist/chunk-D7VGG3WS.js +90 -0
- package/dist/chunk-DAD3ONIS.js +245 -0
- package/dist/chunk-DGWHAVRG.js +162 -0
- package/dist/chunk-DX4QR4B2.js +483 -0
- package/dist/chunk-EHP3WPEG.js +21 -0
- package/dist/chunk-ELP2HMXC.js +432 -0
- package/dist/chunk-ERVIASGL.js +21 -0
- package/dist/chunk-ET4Y4XCB.js +865 -0
- package/dist/chunk-ETO6LGLD.js +4750 -0
- package/dist/chunk-EUUUMY7J.js +24 -0
- package/dist/chunk-FQJ2TTHP.js +218 -0
- package/dist/chunk-FQOF7E2E.js +133 -0
- package/dist/chunk-FWD7AL6N.js +21 -0
- package/dist/chunk-FXFV3KU6.js +138 -0
- package/dist/chunk-FXRQOWTE.js +171 -0
- package/dist/chunk-G554NZNI.js +210 -0
- package/dist/chunk-GSGDWJB5.js +13 -0
- package/dist/chunk-H2V3N23D.js +66 -0
- package/dist/chunk-H5C7MBCR.js +159 -0
- package/dist/chunk-HHN734BU.js +371 -0
- package/dist/chunk-HRVBLCVJ.js +243 -0
- package/dist/chunk-HVRUQXGD.js +1264 -0
- package/dist/chunk-I4F5TCJH.js +130 -0
- package/dist/chunk-IDOTCMDV.js +57 -0
- package/dist/chunk-IGOLHKWF.js +427 -0
- package/dist/chunk-JGE7CAWB.js +148 -0
- package/dist/chunk-JTUKLCXS.js +92 -0
- package/dist/chunk-JZGVVJSI.js +66 -0
- package/dist/chunk-K4WX6UUU.js +923 -0
- package/dist/chunk-K5BBGTYZ.js +217 -0
- package/dist/chunk-K6RXBGUB.js +427 -0
- package/dist/chunk-KTSDSD36.js +165 -0
- package/dist/chunk-L5JYN3NM.js +1038 -0
- package/dist/chunk-LIEOKXKD.js +354 -0
- package/dist/chunk-LLNZGEFK.js +51 -0
- package/dist/chunk-LPECSJ2J.js +55 -0
- package/dist/chunk-LQCMKAJ7.js +413 -0
- package/dist/chunk-LRN4ZJCQ.js +1145 -0
- package/dist/chunk-MJ4ZVHKN.js +17 -0
- package/dist/chunk-MXHSQOC4.js +3061 -0
- package/dist/chunk-N5GKCWE5.js +367 -0
- package/dist/chunk-NA3PXMEF.js +10 -0
- package/dist/chunk-NAQDMEHV.js +76 -0
- package/dist/chunk-NWKXM5RD.js +109 -0
- package/dist/chunk-NZOWWHU5.js +196 -0
- package/dist/chunk-OHX6MIUZ.js +184 -0
- package/dist/chunk-OOXWYAA4.js +15 -0
- package/dist/chunk-OPHB5ORL.js +1990 -0
- package/dist/chunk-OXA6PSZT.js +1725 -0
- package/dist/chunk-P2HAGF6H.js +73 -0
- package/dist/chunk-PTHVMXZI.js +3036 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-Q325JKYB.js +189 -0
- package/dist/chunk-Q7DGTQ5G.js +255 -0
- package/dist/chunk-QCNYHBL7.js +601 -0
- package/dist/chunk-QO6BVGS5.js +145 -0
- package/dist/chunk-QXTKSOFI.js +76 -0
- package/dist/chunk-ROY4YAEQ.js +66 -0
- package/dist/chunk-RTJRZFFY.js +447 -0
- package/dist/chunk-SAVJUS2X.js +128 -0
- package/dist/chunk-SFLHVCKX.js +173 -0
- package/dist/chunk-STSFNCY4.js +127 -0
- package/dist/chunk-SWBF2LTK.js +170 -0
- package/dist/chunk-T5KELPAR.js +109 -0
- package/dist/chunk-TFFGOFVZ.js +1481 -0
- package/dist/chunk-TLHIFK4M.js +256 -0
- package/dist/chunk-TLQE7ZN3.js +156 -0
- package/dist/chunk-TPHWJ7UG.js +1981 -0
- package/dist/chunk-TRJCALW3.js +291 -0
- package/dist/chunk-TTEIYD5P.js +133 -0
- package/dist/chunk-U64O2MXY.js +407 -0
- package/dist/chunk-UCQ2VUTG.js +630 -0
- package/dist/chunk-UTI5G6OJ.js +44 -0
- package/dist/chunk-UVHDMMIP.js +188 -0
- package/dist/chunk-UZ6QQWJT.js +120 -0
- package/dist/chunk-VAX3UZOY.js +686 -0
- package/dist/chunk-W3HBUKFO.js +57 -0
- package/dist/chunk-WKQLGKCL.js +2823 -0
- package/dist/chunk-WQFNASK4.js +560 -0
- package/dist/chunk-WRBKLYSJ.js +224 -0
- package/dist/chunk-WTPZRR4I.js +17 -0
- package/dist/chunk-WZDJ2LLX.js +2385 -0
- package/dist/chunk-X2NL4KUO.js +14 -0
- package/dist/chunk-X4DVXBFY.js +38 -0
- package/dist/chunk-X677DMZM.js +7050 -0
- package/dist/chunk-XBKMWY7F.js +612 -0
- package/dist/chunk-XNCP4KYO.js +78 -0
- package/dist/chunk-XVBGLISP.js +35 -0
- package/dist/chunk-XW6KISBB.js +1192 -0
- package/dist/chunk-YGZHHAAB.js +8156 -0
- package/dist/chunk-YHEFQUQB.js +186 -0
- package/dist/chunk-YLDALTWZ.js +653 -0
- package/dist/chunk-YU4HSQW7.js +229 -0
- package/dist/chunk-ZDPP6RKB.js +27 -0
- package/dist/chunk-ZFDZKNGG.js +194 -0
- package/dist/chunk-ZIY7RNUT.js +49 -0
- package/dist/chunk-ZYJP6BOO.js +30 -0
- package/dist/cli.d.ts +1111 -0
- package/dist/cli.js +165 -0
- package/dist/codegen-command-VR2GWR6C.js +173 -0
- package/dist/codegen.d.ts +115 -0
- package/dist/codegen.js +19 -0
- package/dist/commands-GJMJ4XYZ.js +76 -0
- package/dist/completion-ZQLO6PB6.js +738 -0
- package/dist/config-MBYGCAFK.js +136 -0
- package/dist/deploy-command-JVZPWHMK.js +180 -0
- package/dist/deploy-source-3W45CXMP.js +81 -0
- package/dist/dev-env-sync-HN44K4D5.js +188 -0
- package/dist/diagnostics-UEAAHWVF.js +30 -0
- package/dist/display-name-hint-ABBPVQIR.js +46 -0
- package/dist/emit-CyhBDxli.d.ts +7007 -0
- package/dist/env-example-refresh-ET5HMMDW.js +126 -0
- package/dist/env-pull-command-TNMNB3CV.js +323 -0
- package/dist/env-target-O4HRKTGZ.js +40 -0
- package/dist/env-var-command-ZIRDCAZA.js +427 -0
- package/dist/ephemeral-P7F3PMAD.js +54 -0
- package/dist/ephemeral-command-CLJJKOFT.js +592 -0
- package/dist/ephemeral-state-PYCBSOGX.js +61 -0
- package/dist/file-lock-PT74GWYW.js +10 -0
- package/dist/generate-command-AYEOLA26.js +510 -0
- package/dist/gitignore-3SJ3WNRG.js +51 -0
- package/dist/guards-4EBNCZDC.js +162 -0
- package/dist/hosted-file-PSHJB3HX.js +28 -0
- package/dist/impersonate-command-5JAS3WSV.js +152 -0
- package/dist/import-EQSFU6JC.js +19 -0
- package/dist/index.d.ts +5470 -0
- package/dist/index.js +371 -0
- package/dist/init-command-X2FR4UAK.js +125 -0
- package/dist/init-modules-RY7UHAOL.js +50 -0
- package/dist/init-web-M4YZSZK6.js +42 -0
- package/dist/internal.d.ts +179 -0
- package/dist/internal.js +2634 -0
- package/dist/io-RC56QSN5.js +26 -0
- package/dist/keep-data-merge-7MPLVAVI.js +1119 -0
- package/dist/lambda-config-reconcile-OUZ4OYAB.js +116 -0
- package/dist/landed-753YLJ5H.js +40 -0
- package/dist/landing-record-SU52SKXU.js +61 -0
- package/dist/live-diff-YONW2VI3.js +65 -0
- package/dist/local-engine-choice-CH5X3W7E.js +79 -0
- package/dist/local-engine-command-Z3OL7VOD.js +766 -0
- package/dist/local-engine-config-5U3SC434.js +39 -0
- package/dist/local-engine-deploy-PCQ4SNPB.js +39 -0
- package/dist/local-engine-process-EHTE5LLU.js +63 -0
- package/dist/local-engine-state-A4FTRFAF.js +32 -0
- package/dist/local-engine-update-check-6L645VBL.js +162 -0
- package/dist/lock-MRRHW5GS.js +87 -0
- package/dist/lock-commands-2QG25HL7.js +963 -0
- package/dist/login-command-QPYRWOXZ.js +538 -0
- package/dist/logout-command-WOIQLDP6.js +56 -0
- package/dist/loop-ALIZLOSX.js +191 -0
- package/dist/marketplace-command-K5YL42NO.js +977 -0
- package/dist/marketplace-resolve-LY32JES5.js +40 -0
- package/dist/meta-client-YXGPW53C.js +244 -0
- package/dist/module-manifest-JFGHU2TC.js +38 -0
- package/dist/near-key.d.ts +13 -0
- package/dist/near-key.js +8 -0
- package/dist/node.d.ts +95 -0
- package/dist/node.js +969 -0
- package/dist/operation-outcome-TZSESNC7.js +51 -0
- package/dist/output-target-AL3I44GG.js +47 -0
- package/dist/package-manager-PRAHUSCN.js +34 -0
- package/dist/plan-disclosure-6G4MLZKD.js +114 -0
- package/dist/plugin-contributions-WRNY5ABG.js +28 -0
- package/dist/plugin-prompt-4VA3B4FF.js +20 -0
- package/dist/plugin-questions-JTSYA74Q.js +24 -0
- package/dist/plugin.d.ts +396 -0
- package/dist/plugin.js +1 -0
- package/dist/preflight-command-2T5Z36MI.js +321 -0
- package/dist/profile-command-AH3PIM4X.js +800 -0
- package/dist/profile-pointer-GRWJU3YD.js +31 -0
- package/dist/profile-select-74TRDEPD.js +23 -0
- package/dist/project-dependency-KSH63ODT.js +35 -0
- package/dist/project-sdk-REPPOIBD.js +24 -0
- package/dist/promote-command-PCWT5N6S.js +140 -0
- package/dist/prompt-II3F3LND.js +27 -0
- package/dist/publish-command-TTDUUJI5.js +414 -0
- package/dist/pull-command-VBO7C4S3.js +161 -0
- package/dist/pull-superseded-GJWLG7XO.js +20 -0
- package/dist/release-command-N4ZPKMHR.js +146 -0
- package/dist/release-ns-command-3KFDMZ6G.js +1745 -0
- package/dist/response-HlXahv4K.d.ts +925 -0
- package/dist/retry-command-AS5EVREX.js +34 -0
- package/dist/routes-manifest-SNWUVBT6.js +43 -0
- package/dist/runtime-XETHVF33.js +14 -0
- package/dist/scaffold.d.ts +1911 -0
- package/dist/scaffold.js +107 -0
- package/dist/secrets-file-LVZD6IIM.js +56 -0
- package/dist/secrets-fill-command-TTCPSVXN.js +218 -0
- package/dist/seed-VU7C3QYS.js +46 -0
- package/dist/sent-writes-N7X4OVXT.js +22 -0
- package/dist/source-resolve-S2XA3XZF.js +83 -0
- package/dist/static-host-B2Y6AG3W.js +352 -0
- package/dist/status-command-RUDXTF7I.js +554 -0
- package/dist/store-6VNCD4D7.js +20 -0
- package/dist/store-ARM6VMO5.js +98 -0
- package/dist/store-DuYfzKlW.d.ts +3144 -0
- package/dist/suggest-6FOOYKHG.js +12 -0
- package/dist/sveltekit.d.ts +154 -0
- package/dist/sveltekit.js +109 -0
- package/dist/sync-contributions-UCEROO26.js +415 -0
- package/dist/table-ENAVMITR.js +42 -0
- package/dist/tables-command-GUPXXSB5.js +156 -0
- package/dist/tenant-IIHPOHGP.js +42 -0
- package/dist/tenant-command-D5HGI2X4.js +965 -0
- package/dist/test-command-TIKZMDPZ.js +476 -0
- package/dist/tests-BGGIOK3L.js +26 -0
- package/dist/token-NICJUTMT.js +72 -0
- package/dist/toolchain-hooks-GHKLUJOH.js +96 -0
- package/dist/toolchain-modules-5EAZUONB.js +24 -0
- package/dist/tracked-backend-EIBUMDZA.js +80 -0
- package/dist/update-check-2W2NLDTC.js +136 -0
- package/dist/upgrade-command-QHNFWM7O.js +531 -0
- package/dist/verify-rollout-DRCK5TDD.js +61 -0
- package/dist/whoami-command-STGINTXH.js +51 -0
- package/dist/workspace-2CLHU2LK.js +93 -0
- package/dist/workspace-binding-56PIIPCP.js +54 -0
- package/dist/workspace-command-JEXQETJD.js +535 -0
- package/dist/workspace-env-F2RFMSC5.js +70 -0
- package/dist/workspace-export-OJSH2HIW.js +21 -0
- package/dist/writable-VA7OISSK.js +25 -0
- package/dist/xano-ICFUSPFR.js +42 -0
- package/dist/xanosdk-import-GN42TO2B.js +56 -0
- package/dist/xanosdk-project-S6DXJONQ.js +41 -0
- package/dist/xdo-CxDr2Q1C.d.ts +1371 -0
- package/guides/README.md +33 -0
- package/guides/authoring.md +921 -0
- package/guides/cli.md +401 -0
- package/guides/codegen.md +177 -0
- package/guides/codes.md +404 -0
- package/guides/coverage.md +74 -0
- package/guides/deploying.md +1525 -0
- package/guides/environment.md +400 -0
- package/guides/marketplace.md +415 -0
- package/guides/module-contract.md +558 -0
- package/guides/object-kinds.md +433 -0
- package/guides/project-structure.md +43 -0
- package/guides/scaffold.md +351 -0
- package/guides/typed-frontend.md +242 -0
- package/llms/client.md +63 -0
- package/llms/errors.md +56 -0
- package/llms/fields.md +176 -0
- package/llms/filters.md +183 -0
- package/llms/kinds-agent-mcp.md +30 -0
- package/llms/kinds-core.md +100 -0
- package/llms/kinds-knowledge.md +20 -0
- package/llms/kinds-realtime.md +76 -0
- package/llms/lambda.md +94 -0
- package/llms/legacy.md +44 -0
- package/llms/lock.md +40 -0
- package/llms/object-kinds.md +34 -0
- package/llms/statements-calls.md +62 -0
- package/llms/statements-catalog.md +320 -0
- package/llms/statements-data.md +66 -0
- package/llms/statements-runtime.md +68 -0
- package/llms/tests.md +59 -0
- package/llms/toolchain.md +16 -0
- package/llms/triggers.md +36 -0
- package/llms/values.md +29 -0
- package/llms-full.txt +2085 -0
- package/llms.txt +493 -0
- package/manifest.json +11224 -0
- package/package.json +162 -0
- package/types/lambda-globals.d.ts +129 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hasString,
|
|
3
|
+
isRecord,
|
|
4
|
+
listAnswer,
|
|
5
|
+
recordAnswer,
|
|
6
|
+
writeTransportFailure
|
|
7
|
+
} from "./chunk-6PBR37LN.js";
|
|
8
|
+
import {
|
|
9
|
+
appendSentence,
|
|
10
|
+
fetchOrExplain,
|
|
11
|
+
httpFailure,
|
|
12
|
+
serverMessage,
|
|
13
|
+
statusLabel,
|
|
14
|
+
transportTarget
|
|
15
|
+
} from "./chunk-YLDALTWZ.js";
|
|
16
|
+
|
|
17
|
+
// src/deploy/tests.ts
|
|
18
|
+
function labelledMessage(text) {
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(text);
|
|
22
|
+
} catch {
|
|
23
|
+
return void 0;
|
|
24
|
+
}
|
|
25
|
+
if (!isRecord(parsed) || typeof parsed.message !== "string" || parsed.message.trim() === "") return void 0;
|
|
26
|
+
return serverMessage(text);
|
|
27
|
+
}
|
|
28
|
+
var PERMANENT_CODES = /* @__PURE__ */ new Set([
|
|
29
|
+
"ERROR_CODE_NOT_FOUND",
|
|
30
|
+
"ERROR_CODE_ACCESS_DENIED",
|
|
31
|
+
"ERROR_CODE_UNAUTHORIZED",
|
|
32
|
+
"ERROR_CODE_BAD_REQUEST",
|
|
33
|
+
"ERROR_CODE_INPUT_ERROR",
|
|
34
|
+
"ERROR_CODE_PERMISSION_DENIED"
|
|
35
|
+
]);
|
|
36
|
+
function permanentEngineError(text) {
|
|
37
|
+
let parsed;
|
|
38
|
+
try {
|
|
39
|
+
parsed = JSON.parse(text);
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (!isRecord(parsed)) return false;
|
|
44
|
+
if (typeof parsed.code === "string" && PERMANENT_CODES.has(parsed.code)) return true;
|
|
45
|
+
const message = typeof parsed.message === "string" ? parsed.message : "";
|
|
46
|
+
return /^\s*invalid\b|\bnot found\b|\baccess denied\b|\bpermission denied\b|\bunauthori[sz]ed\b/i.test(message);
|
|
47
|
+
}
|
|
48
|
+
var TIMEOUT_MS = 12e4;
|
|
49
|
+
var PAGE_SIZE = 100;
|
|
50
|
+
var MAX_PAGES = 100;
|
|
51
|
+
function qualifiedName(handle) {
|
|
52
|
+
if (handle.kind === "workflow") return `workflow:${handle.name}`;
|
|
53
|
+
const object = handle.object;
|
|
54
|
+
if (object === void 0) return handle.name;
|
|
55
|
+
const owner = object.type === "query" && object.group !== void 0 && object.verb !== void 0 ? `${object.group}|${object.verb}|${object.name}` : object.name;
|
|
56
|
+
return `${object.type}:${owner}/${handle.name}`;
|
|
57
|
+
}
|
|
58
|
+
function objectQualifiedName(handle) {
|
|
59
|
+
return handle.object === void 0 ? void 0 : `${handle.object.type}:${handle.object.name}/${handle.name}`;
|
|
60
|
+
}
|
|
61
|
+
function asString(v) {
|
|
62
|
+
return typeof v === "string" && v !== "" ? v : void 0;
|
|
63
|
+
}
|
|
64
|
+
async function metaFetch(auth, url, action, init) {
|
|
65
|
+
return fetchOrExplain(
|
|
66
|
+
url,
|
|
67
|
+
{
|
|
68
|
+
...init,
|
|
69
|
+
headers: {
|
|
70
|
+
accept: "application/json",
|
|
71
|
+
Authorization: `Bearer ${auth.access_token}`,
|
|
72
|
+
...init?.headers ?? {}
|
|
73
|
+
},
|
|
74
|
+
signal: AbortSignal.timeout(TIMEOUT_MS)
|
|
75
|
+
},
|
|
76
|
+
action,
|
|
77
|
+
TIMEOUT_MS
|
|
78
|
+
).catch((err) => {
|
|
79
|
+
throw (init?.method ?? "GET").toUpperCase() !== "GET" ? writeTransportFailure(err) : err;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function readPage(text, action, url, isRow) {
|
|
83
|
+
const { rows, envelope } = listAnswer(text, action, url, isRow);
|
|
84
|
+
return { rows, nextPage: typeof envelope?.nextPage === "number" ? envelope.nextPage : void 0 };
|
|
85
|
+
}
|
|
86
|
+
async function collectPages(auth, buildUrl, action, isRow, onTruncate) {
|
|
87
|
+
const rows = [];
|
|
88
|
+
for (let page = 1; page <= MAX_PAGES; page++) {
|
|
89
|
+
const url = buildUrl(page);
|
|
90
|
+
const res = await metaFetch(auth, url, action, { method: "GET" });
|
|
91
|
+
const text = await res.text();
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
const message = httpFailure(action, res, text);
|
|
94
|
+
const unanswered = res.status >= 500 && !permanentEngineError(text) || res.status === 429;
|
|
95
|
+
throw unanswered ? new TestRunUnansweredError(message, res.status) : new Error(message);
|
|
96
|
+
}
|
|
97
|
+
const { rows: pageRows, nextPage } = readPage(text, action, url, isRow);
|
|
98
|
+
rows.push(...pageRows);
|
|
99
|
+
if (pageRows.length === 0 || nextPage === void 0) return rows;
|
|
100
|
+
}
|
|
101
|
+
onTruncate?.(rows.length);
|
|
102
|
+
return rows;
|
|
103
|
+
}
|
|
104
|
+
async function listUnitTests(auth, target, onTruncate) {
|
|
105
|
+
const rows = await collectPages(
|
|
106
|
+
auth,
|
|
107
|
+
(page) => `${target.base}/api:meta/workspace/${target.workspaceId}/unit_test?page=${page}&per_page=${PAGE_SIZE}`,
|
|
108
|
+
"list unit tests",
|
|
109
|
+
// A unit test is addressed by its string id and shown by its name.
|
|
110
|
+
(row) => hasString(row, "id") && hasString(row, "name"),
|
|
111
|
+
onTruncate
|
|
112
|
+
);
|
|
113
|
+
const queryIds = new Set(
|
|
114
|
+
rows.flatMap((row) => row.obj_type === "query" && typeof row.obj_id === "number" ? [row.obj_id] : [])
|
|
115
|
+
);
|
|
116
|
+
const located = queryIds.size === 0 ? /* @__PURE__ */ new Map() : await locateQueries(auth, target, queryIds);
|
|
117
|
+
return rows.flatMap((row) => {
|
|
118
|
+
const id = asString(row.id);
|
|
119
|
+
const name = asString(row.name);
|
|
120
|
+
if (id === void 0 || name === void 0) return [];
|
|
121
|
+
const objectType = asString(row.obj_type);
|
|
122
|
+
const objectName = asString(row.obj_name);
|
|
123
|
+
const place = objectType === "query" && typeof row.obj_id === "number" ? located.get(row.obj_id) : void 0;
|
|
124
|
+
return [
|
|
125
|
+
{
|
|
126
|
+
kind: "unit",
|
|
127
|
+
id,
|
|
128
|
+
name,
|
|
129
|
+
object: objectType !== void 0 && objectName !== void 0 ? { type: objectType, name: objectName, ...place ?? {} } : void 0,
|
|
130
|
+
datasource: typeof row.datasource === "string" ? row.datasource : void 0
|
|
131
|
+
}
|
|
132
|
+
];
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async function locateQueries(auth, target, ids) {
|
|
136
|
+
const root = `${target.base}/api:meta/workspace/${target.workspaceId}/apigroup`;
|
|
137
|
+
const groups = await collectPages(
|
|
138
|
+
auth,
|
|
139
|
+
(page) => `${root}?page=${page}&per_page=${PAGE_SIZE}`,
|
|
140
|
+
"list API groups",
|
|
141
|
+
(row) => typeof row.id === "number" && hasString(row, "name")
|
|
142
|
+
);
|
|
143
|
+
const placed = /* @__PURE__ */ new Map();
|
|
144
|
+
for (const group of groups) {
|
|
145
|
+
if (placed.size === ids.size) break;
|
|
146
|
+
const groupName = group.name;
|
|
147
|
+
const queries = await collectPages(
|
|
148
|
+
auth,
|
|
149
|
+
(page) => `${root}/${group.id}/api?page=${page}&per_page=${PAGE_SIZE}`,
|
|
150
|
+
`list the queries in API group "${groupName}"`,
|
|
151
|
+
(row) => typeof row.id === "number" && hasString(row, "verb")
|
|
152
|
+
);
|
|
153
|
+
for (const query of queries) {
|
|
154
|
+
const id = query.id;
|
|
155
|
+
if (ids.has(id)) placed.set(id, { group: groupName, verb: query.verb });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return placed;
|
|
159
|
+
}
|
|
160
|
+
async function listWorkflowTests(auth, target, onTruncate) {
|
|
161
|
+
const rows = await collectPages(
|
|
162
|
+
auth,
|
|
163
|
+
(page) => `${target.base}/api:meta/workspace/${target.workspaceId}/workflow_test?page=${page}&per_page=${PAGE_SIZE}&include_xanoscript=false`,
|
|
164
|
+
"list workflow tests",
|
|
165
|
+
// A workflow test is addressed by its numeric id and shown by its name.
|
|
166
|
+
(row) => typeof row.id === "number" && hasString(row, "name"),
|
|
167
|
+
onTruncate
|
|
168
|
+
);
|
|
169
|
+
return rows.flatMap((row) => {
|
|
170
|
+
const name = asString(row.name);
|
|
171
|
+
if (typeof row.id !== "number" || name === void 0) return [];
|
|
172
|
+
return [
|
|
173
|
+
{
|
|
174
|
+
kind: "workflow",
|
|
175
|
+
id: row.id,
|
|
176
|
+
name,
|
|
177
|
+
datasource: typeof row.datasource === "string" ? row.datasource : void 0
|
|
178
|
+
}
|
|
179
|
+
];
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async function listTests(auth, target, opts = {}) {
|
|
183
|
+
const out = [];
|
|
184
|
+
if (opts.kind !== "workflow") out.push(...await listUnitTests(auth, target, opts.onTruncate));
|
|
185
|
+
if (opts.kind !== "unit") out.push(...await listWorkflowTests(auth, target, opts.onTruncate));
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
function readExpectations(results) {
|
|
189
|
+
if (!Array.isArray(results)) return void 0;
|
|
190
|
+
const expectations = results.flatMap((entry, index) => {
|
|
191
|
+
if (entry === null || typeof entry !== "object") return [];
|
|
192
|
+
const row = entry;
|
|
193
|
+
if (row.status !== "pass" && row.status !== "fail") return [];
|
|
194
|
+
const message = asString(row.message);
|
|
195
|
+
return [{ index, status: row.status, ...row.status === "fail" && message !== void 0 ? { message } : {} }];
|
|
196
|
+
});
|
|
197
|
+
return expectations.length > 0 ? expectations : void 0;
|
|
198
|
+
}
|
|
199
|
+
var TestRunUnansweredError = class extends Error {
|
|
200
|
+
constructor(message, status) {
|
|
201
|
+
super(message);
|
|
202
|
+
this.status = status;
|
|
203
|
+
}
|
|
204
|
+
status;
|
|
205
|
+
name = "TestRunUnansweredError";
|
|
206
|
+
};
|
|
207
|
+
async function runTest(auth, target, handle) {
|
|
208
|
+
const route = handle.kind === "unit" ? "unit_test" : "workflow_test";
|
|
209
|
+
const url = `${target.base}/api:meta/workspace/${target.workspaceId}/${route}/${handle.id}/run`;
|
|
210
|
+
const action = `run ${handle.kind} test "${handle.name}"`;
|
|
211
|
+
const res = await metaFetch(auth, url, action, {
|
|
212
|
+
method: "POST",
|
|
213
|
+
headers: { "Content-Type": "application/json" },
|
|
214
|
+
// The unit-test route reads an optional `{branch}`; Xano SDK models no branch
|
|
215
|
+
// concept, so an empty object takes the engine's live-branch default. The
|
|
216
|
+
// workflow route reads no body at all and ignores this.
|
|
217
|
+
body: "{}"
|
|
218
|
+
});
|
|
219
|
+
const text = await res.text();
|
|
220
|
+
if (!res.ok) {
|
|
221
|
+
if (res.status >= 500 || res.status === 401 || res.status === 403 || res.status === 429 || labelledMessage(text) === void 0) {
|
|
222
|
+
const message = appendSentence(
|
|
223
|
+
httpFailure(action, res, text),
|
|
224
|
+
`Nothing was run to a result \u2014 ${transportTarget(url)} did not report one.`
|
|
225
|
+
);
|
|
226
|
+
throw res.status >= 500 || res.status === 429 ? new TestRunUnansweredError(message, res.status) : new Error(message);
|
|
227
|
+
}
|
|
228
|
+
return { ...handle, status: "fail", message: `${statusLabel(res)}: ${labelledMessage(text)}` };
|
|
229
|
+
}
|
|
230
|
+
const body = recordAnswer(text, action, url, (row) => typeof row.status === "string");
|
|
231
|
+
const passed = body.status === "ok";
|
|
232
|
+
const expectations = readExpectations(body.results);
|
|
233
|
+
return {
|
|
234
|
+
...handle,
|
|
235
|
+
status: passed ? "pass" : "fail",
|
|
236
|
+
message: passed ? void 0 : expectations?.find((e) => e.status === "fail" && e.message !== void 0)?.message ?? asString(body.message) ?? `status: ${String(body.status)}`,
|
|
237
|
+
...expectations !== void 0 ? { expectations } : {},
|
|
238
|
+
// Optional by contract — read defensively, never format unguarded.
|
|
239
|
+
timing: typeof body.timing === "number" ? body.timing : void 0
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export {
|
|
244
|
+
qualifiedName,
|
|
245
|
+
objectQualifiedName,
|
|
246
|
+
listTests,
|
|
247
|
+
TestRunUnansweredError,
|
|
248
|
+
runTest
|
|
249
|
+
};
|
|
250
|
+
//# sourceMappingURL=chunk-73IVBKMA.js.map
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import {
|
|
2
|
+
deleteAnswer,
|
|
3
|
+
hasString,
|
|
4
|
+
listAnswer,
|
|
5
|
+
recordAnswer,
|
|
6
|
+
writeTransportFailure
|
|
7
|
+
} from "./chunk-6PBR37LN.js";
|
|
8
|
+
import {
|
|
9
|
+
contextFlags
|
|
10
|
+
} from "./chunk-NAQDMEHV.js";
|
|
11
|
+
import {
|
|
12
|
+
TransportError,
|
|
13
|
+
fetchOrExplain,
|
|
14
|
+
httpFailure,
|
|
15
|
+
readBodyText,
|
|
16
|
+
withWriteStatusAftermath
|
|
17
|
+
} from "./chunk-YLDALTWZ.js";
|
|
18
|
+
import {
|
|
19
|
+
shellQuote
|
|
20
|
+
} from "./chunk-5ZSO4T2G.js";
|
|
21
|
+
import {
|
|
22
|
+
withArticle
|
|
23
|
+
} from "./chunk-36JUQZVQ.js";
|
|
24
|
+
|
|
25
|
+
// src/deploy/ephemeral.ts
|
|
26
|
+
var TIMEOUT_MS = 3e4;
|
|
27
|
+
var READY_TIMEOUT_MS = 12e4;
|
|
28
|
+
var READY_INTERVAL_MS = 2e3;
|
|
29
|
+
function namedEphemeral(summary) {
|
|
30
|
+
const shown = summary.display !== void 0 && summary.display !== "" && summary.display !== summary.name ? ` (${JSON.stringify(summary.display)})` : "";
|
|
31
|
+
return `ephemeral ${JSON.stringify(summary.name)}${shown}`;
|
|
32
|
+
}
|
|
33
|
+
function asString(v) {
|
|
34
|
+
return typeof v === "string" && v !== "" ? v : void 0;
|
|
35
|
+
}
|
|
36
|
+
function asNumber(v) {
|
|
37
|
+
return typeof v === "number" ? v : void 0;
|
|
38
|
+
}
|
|
39
|
+
function tenantBaseUrl(tenant, instance) {
|
|
40
|
+
const host = asString(tenant.xano_domain);
|
|
41
|
+
if (host !== void 0) {
|
|
42
|
+
const scheme = host.startsWith("localhost:") ? "http" : "https";
|
|
43
|
+
return `${scheme}://${host}`;
|
|
44
|
+
}
|
|
45
|
+
const name = asString(tenant.name);
|
|
46
|
+
if (name !== void 0) return new URL(`/tenant/${name}`, instance).href.replace(/\/$/, "");
|
|
47
|
+
return instance.replace(/\/$/, "");
|
|
48
|
+
}
|
|
49
|
+
function expiresAtMs(expiresAt) {
|
|
50
|
+
if (expiresAt === void 0 || expiresAt === null) return NaN;
|
|
51
|
+
return typeof expiresAt === "number" ? expiresAt * 1e3 : Date.parse(String(expiresAt).replace(" ", "T"));
|
|
52
|
+
}
|
|
53
|
+
function isoExpiry(v) {
|
|
54
|
+
if (typeof v === "number") return Number.isFinite(v) ? new Date(v * 1e3).toISOString() : v;
|
|
55
|
+
if (typeof v !== "string" || v === "") return void 0;
|
|
56
|
+
const ms = expiresAtMs(v);
|
|
57
|
+
return Number.isFinite(ms) ? new Date(ms).toISOString() : v;
|
|
58
|
+
}
|
|
59
|
+
function isExpired(expiresAt) {
|
|
60
|
+
const ms = expiresAtMs(expiresAt);
|
|
61
|
+
return Number.isFinite(ms) && ms <= Date.now();
|
|
62
|
+
}
|
|
63
|
+
function projectTenant(tenant, instance) {
|
|
64
|
+
const name = asString(tenant.name);
|
|
65
|
+
return {
|
|
66
|
+
id: asNumber(tenant.id),
|
|
67
|
+
name: name ?? "",
|
|
68
|
+
display: asString(tenant.display),
|
|
69
|
+
url: name !== void 0 || asString(tenant.xano_domain) ? tenantBaseUrl(tenant, instance) : void 0,
|
|
70
|
+
state: asString(tenant.state),
|
|
71
|
+
expiresAt: isoExpiry(tenant.ephemeral_expires_at),
|
|
72
|
+
workspaceId: asNumber(tenant.workspace_id),
|
|
73
|
+
type: asString(tenant.type),
|
|
74
|
+
// `{ id: 0 }` is the row's empty relation: nothing landed.
|
|
75
|
+
...releaseIdOf(tenant.release)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async function metaFetch(auth, path, action, init) {
|
|
79
|
+
const url = new URL(path, auth.instance);
|
|
80
|
+
const write = (init?.method ?? "GET").toUpperCase() !== "GET";
|
|
81
|
+
return fetchOrExplain(
|
|
82
|
+
url.href,
|
|
83
|
+
{
|
|
84
|
+
...init,
|
|
85
|
+
headers: {
|
|
86
|
+
accept: "application/json",
|
|
87
|
+
Authorization: `Bearer ${auth.access_token}`,
|
|
88
|
+
...init?.headers ?? {}
|
|
89
|
+
},
|
|
90
|
+
signal: AbortSignal.timeout(TIMEOUT_MS)
|
|
91
|
+
},
|
|
92
|
+
action,
|
|
93
|
+
TIMEOUT_MS
|
|
94
|
+
).catch((err) => {
|
|
95
|
+
throw write ? writeTransportFailure(err) : err;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async function readText(res, action, url, opts = {}) {
|
|
99
|
+
const text = await readBodyText(res, action, { url });
|
|
100
|
+
if (!res.ok) {
|
|
101
|
+
const head = httpFailure(action, res, text);
|
|
102
|
+
const err = new Error(opts.write === true ? withWriteStatusAftermath(head, res.status) : head);
|
|
103
|
+
Object.defineProperty(err, "status", { value: res.status, enumerable: false });
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
return text;
|
|
107
|
+
}
|
|
108
|
+
async function readTenant(res, action, path, instance, opts = {}) {
|
|
109
|
+
const url = new URL(path, instance).href;
|
|
110
|
+
return recordAnswer(await readText(res, action, url, opts), action, url, (row) => hasString(row, "name"), opts);
|
|
111
|
+
}
|
|
112
|
+
function isEphemeralDisabled(err) {
|
|
113
|
+
return err instanceof Error && /ephemeral tenants are not enabled/i.test(err.message);
|
|
114
|
+
}
|
|
115
|
+
async function createEphemeral(auth, opts) {
|
|
116
|
+
const path = `/api:meta/workspace/${opts.parentWorkspaceId}/ephemeral`;
|
|
117
|
+
const body = { display: opts.display, tag: [] };
|
|
118
|
+
if (opts.description !== void 0) body.description = opts.description;
|
|
119
|
+
if (opts.expiresHours !== void 0) body.expires_hours = opts.expiresHours;
|
|
120
|
+
const res = await metaFetch(auth, path, "create ephemeral", {
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers: { "Content-Type": "application/json" },
|
|
123
|
+
body: JSON.stringify(body)
|
|
124
|
+
});
|
|
125
|
+
const tenant = await readTenant(res, "create ephemeral", path, auth.instance, { write: true });
|
|
126
|
+
return projectTenant(tenant, auth.instance);
|
|
127
|
+
}
|
|
128
|
+
var NotAnEphemeralError = class extends Error {
|
|
129
|
+
constructor(tenant, type, display) {
|
|
130
|
+
const named = `tenant ${JSON.stringify(tenant)}${display !== void 0 && display !== "" && display !== tenant ? ` (${JSON.stringify(display)})` : ""}`;
|
|
131
|
+
super(
|
|
132
|
+
(type === void 0 ? `No ephemeral named "${tenant}": ${named} exists but reports no type, so it is not treated as one.` : `No ephemeral named "${tenant}": ${named} is ${withArticle(type)} tenant, not an ephemeral.`) + // With this run's credential flags, which a bare `tenant` command would not read.
|
|
133
|
+
` Nothing was changed. \`xanosdk tenant get ${shellQuote(tenant)}${contextFlags()}\` shows it, and \`tenant:${tenant}\` selects it (\`xanosdk tenant delete ${shellQuote(tenant)}${contextFlags()}\` is how a tenant is deleted).`
|
|
134
|
+
);
|
|
135
|
+
this.tenant = tenant;
|
|
136
|
+
this.type = type;
|
|
137
|
+
this.display = display;
|
|
138
|
+
}
|
|
139
|
+
tenant;
|
|
140
|
+
type;
|
|
141
|
+
display;
|
|
142
|
+
name = "NotAnEphemeralError";
|
|
143
|
+
exitCode = 8;
|
|
144
|
+
};
|
|
145
|
+
async function getEphemeral(auth, opts) {
|
|
146
|
+
const path = `/api:meta/workspace/${opts.parentWorkspaceId}/tenant/${encodeURIComponent(opts.name)}`;
|
|
147
|
+
const res = await metaFetch(auth, path, "get ephemeral", { method: "GET" });
|
|
148
|
+
if (res.status === 404) {
|
|
149
|
+
await res.text().catch(() => "");
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
const tenant = await readTenant(res, "get ephemeral", path, auth.instance);
|
|
153
|
+
const summary = projectTenant(tenant, auth.instance);
|
|
154
|
+
if (summary.type !== void 0 && summary.type !== "ephemeral") throw new NotAnEphemeralError(opts.name, summary.type, summary.display);
|
|
155
|
+
return summary;
|
|
156
|
+
}
|
|
157
|
+
async function renameEphemeral(auth, opts) {
|
|
158
|
+
const path = `/api:meta/workspace/${opts.parentWorkspaceId}/tenant/${encodeURIComponent(opts.name)}`;
|
|
159
|
+
const current = await readTenant(
|
|
160
|
+
await metaFetch(auth, path, "read ephemeral", { method: "GET" }),
|
|
161
|
+
"read ephemeral",
|
|
162
|
+
path,
|
|
163
|
+
auth.instance
|
|
164
|
+
);
|
|
165
|
+
const type = asString(current.type);
|
|
166
|
+
if (type !== "ephemeral") throw new NotAnEphemeralError(opts.name, type, asString(current.display));
|
|
167
|
+
const rbac = current.rbac;
|
|
168
|
+
const body = {
|
|
169
|
+
display: opts.display,
|
|
170
|
+
description: typeof current.description === "string" ? current.description : "",
|
|
171
|
+
domain: current.domain ?? null,
|
|
172
|
+
proxy: current.proxy ?? null,
|
|
173
|
+
tag: Array.isArray(current.tag) ? current.tag : [],
|
|
174
|
+
rbac: { enabled: rbac?.enabled === true },
|
|
175
|
+
tasks: current.tasks === true,
|
|
176
|
+
ingress: current.ingress === true
|
|
177
|
+
};
|
|
178
|
+
const res = await metaFetch(auth, path, "rename ephemeral", {
|
|
179
|
+
method: "PUT",
|
|
180
|
+
headers: { "Content-Type": "application/json" },
|
|
181
|
+
body: JSON.stringify(body)
|
|
182
|
+
});
|
|
183
|
+
const url = new URL(path, auth.instance).href;
|
|
184
|
+
recordAnswer(await readText(res, "rename ephemeral", url, { write: true }), "rename ephemeral", url, () => true, { write: true });
|
|
185
|
+
}
|
|
186
|
+
function releaseIdOf(release) {
|
|
187
|
+
const id = release !== null && typeof release === "object" ? release.id : void 0;
|
|
188
|
+
return typeof id === "number" && id > 0 ? { deployedReleaseId: id } : {};
|
|
189
|
+
}
|
|
190
|
+
async function listEphemeral(auth, opts) {
|
|
191
|
+
const path = `/api:meta/workspace/${opts.parentWorkspaceId}/ephemeral`;
|
|
192
|
+
return (await readRows(auth, path)).map((t) => projectTenant(t, auth.instance));
|
|
193
|
+
}
|
|
194
|
+
async function listAllEphemeral(auth) {
|
|
195
|
+
const path = `/api:meta/ephemeral`;
|
|
196
|
+
return (await readRows(auth, path)).map((t) => projectTenant(t, auth.instance));
|
|
197
|
+
}
|
|
198
|
+
async function readRows(auth, path) {
|
|
199
|
+
const res = await metaFetch(auth, path, "list ephemerals", { method: "GET" });
|
|
200
|
+
const url = new URL(path, auth.instance).href;
|
|
201
|
+
return listAnswer(await readText(res, "list ephemerals", url), "list ephemerals", url, (row) => hasString(row, "name")).rows;
|
|
202
|
+
}
|
|
203
|
+
async function deleteEphemeral(auth, opts) {
|
|
204
|
+
if (opts.verified !== true) {
|
|
205
|
+
const found = await getEphemeral(auth, opts);
|
|
206
|
+
if (found === null) return { alreadyGone: true };
|
|
207
|
+
if (found.type !== "ephemeral") throw new NotAnEphemeralError(opts.name, found.type, found.display);
|
|
208
|
+
}
|
|
209
|
+
const path = `/api:meta/workspace/${opts.parentWorkspaceId}/tenant/${encodeURIComponent(opts.name)}`;
|
|
210
|
+
const res = await metaFetch(auth, path, "delete ephemeral", { method: "DELETE" });
|
|
211
|
+
if (res.status === 404) {
|
|
212
|
+
await res.text().catch(() => "");
|
|
213
|
+
return { alreadyGone: true };
|
|
214
|
+
}
|
|
215
|
+
const url = new URL(path, auth.instance).href;
|
|
216
|
+
deleteAnswer(await readText(res, "delete ephemeral", url, { write: true }), "delete ephemeral", url);
|
|
217
|
+
return { alreadyGone: false };
|
|
218
|
+
}
|
|
219
|
+
async function impersonateEphemeral(auth, opts) {
|
|
220
|
+
const query = opts.guest ? "?guest_read_only=true" : "";
|
|
221
|
+
const path = `/api:meta/workspace/${opts.parentWorkspaceId}/tenant/${encodeURIComponent(opts.name)}/impersonate${query}`;
|
|
222
|
+
const url = new URL(path, auth.instance).href;
|
|
223
|
+
const action = "open a dashboard session";
|
|
224
|
+
const res = await metaFetch(auth, path, action, { method: "GET" });
|
|
225
|
+
const data = recordAnswer(await readText(res, action, url), action, url, (row) => hasString(row, "_ti"));
|
|
226
|
+
return { _ti: data._ti };
|
|
227
|
+
}
|
|
228
|
+
async function waitUntilReady(auth, opts, cfg = {}) {
|
|
229
|
+
const timeoutMs = cfg.timeoutMs ?? READY_TIMEOUT_MS;
|
|
230
|
+
const intervalMs = cfg.intervalMs ?? READY_INTERVAL_MS;
|
|
231
|
+
const sleep = cfg.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
232
|
+
const deadline = Date.now() + timeoutMs;
|
|
233
|
+
let last = null;
|
|
234
|
+
let stateless = 0;
|
|
235
|
+
for (; ; ) {
|
|
236
|
+
try {
|
|
237
|
+
last = await getEphemeral(auth, opts);
|
|
238
|
+
} catch (err) {
|
|
239
|
+
if (!isServerErrorPoll(err) || Date.now() >= deadline) throw err;
|
|
240
|
+
await sleep(intervalMs);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (last && last.state === "ok") return last;
|
|
244
|
+
stateless = last !== null && last.state === void 0 ? stateless + 1 : 0;
|
|
245
|
+
if (stateless >= STATELESS_ANSWERS_TOLERATED) {
|
|
246
|
+
throw new Error(
|
|
247
|
+
`Ephemeral "${opts.name}" answered ${stateless} times with no \`state\`, so whether it is ready cannot be read \u2014 stopped waiting rather than polling for ${Math.round(timeoutMs / 1e3)}s.`
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
if (Date.now() >= deadline) {
|
|
251
|
+
const lastSaid = last === null ? "the last answer was not found \u2014 the ephemeral is gone" : last.state === void 0 ? "the last answer carried no state" : `last state: ${last.state}`;
|
|
252
|
+
throw new Error(
|
|
253
|
+
`Ephemeral "${opts.name}" did not become ready within ${Math.round(timeoutMs / 1e3)}s (${lastSaid}).`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
await sleep(intervalMs);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function isUnansweredPoll(err) {
|
|
260
|
+
return err instanceof TransportError || isServerErrorPoll(err);
|
|
261
|
+
}
|
|
262
|
+
function isServerErrorPoll(err) {
|
|
263
|
+
const status = err?.status;
|
|
264
|
+
return typeof status === "number" && (status >= 500 && status < 600 || status === 429);
|
|
265
|
+
}
|
|
266
|
+
var STATELESS_ANSWERS_TOLERATED = 3;
|
|
267
|
+
|
|
268
|
+
export {
|
|
269
|
+
namedEphemeral,
|
|
270
|
+
tenantBaseUrl,
|
|
271
|
+
expiresAtMs,
|
|
272
|
+
isExpired,
|
|
273
|
+
projectTenant,
|
|
274
|
+
isEphemeralDisabled,
|
|
275
|
+
createEphemeral,
|
|
276
|
+
NotAnEphemeralError,
|
|
277
|
+
getEphemeral,
|
|
278
|
+
renameEphemeral,
|
|
279
|
+
listEphemeral,
|
|
280
|
+
listAllEphemeral,
|
|
281
|
+
deleteEphemeral,
|
|
282
|
+
impersonateEphemeral,
|
|
283
|
+
waitUntilReady,
|
|
284
|
+
isUnansweredPoll
|
|
285
|
+
};
|
|
286
|
+
//# sourceMappingURL=chunk-7G3CTU7I.js.map
|