@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.
Files changed (336) hide show
  1. package/CHANGELOG.md +788 -0
  2. package/LICENSE +21 -0
  3. package/README.md +541 -0
  4. package/dist/.build-fingerprint +1 -0
  5. package/dist/agent-file-refresh-ZEMK33AX.js +38 -0
  6. package/dist/answer-shape-K67TAAPY.js +33 -0
  7. package/dist/backend-dir-2U53CIAL.js +39 -0
  8. package/dist/backend-slot-7QXW2QYC.js +28 -0
  9. package/dist/bin.d.ts +1 -0
  10. package/dist/bin.js +255 -0
  11. package/dist/branch-NCRNWQBQ.js +61 -0
  12. package/dist/branch-commands-ACIRCEQJ.js +79 -0
  13. package/dist/bundle.d.ts +223 -0
  14. package/dist/bundle.js +153 -0
  15. package/dist/capture-WAXPD7DR.js +41 -0
  16. package/dist/chunk-27GWNP2I.js +23 -0
  17. package/dist/chunk-2CMJZDCL.js +177 -0
  18. package/dist/chunk-2EZ3ZJZZ.js +302 -0
  19. package/dist/chunk-2GNFDZA2.js +390 -0
  20. package/dist/chunk-2MNLRIOX.js +11 -0
  21. package/dist/chunk-2TFRR6JV.js +104 -0
  22. package/dist/chunk-2ZUEE4EK.js +408 -0
  23. package/dist/chunk-36JUQZVQ.js +22 -0
  24. package/dist/chunk-3DRXWLJ5.js +83 -0
  25. package/dist/chunk-3JDU4VRL.js +137 -0
  26. package/dist/chunk-3KZCLN4Z.js +241 -0
  27. package/dist/chunk-3LDULPRE.js +168 -0
  28. package/dist/chunk-3M4LFYNQ.js +111 -0
  29. package/dist/chunk-3XI5CTUE.js +22 -0
  30. package/dist/chunk-3YW23UFH.js +50 -0
  31. package/dist/chunk-45UIT5T2.js +862 -0
  32. package/dist/chunk-4BW2SG2N.js +46 -0
  33. package/dist/chunk-4KHEMC32.js +79 -0
  34. package/dist/chunk-4POWHT2K.js +321 -0
  35. package/dist/chunk-4Q2GN7NW.js +192 -0
  36. package/dist/chunk-5A2PLKZB.js +70 -0
  37. package/dist/chunk-5FBYXK5P.js +159 -0
  38. package/dist/chunk-5HVXPTU4.js +323 -0
  39. package/dist/chunk-5QU2P5CA.js +304 -0
  40. package/dist/chunk-5V5XU32D.js +191 -0
  41. package/dist/chunk-5ZSO4T2G.js +10 -0
  42. package/dist/chunk-622HUCZT.js +10 -0
  43. package/dist/chunk-65HWOMGV.js +177 -0
  44. package/dist/chunk-6ELFRN3P.js +365 -0
  45. package/dist/chunk-6HO3NCSJ.js +1055 -0
  46. package/dist/chunk-6IUMKYWI.js +457 -0
  47. package/dist/chunk-6KEB3C3U.js +65 -0
  48. package/dist/chunk-6MR5TI5V.js +987 -0
  49. package/dist/chunk-6NNTNXN7.js +157 -0
  50. package/dist/chunk-6PBR37LN.js +97 -0
  51. package/dist/chunk-6QXLMMT3.js +155 -0
  52. package/dist/chunk-6ZGJCBZS.js +224 -0
  53. package/dist/chunk-73IVBKMA.js +250 -0
  54. package/dist/chunk-7G3CTU7I.js +286 -0
  55. package/dist/chunk-A3UDOZB6.js +222 -0
  56. package/dist/chunk-A6E77GDW.js +85 -0
  57. package/dist/chunk-AHJWCYQO.js +660 -0
  58. package/dist/chunk-AKNCFVKZ.js +36 -0
  59. package/dist/chunk-AM4FKL4J.js +237 -0
  60. package/dist/chunk-AN6BL47T.js +26 -0
  61. package/dist/chunk-AOSYVMUS.js +147 -0
  62. package/dist/chunk-APWXY5SL.js +182 -0
  63. package/dist/chunk-AWEIIR2U.js +218 -0
  64. package/dist/chunk-AWQ7BQTQ.js +73 -0
  65. package/dist/chunk-BAUZOWGX.js +393 -0
  66. package/dist/chunk-BHACRS6R.js +940 -0
  67. package/dist/chunk-BWPNT55T.js +680 -0
  68. package/dist/chunk-C6RIMRU4.js +187 -0
  69. package/dist/chunk-CGVQZXYG.js +263 -0
  70. package/dist/chunk-CIMQZRRE.js +162 -0
  71. package/dist/chunk-CJHQKJU4.js +113 -0
  72. package/dist/chunk-CTMO46PK.js +1897 -0
  73. package/dist/chunk-D53J55C5.js +106 -0
  74. package/dist/chunk-D7VGG3WS.js +90 -0
  75. package/dist/chunk-DAD3ONIS.js +245 -0
  76. package/dist/chunk-DGWHAVRG.js +162 -0
  77. package/dist/chunk-DX4QR4B2.js +483 -0
  78. package/dist/chunk-EHP3WPEG.js +21 -0
  79. package/dist/chunk-ELP2HMXC.js +432 -0
  80. package/dist/chunk-ERVIASGL.js +21 -0
  81. package/dist/chunk-ET4Y4XCB.js +865 -0
  82. package/dist/chunk-ETO6LGLD.js +4750 -0
  83. package/dist/chunk-EUUUMY7J.js +24 -0
  84. package/dist/chunk-FQJ2TTHP.js +218 -0
  85. package/dist/chunk-FQOF7E2E.js +133 -0
  86. package/dist/chunk-FWD7AL6N.js +21 -0
  87. package/dist/chunk-FXFV3KU6.js +138 -0
  88. package/dist/chunk-FXRQOWTE.js +171 -0
  89. package/dist/chunk-G554NZNI.js +210 -0
  90. package/dist/chunk-GSGDWJB5.js +13 -0
  91. package/dist/chunk-H2V3N23D.js +66 -0
  92. package/dist/chunk-H5C7MBCR.js +159 -0
  93. package/dist/chunk-HHN734BU.js +371 -0
  94. package/dist/chunk-HRVBLCVJ.js +243 -0
  95. package/dist/chunk-HVRUQXGD.js +1264 -0
  96. package/dist/chunk-I4F5TCJH.js +130 -0
  97. package/dist/chunk-IDOTCMDV.js +57 -0
  98. package/dist/chunk-IGOLHKWF.js +427 -0
  99. package/dist/chunk-JGE7CAWB.js +148 -0
  100. package/dist/chunk-JTUKLCXS.js +92 -0
  101. package/dist/chunk-JZGVVJSI.js +66 -0
  102. package/dist/chunk-K4WX6UUU.js +923 -0
  103. package/dist/chunk-K5BBGTYZ.js +217 -0
  104. package/dist/chunk-K6RXBGUB.js +427 -0
  105. package/dist/chunk-KTSDSD36.js +165 -0
  106. package/dist/chunk-L5JYN3NM.js +1038 -0
  107. package/dist/chunk-LIEOKXKD.js +354 -0
  108. package/dist/chunk-LLNZGEFK.js +51 -0
  109. package/dist/chunk-LPECSJ2J.js +55 -0
  110. package/dist/chunk-LQCMKAJ7.js +413 -0
  111. package/dist/chunk-LRN4ZJCQ.js +1145 -0
  112. package/dist/chunk-MJ4ZVHKN.js +17 -0
  113. package/dist/chunk-MXHSQOC4.js +3061 -0
  114. package/dist/chunk-N5GKCWE5.js +367 -0
  115. package/dist/chunk-NA3PXMEF.js +10 -0
  116. package/dist/chunk-NAQDMEHV.js +76 -0
  117. package/dist/chunk-NWKXM5RD.js +109 -0
  118. package/dist/chunk-NZOWWHU5.js +196 -0
  119. package/dist/chunk-OHX6MIUZ.js +184 -0
  120. package/dist/chunk-OOXWYAA4.js +15 -0
  121. package/dist/chunk-OPHB5ORL.js +1990 -0
  122. package/dist/chunk-OXA6PSZT.js +1725 -0
  123. package/dist/chunk-P2HAGF6H.js +73 -0
  124. package/dist/chunk-PTHVMXZI.js +3036 -0
  125. package/dist/chunk-PZ5AY32C.js +10 -0
  126. package/dist/chunk-Q325JKYB.js +189 -0
  127. package/dist/chunk-Q7DGTQ5G.js +255 -0
  128. package/dist/chunk-QCNYHBL7.js +601 -0
  129. package/dist/chunk-QO6BVGS5.js +145 -0
  130. package/dist/chunk-QXTKSOFI.js +76 -0
  131. package/dist/chunk-ROY4YAEQ.js +66 -0
  132. package/dist/chunk-RTJRZFFY.js +447 -0
  133. package/dist/chunk-SAVJUS2X.js +128 -0
  134. package/dist/chunk-SFLHVCKX.js +173 -0
  135. package/dist/chunk-STSFNCY4.js +127 -0
  136. package/dist/chunk-SWBF2LTK.js +170 -0
  137. package/dist/chunk-T5KELPAR.js +109 -0
  138. package/dist/chunk-TFFGOFVZ.js +1481 -0
  139. package/dist/chunk-TLHIFK4M.js +256 -0
  140. package/dist/chunk-TLQE7ZN3.js +156 -0
  141. package/dist/chunk-TPHWJ7UG.js +1981 -0
  142. package/dist/chunk-TRJCALW3.js +291 -0
  143. package/dist/chunk-TTEIYD5P.js +133 -0
  144. package/dist/chunk-U64O2MXY.js +407 -0
  145. package/dist/chunk-UCQ2VUTG.js +630 -0
  146. package/dist/chunk-UTI5G6OJ.js +44 -0
  147. package/dist/chunk-UVHDMMIP.js +188 -0
  148. package/dist/chunk-UZ6QQWJT.js +120 -0
  149. package/dist/chunk-VAX3UZOY.js +686 -0
  150. package/dist/chunk-W3HBUKFO.js +57 -0
  151. package/dist/chunk-WKQLGKCL.js +2823 -0
  152. package/dist/chunk-WQFNASK4.js +560 -0
  153. package/dist/chunk-WRBKLYSJ.js +224 -0
  154. package/dist/chunk-WTPZRR4I.js +17 -0
  155. package/dist/chunk-WZDJ2LLX.js +2385 -0
  156. package/dist/chunk-X2NL4KUO.js +14 -0
  157. package/dist/chunk-X4DVXBFY.js +38 -0
  158. package/dist/chunk-X677DMZM.js +7050 -0
  159. package/dist/chunk-XBKMWY7F.js +612 -0
  160. package/dist/chunk-XNCP4KYO.js +78 -0
  161. package/dist/chunk-XVBGLISP.js +35 -0
  162. package/dist/chunk-XW6KISBB.js +1192 -0
  163. package/dist/chunk-YGZHHAAB.js +8156 -0
  164. package/dist/chunk-YHEFQUQB.js +186 -0
  165. package/dist/chunk-YLDALTWZ.js +653 -0
  166. package/dist/chunk-YU4HSQW7.js +229 -0
  167. package/dist/chunk-ZDPP6RKB.js +27 -0
  168. package/dist/chunk-ZFDZKNGG.js +194 -0
  169. package/dist/chunk-ZIY7RNUT.js +49 -0
  170. package/dist/chunk-ZYJP6BOO.js +30 -0
  171. package/dist/cli.d.ts +1111 -0
  172. package/dist/cli.js +165 -0
  173. package/dist/codegen-command-VR2GWR6C.js +173 -0
  174. package/dist/codegen.d.ts +115 -0
  175. package/dist/codegen.js +19 -0
  176. package/dist/commands-GJMJ4XYZ.js +76 -0
  177. package/dist/completion-ZQLO6PB6.js +738 -0
  178. package/dist/config-MBYGCAFK.js +136 -0
  179. package/dist/deploy-command-JVZPWHMK.js +180 -0
  180. package/dist/deploy-source-3W45CXMP.js +81 -0
  181. package/dist/dev-env-sync-HN44K4D5.js +188 -0
  182. package/dist/diagnostics-UEAAHWVF.js +30 -0
  183. package/dist/display-name-hint-ABBPVQIR.js +46 -0
  184. package/dist/emit-CyhBDxli.d.ts +7007 -0
  185. package/dist/env-example-refresh-ET5HMMDW.js +126 -0
  186. package/dist/env-pull-command-TNMNB3CV.js +323 -0
  187. package/dist/env-target-O4HRKTGZ.js +40 -0
  188. package/dist/env-var-command-ZIRDCAZA.js +427 -0
  189. package/dist/ephemeral-P7F3PMAD.js +54 -0
  190. package/dist/ephemeral-command-CLJJKOFT.js +592 -0
  191. package/dist/ephemeral-state-PYCBSOGX.js +61 -0
  192. package/dist/file-lock-PT74GWYW.js +10 -0
  193. package/dist/generate-command-AYEOLA26.js +510 -0
  194. package/dist/gitignore-3SJ3WNRG.js +51 -0
  195. package/dist/guards-4EBNCZDC.js +162 -0
  196. package/dist/hosted-file-PSHJB3HX.js +28 -0
  197. package/dist/impersonate-command-5JAS3WSV.js +152 -0
  198. package/dist/import-EQSFU6JC.js +19 -0
  199. package/dist/index.d.ts +5470 -0
  200. package/dist/index.js +371 -0
  201. package/dist/init-command-X2FR4UAK.js +125 -0
  202. package/dist/init-modules-RY7UHAOL.js +50 -0
  203. package/dist/init-web-M4YZSZK6.js +42 -0
  204. package/dist/internal.d.ts +179 -0
  205. package/dist/internal.js +2634 -0
  206. package/dist/io-RC56QSN5.js +26 -0
  207. package/dist/keep-data-merge-7MPLVAVI.js +1119 -0
  208. package/dist/lambda-config-reconcile-OUZ4OYAB.js +116 -0
  209. package/dist/landed-753YLJ5H.js +40 -0
  210. package/dist/landing-record-SU52SKXU.js +61 -0
  211. package/dist/live-diff-YONW2VI3.js +65 -0
  212. package/dist/local-engine-choice-CH5X3W7E.js +79 -0
  213. package/dist/local-engine-command-Z3OL7VOD.js +766 -0
  214. package/dist/local-engine-config-5U3SC434.js +39 -0
  215. package/dist/local-engine-deploy-PCQ4SNPB.js +39 -0
  216. package/dist/local-engine-process-EHTE5LLU.js +63 -0
  217. package/dist/local-engine-state-A4FTRFAF.js +32 -0
  218. package/dist/local-engine-update-check-6L645VBL.js +162 -0
  219. package/dist/lock-MRRHW5GS.js +87 -0
  220. package/dist/lock-commands-2QG25HL7.js +963 -0
  221. package/dist/login-command-QPYRWOXZ.js +538 -0
  222. package/dist/logout-command-WOIQLDP6.js +56 -0
  223. package/dist/loop-ALIZLOSX.js +191 -0
  224. package/dist/marketplace-command-K5YL42NO.js +977 -0
  225. package/dist/marketplace-resolve-LY32JES5.js +40 -0
  226. package/dist/meta-client-YXGPW53C.js +244 -0
  227. package/dist/module-manifest-JFGHU2TC.js +38 -0
  228. package/dist/near-key.d.ts +13 -0
  229. package/dist/near-key.js +8 -0
  230. package/dist/node.d.ts +95 -0
  231. package/dist/node.js +969 -0
  232. package/dist/operation-outcome-TZSESNC7.js +51 -0
  233. package/dist/output-target-AL3I44GG.js +47 -0
  234. package/dist/package-manager-PRAHUSCN.js +34 -0
  235. package/dist/plan-disclosure-6G4MLZKD.js +114 -0
  236. package/dist/plugin-contributions-WRNY5ABG.js +28 -0
  237. package/dist/plugin-prompt-4VA3B4FF.js +20 -0
  238. package/dist/plugin-questions-JTSYA74Q.js +24 -0
  239. package/dist/plugin.d.ts +396 -0
  240. package/dist/plugin.js +1 -0
  241. package/dist/preflight-command-2T5Z36MI.js +321 -0
  242. package/dist/profile-command-AH3PIM4X.js +800 -0
  243. package/dist/profile-pointer-GRWJU3YD.js +31 -0
  244. package/dist/profile-select-74TRDEPD.js +23 -0
  245. package/dist/project-dependency-KSH63ODT.js +35 -0
  246. package/dist/project-sdk-REPPOIBD.js +24 -0
  247. package/dist/promote-command-PCWT5N6S.js +140 -0
  248. package/dist/prompt-II3F3LND.js +27 -0
  249. package/dist/publish-command-TTDUUJI5.js +414 -0
  250. package/dist/pull-command-VBO7C4S3.js +161 -0
  251. package/dist/pull-superseded-GJWLG7XO.js +20 -0
  252. package/dist/release-command-N4ZPKMHR.js +146 -0
  253. package/dist/release-ns-command-3KFDMZ6G.js +1745 -0
  254. package/dist/response-HlXahv4K.d.ts +925 -0
  255. package/dist/retry-command-AS5EVREX.js +34 -0
  256. package/dist/routes-manifest-SNWUVBT6.js +43 -0
  257. package/dist/runtime-XETHVF33.js +14 -0
  258. package/dist/scaffold.d.ts +1911 -0
  259. package/dist/scaffold.js +107 -0
  260. package/dist/secrets-file-LVZD6IIM.js +56 -0
  261. package/dist/secrets-fill-command-TTCPSVXN.js +218 -0
  262. package/dist/seed-VU7C3QYS.js +46 -0
  263. package/dist/sent-writes-N7X4OVXT.js +22 -0
  264. package/dist/source-resolve-S2XA3XZF.js +83 -0
  265. package/dist/static-host-B2Y6AG3W.js +352 -0
  266. package/dist/status-command-RUDXTF7I.js +554 -0
  267. package/dist/store-6VNCD4D7.js +20 -0
  268. package/dist/store-ARM6VMO5.js +98 -0
  269. package/dist/store-DuYfzKlW.d.ts +3144 -0
  270. package/dist/suggest-6FOOYKHG.js +12 -0
  271. package/dist/sveltekit.d.ts +154 -0
  272. package/dist/sveltekit.js +109 -0
  273. package/dist/sync-contributions-UCEROO26.js +415 -0
  274. package/dist/table-ENAVMITR.js +42 -0
  275. package/dist/tables-command-GUPXXSB5.js +156 -0
  276. package/dist/tenant-IIHPOHGP.js +42 -0
  277. package/dist/tenant-command-D5HGI2X4.js +965 -0
  278. package/dist/test-command-TIKZMDPZ.js +476 -0
  279. package/dist/tests-BGGIOK3L.js +26 -0
  280. package/dist/token-NICJUTMT.js +72 -0
  281. package/dist/toolchain-hooks-GHKLUJOH.js +96 -0
  282. package/dist/toolchain-modules-5EAZUONB.js +24 -0
  283. package/dist/tracked-backend-EIBUMDZA.js +80 -0
  284. package/dist/update-check-2W2NLDTC.js +136 -0
  285. package/dist/upgrade-command-QHNFWM7O.js +531 -0
  286. package/dist/verify-rollout-DRCK5TDD.js +61 -0
  287. package/dist/whoami-command-STGINTXH.js +51 -0
  288. package/dist/workspace-2CLHU2LK.js +93 -0
  289. package/dist/workspace-binding-56PIIPCP.js +54 -0
  290. package/dist/workspace-command-JEXQETJD.js +535 -0
  291. package/dist/workspace-env-F2RFMSC5.js +70 -0
  292. package/dist/workspace-export-OJSH2HIW.js +21 -0
  293. package/dist/writable-VA7OISSK.js +25 -0
  294. package/dist/xano-ICFUSPFR.js +42 -0
  295. package/dist/xanosdk-import-GN42TO2B.js +56 -0
  296. package/dist/xanosdk-project-S6DXJONQ.js +41 -0
  297. package/dist/xdo-CxDr2Q1C.d.ts +1371 -0
  298. package/guides/README.md +33 -0
  299. package/guides/authoring.md +921 -0
  300. package/guides/cli.md +401 -0
  301. package/guides/codegen.md +177 -0
  302. package/guides/codes.md +404 -0
  303. package/guides/coverage.md +74 -0
  304. package/guides/deploying.md +1525 -0
  305. package/guides/environment.md +400 -0
  306. package/guides/marketplace.md +415 -0
  307. package/guides/module-contract.md +558 -0
  308. package/guides/object-kinds.md +433 -0
  309. package/guides/project-structure.md +43 -0
  310. package/guides/scaffold.md +351 -0
  311. package/guides/typed-frontend.md +242 -0
  312. package/llms/client.md +63 -0
  313. package/llms/errors.md +56 -0
  314. package/llms/fields.md +176 -0
  315. package/llms/filters.md +183 -0
  316. package/llms/kinds-agent-mcp.md +30 -0
  317. package/llms/kinds-core.md +100 -0
  318. package/llms/kinds-knowledge.md +20 -0
  319. package/llms/kinds-realtime.md +76 -0
  320. package/llms/lambda.md +94 -0
  321. package/llms/legacy.md +44 -0
  322. package/llms/lock.md +40 -0
  323. package/llms/object-kinds.md +34 -0
  324. package/llms/statements-calls.md +62 -0
  325. package/llms/statements-catalog.md +320 -0
  326. package/llms/statements-data.md +66 -0
  327. package/llms/statements-runtime.md +68 -0
  328. package/llms/tests.md +59 -0
  329. package/llms/toolchain.md +16 -0
  330. package/llms/triggers.md +36 -0
  331. package/llms/values.md +29 -0
  332. package/llms-full.txt +2085 -0
  333. package/llms.txt +493 -0
  334. package/manifest.json +11224 -0
  335. package/package.json +162 -0
  336. package/types/lambda-globals.d.ts +129 -0
