@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,965 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertNoMergeFlags,
|
|
3
|
+
reportEnvLanding,
|
|
4
|
+
reportNotRun
|
|
5
|
+
} from "./chunk-BHACRS6R.js";
|
|
6
|
+
import {
|
|
7
|
+
OperationError,
|
|
8
|
+
createOperation,
|
|
9
|
+
runOperation
|
|
10
|
+
} from "./chunk-TLHIFK4M.js";
|
|
11
|
+
import "./chunk-X677DMZM.js";
|
|
12
|
+
import "./chunk-LRN4ZJCQ.js";
|
|
13
|
+
import "./chunk-RTJRZFFY.js";
|
|
14
|
+
import {
|
|
15
|
+
assertReleaseIdentitiesFree
|
|
16
|
+
} from "./chunk-WKQLGKCL.js";
|
|
17
|
+
import {
|
|
18
|
+
passwordHashesWarning,
|
|
19
|
+
passwordOrigin,
|
|
20
|
+
readUnanswered
|
|
21
|
+
} from "./chunk-AWEIIR2U.js";
|
|
22
|
+
import "./chunk-FQJ2TTHP.js";
|
|
23
|
+
import "./chunk-K6RXBGUB.js";
|
|
24
|
+
import {
|
|
25
|
+
confirm
|
|
26
|
+
} from "./chunk-65HWOMGV.js";
|
|
27
|
+
import {
|
|
28
|
+
forgetLanding,
|
|
29
|
+
holdsLanding,
|
|
30
|
+
landingLockPath,
|
|
31
|
+
recordForeignLanding
|
|
32
|
+
} from "./chunk-CGVQZXYG.js";
|
|
33
|
+
import {
|
|
34
|
+
CONSTRAINT_FIX,
|
|
35
|
+
CONSTRAINT_PHRASE,
|
|
36
|
+
additiveChanges,
|
|
37
|
+
alteringChanges,
|
|
38
|
+
assertStorageModesKept,
|
|
39
|
+
constraintStop,
|
|
40
|
+
constraintWhere,
|
|
41
|
+
discloseCanonicalMoves,
|
|
42
|
+
discloseTableEffects,
|
|
43
|
+
droppedAndAdded,
|
|
44
|
+
droppedTableLine,
|
|
45
|
+
movesClause,
|
|
46
|
+
namedConstraint,
|
|
47
|
+
readOnce,
|
|
48
|
+
releaseCanonicalMoves,
|
|
49
|
+
releaseTableEffects,
|
|
50
|
+
stoppingRetypes,
|
|
51
|
+
tableEffectsPayload,
|
|
52
|
+
xdoConversionRefusal,
|
|
53
|
+
xdoConversionRefused
|
|
54
|
+
} from "./chunk-BWPNT55T.js";
|
|
55
|
+
import "./chunk-TPHWJ7UG.js";
|
|
56
|
+
import {
|
|
57
|
+
countTableRows,
|
|
58
|
+
listTables,
|
|
59
|
+
tableRowCounter
|
|
60
|
+
} from "./chunk-C6RIMRU4.js";
|
|
61
|
+
import "./chunk-WQFNASK4.js";
|
|
62
|
+
import {
|
|
63
|
+
asWorkspaceArchive,
|
|
64
|
+
passwordSeedColumns
|
|
65
|
+
} from "./chunk-AOSYVMUS.js";
|
|
66
|
+
import {
|
|
67
|
+
exportWorkspaceBundle
|
|
68
|
+
} from "./chunk-CJHQKJU4.js";
|
|
69
|
+
import {
|
|
70
|
+
decodeWorkspaceArchive
|
|
71
|
+
} from "./chunk-3DRXWLJ5.js";
|
|
72
|
+
import "./chunk-X4DVXBFY.js";
|
|
73
|
+
import {
|
|
74
|
+
SettledWriteFailure
|
|
75
|
+
} from "./chunk-A6E77GDW.js";
|
|
76
|
+
import "./chunk-TRJCALW3.js";
|
|
77
|
+
import "./chunk-LIEOKXKD.js";
|
|
78
|
+
import "./chunk-D7VGG3WS.js";
|
|
79
|
+
import "./chunk-2TFRR6JV.js";
|
|
80
|
+
import "./chunk-45UIT5T2.js";
|
|
81
|
+
import "./chunk-HRVBLCVJ.js";
|
|
82
|
+
import "./chunk-YHEFQUQB.js";
|
|
83
|
+
import "./chunk-ETO6LGLD.js";
|
|
84
|
+
import {
|
|
85
|
+
assertOneName
|
|
86
|
+
} from "./chunk-ZIY7RNUT.js";
|
|
87
|
+
import "./chunk-DAD3ONIS.js";
|
|
88
|
+
import "./chunk-HHN734BU.js";
|
|
89
|
+
import "./chunk-LPECSJ2J.js";
|
|
90
|
+
import "./chunk-6NNTNXN7.js";
|
|
91
|
+
import {
|
|
92
|
+
SourceError,
|
|
93
|
+
describeBackend,
|
|
94
|
+
isUnansweredLookup,
|
|
95
|
+
resolveSource
|
|
96
|
+
} from "./chunk-QCNYHBL7.js";
|
|
97
|
+
import {
|
|
98
|
+
downloadRelease,
|
|
99
|
+
listReleases,
|
|
100
|
+
promotableReleaseName,
|
|
101
|
+
untenantDeployableReleasePart
|
|
102
|
+
} from "./chunk-2ZUEE4EK.js";
|
|
103
|
+
import "./chunk-AN6BL47T.js";
|
|
104
|
+
import {
|
|
105
|
+
getAccessToken
|
|
106
|
+
} from "./chunk-ET4Y4XCB.js";
|
|
107
|
+
import "./chunk-SWBF2LTK.js";
|
|
108
|
+
import {
|
|
109
|
+
displayNameHint,
|
|
110
|
+
displayNameOwner,
|
|
111
|
+
displayNameOwnerOfEither,
|
|
112
|
+
isShared,
|
|
113
|
+
sharedDisplayHint
|
|
114
|
+
} from "./chunk-UZ6QQWJT.js";
|
|
115
|
+
import {
|
|
116
|
+
deleteTenant,
|
|
117
|
+
deployReleaseToTenant,
|
|
118
|
+
getTenant,
|
|
119
|
+
isFailedMicroservice,
|
|
120
|
+
listTenants,
|
|
121
|
+
tenantHasWorkspace
|
|
122
|
+
} from "./chunk-A3UDOZB6.js";
|
|
123
|
+
import "./chunk-2MNLRIOX.js";
|
|
124
|
+
import "./chunk-3M4LFYNQ.js";
|
|
125
|
+
import "./chunk-AM4FKL4J.js";
|
|
126
|
+
import "./chunk-Q325JKYB.js";
|
|
127
|
+
import "./chunk-STSFNCY4.js";
|
|
128
|
+
import "./chunk-I4F5TCJH.js";
|
|
129
|
+
import {
|
|
130
|
+
clearEnvironment,
|
|
131
|
+
ephemeralStatePath,
|
|
132
|
+
getEnvironment,
|
|
133
|
+
readEphemeralState
|
|
134
|
+
} from "./chunk-5QU2P5CA.js";
|
|
135
|
+
import "./chunk-ZYJP6BOO.js";
|
|
136
|
+
import "./chunk-QO6BVGS5.js";
|
|
137
|
+
import "./chunk-JZGVVJSI.js";
|
|
138
|
+
import "./chunk-7G3CTU7I.js";
|
|
139
|
+
import "./chunk-6PBR37LN.js";
|
|
140
|
+
import "./chunk-T5KELPAR.js";
|
|
141
|
+
import "./chunk-622HUCZT.js";
|
|
142
|
+
import {
|
|
143
|
+
contextFlags
|
|
144
|
+
} from "./chunk-NAQDMEHV.js";
|
|
145
|
+
import "./chunk-5A2PLKZB.js";
|
|
146
|
+
import "./chunk-AHJWCYQO.js";
|
|
147
|
+
import "./chunk-DX4QR4B2.js";
|
|
148
|
+
import "./chunk-6QXLMMT3.js";
|
|
149
|
+
import "./chunk-ZFDZKNGG.js";
|
|
150
|
+
import {
|
|
151
|
+
shellWord
|
|
152
|
+
} from "./chunk-FWD7AL6N.js";
|
|
153
|
+
import "./chunk-2GNFDZA2.js";
|
|
154
|
+
import "./chunk-JTUKLCXS.js";
|
|
155
|
+
import {
|
|
156
|
+
describeWrite
|
|
157
|
+
} from "./chunk-4KHEMC32.js";
|
|
158
|
+
import "./chunk-U64O2MXY.js";
|
|
159
|
+
import "./chunk-ROY4YAEQ.js";
|
|
160
|
+
import "./chunk-P2HAGF6H.js";
|
|
161
|
+
import "./chunk-TLQE7ZN3.js";
|
|
162
|
+
import "./chunk-WRBKLYSJ.js";
|
|
163
|
+
import "./chunk-3LDULPRE.js";
|
|
164
|
+
import "./chunk-XW6KISBB.js";
|
|
165
|
+
import "./chunk-AWQ7BQTQ.js";
|
|
166
|
+
import "./chunk-EUUUMY7J.js";
|
|
167
|
+
import {
|
|
168
|
+
UNTRUSTED_CERTIFICATE,
|
|
169
|
+
certificateFailureCode,
|
|
170
|
+
certificateFailureHost
|
|
171
|
+
} from "./chunk-YLDALTWZ.js";
|
|
172
|
+
import "./chunk-5FBYXK5P.js";
|
|
173
|
+
import "./chunk-LLNZGEFK.js";
|
|
174
|
+
import "./chunk-QXTKSOFI.js";
|
|
175
|
+
import "./chunk-X2NL4KUO.js";
|
|
176
|
+
import "./chunk-3KZCLN4Z.js";
|
|
177
|
+
import "./chunk-FXFV3KU6.js";
|
|
178
|
+
import "./chunk-OPHB5ORL.js";
|
|
179
|
+
import "./chunk-UCQ2VUTG.js";
|
|
180
|
+
import "./chunk-DGWHAVRG.js";
|
|
181
|
+
import "./chunk-27GWNP2I.js";
|
|
182
|
+
import "./chunk-3YW23UFH.js";
|
|
183
|
+
import "./chunk-JGE7CAWB.js";
|
|
184
|
+
import {
|
|
185
|
+
UsageError,
|
|
186
|
+
backendDestinationPayload,
|
|
187
|
+
detail,
|
|
188
|
+
discloseWriteTarget,
|
|
189
|
+
displayPath,
|
|
190
|
+
info,
|
|
191
|
+
isBackendHandle,
|
|
192
|
+
isMachineOutput,
|
|
193
|
+
parseSource,
|
|
194
|
+
printHuman,
|
|
195
|
+
safeText,
|
|
196
|
+
stdoutStyle,
|
|
197
|
+
step,
|
|
198
|
+
success,
|
|
199
|
+
unknownSubcommand,
|
|
200
|
+
verbBackendName,
|
|
201
|
+
warn,
|
|
202
|
+
writeJson,
|
|
203
|
+
writeTargetPayload
|
|
204
|
+
} from "./chunk-PTHVMXZI.js";
|
|
205
|
+
import "./chunk-MXHSQOC4.js";
|
|
206
|
+
import "./chunk-6IUMKYWI.js";
|
|
207
|
+
import "./chunk-2CMJZDCL.js";
|
|
208
|
+
import "./chunk-CTMO46PK.js";
|
|
209
|
+
import "./chunk-ZDPP6RKB.js";
|
|
210
|
+
import "./chunk-K5BBGTYZ.js";
|
|
211
|
+
import "./chunk-LQCMKAJ7.js";
|
|
212
|
+
import "./chunk-YGZHHAAB.js";
|
|
213
|
+
import "./chunk-XVBGLISP.js";
|
|
214
|
+
import "./chunk-6HO3NCSJ.js";
|
|
215
|
+
import "./chunk-5V5XU32D.js";
|
|
216
|
+
import "./chunk-GSGDWJB5.js";
|
|
217
|
+
import "./chunk-HVRUQXGD.js";
|
|
218
|
+
import "./chunk-ERVIASGL.js";
|
|
219
|
+
import "./chunk-4POWHT2K.js";
|
|
220
|
+
import "./chunk-H2V3N23D.js";
|
|
221
|
+
import "./chunk-3JDU4VRL.js";
|
|
222
|
+
import "./chunk-WTPZRR4I.js";
|
|
223
|
+
import "./chunk-UTI5G6OJ.js";
|
|
224
|
+
import "./chunk-2EZ3ZJZZ.js";
|
|
225
|
+
import "./chunk-6MR5TI5V.js";
|
|
226
|
+
import "./chunk-5ZSO4T2G.js";
|
|
227
|
+
import "./chunk-XNCP4KYO.js";
|
|
228
|
+
import "./chunk-AKNCFVKZ.js";
|
|
229
|
+
import "./chunk-YU4HSQW7.js";
|
|
230
|
+
import "./chunk-TFFGOFVZ.js";
|
|
231
|
+
import "./chunk-EHP3WPEG.js";
|
|
232
|
+
import "./chunk-L5JYN3NM.js";
|
|
233
|
+
import "./chunk-Q7DGTQ5G.js";
|
|
234
|
+
import "./chunk-G554NZNI.js";
|
|
235
|
+
import "./chunk-N5GKCWE5.js";
|
|
236
|
+
import "./chunk-OXA6PSZT.js";
|
|
237
|
+
import "./chunk-VAX3UZOY.js";
|
|
238
|
+
import "./chunk-NZOWWHU5.js";
|
|
239
|
+
import "./chunk-4BW2SG2N.js";
|
|
240
|
+
import "./chunk-TTEIYD5P.js";
|
|
241
|
+
import "./chunk-CIMQZRRE.js";
|
|
242
|
+
import "./chunk-OHX6MIUZ.js";
|
|
243
|
+
import "./chunk-36JUQZVQ.js";
|
|
244
|
+
import "./chunk-PZ5AY32C.js";
|
|
245
|
+
|
|
246
|
+
// src/emit/tenant-command.ts
|
|
247
|
+
async function runTenantCommand(args) {
|
|
248
|
+
switch (args.subcommand) {
|
|
249
|
+
case "list":
|
|
250
|
+
return runList(args);
|
|
251
|
+
case "get":
|
|
252
|
+
return runGet(args);
|
|
253
|
+
case "deploy":
|
|
254
|
+
return runDeploy(args);
|
|
255
|
+
case "delete":
|
|
256
|
+
return runDelete(args);
|
|
257
|
+
default:
|
|
258
|
+
throw unknownSubcommand("tenant", args.subcommand, args.positionals);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function requireTenant(args, verb, at = 0) {
|
|
262
|
+
const name = args.positionals[at];
|
|
263
|
+
if (name === void 0 || name === "") {
|
|
264
|
+
throw new UsageError(
|
|
265
|
+
`\`xanosdk tenant ${verb}\` needs a tenant name. Run \`xanosdk tenant list${contextFlags(args)}\` to see them.`,
|
|
266
|
+
// One line and the pointer: the sentence says what to type.
|
|
267
|
+
{ hintFor: { command: "tenant", subcommand: verb } }
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
assertOneName(name, "the tenant name", { args, helpFor: { command: "tenant", subcommand: verb } });
|
|
271
|
+
return verbBackendName(name, "tenant", { command: "tenant", subcommand: verb }, contextFlags(args));
|
|
272
|
+
}
|
|
273
|
+
function tenantVerbHint(verb, args, lead = "") {
|
|
274
|
+
return {
|
|
275
|
+
displayNameOf: displayNameOwner,
|
|
276
|
+
displayNameFix: (_kind, name, typo) => typo === true ? `run \`xanosdk tenant ${verb} ${shellWord(name)}${lead}${jsonFlag(args)}${contextFlags()}\`.` : `tenant commands take its name: \`xanosdk tenant ${verb} ${shellWord(name)}${lead}${answerFlags(args)}${contextFlags()}\`.`
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
async function swappedDeployArgs(err, auth, first, second, args) {
|
|
280
|
+
if (!(err instanceof SourceError) || err.liveness !== "gone" || isMalformedName(second)) return void 0;
|
|
281
|
+
const bare = second.startsWith("tenant:") ? second.slice("tenant:".length) : second;
|
|
282
|
+
const tenant = await getTenant(auth, { workspaceId: auth.workspaceId, name: bare }).catch(() => null);
|
|
283
|
+
if (tenant === null) return void 0;
|
|
284
|
+
const release = first.startsWith("release:") ? first.slice("release:".length) : first;
|
|
285
|
+
return new SourceError(
|
|
286
|
+
`No tenant named "${first}", and "${bare}" is a tenant \u2014 \`xanosdk tenant deploy\` takes the tenant first, then the release. Nothing was sent.
|
|
287
|
+
Run \`xanosdk tenant deploy ${shellWord(bare)} ${shellWord(release)}${jsonFlag(args)}${contextFlags()}\`.`,
|
|
288
|
+
"gone",
|
|
289
|
+
"tenant",
|
|
290
|
+
bare
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
function isMalformedName(value) {
|
|
294
|
+
return /^(?:release|ephemeral|workspace|branch|local):/.test(value);
|
|
295
|
+
}
|
|
296
|
+
function jsonFlag(args) {
|
|
297
|
+
return args.json === true ? " --json" : "";
|
|
298
|
+
}
|
|
299
|
+
function answerFlags(args) {
|
|
300
|
+
return `${args.yes ? " --yes" : ""}${args.json === true ? " --json" : ""}`;
|
|
301
|
+
}
|
|
302
|
+
async function runList(args) {
|
|
303
|
+
const auth = await getAccessToken(args);
|
|
304
|
+
const rows = await listTenants(auth, { workspaceId: auth.workspaceId }).catch((err) => {
|
|
305
|
+
throw readUnanswered("tenant", "list tenants", "an empty list", err);
|
|
306
|
+
});
|
|
307
|
+
const releases = await releaseNamesById(auth, rows);
|
|
308
|
+
if (isMachineOutput(args)) {
|
|
309
|
+
writeJson({
|
|
310
|
+
tenants: rows.map((t) => ({ ...withDeployFields(t, releases), selector: `tenant:${t.name}`, workspaceId: auth.workspaceId }))
|
|
311
|
+
});
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (rows.length === 0) {
|
|
315
|
+
info("No tenants under this workspace.");
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const s = stdoutStyle();
|
|
319
|
+
for (const t of rows) {
|
|
320
|
+
const display = t.display !== void 0 && t.display !== t.name ? ` ${s.dim(`(${safeText(t.display)})`)}` : "";
|
|
321
|
+
printHuman(`${s.bold(safeText(t.name))}${display} ${safeText(t.state ?? "-")} ${safeText(t.url ?? "")}
|
|
322
|
+
`);
|
|
323
|
+
detail(deployedLine(t, releases));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function withDeployFields(t, releases) {
|
|
327
|
+
return {
|
|
328
|
+
...t,
|
|
329
|
+
deployedAt: t.deployedAt ?? null,
|
|
330
|
+
deployedReleaseId: t.deployedReleaseId ?? null,
|
|
331
|
+
deployedReleaseName: t.deployedReleaseId === void 0 ? null : releases.get(t.deployedReleaseId) ?? null
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function deployedLine(t, releases) {
|
|
335
|
+
if (t.deployedReleaseId === void 0) return "release: none deployed";
|
|
336
|
+
const name = releases.get(t.deployedReleaseId);
|
|
337
|
+
const which = name === void 0 ? `#${t.deployedReleaseId} (no longer listed)` : `${safeText(name)} (#${t.deployedReleaseId})`;
|
|
338
|
+
return `release: ${which}${t.deployedAt === void 0 ? "" : `, deployed ${safeText(t.deployedAt)}`}`;
|
|
339
|
+
}
|
|
340
|
+
async function releaseNamesById(auth, tenants) {
|
|
341
|
+
if (!tenants.some((t) => t.deployedReleaseId !== void 0)) return /* @__PURE__ */ new Map();
|
|
342
|
+
const rows = await listReleases(auth, { workspaceId: auth.workspaceId }).catch(() => []);
|
|
343
|
+
return new Map(rows.flatMap((r) => r.id === void 0 ? [] : [[r.id, r.name]]));
|
|
344
|
+
}
|
|
345
|
+
async function runGet(args) {
|
|
346
|
+
const name = requireTenant(args, "get");
|
|
347
|
+
const auth = await getAccessToken(args);
|
|
348
|
+
let record = null;
|
|
349
|
+
const resolved = await resolveSource(
|
|
350
|
+
parseSource(name, ["tenant"], { command: "tenant", subcommand: "get" }),
|
|
351
|
+
async () => auth,
|
|
352
|
+
{ getTenant: async (a, o) => record = await getTenant(a, o), workspaceless: "any", ...tenantVerbHint("get", args) }
|
|
353
|
+
);
|
|
354
|
+
const seen = record;
|
|
355
|
+
const releases = seen === null ? /* @__PURE__ */ new Map() : await releaseNamesById(auth, [seen]);
|
|
356
|
+
if (isMachineOutput(args)) {
|
|
357
|
+
writeJson({
|
|
358
|
+
id: seen?.id,
|
|
359
|
+
name,
|
|
360
|
+
display: seen?.display,
|
|
361
|
+
type: seen?.type,
|
|
362
|
+
url: resolved.target.base,
|
|
363
|
+
state: seen?.state,
|
|
364
|
+
deployedAt: seen?.deployedAt ?? null,
|
|
365
|
+
deployedReleaseId: seen?.deployedReleaseId ?? null,
|
|
366
|
+
deployedReleaseName: seen?.deployedReleaseId === void 0 ? null : releases.get(seen.deployedReleaseId) ?? null,
|
|
367
|
+
selector: `tenant:${name}`,
|
|
368
|
+
workspaceId: auth.workspaceId
|
|
369
|
+
});
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const s = stdoutStyle();
|
|
373
|
+
const display = seen?.display !== void 0 && seen.display !== name ? ` ${s.dim(`(${safeText(seen.display)})`)}` : "";
|
|
374
|
+
printHuman(`${s.bold(safeText(name))}${display}
|
|
375
|
+
`);
|
|
376
|
+
detail(resolved.target.base);
|
|
377
|
+
if (seen?.type !== void 0) detail(`type: ${safeText(seen.type)}`);
|
|
378
|
+
if (seen?.state !== void 0) detail(`state: ${safeText(seen.state)}`);
|
|
379
|
+
if (seen !== null) detail(deployedLine(seen, releases));
|
|
380
|
+
}
|
|
381
|
+
async function runDeploy(args) {
|
|
382
|
+
assertNoMergeFlags(args);
|
|
383
|
+
const tenant = requireTenant(args, "deploy");
|
|
384
|
+
const releaseArg = args.positionals[1];
|
|
385
|
+
if (releaseArg === void 0 || releaseArg === "") {
|
|
386
|
+
throw new UsageError(
|
|
387
|
+
`\`xanosdk tenant deploy\` needs a release: \`xanosdk tenant deploy ${shellWord(tenant)} <release>${contextFlags(args)}\`. Run \`xanosdk release list${contextFlags(args)}\` to see them.`,
|
|
388
|
+
{ hintFor: { command: "tenant", subcommand: "deploy" } }
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
assertOneName(releaseArg, "the release name", { args, helpFor: { command: "tenant", subcommand: "deploy" } });
|
|
392
|
+
const unlandable = untenantDeployableReleasePart(releaseArg);
|
|
393
|
+
if (unlandable !== void 0) {
|
|
394
|
+
throw new UsageError(
|
|
395
|
+
`Release "${releaseArg}" cannot be landed on a tenant: its name holds \`${unlandable}\`, which the landing route cannot address (\`|\` reads as a filter, and a name holding \`=\` is never found). Nothing was sent.
|
|
396
|
+
Cut it again as \`xanosdk release create ${shellWord(promotableReleaseName(releaseArg))}\` from the source \`xanosdk release show ${shellWord(releaseArg)}${contextFlags(args)}\` names, and land that.`,
|
|
397
|
+
{ hintFor: { command: "tenant", subcommand: "deploy" } }
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
if (args.static !== void 0) {
|
|
401
|
+
throw new UsageError(
|
|
402
|
+
`\`--static\` publishes a site into the workspace a deploy writes, and a tenant's static hosting is scoped to the tenant. \`xanosdk tenant deploy\` does not publish one.`,
|
|
403
|
+
{ helpFor: { command: "tenant", subcommand: "deploy" } }
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
const auth = await getAccessToken(args);
|
|
407
|
+
let before = null;
|
|
408
|
+
const target = await resolveSource(
|
|
409
|
+
parseSource(tenant, ["tenant"], { command: "tenant", subcommand: "deploy" }),
|
|
410
|
+
async () => auth,
|
|
411
|
+
{
|
|
412
|
+
getTenant: async (a, o) => before = await getTenant(a, o),
|
|
413
|
+
// A tenant with no workspace yet gets one from this landing.
|
|
414
|
+
workspaceless: "any",
|
|
415
|
+
...tenantVerbHint("deploy", args, ` ${shellWord(releaseArg)}`)
|
|
416
|
+
}
|
|
417
|
+
).catch(async (err) => {
|
|
418
|
+
throw await swappedDeployArgs(err, auth, tenant, releaseArg, args) ?? err;
|
|
419
|
+
});
|
|
420
|
+
const release = await resolveSource(
|
|
421
|
+
parseSource(releaseArg, ["release"], { command: "tenant", subcommand: "deploy" }),
|
|
422
|
+
async () => auth
|
|
423
|
+
);
|
|
424
|
+
const previous = before;
|
|
425
|
+
const previousDeployedAt = previous?.deployedAt ?? null;
|
|
426
|
+
const previousDeployedReleaseId = previous?.deployedReleaseId ?? null;
|
|
427
|
+
let previousReleaseDeleted = false;
|
|
428
|
+
const previousDeployedReleaseName = previousDeployedReleaseId === null ? null : previousDeployedReleaseId === release.release?.id ? release.release.name : await listReleases(auth, { workspaceId: auth.workspaceId }).then(
|
|
429
|
+
(rows) => {
|
|
430
|
+
const hit = rows.find((r) => r.id === previousDeployedReleaseId);
|
|
431
|
+
previousReleaseDeleted = hit === void 0;
|
|
432
|
+
return hit?.name ?? null;
|
|
433
|
+
},
|
|
434
|
+
() => null
|
|
435
|
+
);
|
|
436
|
+
const ephemeral = target.target.tenantType === "ephemeral";
|
|
437
|
+
const named = `${ephemeral ? "ephemeral" : "tenant"} "${tenant}"`;
|
|
438
|
+
const display = target.target.display !== void 0 && target.target.display !== "" ? target.target.display : void 0;
|
|
439
|
+
const destination = {
|
|
440
|
+
base: auth.instance,
|
|
441
|
+
workspaceId: auth.workspaceId
|
|
442
|
+
};
|
|
443
|
+
step(`Deploying release ${release.target.label} to ${describeBackend(target)}`);
|
|
444
|
+
discloseWriteTarget(destination);
|
|
445
|
+
if (previousDeployedReleaseId !== null) {
|
|
446
|
+
const shown = previousDeployedReleaseName !== null ? `"${previousDeployedReleaseName}"` : `#${previousDeployedReleaseId}${previousReleaseDeleted ? " (deleted since)" : ""}`;
|
|
447
|
+
detail(
|
|
448
|
+
`last landed release ${shown}${previousDeployedAt !== null ? ` (deployed ${previousDeployedAt})` : ""}` + (previousDeployedReleaseId === release.release?.id ? " \u2014 this lands it again" : "") + ` \u2014 any \`deploy --to tenant:\` merge since may have changed what it runs`
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
let archiveBytes;
|
|
452
|
+
const releaseBytes = () => {
|
|
453
|
+
const id = release.release?.id;
|
|
454
|
+
if (id === void 0) return Promise.reject(new Error("the release carries no id"));
|
|
455
|
+
archiveBytes ??= downloadRelease(auth, { workspaceId: release.target.workspaceId, id, base: release.target.base }).catch(
|
|
456
|
+
(err) => {
|
|
457
|
+
archiveBytes = void 0;
|
|
458
|
+
throw err;
|
|
459
|
+
}
|
|
460
|
+
);
|
|
461
|
+
return archiveBytes;
|
|
462
|
+
};
|
|
463
|
+
const loadArchive = readOnce(
|
|
464
|
+
async () => release.release?.id === void 0 ? void 0 : decodeWorkspaceArchive(await releaseBytes())
|
|
465
|
+
);
|
|
466
|
+
const firstLanding = !ephemeral && !await tenantHasWorkspace(auth, target.target.base);
|
|
467
|
+
const loadLive = readOnce(
|
|
468
|
+
() => firstLanding ? Promise.resolve({ payload: {} }) : exportWorkspaceBundle(auth, {
|
|
469
|
+
base: target.target.base,
|
|
470
|
+
workspaceId: target.target.workspaceId,
|
|
471
|
+
label: `reading ${named}`,
|
|
472
|
+
safeErrors: true
|
|
473
|
+
})
|
|
474
|
+
);
|
|
475
|
+
if (firstLanding) {
|
|
476
|
+
detail(`${named} has no workspace yet, so this is its first landing: nothing is served there to preview or replace.`);
|
|
477
|
+
} else {
|
|
478
|
+
await assertPreLandingReadsAnswered(args, {
|
|
479
|
+
reads: [
|
|
480
|
+
...release.release?.id === void 0 ? [] : [{ what: `release "${release.target.label}"'s archive`, read: releaseBytes }],
|
|
481
|
+
{ what: `what ${named} serves`, read: loadLive }
|
|
482
|
+
],
|
|
483
|
+
command: `tenant deploy ${shellWord(tenant)} ${shellWord(release.target.label)}`,
|
|
484
|
+
named
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
if (!firstLanding) await assertTenantIdentitiesFree(args, auth, {
|
|
488
|
+
releaseBytes,
|
|
489
|
+
loadArchive,
|
|
490
|
+
loadLive,
|
|
491
|
+
label: release.target.label,
|
|
492
|
+
tenant: {
|
|
493
|
+
base: target.target.base,
|
|
494
|
+
workspaceId: target.target.workspaceId,
|
|
495
|
+
type: ephemeral ? "ephemeral" : "tenant",
|
|
496
|
+
name: tenant,
|
|
497
|
+
...display === void 0 ? {} : { display }
|
|
498
|
+
},
|
|
499
|
+
named
|
|
500
|
+
});
|
|
501
|
+
const tables = firstLanding ? void 0 : await releaseTableEffects(loadArchive, loadLive, {
|
|
502
|
+
mode: "replace",
|
|
503
|
+
skipTables: new Set((release.release?.seededTables ?? []).map((t) => t.name))
|
|
504
|
+
});
|
|
505
|
+
const landingEffects = tables !== void 0 && "effects" in tables ? await withDroppedRows(auth, tables.effects, target.target) : void 0;
|
|
506
|
+
if (!firstLanding) {
|
|
507
|
+
reportNotRun(
|
|
508
|
+
"tenant",
|
|
509
|
+
landingEffects === void 0 || alteringChanges(landingEffects).length + additiveChanges(landingEffects).length > 0
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
await reportEnvLanding(auth, {
|
|
513
|
+
release: { id: release.release?.id, name: release.target.label },
|
|
514
|
+
releaseHost: { base: release.target.base, workspaceId: auth.workspaceId },
|
|
515
|
+
target: target.target,
|
|
516
|
+
targetLabel: named,
|
|
517
|
+
// A tenant write asks first and refuses off a terminal without `--yes`; an
|
|
518
|
+
// ephemeral write does not ask.
|
|
519
|
+
envSetTo: ephemeral ? ` --to ${shellWord(`ephemeral:${tenant}`)}${contextFlags(args)}` : ` --to ${shellWord(`tenant:${tenant}`)} --yes${contextFlags(args)}`,
|
|
520
|
+
loadArchive,
|
|
521
|
+
loadLive
|
|
522
|
+
});
|
|
523
|
+
const seedRows = firstLanding ? [] : await seedRowsReplaced(auth, release, target.target, named);
|
|
524
|
+
if (landingEffects !== void 0) {
|
|
525
|
+
discloseTableEffects(landingEffects, { subject: "the tenant deploy", additiveWhere: `${named}'s tables` });
|
|
526
|
+
await assertStorageModesKept(landingEffects.storageChanges, tableRowCounter(auth, target.target), {
|
|
527
|
+
target: named,
|
|
528
|
+
subject: "the tenant deploy",
|
|
529
|
+
mode: "replace"
|
|
530
|
+
});
|
|
531
|
+
} else if (tables !== void 0 && "failure" in tables) {
|
|
532
|
+
warn(
|
|
533
|
+
`Could not read ${named}'s tables (${tables.failure}), so what the landing does to the columns it keeps \u2014 drops, retypes, removed enum values \u2014 is not checked.`,
|
|
534
|
+
"plan.target-unreadable"
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
const moves = await Promise.all([loadArchive(), loadLive()]).then(
|
|
538
|
+
([archive, live]) => releaseCanonicalMoves(archive, live),
|
|
539
|
+
() => []
|
|
540
|
+
);
|
|
541
|
+
discloseCanonicalMoves(moves, { subject: "the tenant deploy" });
|
|
542
|
+
const passwordHashesUnverifiable = await warnPasswordHashes(auth, release, tenant, named, ephemeral, releaseBytes);
|
|
543
|
+
const op = createOperation({
|
|
544
|
+
operation: "tenant deploy",
|
|
545
|
+
// The one destination shape: `kind` by the target's actual type (a tenant
|
|
546
|
+
// deploy can name an ephemeral), `label` its bare name, `url` its own URL.
|
|
547
|
+
destination: backendDestinationPayload(auth, {
|
|
548
|
+
kind: ephemeral ? "ephemeral" : "tenant",
|
|
549
|
+
name: tenant,
|
|
550
|
+
url: target.target.base,
|
|
551
|
+
...display === void 0 ? {} : { display }
|
|
552
|
+
}),
|
|
553
|
+
release: {
|
|
554
|
+
instance: release.target.base,
|
|
555
|
+
workspaceId: release.target.workspaceId,
|
|
556
|
+
id: release.release?.id,
|
|
557
|
+
name: release.release?.name ?? release.target.label
|
|
558
|
+
},
|
|
559
|
+
branch: null,
|
|
560
|
+
steps: ["deploy"],
|
|
561
|
+
extras: {
|
|
562
|
+
tenant: { name: tenant, url: target.target.base, ...display === void 0 ? {} : { display } },
|
|
563
|
+
previousDeployedAt,
|
|
564
|
+
previousDeployedReleaseId,
|
|
565
|
+
previousDeployedReleaseName,
|
|
566
|
+
// The text's caveat, for the `--json` reader (E2E pass 30): the previous
|
|
567
|
+
// release is the last one LANDED, not necessarily what it runs.
|
|
568
|
+
previousDeployedCaveat: previousDeployedReleaseId === null ? null : "the last landed release; a `deploy --to tenant:` merge since may have changed what it runs",
|
|
569
|
+
declined: false,
|
|
570
|
+
firstLanding,
|
|
571
|
+
landingRecord: null,
|
|
572
|
+
seedRowsReplaced: seedRows,
|
|
573
|
+
tableEffects: landingEffects === void 0 ? null : tableEffectsPayload(landingEffects),
|
|
574
|
+
canonicalMoves: moves.map((m) => ({ ...m })),
|
|
575
|
+
// The stderr warning's columns, for the `--json` reader who never sees it.
|
|
576
|
+
...passwordHashesUnverifiable !== void 0 ? { passwordHashesUnverifiable } : {}
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
const resolveWith = `xanosdk tenant get ${shellWord(tenant)} --json${contextFlags(args)}`;
|
|
580
|
+
const { pipedYes } = await import("./retry-command-AS5EVREX.js");
|
|
581
|
+
const noRecovery = previousReleaseDeleted ? `The release it last landed (#${previousDeployedReleaseId}) has been deleted, so there is none to put back. Re-cut it from the source it came from and land that, or put this project's code back with \`xanosdk deploy --to ${shellWord(`tenant:${tenant}`)}${pipedYes(args)}${contextFlags(args)}\`.` : "No earlier release is recorded on it to put back.";
|
|
582
|
+
const recoverWith = previousDeployedReleaseName === null ? null : `xanosdk tenant deploy ${shellWord(tenant)} ${shellWord(previousDeployedReleaseName)} --yes${contextFlags(args)}`;
|
|
583
|
+
let outcome;
|
|
584
|
+
let declined = false;
|
|
585
|
+
try {
|
|
586
|
+
await runOperation(
|
|
587
|
+
op,
|
|
588
|
+
{ machine: isMachineOutput(args), resolveWith, what: "the tenant deploy" },
|
|
589
|
+
async (o) => {
|
|
590
|
+
if (args.yes !== true) {
|
|
591
|
+
const { yesRerun } = await import("./retry-command-AS5EVREX.js");
|
|
592
|
+
const { rerun, note } = yesRerun(args, `tenant deploy ${shellWord(tenant)} ${shellWord(release.target.label)}`);
|
|
593
|
+
const dropped = landingEffects?.droppedTables ?? [];
|
|
594
|
+
const droppedColumns = landingEffects?.droppedColumns ?? [];
|
|
595
|
+
const paired = landingEffects === void 0 ? [] : droppedAndAdded(landingEffects);
|
|
596
|
+
const stopping = landingEffects === void 0 ? [] : stoppingRetypes(landingEffects);
|
|
597
|
+
const ok = await confirm(
|
|
598
|
+
(firstLanding ? `Land release "${release.target.label}" on ${named}? It is the tenant's first landing.` : `Replace what ${named} serves with release "${release.target.label}"? Anything not in the release \u2014 an API an earlier landing or a \`deploy --to tenant:\` merge added \u2014 is removed. Static hosting is kept.`) + (dropped.length === 0 ? "" : ` It DROPS ${dropped.length === 1 ? "table" : "tables"} ${dropped.map(droppedTableLine).join(", ")} with every row \u2014 the release does not carry ${dropped.length === 1 ? "it" : "them"}.`) + (droppedColumns.length === 0 ? "" : ` It DROPS ${droppedColumns.length === 1 ? "column" : "columns"} ${droppedColumns.join(", ")} with every value.`) + (seedRows.length === 0 ? "" : ` It also REPLACES the rows of ${seedRows.map((r) => `${r.table} (${rowsPhrase(r)})`).join(", ")}.`) + (stopping.length === 0 ? "" : ` It can STOP partway on ${stopping.join(", ")} (see above), leaving ${named} partly replaced.`) + movesClause(moves),
|
|
599
|
+
{
|
|
600
|
+
flag: "--yes",
|
|
601
|
+
refusal: {
|
|
602
|
+
details: {
|
|
603
|
+
landed: false,
|
|
604
|
+
declined: false,
|
|
605
|
+
droppedTables: dropped.map((t) => ({ ...t })),
|
|
606
|
+
droppedColumns: [...droppedColumns],
|
|
607
|
+
pairedColumns: paired,
|
|
608
|
+
canonicalMoves: moves.map((m) => ({ ...m }))
|
|
609
|
+
},
|
|
610
|
+
rerun,
|
|
611
|
+
note
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
);
|
|
615
|
+
if (!ok) {
|
|
616
|
+
info("Deploy cancelled \u2014 nothing was written.");
|
|
617
|
+
o.set("declined", true);
|
|
618
|
+
declined = true;
|
|
619
|
+
o.finish("deploy", "no");
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
step(`Landing ${release.target.label} on ${tenant}`);
|
|
624
|
+
o.begin("deploy");
|
|
625
|
+
o.sending();
|
|
626
|
+
outcome = await deployReleaseToTenant(auth, {
|
|
627
|
+
workspaceId: auth.workspaceId,
|
|
628
|
+
tenant,
|
|
629
|
+
release: release.target.label
|
|
630
|
+
}).catch((err) => {
|
|
631
|
+
if (xdoConversionRefused(err)) {
|
|
632
|
+
throw xdoConversionRefusal(named, err, new SettledWriteFailure(err.message, { cause: err }));
|
|
633
|
+
}
|
|
634
|
+
const found = constraintStop(err);
|
|
635
|
+
if (found === void 0) throw err;
|
|
636
|
+
const stop = namedConstraint(found, landingEffects);
|
|
637
|
+
o.set("partlyReplaced", true);
|
|
638
|
+
o.set("constraint", stop);
|
|
639
|
+
o.set("recoverWith", recoverWith);
|
|
640
|
+
throw new SettledWriteFailure(err instanceof Error ? err.message : String(err), { cause: err });
|
|
641
|
+
});
|
|
642
|
+
o.set("deployedAt", outcome.deployedAt ?? null);
|
|
643
|
+
o.set("microservices", outcome.microservices);
|
|
644
|
+
o.finish("deploy");
|
|
645
|
+
o.set("landingRecord", await recordTenantLanding(auth, args, release, tenant, ephemeral, releaseBytes));
|
|
646
|
+
}
|
|
647
|
+
);
|
|
648
|
+
} catch (err) {
|
|
649
|
+
if (declined) return;
|
|
650
|
+
if (err instanceof SettledWriteFailure) {
|
|
651
|
+
const stop = namedConstraint(constraintStop(err.cause), landingEffects);
|
|
652
|
+
const conversion = stop.kind === "conversion";
|
|
653
|
+
warn(
|
|
654
|
+
`The deploy stopped partway: ${conversion ? "a stored value does not convert to a column type" : `the tenant's data breaks ${CONSTRAINT_PHRASE[stop.kind]}`} release "${release.target.label}" declares${constraintWhere(stop)}` + (stop.notNull === true ? ` \u2014 answered as a NOT NULL violation, though the release makes no field required: the value converts to null, and the column is not nullable. ` : `. `) + `${named} may be partly replaced \u2014 serving some of "${release.target.label}" and some of what it ran before` + (conversion ? `, with the values of the tables it reached already converted for good.` : `.`),
|
|
655
|
+
"tenant.deploy-partial",
|
|
656
|
+
recoverWith === null ? [noRecovery, `${CONSTRAINT_FIX[stop.kind]}, then land "${release.target.label}" again.`] : [
|
|
657
|
+
`Put back what it ran: \`${recoverWith}\``,
|
|
658
|
+
`Then ${lowerFirst(CONSTRAINT_FIX[stop.kind])}, and land "${release.target.label}" again.`
|
|
659
|
+
]
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
if (err instanceof OperationError && err.result.completed === "unknown") {
|
|
663
|
+
warn(
|
|
664
|
+
`Compare its \`deployedAt\` and \`deployedReleaseId\` with what they were before this deploy (deployedAt ${previousDeployedAt ?? "none"}, deployedReleaseId ${previousDeployedReleaseId ?? "none"}). A redeploy of the same release leaves the id unchanged, so \`deployedAt\` is the one that moves.`,
|
|
665
|
+
"tenant.deploy-unconfirmed",
|
|
666
|
+
[
|
|
667
|
+
`Moved: "${release.target.label}" landed.`,
|
|
668
|
+
`Unmoved: it did not land, but a deploy that stopped partway can leave ${named} partly replaced` + (recoverWith === null ? `.` : ` \u2014 \`${recoverWith}\` puts back what it ran.`),
|
|
669
|
+
...recoverWith === null ? [noRecovery] : []
|
|
670
|
+
]
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
throw err;
|
|
674
|
+
}
|
|
675
|
+
const failed = (outcome?.microservices ?? []).filter(isFailedMicroservice);
|
|
676
|
+
if (failed.length > 0) {
|
|
677
|
+
warn(
|
|
678
|
+
`${failed.length} microservice(s) did not come up on ${named}: ` + failed.map((m) => m.detail === void 0 ? m.name : `${m.name} (${m.detail})`).join("; ") + `. The release landed; these need attention.`,
|
|
679
|
+
"microservice.failed"
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
success(`Landed ${release.target.label} on ${tenant}${firstLanding ? " (its first landing)" : ""}`);
|
|
683
|
+
detail(target.target.base);
|
|
684
|
+
}
|
|
685
|
+
async function assertPreLandingReadsAnswered(args, ctx) {
|
|
686
|
+
for (const { what, read } of ctx.reads) {
|
|
687
|
+
let failure;
|
|
688
|
+
try {
|
|
689
|
+
await read();
|
|
690
|
+
continue;
|
|
691
|
+
} catch (err) {
|
|
692
|
+
failure = err;
|
|
693
|
+
}
|
|
694
|
+
const { LookupFailedError, isTransportFailure, isUnansweredLookup: isUnansweredLookup2 } = await import("./source-resolve-S2XA3XZF.js");
|
|
695
|
+
if (!isUnansweredLookup2(failure)) continue;
|
|
696
|
+
const { retryCommand, withheldNote } = await import("./retry-command-AS5EVREX.js");
|
|
697
|
+
const retry = retryCommand(args, { command: ctx.command });
|
|
698
|
+
const certificate = certificateFailureCode(failure);
|
|
699
|
+
const cause = certificate !== void 0 ? `${UNTRUSTED_CERTIFICATE} (${certificate}) at ${certificateFailureHost(failure)} \u2014 a certificate or proxy configuration problem, not a network blip` : isTransportFailure(failure) ? "a network failure" : "a server error";
|
|
700
|
+
const refused = new LookupFailedError(
|
|
701
|
+
`Could not read ${what}, which the checks before a landing compare (${cause}). Nothing was sent and ${ctx.named} is untouched \u2014 a replace does not land with its checks off`,
|
|
702
|
+
"unreachable",
|
|
703
|
+
"tenant",
|
|
704
|
+
`run \`${retry.command}\` again`
|
|
705
|
+
);
|
|
706
|
+
refused.message += withheldNote(retry.withheld);
|
|
707
|
+
throw refused;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
async function assertTenantIdentitiesFree(args, auth, ctx) {
|
|
711
|
+
let typed;
|
|
712
|
+
let bundle;
|
|
713
|
+
try {
|
|
714
|
+
typed = asWorkspaceArchive(await ctx.releaseBytes(), ctx.label);
|
|
715
|
+
bundle = await ctx.loadArchive();
|
|
716
|
+
} catch {
|
|
717
|
+
typed = void 0;
|
|
718
|
+
}
|
|
719
|
+
let reason;
|
|
720
|
+
if (typed === void 0 || bundle === void 0) {
|
|
721
|
+
reason = "the release archive could not be read";
|
|
722
|
+
} else {
|
|
723
|
+
const check = await assertReleaseIdentitiesFree(args, auth, {
|
|
724
|
+
archive: typed,
|
|
725
|
+
bundle,
|
|
726
|
+
lockPath: landingLockPath(args),
|
|
727
|
+
live: await ctx.loadLive().catch(() => void 0),
|
|
728
|
+
tenant: ctx.tenant,
|
|
729
|
+
subject: `deploy release "${ctx.label}"`,
|
|
730
|
+
verb: "tenant deploy",
|
|
731
|
+
remedySuffix: `A release's names and slugs are fixed when it is cut: make the change in the project, deploy it, cut a new release from it with \`xanosdk release create\`, and deploy that one.`
|
|
732
|
+
});
|
|
733
|
+
if (!check.checked) reason = check.reason;
|
|
734
|
+
}
|
|
735
|
+
if (reason === void 0) return;
|
|
736
|
+
warn(
|
|
737
|
+
`Whether this release's names and pinned public URL slugs are free on ${ctx.named} was not checked \u2014 ${reason}.`,
|
|
738
|
+
"tenant.identities-unchecked",
|
|
739
|
+
[
|
|
740
|
+
`A name the tenant gives to another object lands as a suffixed second object, and the tenant's own is dropped \u2014 a table with its rows.`
|
|
741
|
+
]
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
async function recordTenantLanding(auth, args, release, tenant, ephemeral, releaseBytes) {
|
|
745
|
+
const lockPath = landingLockPath(args);
|
|
746
|
+
const id = release.release?.id;
|
|
747
|
+
if (lockPath === void 0 && !ephemeral || id === void 0) return null;
|
|
748
|
+
let archive;
|
|
749
|
+
try {
|
|
750
|
+
archive = decodeWorkspaceArchive(await releaseBytes());
|
|
751
|
+
} catch {
|
|
752
|
+
archive = void 0;
|
|
753
|
+
}
|
|
754
|
+
return recordForeignLanding({
|
|
755
|
+
lockPath,
|
|
756
|
+
instance: auth.instance,
|
|
757
|
+
dest: { kind: ephemeral ? "ephemeral" : "tenant", name: tenant },
|
|
758
|
+
// Unreadable: nothing on the tenant is known to be this project's any more.
|
|
759
|
+
bundle: archive ?? {},
|
|
760
|
+
mode: "replace",
|
|
761
|
+
...archive === void 0 ? { unreadable: true } : {}
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
async function warnPasswordHashes(auth, release, tenant, named, ephemeral, releaseBytes) {
|
|
765
|
+
const found = release.release;
|
|
766
|
+
if (found?.id === void 0 || (found.seededTables ?? []).length === 0) return void 0;
|
|
767
|
+
try {
|
|
768
|
+
const bytes = await releaseBytes();
|
|
769
|
+
const columns = passwordSeedColumns(bytes);
|
|
770
|
+
if (columns.length === 0) return void 0;
|
|
771
|
+
const origin = await passwordOrigin(auth, found);
|
|
772
|
+
if (origin?.name === tenant) return void 0;
|
|
773
|
+
warn(passwordHashesWarning(found.name, columns, named, "the landing", origin?.phrase, ephemeral), "seed.password-hashes");
|
|
774
|
+
return [...columns];
|
|
775
|
+
} catch {
|
|
776
|
+
return void 0;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
async function withDroppedRows(auth, effects, target) {
|
|
780
|
+
if (effects.droppedTables.length === 0) return effects;
|
|
781
|
+
const listed = await listTables(auth, { workspaceId: target.workspaceId, base: target.base }).catch(() => void 0);
|
|
782
|
+
const droppedTables = [];
|
|
783
|
+
for (const t of effects.droppedTables) {
|
|
784
|
+
const here = listed?.find((l) => l.name === t.table);
|
|
785
|
+
const rows = here === void 0 ? null : await countTableRows(auth, { workspaceId: target.workspaceId, tableId: here.id, base: target.base }).catch(
|
|
786
|
+
() => void 0
|
|
787
|
+
) ?? null;
|
|
788
|
+
droppedTables.push({ ...t, rows });
|
|
789
|
+
}
|
|
790
|
+
return { ...effects, droppedTables };
|
|
791
|
+
}
|
|
792
|
+
function rowsPhrase(r) {
|
|
793
|
+
const live = r.liveRows === null ? "its rows" : `${r.liveRows} ${r.liveRows === 1 ? "row" : "rows"}`;
|
|
794
|
+
const seed = r.seedRows === null ? "the release's rows" : `${r.seedRows} seed ${r.seedRows === 1 ? "row" : "rows"}`;
|
|
795
|
+
return `${live} replaced by ${seed}`;
|
|
796
|
+
}
|
|
797
|
+
async function seedRowsReplaced(auth, release, target, named) {
|
|
798
|
+
const seeded = release.release?.seededTables ?? [];
|
|
799
|
+
if (seeded.length === 0) return [];
|
|
800
|
+
const listed = await listTables(auth, { workspaceId: target.workspaceId, base: target.base }).catch(() => void 0);
|
|
801
|
+
const out = [];
|
|
802
|
+
for (const t of seeded) {
|
|
803
|
+
const here = listed?.find((l) => t.guid !== void 0 && l.guid === t.guid || l.name === t.name);
|
|
804
|
+
const liveRows = listed === void 0 ? null : here === void 0 ? 0 : await countTableRows(auth, { workspaceId: target.workspaceId, tableId: here.id, base: target.base }).catch(
|
|
805
|
+
() => void 0
|
|
806
|
+
) ?? null;
|
|
807
|
+
out.push({ table: t.name, liveRows, seedRows: t.count ?? null });
|
|
808
|
+
}
|
|
809
|
+
const one = out.length === 1;
|
|
810
|
+
warn(
|
|
811
|
+
`"${release.target.label}" was cut with rows, and a tenant deploy REPLACES ${one ? "that table's" : "those tables'"} rows on ${named} with the release's \u2014 every row there now is deleted:`,
|
|
812
|
+
"tenant.seed-replaces-rows",
|
|
813
|
+
[
|
|
814
|
+
...out.map((r) => `table ${r.table}: ${rowsPhrase(r)}`),
|
|
815
|
+
`Every other table the release carries keeps its rows. To keep these too, land a release cut without \`--seed\`.`
|
|
816
|
+
]
|
|
817
|
+
);
|
|
818
|
+
return out;
|
|
819
|
+
}
|
|
820
|
+
function lowerFirst(s) {
|
|
821
|
+
return s.charAt(0).toLowerCase() + s.slice(1);
|
|
822
|
+
}
|
|
823
|
+
async function runDelete(args) {
|
|
824
|
+
const name = requireTenant(args, "delete");
|
|
825
|
+
const auth = await getAccessToken(args);
|
|
826
|
+
let readFailed = false;
|
|
827
|
+
const record = await getTenant(auth, { workspaceId: auth.workspaceId, name }).catch(async (err) => {
|
|
828
|
+
if (isUnansweredLookup(err)) {
|
|
829
|
+
step(`Deleting tenant "${name}"`);
|
|
830
|
+
discloseWriteTarget({ base: auth.instance, workspaceId: auth.workspaceId });
|
|
831
|
+
const { deleteLookupFailed } = await import("./ephemeral-command-CLJJKOFT.js");
|
|
832
|
+
throw deleteLookupFailed("tenant", name, err);
|
|
833
|
+
}
|
|
834
|
+
readFailed = true;
|
|
835
|
+
return null;
|
|
836
|
+
});
|
|
837
|
+
const kind = record?.type === "ephemeral" ? "ephemeral" : "tenant";
|
|
838
|
+
const display = record?.display !== void 0 && record.display !== name ? record.display : void 0;
|
|
839
|
+
const named = `${kind} "${name}"${display === void 0 ? "" : ` (${JSON.stringify(display)})`}`;
|
|
840
|
+
const destination = {
|
|
841
|
+
...writeTargetPayload({ base: auth.instance, workspaceId: auth.workspaceId, kind, label: name }),
|
|
842
|
+
url: record?.url ?? null,
|
|
843
|
+
display: display ?? null
|
|
844
|
+
};
|
|
845
|
+
if (record === null) {
|
|
846
|
+
const owner = await displayNameOwnerOfEither(auth, name);
|
|
847
|
+
if (isShared(owner)) {
|
|
848
|
+
throw new SourceError(
|
|
849
|
+
`No tenant or ephemeral named "${name}" \u2014 nothing was deleted.
|
|
850
|
+
` + sharedDisplayHint(name, owner, (o) => `\`xanosdk tenant delete ${shellWord(o.name)}${jsonFlag(args)}${contextFlags(args)}\` deletes it, after asking to confirm.`),
|
|
851
|
+
"gone",
|
|
852
|
+
"tenant",
|
|
853
|
+
owner.owners[0].name,
|
|
854
|
+
owner.owners.map((o) => o.name)
|
|
855
|
+
);
|
|
856
|
+
}
|
|
857
|
+
if (owner !== void 0) {
|
|
858
|
+
throw new SourceError(
|
|
859
|
+
`No tenant or ephemeral named "${name}" \u2014 nothing was deleted.
|
|
860
|
+
` + displayNameHint(owner.kind, name, owner.name, `tenant commands take its name: \`xanosdk tenant delete ${shellWord(owner.name)}${answerFlags(args)}${contextFlags(args)}\`.`),
|
|
861
|
+
"gone",
|
|
862
|
+
"tenant"
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
if (!readFailed) {
|
|
866
|
+
const { nearForDelete, confirmMissEverywhere } = await import("./ephemeral-command-CLJJKOFT.js");
|
|
867
|
+
const { nearBackendLines } = await import("./display-name-hint-ABBPVQIR.js");
|
|
868
|
+
const near = await nearForDelete(auth, ["tenant", "ephemeral"], name, "tenant");
|
|
869
|
+
const names = near === void 0 ? [] : [...near.names ?? [near.name]];
|
|
870
|
+
const deleteFix = (n) => `\`xanosdk tenant delete ${shellWord(n)}${jsonFlag(args)}${contextFlags(args)}\` deletes it, after asking to confirm.`;
|
|
871
|
+
if (!isBackendHandle(name) || names.length > 0) {
|
|
872
|
+
throw new SourceError(
|
|
873
|
+
`No tenant or ephemeral named "${name}" \u2014 nothing was deleted. \`xanosdk tenant list${contextFlags(args)}\` shows the tenants that exist.` + (near === void 0 ? "" : nearBackendLines(near, deleteFix)),
|
|
874
|
+
"gone",
|
|
875
|
+
"tenant",
|
|
876
|
+
names[0],
|
|
877
|
+
names.length > 1 ? names : void 0
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
await confirmMissEverywhere(auth, name, "either", "tenant", `xanosdk tenant delete ${shellWord(name)}${answerFlags(args)}${contextFlags(args)}`);
|
|
881
|
+
const lockPath = landingLockPath(args);
|
|
882
|
+
const ephemeralLanding = forgetLanding(lockPath, auth.instance, { kind: "ephemeral", name });
|
|
883
|
+
const tracked = getEnvironment(readEphemeralState(process.cwd()), auth)?.name === name && clearEnvironment(process.cwd(), auth);
|
|
884
|
+
if (ephemeralLanding !== void 0 || tracked) {
|
|
885
|
+
info(`Removed this project's record of ephemeral "${name}" from ${displayPath(ephemeralStatePath(process.cwd()))}.`);
|
|
886
|
+
}
|
|
887
|
+
const clearedLandingRecord2 = forgetLanding(lockPath, auth.instance, { kind: "tenant", name }) !== void 0 || ephemeralLanding !== void 0 || tracked;
|
|
888
|
+
warn(
|
|
889
|
+
`No tenant or ephemeral named "${name}" \u2014 nothing was deleted${clearedLandingRecord2 ? "; this project's landing record for it was stale, so it was cleared" : ""}.`,
|
|
890
|
+
"tenant.not-found",
|
|
891
|
+
names.map((n) => `Did you mean ${near.kind} "${safeText(n)}"? \`xanosdk tenant delete ${shellWord(n)}${jsonFlag(args)}${contextFlags(args)}\` deletes it, after asking to confirm.`)
|
|
892
|
+
);
|
|
893
|
+
if (isMachineOutput(args)) {
|
|
894
|
+
writeJson({
|
|
895
|
+
verb: "delete",
|
|
896
|
+
destination,
|
|
897
|
+
name,
|
|
898
|
+
deleted: false,
|
|
899
|
+
alreadyGone: true,
|
|
900
|
+
declined: false,
|
|
901
|
+
clearedLandingRecord: clearedLandingRecord2,
|
|
902
|
+
// As every did-you-mean in a document: `suggestion`, and `suggestions` when a tie named several.
|
|
903
|
+
...names.length === 0 ? {} : { suggestion: names[0] },
|
|
904
|
+
...names.length > 1 ? { suggestions: names } : {}
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
const refusing = args.yes !== true && process.stdin.isTTY !== true;
|
|
911
|
+
step(`${refusing ? "Would delete" : "Deleting"} ${named}`);
|
|
912
|
+
discloseWriteTarget({ base: auth.instance, workspaceId: auth.workspaceId });
|
|
913
|
+
if (args.yes !== true) {
|
|
914
|
+
const ok = await confirm(`Delete ${named}? This destroys it and everything it serves.`, {
|
|
915
|
+
flag: "--yes",
|
|
916
|
+
refusal: {
|
|
917
|
+
details: { verb: "delete", name, deleted: false, alreadyGone: false, declined: false, clearedLandingRecord: false },
|
|
918
|
+
rerun: `xanosdk tenant delete ${shellWord(name)} --yes${args.json === true ? " --json" : ""}${contextFlags(args)}`
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
if (!ok) {
|
|
922
|
+
info("Deletion cancelled \u2014 nothing was deleted.");
|
|
923
|
+
if (isMachineOutput(args)) {
|
|
924
|
+
writeJson({ verb: "delete", destination, name, deleted: false, alreadyGone: false, declined: true, clearedLandingRecord: false });
|
|
925
|
+
}
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
const { alreadyGone } = await describeWrite(
|
|
930
|
+
{ what: `the delete of ${named}`, resolveWith: `xanosdk tenant get ${shellWord(name)}${contextFlags(args)}` },
|
|
931
|
+
() => deleteTenant(auth, { workspaceId: auth.workspaceId, name })
|
|
932
|
+
).catch(async (err) => {
|
|
933
|
+
const { unknownDeleteOutcome } = await import("./ephemeral-command-CLJJKOFT.js");
|
|
934
|
+
const recordKept = holdsLanding(landingLockPath(args), auth.instance, { kind, name }) || kind === "ephemeral" && getEnvironment(readEphemeralState(process.cwd()), auth)?.name === name;
|
|
935
|
+
throw unknownDeleteOutcome(err, named, name, contextFlags(args), kind === "ephemeral" ? "ephemeral" : "tenant", recordKept);
|
|
936
|
+
});
|
|
937
|
+
if (alreadyGone && record === null) {
|
|
938
|
+
const { confirmMissEverywhere } = await import("./ephemeral-command-CLJJKOFT.js");
|
|
939
|
+
await confirmMissEverywhere(auth, name, "either", "tenant", `xanosdk tenant delete ${shellWord(name)}${answerFlags(args)}${contextFlags(args)}`);
|
|
940
|
+
}
|
|
941
|
+
let clearedLandingRecord = false;
|
|
942
|
+
if (kind === "ephemeral") {
|
|
943
|
+
clearedLandingRecord = forgetLanding(landingLockPath(args), auth.instance, { kind, name }) !== void 0;
|
|
944
|
+
const tracked = getEnvironment(readEphemeralState(process.cwd()), auth);
|
|
945
|
+
if (tracked?.name === name) clearedLandingRecord = clearEnvironment(process.cwd(), auth) || clearedLandingRecord;
|
|
946
|
+
}
|
|
947
|
+
const clearedNote = kind === "ephemeral" && clearedLandingRecord ? " (cleared its local record)" : "";
|
|
948
|
+
if (alreadyGone) {
|
|
949
|
+
warn(
|
|
950
|
+
record === null ? `No tenant or ephemeral named "${name}" \u2014 nothing was deleted.` : `${kind === "ephemeral" ? "Ephemeral" : "Tenant"} "${name}" was already gone${clearedNote}.`,
|
|
951
|
+
"tenant.not-found"
|
|
952
|
+
);
|
|
953
|
+
} else success(`Deleted ${named}${clearedNote}`);
|
|
954
|
+
if (kind !== "ephemeral") {
|
|
955
|
+
clearedLandingRecord = forgetLanding(landingLockPath(args), auth.instance, { kind, name }) !== void 0;
|
|
956
|
+
}
|
|
957
|
+
if (isMachineOutput(args)) {
|
|
958
|
+
writeJson({ verb: "delete", destination, name, deleted: !alreadyGone, alreadyGone, declined: false, clearedLandingRecord });
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
export {
|
|
962
|
+
constraintStop,
|
|
963
|
+
runTenantCommand
|
|
964
|
+
};
|
|
965
|
+
//# sourceMappingURL=tenant-command-D5HGI2X4.js.map
|