@@ -0,0 +1,940 @@
1
+ import {
2
+ createOperation,
3
+ runOperation
4
+ } from "./chunk-TLHIFK4M.js";
5
+ import {
6
+ fetchWorkspaceBundle
7
+ } from "./chunk-X677DMZM.js";
8
+ import {
9
+ assertReleaseIdentitiesFree,
10
+ pinnedCanonicalGuids,
11
+ setLiveRollback
12
+ } from "./chunk-WKQLGKCL.js";
13
+ import {
14
+ liveBranchMismatch,
15
+ liveMismatch
16
+ } from "./chunk-K6RXBGUB.js";
17
+ import {
18
+ confirm
19
+ } from "./chunk-65HWOMGV.js";
20
+ import {
21
+ landingLockPath,
22
+ recordForeignLanding
23
+ } from "./chunk-CGVQZXYG.js";
24
+ import {
25
+ CONSTRAINT_FIX,
26
+ CONSTRAINT_PHRASE,
27
+ additiveChanges,
28
+ alteringChanges,
29
+ assertStorageModesKept,
30
+ constraintStop,
31
+ constraintWhere,
32
+ discloseCanonicalMoves,
33
+ discloseTableEffects,
34
+ droppedAndAdded,
35
+ movesClause,
36
+ namedConstraint,
37
+ readOnce,
38
+ releaseCanonicalMoves,
39
+ releaseTableEffects,
40
+ renameHint,
41
+ tableEffectsPayload
42
+ } from "./chunk-BWPNT55T.js";
43
+ import {
44
+ tableRowCounter
45
+ } from "./chunk-C6RIMRU4.js";
46
+ import {
47
+ asWorkspaceArchive,
48
+ resolveProjectEntry
49
+ } from "./chunk-AOSYVMUS.js";
50
+ import {
51
+ exportWorkspaceBundle
52
+ } from "./chunk-CJHQKJU4.js";
53
+ import {
54
+ decodeWorkspaceArchive
55
+ } from "./chunk-3DRXWLJ5.js";
56
+ import {
57
+ SettledWriteFailure,
58
+ classifyFailure
59
+ } from "./chunk-A6E77GDW.js";
60
+ import {
61
+ BranchTakenError,
62
+ assertBranchAbsent,
63
+ assertUsableBranchLabel,
64
+ derivedLabelTail,
65
+ findBranch,
66
+ freeBranchLabel,
67
+ listBranchListing,
68
+ liveBranchLabel,
69
+ setLiveBranch
70
+ } from "./chunk-TRJCALW3.js";
71
+ import {
72
+ envValuesOf
73
+ } from "./chunk-45UIT5T2.js";
74
+ import {
75
+ assertOneName
76
+ } from "./chunk-ZIY7RNUT.js";
77
+ import {
78
+ resolveSource
79
+ } from "./chunk-QCNYHBL7.js";
80
+ import {
81
+ ReleaseHttpError,
82
+ UNPROMOTABLE_RELEASE_PARTS,
83
+ deployRelease,
84
+ downloadRelease,
85
+ promotableReleaseName,
86
+ unpromotableReleasePart,
87
+ untenantDeployableReleasePart
88
+ } from "./chunk-2ZUEE4EK.js";
89
+ import {
90
+ getAccessToken
91
+ } from "./chunk-ET4Y4XCB.js";
92
+ import {
93
+ pipedYes,
94
+ retryCommand,
95
+ withheldNote
96
+ } from "./chunk-T5KELPAR.js";
97
+ import {
98
+ contextFlags
99
+ } from "./chunk-NAQDMEHV.js";
100
+ import {
101
+ shellWord
102
+ } from "./chunk-FWD7AL6N.js";
103
+ import {
104
+ readLockFile
105
+ } from "./chunk-P2HAGF6H.js";
106
+ import {
107
+ withoutReadAftermath
108
+ } from "./chunk-YLDALTWZ.js";
109
+ import {
110
+ CliError,
111
+ LocalFileNotFoundError,
112
+ UsageError,
113
+ blank,
114
+ credentialWriteTarget,
115
+ detail,
116
+ discloseWriteTarget,
117
+ error,
118
+ info,
119
+ isMachineOutput,
120
+ parseSource,
121
+ pastePath,
122
+ step,
123
+ success,
124
+ warn,
125
+ withoutUrls
126
+ } from "./chunk-PTHVMXZI.js";
127
+ import {
128
+ envNamesRead
129
+ } from "./chunk-YGZHHAAB.js";
130
+ import {
131
+ safeNames
132
+ } from "./chunk-GSGDWJB5.js";
133
+ import {
134
+ setDiagnosticSink
135
+ } from "./chunk-2EZ3ZJZZ.js";
136
+ import {
137
+ sdkKindName2 as sdkKindName
138
+ } from "./chunk-6MR5TI5V.js";
139
+ import {
140
+ shellQuote
141
+ } from "./chunk-5ZSO4T2G.js";
142
+
143
+ // src/emit/promote-command.ts
144
+ import { existsSync, statSync } from "fs";
145
+
146
+ // src/emit/env-landing-report.ts
147
+ async function reportEnvLanding(auth, opts) {
148
+ if (opts.release.id === void 0) return;
149
+ try {
150
+ const archive = opts.loadArchive !== void 0 ? await opts.loadArchive() : decodeWorkspaceArchive(
151
+ await downloadRelease(auth, {
152
+ workspaceId: opts.releaseHost.workspaceId,
153
+ id: opts.release.id,
154
+ base: opts.releaseHost.base
155
+ })
156
+ );
157
+ const releaseEnv = envValuesOf(archive);
158
+ const read = envNamesRead(payloadSections(archive));
159
+ const named = [.../* @__PURE__ */ new Set([...releaseEnv.keys(), ...read])];
160
+ if (named.length === 0) return;
161
+ const live = opts.loadLive !== void 0 ? await opts.loadLive() : await exportWorkspaceBundle(auth, {
162
+ base: opts.target.base,
163
+ workspaceId: opts.target.workspaceId,
164
+ label: `reading ${opts.targetLabel}`,
165
+ // This reads a destination someone keeps. A failure here must not echo a
166
+ // response body, for the same reason `env pull` must not.
167
+ safeErrors: true
168
+ });
169
+ const destination = envValuesOf(live);
170
+ const missing = named.filter((name) => !destination.has(name));
171
+ const created = missing.filter((name) => releaseEnv.has(name));
172
+ if (created.length > 0) {
173
+ warn(
174
+ `${created.length} env var${created.length === 1 ? "" : "s"} in "${opts.release.name}" ${created.length === 1 ? "is" : "are"} NOT set on ${opts.targetLabel} and will be CREATED carrying the value the release was cut with: ${safeNames(created)}.`,
175
+ "release.env-created",
176
+ [
177
+ `Every other name keeps ${opts.targetLabel}'s own value \u2014 a release merge is add-only by name.`,
178
+ `Set these on the destination first if they should differ there.`
179
+ ]
180
+ );
181
+ }
182
+ const unset = missing.filter((name) => !releaseEnv.has(name));
183
+ if (unset.length > 0) {
184
+ const one = unset.length === 1;
185
+ warn(
186
+ `Release "${opts.release.name}" reads ${unset.length} env var${one ? "" : "s"} ${opts.targetLabel} doesn't set: ${safeNames(unset)}. A release carries no env values, so ${one ? "it reads" : "they read"} as null there until set \u2014 run:`,
187
+ "release.env-unset",
188
+ unset.map((name) => `printf %s "$VALUE" | xanosdk env set ${shellQuote(name)}${opts.envSetTo}`)
189
+ );
190
+ }
191
+ } catch (err) {
192
+ detail(
193
+ `Could not check which env vars this release reads that the destination lacks (${withoutUrls(((err instanceof Error ? err.message : String(err)).trim().split("\n")[0] ?? "").replace(/[.:]$/, ""))}).`
194
+ );
195
+ }
196
+ }
197
+ function payloadSections(archive) {
198
+ const payload = archive?.payload;
199
+ const out = {};
200
+ if (payload === null || typeof payload !== "object") return out;
201
+ for (const [key, value] of Object.entries(payload)) if (Array.isArray(value)) out[key] = value;
202
+ return out;
203
+ }
204
+
205
+ // src/emit/promote-command.ts
206
+ function derivedPromoteLabel(releaseName, now, random) {
207
+ return `${promoteLabelStem(releaseName)}-${derivedLabelTail(now, random)}`;
208
+ }
209
+ function promoteLabelStem(releaseName) {
210
+ const stem = releaseName.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[-.]+|-+$/g, "");
211
+ return stem === "" ? "release" : stem;
212
+ }
213
+ function isDerivedPromoteLabel(label, releaseName) {
214
+ const stem = promoteLabelStem(releaseName);
215
+ return label.startsWith(`${stem}-`) && /^\d{8}T\d{6}Z-[0-9a-f]{4}$/.test(label.slice(stem.length + 1));
216
+ }
217
+ var MERGE_ONLY = [
218
+ { key: "prune", flag: "--prune" },
219
+ { key: "replace", flag: "--replace" },
220
+ { key: "resetData", flag: "--reset-data" },
221
+ { key: "seed", flag: "--seed" },
222
+ { key: "dryRun", flag: "--dry-run" }
223
+ ];
224
+ function assertNoBackupFlag(args) {
225
+ if (args.backupBranch === void 0) return;
226
+ throw new UsageError(
227
+ `\`--backup-branch\` snapshots the live branch before an import overwrites it, and a promote overwrites nothing: the release lands on a branch of its own and the live one keeps serving until \`--set-live\`. There is no point to snapshot.
228
+ \`xanosdk deploy --to workspace${contextFlags(args)}\` is the path that imports over live, and the one that has it.`,
229
+ // Both flags parsed fine; the sentence says what to drop, so a pointer, not the block.
230
+ { hintFor: { command: "promote" } }
231
+ );
232
+ }
233
+ function assertNoMergeFlags(args) {
234
+ const passed = MERGE_ONLY.filter((f) => args[f.key] !== void 0 && args[f.key] !== false);
235
+ if (passed.length === 0) return;
236
+ const names = passed.map((f) => f.flag);
237
+ throw new UsageError(
238
+ `${names.join(" and ")} ${names.length === 1 ? "scopes" : "scope"} a merge computed from a local build, and a promote lands a release the server already holds \u2014 there is nothing here for ${names.length === 1 ? "it" : "them"} to act on. \`xanosdk deploy --to workspace${contextFlags(args)}\` is the path that has ${names.length === 1 ? "it" : "them"}.`,
239
+ { helpFor: { command: "promote" } }
240
+ );
241
+ }
242
+ var EXIT_VERIFICATION_FAILED = 2;
243
+ var CANONICAL_SECTIONS = ["app", "toolset", "realtime_server"];
244
+ function sectionRows(bundle, key) {
245
+ const payload = bundle?.payload;
246
+ if (payload === null || typeof payload !== "object") return [];
247
+ const rows = payload[key];
248
+ return Array.isArray(rows) ? rows.filter((r) => r !== null && typeof r === "object") : [];
249
+ }
250
+ function canonicalMismatches(declared, landed, pinned) {
251
+ const out = [];
252
+ for (const key of CANONICAL_SECTIONS) {
253
+ const served = /* @__PURE__ */ new Map();
254
+ for (const row of sectionRows(landed, key)) {
255
+ if (typeof row.guid !== "string" || typeof row.canonical !== "string") continue;
256
+ served.set(row.guid, [...served.get(row.guid) ?? [], row.canonical]);
257
+ }
258
+ for (const row of sectionRows(declared, key)) {
259
+ const { guid, name, canonical } = row;
260
+ if (typeof guid !== "string" || guid === "" || typeof name !== "string") continue;
261
+ if (typeof canonical !== "string" || canonical === "") continue;
262
+ const there = served.get(guid);
263
+ if (there === void 0 || there.includes(canonical)) continue;
264
+ const kind = key === "toolset" ? row.type === "agent" ? "agent" : "mcpServer" : sdkKindName(key);
265
+ out.push({ kind, name, declared: canonical, served: there[0], pinned: pinned.has(guid) });
266
+ }
267
+ }
268
+ return out;
269
+ }
270
+ async function verifyLanding(auth, opts) {
271
+ const unverified = (reason) => ({
272
+ outcome: "unverified",
273
+ missing: [],
274
+ undeclared: [],
275
+ suffixed: [],
276
+ compared: 0,
277
+ canonicals: [],
278
+ reason
279
+ });
280
+ let declared;
281
+ try {
282
+ declared = await opts.loadArchive();
283
+ } catch {
284
+ return unverified("the release archive could not be read");
285
+ }
286
+ if (declared === void 0) {
287
+ return unverified("the release carries no id to read its archive from");
288
+ }
289
+ let landedBundle;
290
+ try {
291
+ landedBundle = await fetchWorkspaceBundle(auth, opts.branch);
292
+ } catch (err) {
293
+ return unverified(shortReason(err));
294
+ }
295
+ const { compareToLive, declaredLabels } = await import("./live-diff-YONW2VI3.js");
296
+ let result;
297
+ try {
298
+ result = compareToLive(declared, landedBundle, void 0, { sample: "all" });
299
+ } catch {
300
+ return unverified("the release archive and the landed branch could not be compared");
301
+ }
302
+ if (result.compared === 0) {
303
+ return unverified("the release archive declared no comparable objects");
304
+ }
305
+ const missing = [...new Set(result.missing)];
306
+ const undeclared = [...new Set(result.liveOnly)];
307
+ const canonicals = canonicalMismatches(declared, landedBundle, opts.pinned(declared));
308
+ return {
309
+ outcome: missing.length === 0 && !canonicals.some((c) => c.pinned) ? "passed" : "failed",
310
+ missing,
311
+ undeclared,
312
+ suffixed: suffixedSiblings(declaredLabels(declared), undeclared),
313
+ compared: result.compared,
314
+ canonicals
315
+ };
316
+ }
317
+ function shortReason(err) {
318
+ const raw = err instanceof Error ? withoutReadAftermath(err.message) : "the landed branch could not be read";
319
+ const scrubbed = withoutUrls(raw).replace(/\s+/g, " ").trim().replace(/\.+$/, "");
320
+ return scrubbed.length > 200 ? `${scrubbed.slice(0, 200)}\u2026` : scrubbed;
321
+ }
322
+ function verificationPayload(v) {
323
+ return {
324
+ outcome: v.outcome,
325
+ missing: v.missing,
326
+ undeclared: v.undeclared,
327
+ compared: v.compared,
328
+ canonicals: v.canonicals,
329
+ ...v.reason === void 0 ? {} : { reason: v.reason }
330
+ };
331
+ }
332
+ function suffixedSiblings(declared, undeclared) {
333
+ const stems = new Set(declared);
334
+ return undeclared.filter((entry) => {
335
+ const stripped = entry.replace(/_\d+( \(apiGroup .*\))?$/, "$1");
336
+ return stripped !== entry && stems.has(stripped);
337
+ });
338
+ }
339
+ function reportNotRun(target = "workspace", tablesBelow = true) {
340
+ const lines = [
341
+ tablesBelow ? "no plan preview, no prune scope \u2014 its table changes are checked against the destination below" : "no plan preview, no prune scope \u2014 its tables were checked against the destination, and it alters none there"
342
+ ];
343
+ if (target === "workspace") {
344
+ lines.push(
345
+ "and the release's workspace settings (preferences, request history, realtime, workspace middleware) apply to the whole workspace \u2014 they are shared by every branch; its name and description are kept"
346
+ );
347
+ }
348
+ lines.push("what it has instead: a named release that came up and answered, and can be re-landed");
349
+ warn(
350
+ "This lands a release the server holds, so the local pre-flight did not run:",
351
+ target === "tenant" ? "tenant.server-release" : "promote.server-release",
352
+ lines
353
+ );
354
+ }
355
+ function archiveLoader(auth, release, host) {
356
+ let bytes;
357
+ let decoded;
358
+ const loadBytes = async () => {
359
+ if (bytes !== void 0) return bytes;
360
+ if (release.id === void 0) return void 0;
361
+ bytes = await downloadRelease(auth, {
362
+ workspaceId: host.workspaceId,
363
+ id: release.id,
364
+ base: host.base
365
+ });
366
+ return bytes;
367
+ };
368
+ return {
369
+ bytes: loadBytes,
370
+ decoded: async () => {
371
+ if (decoded !== void 0) return decoded;
372
+ const raw = await loadBytes();
373
+ if (raw === void 0) return void 0;
374
+ decoded = decodeWorkspaceArchive(raw);
375
+ return decoded;
376
+ }
377
+ };
378
+ }
379
+ function gatedTableChanges(e) {
380
+ return alteringChanges({ ...e, indexChanges: e.indexChanges.filter((c) => c.action === "add" && c.unique) });
381
+ }
382
+ var LandingIncompleteError = class extends Error {
383
+ name = "LandingIncompleteError";
384
+ exitCode = EXIT_VERIFICATION_FAILED;
385
+ };
386
+ var PROMOTE_WITHOUT_BRANCH = "drop the flag to land on a new branch named after the release (add `--set-live` to make it live)";
387
+ async function projectSeededTables(entry) {
388
+ if (entry === void 0) return void 0;
389
+ const previous = setDiagnosticSink(() => {
390
+ });
391
+ try {
392
+ const { loadDefault } = await import("./cli.js");
393
+ const registry = await loadDefault(entry);
394
+ if (typeof registry?.tables !== "function") return /* @__PURE__ */ new Set();
395
+ return new Set(
396
+ registry.tables().filter((t) => t.seed !== void 0 && typeof t.name === "string").map((t) => t.name)
397
+ );
398
+ } catch {
399
+ return void 0;
400
+ } finally {
401
+ setDiagnosticSink(previous);
402
+ }
403
+ }
404
+ async function seedRowRemedies(release, tables, flags, named) {
405
+ const entry = named ?? resolveProjectEntry(process.cwd());
406
+ const seededHere = await projectSeededTables(entry);
407
+ const resettable = seededHere === void 0 ? [] : tables.filter((t) => seededHere.has(t.name) && t.guid !== void 0);
408
+ const r = shellWord(release.name);
409
+ const before = [
410
+ `The release's rows land with a deploy of the release: \`xanosdk deploy release:${r}${flags}\` on this project's ephemeral, or \`xanosdk tenant deploy <tenant> ${r}${flags}\` on a tenant.`
411
+ ];
412
+ if (resettable.length === 0) return { before };
413
+ const one = resettable.length === 1;
414
+ return {
415
+ before,
416
+ afterLanding: `This project seeds ${resettable.map((t) => t.name).join(", ")} in code: \`xanosdk workspace reset-tables ${shellWord(pastePath(entry))}${resettable.map((t) => ` --table ${shellWord(t.guid)}`).join("")} --write${flags}\` writes ${one ? "its" : "their"} project rows into the workspace.`
417
+ };
418
+ }
419
+ function assertPromotableName(name, args) {
420
+ const part = unpromotableReleasePart(name);
421
+ if (part === void 0) return;
422
+ const flags = contextFlags(args);
423
+ const renamed = promotableReleaseName(name);
424
+ throw new UsageError(
425
+ `Release "${name}" cannot be promoted: its name holds \`${part}\`, and the route a promote lands a release by cannot address a name holding ${UNPROMOTABLE_RELEASE_PARTS}. Nothing was sent.
426
+ Cut it again as \`xanosdk release create ${shellWord(renamed)}\` from the source \`xanosdk release show ${shellWord(name)}${flags}\` names, and promote that.` + (untenantDeployableReleasePart(name) === void 0 ? ` \`xanosdk tenant deploy <tenant> ${shellWord(name)}${flags}\` still lands this one on a tenant.` : ""),
427
+ { hintFor: { command: "promote" } }
428
+ );
429
+ }
430
+ async function runPromoteCommand(args) {
431
+ assertNoMergeFlags(args);
432
+ assertNoBackupFlag(args);
433
+ if (args.expectLive !== void 0 && args.setLive !== true) {
434
+ throw new UsageError(
435
+ `\`--expect-live\` guards the switch to live, and without \`--set-live\` a promote never switches: the release lands on a branch of its own and live keeps serving. Add \`--set-live\`, or drop \`--expect-live\`.`,
436
+ { hintFor: { command: "promote" } }
437
+ );
438
+ }
439
+ const typedBranch = args.branch === void 0 ? void 0 : assertUsableBranchLabel(args.branch, "--branch", PROMOTE_WITHOUT_BRANCH);
440
+ const raw = args.positionals[0];
441
+ if (raw === void 0 || raw === "") {
442
+ throw new UsageError(
443
+ `\`xanosdk promote\` needs a release name. Run \`xanosdk release list${contextFlags(args)}\` to see them.`,
444
+ { hintFor: { command: "promote" } }
445
+ );
446
+ }
447
+ assertOneName(raw, "the release name", { args, helpFor: { command: "promote" } });
448
+ const source = parseSource(raw, ["release"], { command: "promote" });
449
+ if (args.entryPath !== void 0 && (!existsSync(args.entryPath) || !statSync(args.entryPath).isFile())) {
450
+ const Refusal = existsSync(args.entryPath) ? UsageError : LocalFileNotFoundError;
451
+ throw new Refusal(
452
+ `\`--entry ${pastePath(args.entryPath)}\` ${existsSync(args.entryPath) ? "is not a file" : "does not exist"}. Pass the backend's entry file (its \`index.ts\`). Nothing was sent.`,
453
+ { hintFor: { command: "promote" } }
454
+ );
455
+ }
456
+ const auth = await getAccessToken(args);
457
+ const resolved = await resolveSource(source, async () => auth);
458
+ const release = resolved.release;
459
+ if (release === void 0) throw new Error(`promote: resolved no release for "${raw}".`);
460
+ assertPromotableName(release.name, args);
461
+ const setLiveRequested = args.setLive === true;
462
+ const destination = { ...credentialWriteTarget(auth), kind: "workspace" };
463
+ step(`Promoting release ${release.name}`);
464
+ discloseWriteTarget(destination);
465
+ const lockPath = landingLockPath(args, args.entryPath === void 0 ? {} : { entryFile: args.entryPath });
466
+ if (lockPath === void 0 && args.noLock !== true) {
467
+ const { nestedBackendEntries } = await import("./tracked-backend-EIBUMDZA.js");
468
+ const nested = nestedBackendEntries(process.cwd());
469
+ if (nested.length > 0) {
470
+ warn(
471
+ `No landing will be recorded: this directory is no project, so no xano.lock records what lands (a later \`--prune\` deletes only what a lock records).`,
472
+ "promote.no-landing-record",
473
+ nested.length === 1 ? [`The backend below it: \`--entry=${shellWord(nested[0])}\` records the landing in its lock, or run from its directory.`] : [`Backends below it: ${nested.join(", ")}. Name the one this release came from with \`--entry=<entry>\`, or run from its directory.`]
474
+ );
475
+ }
476
+ }
477
+ const entryFlag = args.entryPath === void 0 ? "" : ` --entry=${shellWord(pastePath(args.entryPath))}`;
478
+ const branch = typedBranch ?? assertUsableBranchLabel(derivedPromoteLabel(release.name, /* @__PURE__ */ new Date()), "--branch", PROMOTE_WITHOUT_BRANCH);
479
+ const listFrom = { baseUrl: resolved.target.base, workspaceId: resolved.target.workspaceId };
480
+ const op = createOperation({
481
+ operation: "promote",
482
+ destination,
483
+ release: { instance: auth.instance, workspaceId: auth.workspaceId, id: release.id, name: release.name },
484
+ branch,
485
+ steps: setLiveRequested ? ["land", "verify", "setLive"] : ["land", "verify"],
486
+ // Verification checks the landing; it does not produce it. One that could
487
+ // not run leaves the landing done (and exit 0, as before), rather than
488
+ // sending every caller on an instance with an unreadable export to resolve
489
+ // a write that already answered.
490
+ checks: ["verify"],
491
+ extras: { declined: false, landingRecord: null, tableEffects: null, canonicalMoves: [] }
492
+ });
493
+ const flags = contextFlags(args);
494
+ const yesFlags = `${pipedYes(args)}${flags}`;
495
+ const residue = { name: branch, removeWith: `xanosdk workspace branch delete ${shellWord(branch)}${yesFlags}` };
496
+ const promoteRerun = (onBranch, allowShared = args.allowSharedSchemaChanges === true) => `xanosdk promote ${shellWord(release.name)}${onBranch === void 0 ? "" : ` --branch ${shellWord(onBranch)}`}${setLiveRequested ? " --set-live" : ""}${args.expectLive === void 0 ? "" : ` --expect-live ${shellWord(args.expectLive)}`}${allowShared ? " --allow-shared-schema-changes" : ""} --yes${args.json === true ? " --json" : ""}${entryFlag}${flags}`;
497
+ const labelRace = async (err) => {
498
+ if (!(err instanceof ReleaseHttpError) || err.status !== 500 || !/duplicate record/i.test(err.message)) return err;
499
+ const now = await listBranchListing(auth, listFrom).catch(() => void 0);
500
+ if (now === void 0 || findBranch(now.branches, branch) === void 0) return err;
501
+ const free = typedBranch === void 0 ? void 0 : freeBranchLabel(now.branches, branch);
502
+ return new BranchTakenError(
503
+ `Another landing created branch "${branch}" while this one was landing, and the instance refused the duplicate label. Nothing of release ${release.name} landed.
504
+ ` + (free === void 0 ? `Re-run as \`${promoteRerun(void 0)}\` \u2014 it derives a fresh label.` : `Pick a label that is free: \`${promoteRerun(free)}\`.`),
505
+ branch,
506
+ free
507
+ );
508
+ };
509
+ const resolveWith = `xanosdk workspace branch list --json${flags}`;
510
+ const resolveSteps = [
511
+ `If "${branch}" is absent, nothing landed: re-run as \`${promoteRerun(branch)}\`.`,
512
+ `If it is present and not live, check it with \`xanosdk workspace export --branch ${shellWord(branch)}${flags}\` before \`xanosdk workspace branch set-live ${shellWord(branch)}${yesFlags}\`.`
513
+ ];
514
+ const assertTablesAcknowledged = (read) => {
515
+ if (args.allowSharedSchemaChanges === true) return;
516
+ const rerun = promoteRerun(typedBranch, true);
517
+ if ("failure" in read) {
518
+ throw new CliError(
519
+ "SDK_SHARED_SCHEMA_CHANGE",
520
+ `Refusing to promote "${release.name}": whether it changes your workspace's tables is unknown \u2014 ${read.failure}.
521
+ Tables are shared by every branch, so a promote applies the release's table definitions to live as soon as it lands, before any \`--set-live\`. A failed read is not evidence that it changes none.
522
+ Retry when the instance answers, or land it without the check: \`${rerun}\`.`,
523
+ { exitCode: 2, details: { reason: "tables-unreadable", landed: false, declined: false, changes: null } }
524
+ );
525
+ }
526
+ const gated = gatedTableChanges(read.effects);
527
+ if (gated.length === 0) return;
528
+ const changes = [...gated, ...additiveChanges(read.effects)];
529
+ const paired = droppedAndAdded(read.effects);
530
+ const one = gated.length === 1;
531
+ throw new CliError(
532
+ "SDK_SHARED_SCHEMA_CHANGE",
533
+ `Refusing to promote "${release.name}": it alters ${one ? "a table" : "tables"} your live workspace serves from. A promote lands logic on a branch of its own, but tables are shared by every branch \u2014 ${one ? "this applies" : "these apply"} to live as soon as it lands, before any \`--set-live\`, and are not undone by deleting the branch:
534
+ ${changes.map((c) => ` ${c}`).join("\n")}
535
+ ` + paired.map((p) => `${renameHint(p)}
536
+ `).join("") + `\`--yes\` does not cover this. Cut a release without ${one ? "it" : "them"}, or land ${one ? "it" : "them"} knowing live changes too: \`${rerun}\`.`,
537
+ {
538
+ exitCode: 2,
539
+ details: { reason: "shared-schema-changes", landed: false, declined: false, changes, pairedColumns: paired }
540
+ }
541
+ );
542
+ };
543
+ const constraintRefusal = (err, stop) => {
544
+ const where = constraintWhere(stop);
545
+ return new CliError(
546
+ "SDK_CONSTRAINT_VIOLATION",
547
+ `Release "${release.name}" did not land: your workspace's rows break ${CONSTRAINT_PHRASE[stop.kind]} it declares${where}. Nothing landed \u2014 no branch was made, and live is as it was.
548
+ ${CONSTRAINT_FIX[stop.kind]}, then promote again.`,
549
+ {
550
+ exitCode: 2,
551
+ cause: new SettledWriteFailure(err instanceof Error ? err.message : String(err), { cause: err }),
552
+ details: {
553
+ landed: false,
554
+ declined: false,
555
+ constraint: stop,
556
+ ...stop.kind === "unique" ? { uniqueViolation: true } : {}
557
+ }
558
+ }
559
+ );
560
+ };
561
+ const projectLock = () => {
562
+ if (lockPath === void 0 || !existsSync(lockPath)) return void 0;
563
+ try {
564
+ return readLockFile(lockPath);
565
+ } catch {
566
+ return void 0;
567
+ }
568
+ };
569
+ const pinnedIn = (declared) => new Set(pinnedCanonicalGuids(JSON.stringify(declared), projectLock(), false));
570
+ const assertIdentitiesFree = async (archive, loadLive) => {
571
+ let bytes;
572
+ let bundle;
573
+ try {
574
+ bytes = await archive.bytes();
575
+ bundle = await archive.decoded();
576
+ } catch {
577
+ bytes = void 0;
578
+ }
579
+ let check;
580
+ if (bytes === void 0 || bundle === void 0) {
581
+ check = { checked: false, reason: "the release archive could not be read" };
582
+ } else {
583
+ let typed;
584
+ try {
585
+ typed = asWorkspaceArchive(bytes, release.name);
586
+ } catch {
587
+ typed = void 0;
588
+ }
589
+ check = typed === void 0 ? { checked: false, reason: "the release archive carries no workspace to plan" } : await assertReleaseIdentitiesFree(args, auth, {
590
+ archive: typed,
591
+ bundle,
592
+ branch,
593
+ lockPath,
594
+ live: await loadLive().catch(() => void 0),
595
+ subject: `promote "${release.name}"`,
596
+ verb: "promote",
597
+ 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 promote that one.`
598
+ });
599
+ }
600
+ if (!check.checked) {
601
+ warn(
602
+ `Whether this release's names and pinned public URL slugs are free in your workspace was not checked \u2014 ${check.reason}.`,
603
+ "promote.identities-unchecked",
604
+ [
605
+ `A name another object holds lands as a suffixed second object, and a pinned slug another workspace serves lands under a minted one.`,
606
+ `The landed branch is read back afterwards, and a pinned slug it does not serve fails the promote.`
607
+ ]
608
+ );
609
+ }
610
+ return check;
611
+ };
612
+ const machine = isMachineOutput(args);
613
+ let declined = false;
614
+ let landingEffects;
615
+ let resetTablesAfterLanding;
616
+ try {
617
+ await runOperation(
618
+ op,
619
+ { machine, resolveWith, resolveSteps, what: `the landing of ${release.name}` },
620
+ async () => {
621
+ op.begin("land");
622
+ const before = await listBranchListing(auth, listFrom).catch(async (err) => {
623
+ throw await unansweredBranchRead(err, args);
624
+ });
625
+ assertBranchAbsent(before.branches, branch);
626
+ if (args.expectLive !== void 0) {
627
+ const mismatch = liveMismatch(before, args.expectLive);
628
+ if (mismatch !== void 0) {
629
+ throw liveBranchMismatch(
630
+ `\`--expect-live ${args.expectLive}\` does not hold: ${mismatch.why}. Nothing was landed.
631
+ Check what is serving with \`xanosdk workspace branch list${flags}\`, then promote again.`,
632
+ mismatch.live
633
+ );
634
+ }
635
+ }
636
+ const archive = archiveLoader(auth, release, resolved.target);
637
+ const loadArchive = archive.decoded;
638
+ const loadLive = readOnce(
639
+ () => exportWorkspaceBundle(auth, {
640
+ base: auth.instance,
641
+ workspaceId: auth.workspaceId,
642
+ label: "reading your workspace",
643
+ safeErrors: true
644
+ })
645
+ );
646
+ const firstRead = await releaseTableEffects(loadArchive, loadLive);
647
+ reportNotRun(
648
+ "workspace",
649
+ !("effects" in firstRead) || alteringChanges(firstRead.effects).length + additiveChanges(firstRead.effects).length > 0
650
+ );
651
+ await reportEnvLanding(auth, {
652
+ release: { id: release.id, name: release.name },
653
+ releaseHost: resolved.target,
654
+ target: { base: resolved.target.base, workspaceId: auth.workspaceId },
655
+ targetLabel: "your workspace",
656
+ envSetTo: ` --to workspace --yes${flags}`,
657
+ loadArchive,
658
+ loadLive
659
+ });
660
+ const seededTables = (release.seededTables ?? []).filter((t) => t.count !== 0);
661
+ const seeded = seededTables.map((t) => t.name);
662
+ if (seeded.length > 0) {
663
+ op.set("seedRowsNotWritten", seeded);
664
+ const remedies = await seedRowRemedies(release, seededTables, flags, args.entryPath);
665
+ resetTablesAfterLanding = remedies.afterLanding;
666
+ warn(
667
+ `"${release.name}" carries rows for ${seeded.length} table${seeded.length === 1 ? "" : "s"} (${seeded.join(", ")}), and they are not written: a promote lands logic on a branch, and tables are shared by every branch.`,
668
+ "promote.seed-rows",
669
+ remedies.before
670
+ );
671
+ }
672
+ await assertIdentitiesFree(archive, loadLive);
673
+ const tables = "effects" in firstRead ? firstRead : await releaseTableEffects(loadArchive, loadLive);
674
+ if ("failure" in tables && tables.cause !== void 0 && args.allowSharedSchemaChanges !== true) {
675
+ const what = tables.read === "archive" ? `release "${release.name}"'s archive` : "your workspace";
676
+ const unanswered = await unansweredBranchRead(tables.cause, args, what);
677
+ if (unanswered !== tables.cause) throw unanswered;
678
+ }
679
+ landingEffects = "effects" in tables ? tables.effects : void 0;
680
+ op.set("tableEffects", landingEffects === void 0 ? null : tableEffectsPayload(landingEffects));
681
+ assertTablesAcknowledged(tables);
682
+ const tableChanges = landingEffects === void 0 ? 0 : alteringChanges(landingEffects).length + additiveChanges(landingEffects).length;
683
+ if (landingEffects !== void 0) {
684
+ discloseTableEffects(landingEffects, {
685
+ subject: "the promote",
686
+ additiveWhere: "the tables every branch shares \u2014 live included, as soon as it lands"
687
+ });
688
+ await assertStorageModesKept(landingEffects.storageChanges, tableRowCounter(auth, { workspaceId: auth.workspaceId, base: auth.instance }), {
689
+ target: "your workspace",
690
+ subject: "the promote"
691
+ });
692
+ }
693
+ const moves = await Promise.all([loadArchive(), loadLive()]).then(
694
+ ([archive2, live]) => releaseCanonicalMoves(archive2, live),
695
+ () => []
696
+ );
697
+ op.set("canonicalMoves", moves);
698
+ discloseCanonicalMoves(moves, {
699
+ subject: "the promote",
700
+ will: setLiveRequested ? "will" : "would",
701
+ when: setLiveRequested ? "as it goes live" : "once its branch is made live"
702
+ });
703
+ if (args.yes !== true) {
704
+ const ok = await confirm(
705
+ `Land release "${release.name}" in your workspace${typedBranch === void 0 ? "" : ` on branch "${typedBranch}"`}${setLiveRequested ? ", and make it live" : ""}${tableChanges === 0 ? "" : `, applying its ${tableChanges === 1 ? "table change" : `${tableChanges} table changes`} to the live workspace too`}?` + movesClause(moves, setLiveRequested ? "It" : "Once live, it"),
706
+ {
707
+ flag: "--yes",
708
+ // Off a terminal, the details `tenant deploy` and `deploy --to`
709
+ // carry (E2E pass 29: a bare SDK_USAGE), and this promote with `--yes`.
710
+ refusal: {
711
+ details: { landed: false, declined: false },
712
+ rerun: promoteRerun(typedBranch)
713
+ }
714
+ }
715
+ );
716
+ if (!ok) {
717
+ info("Promote cancelled \u2014 nothing was written.");
718
+ op.set("declined", true);
719
+ declined = true;
720
+ return;
721
+ }
722
+ }
723
+ step(`Landing ${release.name} in your workspace on branch "${branch}"`);
724
+ op.sending();
725
+ const landed = await deployRelease(auth, {
726
+ workspaceId: auth.workspaceId,
727
+ name: release.name,
728
+ branch,
729
+ setLive: false
730
+ }).catch(async (err) => {
731
+ const stop = constraintStop(err);
732
+ if (stop !== void 0) throw constraintRefusal(err, namedConstraint(stop, landingEffects));
733
+ throw await labelRace(err);
734
+ });
735
+ op.finish("land");
736
+ op.setRelease({
737
+ instance: auth.instance,
738
+ workspaceId: auth.workspaceId,
739
+ id: landed.id ?? release.id,
740
+ name: landed.name
741
+ });
742
+ try {
743
+ await afterLanding({ landedName: landed.name, loadArchive, liveBefore: liveBranchLabel(before.branches) });
744
+ } catch (err) {
745
+ if (classifyFailure(err, { writeSent: op.inProgressSent }) === "no") op.setResidue(residue);
746
+ throw err;
747
+ }
748
+ }
749
+ );
750
+ } catch (err) {
751
+ if (declined) return;
752
+ throw err;
753
+ }
754
+ async function afterLanding(ctx) {
755
+ op.begin("verify");
756
+ const verification = await verifyLanding(auth, { loadArchive: ctx.loadArchive, branch, pinned: pinnedIn });
757
+ op.set("verification", verificationPayload(verification));
758
+ op.finish(
759
+ "verify",
760
+ verification.outcome === "passed" ? "yes" : verification.outcome === "failed" ? "no" : "unknown"
761
+ );
762
+ if (verification.outcome === "failed") op.setResidue(residue);
763
+ if (verification.outcome !== "failed") {
764
+ const archive = await ctx.loadArchive().catch(() => void 0);
765
+ if (archive !== void 0) {
766
+ op.set(
767
+ "landingRecord",
768
+ recordForeignLanding({
769
+ lockPath,
770
+ instance: auth.instance,
771
+ dest: { kind: "workspace", workspaceId: auth.workspaceId },
772
+ bundle: archive,
773
+ mode: "merge"
774
+ })
775
+ );
776
+ }
777
+ }
778
+ let live = false;
779
+ let rollback;
780
+ if (setLiveRequested) {
781
+ if (verification.outcome !== "passed") {
782
+ op.finish("setLive", "no");
783
+ op.setResidue(residue);
784
+ } else {
785
+ op.begin("setLive");
786
+ let previousLive = ctx.liveBefore;
787
+ if (args.expectLive !== void 0) {
788
+ const now = await listBranchListing(auth, listFrom);
789
+ previousLive = liveBranchLabel(now.branches);
790
+ const drift = liveMismatch(now, args.expectLive);
791
+ if (drift !== void 0) {
792
+ op.finish("setLive", "no");
793
+ op.setResidue(residue);
794
+ throw liveBranchMismatch(
795
+ `Landed and verified ${ctx.landedName} on branch "${branch}", but did not make it live: \`--expect-live ${args.expectLive}\` no longer holds \u2014 ${drift.why}. Live changed after the landing; the check is not atomic, so it is re-read before switching and the switch refused.
796
+ Nothing was switched. Serve it deliberately with \`xanosdk workspace branch set-live ${branch}${yesFlags}\`, or remove it with \`xanosdk workspace branch delete ${branch}${yesFlags}\`.`,
797
+ drift.live
798
+ );
799
+ }
800
+ }
801
+ step(`Making branch "${branch}" live`);
802
+ op.sending();
803
+ try {
804
+ await setLiveBranch(auth, { baseUrl: auth.instance, workspaceId: auth.workspaceId, label: branch });
805
+ } catch (err) {
806
+ error(`Landed and verified ${ctx.landedName}, but making branch "${branch}" live failed.`);
807
+ if (classifyFailure(err, { writeSent: true }) === "no") {
808
+ detail(`The branch is there and checked; only the live pointer did not move.`);
809
+ detail(`Retry with \`xanosdk workspace branch set-live ${branch}${yesFlags}\`.`);
810
+ } else {
811
+ detail(`Whether the live pointer moved is not known \u2014 \`xanosdk workspace branch list${flags}\` shows it.`);
812
+ }
813
+ throw err;
814
+ }
815
+ op.finish("setLive");
816
+ live = true;
817
+ op.set("previousLive", previousLive ?? null);
818
+ rollback = previousLive === void 0 ? void 0 : setLiveRollback(previousLive, args);
819
+ }
820
+ }
821
+ const substituted = verification.canonicals.filter((c) => !c.pinned);
822
+ if (substituted.length > 0) {
823
+ warn(
824
+ `Public URL slug${substituted.length === 1 ? "" : `s (${substituted.length})`} the release declares ${substituted.length === 1 ? "is" : "are"} served under another value (not pinned in code, so the instance chose):`,
825
+ "promote.canonical-substituted",
826
+ substituted.map((c) => `${c.kind} ${c.name}: serves "${c.served}", declared "${c.declared}"`)
827
+ );
828
+ }
829
+ if (!machine) renderLanding({ landedName: ctx.landedName, verification, live, rollback });
830
+ else if (verification.outcome !== "failed") {
831
+ success(`Landed ${ctx.landedName}`);
832
+ detail(whereItLanded(live));
833
+ if (rollback !== void 0) detail(rollback);
834
+ if (verification.outcome === "unverified") warnUnverified(verification);
835
+ }
836
+ if (verification.outcome === "failed") {
837
+ const unserved = verification.canonicals.filter((c) => c.pinned);
838
+ const what = [
839
+ ...verification.missing.length === 0 ? [] : [`${verification.missing.length} declared object${verification.missing.length === 1 ? "" : "s"} did not arrive`],
840
+ ...unserved.length === 0 ? [] : [
841
+ `${unserved.length} public URL slug${unserved.length === 1 ? "" : "s"} pinned in code ${unserved.length === 1 ? "is" : "are"} not served (${unserved.map((c) => `${c.kind} ${c.name}: "${c.served}", not "${c.declared}"`).join("; ")})`
842
+ ]
843
+ ];
844
+ throw new LandingIncompleteError(`Landed ${ctx.landedName} on branch "${branch}", but ${what.join(", and ")}.`);
845
+ }
846
+ }
847
+ function whereItLanded(live) {
848
+ return live ? `live on branch ${branch}` : `on branch ${branch}, not live yet \u2014 serve it with \`xanosdk workspace branch set-live ${shellWord(branch)}${yesFlags}\` (a promote with \`--set-live\` lands and serves in one run)`;
849
+ }
850
+ function warnUnverified(verification) {
851
+ warn(
852
+ `Contents NOT verified \u2014 the release landed, but verification could not run (${verification.reason}) \u2014 check what landed with \`xanosdk workspace export --branch ${shellWord(branch)} --path -${flags}\``,
853
+ "promote.unverified",
854
+ // The one place this command declines something the caller explicitly
855
+ // asked for, so it says both halves: what it did not do, and the command
856
+ // that does it anyway once they have decided the risk is theirs to take.
857
+ setLiveRequested ? [
858
+ `NOT made live \u2014 \`--set-live\` serves a landing that was checked, and this one could not be.`,
859
+ `Serve it deliberately with \`xanosdk workspace branch set-live ${branch}${yesFlags}\`.`
860
+ ] : []
861
+ );
862
+ }
863
+ function renderLanding(r) {
864
+ const { verification } = r;
865
+ if (verification.outcome === "failed") {
866
+ if (verification.missing.length > 0) {
867
+ warn(
868
+ `${verification.missing.length} declared object${verification.missing.length === 1 ? "" : "s"} did not arrive:`,
869
+ "promote.missing-objects",
870
+ verification.missing
871
+ );
872
+ }
873
+ const unserved = verification.canonicals.filter((c) => c.pinned);
874
+ if (unserved.length > 0) {
875
+ warn(
876
+ `Public URL slug${unserved.length === 1 ? "" : `s (${unserved.length})`} pinned in code ${unserved.length === 1 ? "is" : "are"} served under another value \u2014 every route a frontend builds from ${unserved.length === 1 ? "it" : "them"} answers 404 there:`,
877
+ "promote.canonical-not-served",
878
+ [
879
+ ...unserved.map((c) => `${c.kind} ${c.name}: serves "${c.served}", declared "${c.declared}"`),
880
+ `The slug is held elsewhere on this instance (slugs are unique per instance). Change the \`canonical\` in code to one nothing serves, or free it where it is held; then deploy, cut a new release and promote that.`
881
+ ]
882
+ );
883
+ }
884
+ blank();
885
+ if (setLiveRequested) {
886
+ detail(`Nothing was made live \u2014 the branch that was serving before is still serving.`);
887
+ }
888
+ detail(`Nothing here is cleaned up automatically: the branch is the evidence for why the landing was partial.`);
889
+ detail(`Remove it with \`xanosdk workspace branch delete ${branch}${yesFlags}\` once you have looked.`);
890
+ return;
891
+ }
892
+ success(`Landed ${r.landedName}`);
893
+ detail(whereItLanded(r.live));
894
+ if (r.rollback !== void 0) detail(r.rollback);
895
+ if (resetTablesAfterLanding !== void 0) info(resetTablesAfterLanding);
896
+ if (verification.outcome === "unverified") {
897
+ warnUnverified(verification);
898
+ } else {
899
+ detail(`Verified: all ${verification.compared} declared object(s) arrived.`);
900
+ }
901
+ if (verification.undeclared.length > 0) {
902
+ const suspicious = verification.suffixed;
903
+ detail(
904
+ `${verification.undeclared.length} object(s) on the branch the release did not declare: ` + verification.undeclared.join(", ")
905
+ );
906
+ if (suspicious.length > 0) {
907
+ warn(`${suspicious.join(", ")} look${suspicious.length === 1 ? "s" : ""} like a suffixed rename of a declared name \u2014 check it is the object you meant.`, "promote.suffixed-rename");
908
+ }
909
+ }
910
+ detail(`See what landed with \`xanosdk workspace export --branch ${branch}${flags}\`.`);
911
+ }
912
+ }
913
+ async function unansweredBranchRead(err, args, what) {
914
+ const { LookupFailedError, isServerError, isTransportFailure, unansweredCause } = await import("./source-resolve-S2XA3XZF.js");
915
+ const transport = isTransportFailure(err);
916
+ if (!transport && !isServerError(err)) return err;
917
+ const first = what !== void 0 ? `could not read ${what}` : ((err instanceof Error ? err.message : String(err)).trim().split("\n")[0] ?? "").replace(/[.:]$/, "");
918
+ const retry = retryCommand(args, {
919
+ add: pipedYes(args) === "" ? [] : ["--yes"],
920
+ command: ["promote", ...args.positionals.map(shellWord)].join(" ")
921
+ });
922
+ const failed = new LookupFailedError(
923
+ `${first[0]?.toUpperCase() ?? ""}${first.slice(1)}. ${unansweredCause(err)} before the landing \u2014 nothing was sent`,
924
+ "unreachable",
925
+ "workspace",
926
+ `run \`${retry.command}\` again`
927
+ );
928
+ failed.message += withheldNote(retry.withheld);
929
+ return failed;
930
+ }
931
+
932
+ export {
933
+ reportEnvLanding,
934
+ derivedPromoteLabel,
935
+ isDerivedPromoteLabel,
936
+ assertNoMergeFlags,
937
+ reportNotRun,
938
+ runPromoteCommand
939
+ };
940
+ //# sourceMappingURL=chunk-BHACRS6R.js.map