@xano/sdk 1.0.5 → 1.0.6

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 (249) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +26 -16
  3. package/dist/.build-fingerprint +1 -1
  4. package/dist/{agent-file-refresh-KVLR7M5Y.js → agent-file-refresh-67QIX45H.js} +14 -13
  5. package/dist/{answer-shape-XGR2DGWY.js → answer-shape-UCDUKPAN.js} +5 -5
  6. package/dist/{backend-dir-IE4RMUFH.js → backend-dir-3LIL6SCT.js} +13 -12
  7. package/dist/{backend-slot-6HBWG5FN.js → backend-slot-JREP27UD.js} +4 -4
  8. package/dist/bin.js +53 -52
  9. package/dist/{branch-T2APKPVG.js → branch-2IPHOAYS.js} +9 -9
  10. package/dist/{branch-commands-HXXTCSOO.js → branch-commands-KTKAXBAN.js} +29 -30
  11. package/dist/bundle.js +9 -39
  12. package/dist/{capture-HBXFXZEW.js → capture-GW5KNKMB.js} +3 -3
  13. package/dist/{chunk-JZWUAEMO.js → chunk-26MOFAJT.js} +2 -2
  14. package/dist/{chunk-RXCT3OCU.js → chunk-2FLIJGBZ.js} +3 -3
  15. package/dist/{chunk-UIEFE6FU.js → chunk-2WBH5HUY.js} +7 -7
  16. package/dist/{chunk-Y76ERHLK.js → chunk-3BBIDW3Y.js} +5 -5
  17. package/dist/{chunk-DGWHAVRG.js → chunk-3EDSPMXN.js} +12 -1
  18. package/dist/{chunk-JXKO6JT7.js → chunk-3II44CUJ.js} +14 -14
  19. package/dist/{chunk-7GX445AE.js → chunk-4XHAT7C5.js} +2 -2
  20. package/dist/{chunk-OKNE3TWU.js → chunk-5KJBWIDZ.js} +83 -5
  21. package/dist/{chunk-SRX6B544.js → chunk-5QMJOE2K.js} +5 -5
  22. package/dist/{chunk-UJ6ZZJDD.js → chunk-5TVFLG3C.js} +2 -2
  23. package/dist/{chunk-L3BDO2BI.js → chunk-5YQV35C2.js} +7 -7
  24. package/dist/{chunk-Z4VN347O.js → chunk-6X3MY2JP.js} +2 -2
  25. package/dist/{chunk-65SW2BA5.js → chunk-6X6BJN6Y.js} +3 -3
  26. package/dist/{chunk-M7GJ6YUF.js → chunk-763M6LX3.js} +16 -2
  27. package/dist/{chunk-XJU6UAFV.js → chunk-7FIMUFBP.js} +2 -2
  28. package/dist/{chunk-TEBS7FE6.js → chunk-7GAIJW62.js} +2 -2
  29. package/dist/{chunk-K6CB5TKM.js → chunk-7REDHC4N.js} +2 -2
  30. package/dist/chunk-7VR4IO5B.js +44 -0
  31. package/dist/chunk-A7MRZ4GF.js +78 -0
  32. package/dist/{chunk-CV54PASI.js → chunk-ATJ2W7DC.js} +70 -50
  33. package/dist/{chunk-WYS6XVZ3.js → chunk-AVS4WPPY.js} +2 -2
  34. package/dist/{chunk-5XVBT6CQ.js → chunk-BL3AZ3AP.js} +2 -2
  35. package/dist/chunk-BTVUYHWV.js +111 -0
  36. package/dist/{chunk-NGAODDLX.js → chunk-CCU5CCRX.js} +4 -4
  37. package/dist/{chunk-BBPAXOU6.js → chunk-CHINR7WD.js} +6 -6
  38. package/dist/{chunk-SQPIECXD.js → chunk-CJDPSCMX.js} +45 -5
  39. package/dist/{chunk-3HOGFGKG.js → chunk-D3KEPRRN.js} +2 -2
  40. package/dist/{chunk-XNZURZ7T.js → chunk-D7BUMOKU.js} +2 -2
  41. package/dist/{chunk-WRBKLYSJ.js → chunk-DNBP4GJN.js} +4 -3
  42. package/dist/{chunk-XMDDBEEM.js → chunk-E763QI3G.js} +2 -2
  43. package/dist/{chunk-4NEBBKOP.js → chunk-EADVVTDK.js} +7 -7
  44. package/dist/{chunk-N6BWB35H.js → chunk-ENMBEXOP.js} +3 -3
  45. package/dist/{chunk-57HMNJGB.js → chunk-EQFYOOO6.js} +69 -34
  46. package/dist/{chunk-WOGJB2F6.js → chunk-FNLTFOUD.js} +4 -9
  47. package/dist/{chunk-FV55SRQU.js → chunk-FQ53GTII.js} +9 -9
  48. package/dist/{chunk-TUEFTRC2.js → chunk-FU3VCE5A.js} +45 -26
  49. package/dist/{chunk-YSLMMR2U.js → chunk-GHQ4BVI4.js} +14 -14
  50. package/dist/{chunk-Z2BRSQ6M.js → chunk-GLY552SI.js} +84 -57
  51. package/dist/{chunk-XIABDKFQ.js → chunk-GOLFAEUV.js} +2 -2
  52. package/dist/{chunk-ZHGWR45B.js → chunk-GW5RHGOB.js} +8 -8
  53. package/dist/{chunk-3BJYQGAZ.js → chunk-GWTFI3GA.js} +2 -2
  54. package/dist/{chunk-K6PRKPFX.js → chunk-GZHLCUZ6.js} +7 -7
  55. package/dist/{chunk-LLS2WO2K.js → chunk-HCG7NDIL.js} +4 -4
  56. package/dist/{chunk-NNB7VUCH.js → chunk-I3H3HCPY.js} +47 -26
  57. package/dist/{chunk-KUU7T4ZE.js → chunk-I3VHW6XM.js} +13 -13
  58. package/dist/{chunk-ES5A66IH.js → chunk-IF4PEGVD.js} +8 -8
  59. package/dist/{chunk-Y6NO3DLQ.js → chunk-IMELQ2I6.js} +3 -3
  60. package/dist/{chunk-V4IBHDIY.js → chunk-ITC2R2OT.js} +7 -7
  61. package/dist/{chunk-KQLACS4Q.js → chunk-IXFJORNH.js} +4 -4
  62. package/dist/{chunk-SF2B7MZK.js → chunk-IYXL5NYU.js} +259 -31
  63. package/dist/{chunk-57B56I4B.js → chunk-JFBRXRJD.js} +58 -34
  64. package/dist/chunk-JI3BLXWQ.js +107 -0
  65. package/dist/{chunk-4DJTQ6W4.js → chunk-JIKGT7DO.js} +2 -1
  66. package/dist/{chunk-5D6DGF3W.js → chunk-JRVQ7M7W.js} +8 -8
  67. package/dist/{chunk-AESE434J.js → chunk-JXVJGF3Y.js} +2 -2
  68. package/dist/chunk-KPFS3RGM.js +257 -0
  69. package/dist/{chunk-SNGFEESM.js → chunk-LAOMN6QQ.js} +3 -3
  70. package/dist/{chunk-TM5LRSBB.js → chunk-LBJA7IEM.js} +370 -45
  71. package/dist/{chunk-OVV2HXJ6.js → chunk-LD6ARK3A.js} +2 -2
  72. package/dist/{chunk-F6IKWAIU.js → chunk-LL7SGTRC.js} +18 -19
  73. package/dist/{chunk-OJPZEUPH.js → chunk-M5CSVB23.js} +4 -4
  74. package/dist/{chunk-GMVW6ZZK.js → chunk-MBDFH7XB.js} +4 -4
  75. package/dist/{chunk-5YBNXNKU.js → chunk-MFWF2NZJ.js} +12 -5
  76. package/dist/{chunk-G57RYMKB.js → chunk-N5I37JFB.js} +2 -2
  77. package/dist/{chunk-QOLOQ35F.js → chunk-ND43ZOS3.js} +5 -5
  78. package/dist/chunk-NDWVJ2QZ.js +67 -0
  79. package/dist/{chunk-5RLAF6RL.js → chunk-NPODGBVJ.js} +4 -4
  80. package/dist/{chunk-JQOX6HW4.js → chunk-OIKLDDYC.js} +2 -2
  81. package/dist/{chunk-AMBEITWL.js → chunk-PFBXSVZF.js} +4 -4
  82. package/dist/{chunk-3VX7VAQT.js → chunk-PMMHSX4H.js} +26 -9
  83. package/dist/{chunk-MYLPOVX6.js → chunk-QJM5XZ4K.js} +5 -5
  84. package/dist/{chunk-U6DR6464.js → chunk-QXYMDARD.js} +4 -4
  85. package/dist/{chunk-DEVGLLNZ.js → chunk-QZEAANWP.js} +5 -5
  86. package/dist/{chunk-LZDA6SVD.js → chunk-RIN4YY34.js} +78 -65
  87. package/dist/{chunk-37FBPMNE.js → chunk-S56YBYMN.js} +5 -2
  88. package/dist/{chunk-S5TEJIGP.js → chunk-SKEG3V2V.js} +2 -2
  89. package/dist/{chunk-VZ22VUAS.js → chunk-SLGJIWCY.js} +3 -3
  90. package/dist/{chunk-4QFBEKXI.js → chunk-SPITRSOF.js} +2 -2
  91. package/dist/{chunk-QZTJ2556.js → chunk-SPKA2LV6.js} +4 -4
  92. package/dist/{chunk-YI76TURL.js → chunk-SSITMX7I.js} +8 -8
  93. package/dist/{chunk-JSEVKRVJ.js → chunk-T4LJ5UR2.js} +29 -7
  94. package/dist/{chunk-44CWK6YC.js → chunk-TECTL2NU.js} +4 -4
  95. package/dist/{chunk-AGD7F7YI.js → chunk-TTEIDD5Q.js} +3 -3
  96. package/dist/{chunk-NUU76247.js → chunk-U35MTOXQ.js} +3 -3
  97. package/dist/{chunk-4QBGE3EO.js → chunk-U6MTGB46.js} +4 -4
  98. package/dist/{chunk-3WHWOKU4.js → chunk-UD2Z7K6W.js} +4 -4
  99. package/dist/{chunk-I5VEROXW.js → chunk-UIVMR7UK.js} +2 -2
  100. package/dist/{chunk-F3557PVM.js → chunk-VDHA5SSQ.js} +2 -2
  101. package/dist/{chunk-3IYVHVM6.js → chunk-VJFMUJWZ.js} +4 -4
  102. package/dist/{chunk-4GDEEY2U.js → chunk-VW4CWVYX.js} +4 -4
  103. package/dist/chunk-WAVNUTMT.js +9 -0
  104. package/dist/{chunk-A4NNCI4O.js → chunk-WBH4KJWM.js} +3 -3
  105. package/dist/{chunk-HOOOOJJP.js → chunk-WZHLMU6T.js} +2 -2
  106. package/dist/{chunk-S5KQIFKJ.js → chunk-XFBGXB7X.js} +130 -86
  107. package/dist/{chunk-IV446ZLJ.js → chunk-Y453TW6J.js} +2 -2
  108. package/dist/{chunk-CJ76PSJT.js → chunk-YGLMRH5U.js} +8 -8
  109. package/dist/{chunk-GPI3OWRE.js → chunk-YHB34BN6.js} +2 -1
  110. package/dist/{chunk-BMCZQZMI.js → chunk-YKP4ZKVO.js} +13 -9
  111. package/dist/{chunk-HLQH3AXB.js → chunk-YR2I5HGE.js} +2 -2
  112. package/dist/{chunk-OGUMHW2X.js → chunk-YYC2DZMG.js} +7 -7
  113. package/dist/{chunk-Z3SNX45M.js → chunk-YYLUBYXM.js} +2 -2
  114. package/dist/{chunk-PIPIA7K7.js → chunk-Z4ZGTCCD.js} +7 -7
  115. package/dist/{chunk-AGSCOISO.js → chunk-ZDP6GDAB.js} +75 -75
  116. package/dist/{chunk-7DBM6XHR.js → chunk-ZJSTUD6D.js} +8 -8
  117. package/dist/cli.d.ts +17 -9
  118. package/dist/cli.js +51 -50
  119. package/dist/{codegen-command-L2OO6OTE.js → codegen-command-R5IASBFC.js} +72 -66
  120. package/dist/codegen.d.ts +2 -2
  121. package/dist/codegen.js +2 -2
  122. package/dist/{commands-2E4JB3DB.js → commands-H7CPMMHH.js} +3 -3
  123. package/dist/{completion-LPJIH5VQ.js → completion-W5ZAI6TN.js} +3 -3
  124. package/dist/{config-QDCRKEWD.js → config-MZ5KG4EP.js} +4 -4
  125. package/dist/{deploy-command-HJZNYCUY.js → deploy-command-34T2LKQ5.js} +58 -57
  126. package/dist/{deploy-source-5COWTBOC.js → deploy-source-YLQ7WMYR.js} +32 -31
  127. package/dist/{dev-env-sync-GZ4QQJGV.js → dev-env-sync-TMJTNU3U.js} +52 -51
  128. package/dist/{diagnostics-LSMGB4TY.js → diagnostics-OMN5Y2AH.js} +2 -2
  129. package/dist/{display-name-hint-AHCNH6TF.js → display-name-hint-ZJGFNJKQ.js} +11 -11
  130. package/dist/{emit-DqG6qddr.d.ts → emit-D125xxty.d.ts} +66 -20
  131. package/dist/env-example-refresh-CQP3ZMKM.js +133 -0
  132. package/dist/{env-pull-command-Z4RLVEGJ.js → env-pull-command-UTG6IC2K.js} +46 -46
  133. package/dist/{env-target-ZHQUS5BO.js → env-target-FZROWYFS.js} +12 -12
  134. package/dist/{env-var-command-FKQ4VVQ6.js → env-var-command-VYDBQJJW.js} +41 -40
  135. package/dist/{ephemeral-L4KUOGEU.js → ephemeral-BIE6FMJV.js} +9 -9
  136. package/dist/{ephemeral-command-GRPFI3TD.js → ephemeral-command-OZ26RGXF.js} +47 -47
  137. package/dist/{ephemeral-state-VLYU2BXR.js → ephemeral-state-SNZOX2YK.js} +10 -10
  138. package/dist/{generate-command-XNODJFDQ.js → generate-command-4HR7MR36.js} +80 -72
  139. package/dist/{gitignore-VWRSZX5F.js → gitignore-EWQBXNX2.js} +17 -16
  140. package/dist/{guards-OPSGB6LG.js → guards-KYEOCVHN.js} +6 -6
  141. package/dist/{impersonate-command-AEKIZHHK.js → impersonate-command-WC7OGKUM.js} +37 -36
  142. package/dist/{import-PHSSFFLA.js → import-7Z4GCCPO.js} +5 -5
  143. package/dist/index.d.ts +14 -20
  144. package/dist/index.js +13 -13
  145. package/dist/{init-command-TI3HCKXZ.js → init-command-HAO3WXH3.js} +57 -55
  146. package/dist/{init-modules-SGSX7XEY.js → init-modules-NSKD4ASY.js} +10 -9
  147. package/dist/{init-web-6HX3YLQP.js → init-web-MKFFOQUU.js} +3 -3
  148. package/dist/internal.d.ts +5 -5
  149. package/dist/internal.js +47 -20
  150. package/dist/{io-TAF4WXYQ.js → io-PGTCBSIQ.js} +6 -4
  151. package/dist/{keep-data-merge-GUGF7MVZ.js → keep-data-merge-QR2TMKEO.js} +28 -29
  152. package/dist/{lambda-config-reconcile-65U6I4KU.js → lambda-config-reconcile-7FJXXV6V.js} +3 -3
  153. package/dist/{landed-QA6PRTV2.js → landed-F7PCHGCK.js} +3 -3
  154. package/dist/{landing-record-FCAWLCZU.js → landing-record-MWXFIRCP.js} +22 -21
  155. package/dist/{live-diff-IM4W3ELT.js → live-diff-5E2BQWQ7.js} +9 -8
  156. package/dist/{local-engine-choice-FPJAZSSD.js → local-engine-choice-VD5LNXJU.js} +35 -34
  157. package/dist/{local-engine-command-73NHWD6V.js → local-engine-command-RYLGMQ2O.js} +40 -39
  158. package/dist/{local-engine-deploy-Y4OAWL7K.js → local-engine-deploy-6O7NKZCA.js} +12 -12
  159. package/dist/{local-engine-process-6YPJHKYM.js → local-engine-process-ZLLZEIRF.js} +7 -7
  160. package/dist/{local-engine-update-check-X7TZGRFL.js → local-engine-update-check-LVX4HBBI.js} +5 -5
  161. package/dist/{lock-WXXC3QHL.js → lock-HDCHD2ON.js} +4 -2
  162. package/dist/{lock-commands-PKDBNRSD.js → lock-commands-X2OECR4R.js} +56 -55
  163. package/dist/{login-command-V4U4FA5G.js → login-command-RLLKD565.js} +27 -26
  164. package/dist/{logout-command-TV3P545Z.js → logout-command-XDMSXCDO.js} +15 -15
  165. package/dist/{loop-VKHGQ6MP.js → loop-SUB6C2LK.js} +8 -9
  166. package/dist/{marketplace-command-LEFOAEAV.js → marketplace-command-2NHHY2X3.js} +86 -50
  167. package/dist/{marketplace-resolve-ME7O7JBJ.js → marketplace-resolve-OTZYT4FG.js} +7 -6
  168. package/dist/{meta-client-TEEECA5W.js → meta-client-TMHVBZFY.js} +13 -13
  169. package/dist/{module-manifest-7YLGIRCY.js → module-manifest-FNMW23IX.js} +7 -4
  170. package/dist/node.d.ts +5 -5
  171. package/dist/node.js +57 -57
  172. package/dist/{operation-outcome-GNDD35WL.js → operation-outcome-RN62735X.js} +22 -22
  173. package/dist/{output-target-5FWX3NGZ.js → output-target-MOLCTPBP.js} +18 -17
  174. package/dist/{package-manager-PRAHUSCN.js → package-manager-K762W7XT.js} +2 -2
  175. package/dist/{plan-disclosure-QGL5UYQR.js → plan-disclosure-CY7AF6KP.js} +19 -20
  176. package/dist/{plugin-contributions-GNFTWDEB.js → plugin-contributions-WR26U7NT.js} +6 -6
  177. package/dist/{plugin-prompt-VEQGMZ4T.js → plugin-prompt-ZUYQQIX4.js} +5 -5
  178. package/dist/{plugin-questions-BGRL23GO.js → plugin-questions-HAZOQ67R.js} +4 -4
  179. package/dist/plugin.d.ts +254 -10
  180. package/dist/{preflight-command-VKJKXRRI.js → preflight-command-OHJXYND3.js} +64 -64
  181. package/dist/{profile-command-P7A3BH26.js → profile-command-6JWT2BTL.js} +28 -27
  182. package/dist/{profile-pointer-HG7IXE4I.js → profile-pointer-PDA5XBIB.js} +4 -4
  183. package/dist/{project-dependency-Z4CKOCJI.js → project-dependency-GZWWGWEW.js} +11 -8
  184. package/dist/{project-sdk-JWZWGXXR.js → project-sdk-3W72H5QO.js} +4 -4
  185. package/dist/promote-command-UYAMUXKB.js +146 -0
  186. package/dist/{prompt-SURZOUUW.js → prompt-U37K5RPQ.js} +4 -4
  187. package/dist/{publish-command-HGAB3H4A.js → publish-command-BUS27HGB.js} +61 -60
  188. package/dist/{pull-command-EUEWBRXZ.js → pull-command-ZGUNP27P.js} +75 -69
  189. package/dist/{pull-superseded-TOT5S4QU.js → pull-superseded-EZBGYRZF.js} +4 -4
  190. package/dist/{raw-where-EoWl5fqY.d.ts → raw-where-ZMLND6AG.d.ts} +20 -3
  191. package/dist/{release-command-WOVQAMUY.js → release-command-BQ6OHS3P.js} +69 -66
  192. package/dist/{release-ns-command-WOQE2BDQ.js → release-ns-command-ATGVBVIU.js} +85 -85
  193. package/dist/{retry-command-JRGMZZAC.js → retry-command-QJ57WVW7.js} +8 -8
  194. package/dist/{routes-manifest-URFMAWJE.js → routes-manifest-YR4ZIMLM.js} +15 -7
  195. package/dist/routes-manifest-file-UALYSZLY.js +41 -0
  196. package/dist/scaffold.js +2 -2
  197. package/dist/{secrets-file-YWZWVJ52.js → secrets-file-LMS7KX3E.js} +17 -16
  198. package/dist/{secrets-fill-command-HIHK3VH2.js → secrets-fill-command-QNBDGCGM.js} +55 -54
  199. package/dist/{seed-24DTEY5S.js → seed-SZ6OS5DQ.js} +8 -8
  200. package/dist/{source-resolve-OWD3MIEO.js → source-resolve-MKLNYFWG.js} +20 -20
  201. package/dist/{static-host-UIR2OLPQ.js → static-host-ONEHA4LI.js} +5 -5
  202. package/dist/{status-command-JKTHH5QE.js → status-command-XKIFKBGM.js} +38 -37
  203. package/dist/{store-zxw2go0f.d.ts → store-Bg4Na6Sm.d.ts} +2 -2
  204. package/dist/{store-5YAQS6KU.js → store-X6ZH7EC3.js} +6 -6
  205. package/dist/sync-baseline-DOV5AGIO.js +36 -0
  206. package/dist/{sync-contributions-RBB6JVOL.js → sync-contributions-HNVHDIQW.js} +20 -12
  207. package/dist/sync-record-PRXHLK4S.js +42 -0
  208. package/dist/{table-MQFVYA4K.js → table-DC36QA4Y.js} +8 -8
  209. package/dist/{tables-command-5Q4BSUNO.js → tables-command-UQLKTELN.js} +38 -37
  210. package/dist/{tenant-Q3LPVSSM.js → tenant-EKNQGG5A.js} +10 -10
  211. package/dist/{tenant-command-BFVU2PEX.js → tenant-command-2LWP2MPB.js} +99 -94
  212. package/dist/{test-command-F4VUU4QR.js → test-command-IU5MBBXY.js} +36 -35
  213. package/dist/{tests-5ZSDFVIJ.js → tests-RG2Y5EQ4.js} +6 -6
  214. package/dist/{token-TERSTNU4.js → token-7AWSJLKO.js} +11 -11
  215. package/dist/toolchain-hooks-4ZMQLBPQ.js +46 -0
  216. package/dist/{toolchain-modules-FD5ANV2U.js → toolchain-modules-VU7SURVJ.js} +8 -5
  217. package/dist/toolchain-peers-CIDNEEQV.js +28 -0
  218. package/dist/{tracked-backend-B4HTME4S.js → tracked-backend-4BHSV7NC.js} +34 -33
  219. package/dist/{update-check-O4C2LCZH.js → update-check-A7FXIINW.js} +54 -53
  220. package/dist/{upgrade-command-NVFWLMTA.js → upgrade-command-C5KBITFI.js} +58 -57
  221. package/dist/{whoami-command-YKNTISIV.js → whoami-command-7WQII2H4.js} +14 -14
  222. package/dist/{workspace-GGVGE2S5.js → workspace-Z46PUZNI.js} +5 -5
  223. package/dist/{workspace-binding-OS4ZOX4S.js → workspace-binding-JE6YNDZJ.js} +13 -13
  224. package/dist/{workspace-command-GTUNVN7K.js → workspace-command-FC4IMLAE.js} +113 -82
  225. package/dist/{workspace-env-467C5KHM.js → workspace-env-N4ZPFT6A.js} +14 -13
  226. package/dist/{workspace-export-3XTVGQVM.js → workspace-export-3A5BZTPS.js} +5 -5
  227. package/dist/{writable-7SSWUQJ3.js → writable-D7KCZI5N.js} +4 -4
  228. package/dist/{xano-6RS5XQZE.js → xano-LCI7VWPS.js} +8 -8
  229. package/dist/{xanosdk-import-E3WSIYUE.js → xanosdk-import-P2A2KSXM.js} +8 -8
  230. package/dist/{xanosdk-project-KH5TZ2KI.js → xanosdk-project-6AGMW2SL.js} +15 -14
  231. package/guides/cli.md +4 -4
  232. package/guides/codes.md +7 -2
  233. package/guides/deploying.md +52 -0
  234. package/guides/marketplace.md +21 -0
  235. package/guides/module-contract.md +80 -4
  236. package/guides/typed-frontend.md +37 -0
  237. package/llms/client.md +11 -1
  238. package/llms/filters.md +4 -0
  239. package/llms/kinds-core.md +1 -1
  240. package/llms/statements-data.md +3 -2
  241. package/llms/toolchain.md +12 -0
  242. package/llms-full.txt +34 -7
  243. package/llms.txt +3 -3
  244. package/manifest.json +1 -1
  245. package/package.json +1 -1
  246. package/dist/chunk-MEIJDRHU.js +0 -243
  247. package/dist/env-example-refresh-DWQIOQYR.js +0 -127
  248. package/dist/promote-command-KHTIK44I.js +0 -141
  249. package/dist/toolchain-hooks-QVUZ6HZ4.js +0 -96
package/guides/codes.md CHANGED
@@ -35,7 +35,7 @@ Printed as `! …` on stderr, and as `{ code, message }` in a `--json` document'
35
35
 
36
36
  | Code | Meaning |
37
37
  |---|---|
38
- | `agents.refresh-failed` | A managed agent file (AGENTS.md, …) could not be refreshed; the compile itself went on. |
38
+ | `agents.refresh-failed` | A managed block (AGENTS.md, the README's Built-with footer) could not be refreshed; the compile itself went on. |
39
39
  | `agents.symlink` | … is a symlink — left it and its target untouched. |
40
40
  | `branch.deletion` | … will be permanently deleted and CANNOT be recovered: |
41
41
  | `branch.inventory-unknown` | The branch inventory could not be read, so what this wipe destroys is UNKNOWN. |
@@ -142,7 +142,9 @@ Printed as `! …` on stderr, and as `{ code, message }` in a `--json` document'
142
142
  | `module.install-failed` | … failed — the module was not added. |
143
143
  | `module.kind-unknown` | … does not declare a module kind we recognize, so it is read as an ordinary package. |
144
144
  | `module.legacy-peer-deps` | Installed with --legacy-peer-deps: …. |
145
- | `module.load-failed` | Could not load …/index.ts to update what the module left behind (…). |
145
+ | `module.load-failed` | Could not load …/index.ts to … (…). |
146
+ | `module.peer-mismatch` | The project already declares a peer a toolchain module needs, and the installed version falls outside the module's range; it was left as it is. |
147
+ | `module.peer-not-added` | A peer a toolchain module needs could not be added as a direct dependency; the line names the command that adds it. |
146
148
  | `module.peer-unresolved` | … declares a peer range this project does not satisfy; --legacy-peer-deps did not resolve it either. |
147
149
  | `module.removed-from-marketplace` | … has been removed from the marketplace. |
148
150
  | `module.sdk-skew` | … requires `@xano/sdk` … — the module was not added. |
@@ -224,6 +226,7 @@ Printed as `! …` on stderr, and as `{ code, message }` in a `--json` document'
224
226
  | `release.seed-rows-not-decoded` | … carries seed rows for …, and a decoded tree carries no rows — they are not in …/. |
225
227
  | `release.transfer-cancelled` | Transfer cancelled — nothing was imported. |
226
228
  | `routes.cli-skew` | This CLI is another version than the project's installed SDK, so it left the route table for the installed CLI to render. |
229
+ | `routes.module-failed` | A toolchain module could not generate its section of `routes.gen.ts`; the rest was refreshed and its previous block, if any, was kept. |
227
230
  | `routes.not-written` | The route table (`routes.gen.ts`) was not written this run; the line says why and what writes it. |
228
231
  | `routes.realtime-unresolved` | …: leaving out … — … — whose canonical URL token resolves nowhere, along with their channels. |
229
232
  | `secrets.cleartext-export` | … carries … in cleartext — written owner-only (0600); do not commit it. |
@@ -248,6 +251,7 @@ Printed as `! …` on stderr, and as `{ code, message }` in a `--json` document'
248
251
  | `static.teardown-unknown` | Could not read …'s static hosting, so this cannot say whether a frontend serves there — this replace takes down any that does. |
249
252
  | `static.unconfirmed-live` | Could not confirm the frontend is live within the wait window — the build uploaded and should come online shortly. |
250
253
  | `static.upload-failed` | The static-host upload failed — the backend deploy stands: |
254
+ | `sync.record-failed` | The … succeeded, but its sync baseline could not be recorded in …: … |
251
255
  | `tenant.deploy-partial` | The deploy stopped partway: … release "…" declares… — answered as a NOT NULL violation, though the release makes no field required: the value converts to nul… |
252
256
  | `tenant.deploy-unconfirmed` | Compare its `deployedAt` and `deployedReleaseId` with what they were before this deploy (deployedAt …, deployedReleaseId …). |
253
257
  | `tenant.identities-unchecked` | Whether this release's names and pinned public URL slugs are free on … was not checked — …. |
@@ -309,6 +313,7 @@ Raised while a workspace compiles (`export`, `deploy`, `release`, …). A warnin
309
313
  | `field.email-default-invalid` | The `default` at … is …, which is not an email address — every insert or request that leaves the field out is refused "Invalid email format.". |
310
314
  | `field.enum-default-not-a-value` | The `default` at … is …, which is not one of the enum's values (…) — a value no request can send back. |
311
315
  | `field.input-default-invalid` | The `default` at … is …, which … — every request that leaves the input out is refused. |
316
+ | `field.input-required-default-ignored` | The `default` at …, input "…" is …, but the input is `required: true` — the engine refuses a request that leaves a required input out ("Missing param") befor… |
312
317
  | `field.vector-not-nullable` | table "…", column "…" is a vector with `nullable: false` and no default — an empty default becomes NULL only on a nullable column, and `''` is not a vector,… |
313
318
  | `function.reserved-input-name` | function "…": the input name `…` is reserved by the engine — a call passes its arguments keyed by input name, and the engine skips a `…` key when it evaluate… |
314
319
  | `guard.role-unsatisfiable` | A guard.role on a table passed by name checks a column the table lacks, or a role its enum column cannot hold. |
@@ -1243,6 +1243,58 @@ object with the same key *and* the same identity, so a lock cannot pin a guid th
1243
1243
  never had. If none of the lock's identities appear in the source, that is what pointing a
1244
1244
  project at an unrelated backend looks like, and the pull is refused unless you pass `--yes`.
1245
1245
 
1246
+ ### Which side changed: the sync baseline
1247
+
1248
+ When a workspace and this project differ, `workspace diff` also says **which side moved** since
1249
+ they last matched. Every command that makes them match records a baseline in `xano.lock`, under
1250
+ `synced`. A baseline is one content digest per object, kept per workspace and per branch. The
1251
+ commands that record one are `deploy --to workspace`, a verified `promote`, `pull workspace`
1252
+ and `init --from workspace`. Commit it with the rest of the lock.
1253
+
1254
+ ```bash
1255
+ xanosdk workspace diff ./xano/index.ts --json
1256
+ ```
1257
+
1258
+ ```jsonc
1259
+ {
1260
+ "matched": false,
1261
+ "differing": ["query:GET list (apiGroup orders)", "table:order"],
1262
+ "baseline": { "at": "2026-10-05T13:36:31.000Z", "by": "pull" },
1263
+ "changedThere": ["query:GET list (apiGroup orders)"], // edited in Xano since the baseline
1264
+ "changedHere": ["table:order"], // edited in this project since
1265
+ "changedBoth": [], // edited on both sides: a conflict
1266
+ "unclassified": [] // differs, direction unknown
1267
+ }
1268
+ ```
1269
+
1270
+ - `changedThere`: pull before you deploy, or the deploy overwrites that edit.
1271
+ - `changedHere`: deploy it.
1272
+ - `changedBoth`: reconcile by hand.
1273
+ - `unclassified`: the baseline cannot tell. The object has no baseline entry, both sides
1274
+ already differed when it was taken, or it is the workspace's own settings row, which is
1275
+ never digested. A changed slug also shows only here, because digests leave slugs out.
1276
+
1277
+ Additions and deletions are classified as well. The baseline keeps this project's objects apart
1278
+ from the rest of the branch, so an object the project never held (another source's, or a section
1279
+ a pull does not write into `xano/`) is never reported as deleted here; it shows up only when it
1280
+ changes in Xano. An object that is new in Xano counts as `changedThere` only when the baseline is
1281
+ **complete**: a pull, an `init --from`, a verified
1282
+ `promote` and a `--replace` record every object on the branch, and so does a merge deploy
1283
+ that read the branch first. With no baseline for the branch, `baseline` is `null` and the
1284
+ four lists are empty. A run that finds the branch exactly as recorded leaves the lock alone.
1285
+
1286
+ A few things to know about the baseline:
1287
+
1288
+ - It records what the branch holds after the sync, read back from the branch where the command
1289
+ can do so, so an object stored differently from how it compiles is not reported as changed in
1290
+ Xano. It is recorded whoever's objects landed (a `--bundle` from elsewhere, a release another
1291
+ project cut), because it describes the branch, not ownership.
1292
+ - A baseline taken by a different SDK version under an older digest scheme is set aside
1293
+ (`baseline: null`) and replaced by the next sync, rather than read as every object changed.
1294
+ - An SDK older than this feature drops `synced` when it rewrites `xano.lock`. Nothing breaks: the
1295
+ next sync records a new baseline.
1296
+ - On a merge conflict in `xano.lock`, keep either side's baseline for a branch, or delete it.
1297
+
1246
1298
  ### Deploying to a branch
1247
1299
 
1248
1300
  `--branch <label>` stages on a Xano branch instead of the live one, which is the safer shape
@@ -169,6 +169,23 @@ that arrived some other way is configured by this run too: a plain `npm install`
169
169
  pull request, a `git pull` that changed `package.json`. It also means nothing has to recover
170
170
  a package name out of a `file:` or tarball specifier in order to configure it.
171
171
 
172
+ A **toolchain module** gets two more steps, and `reinstall` runs both as well. Its peers other
173
+ than `@xano/sdk` (`zod`, say) are added as direct dependencies through the project's package
174
+ manager: yarn never installs peers, and pnpm does not link them where `routes.gen.ts` can import
175
+ them. Then, when the project keeps a `routes.gen.ts` beside its entry, the file is regenerated,
176
+ so the module's section lands with the module rather than at the next `xano:routes`. Under
177
+ `--json`, `peers` lists the specs that were added (`["zod@^4.0.0"]`, or `[]`), and `routes` says
178
+ what happened to the file:
179
+
180
+ | `routes` | Meaning |
181
+ |---|---|
182
+ | `written` | Regenerated. |
183
+ | `unchanged` | Already up to date. |
184
+ | `absent` | The project has no `routes.gen.ts` to refresh. |
185
+ | `skipped` | It could not be regenerated here. The warning says why; run `npm run xano:routes`. |
186
+
187
+ `remove` reports `routes` the same way, for the file it regenerates without the removed module.
188
+
172
189
  `init` takes the same names and resolves them the same way — `--marketplace auth` is
173
190
  `@xano-sdk/auth`, and an unlisted name exits 8 before anything is written — so a project can be
174
191
  scaffolded with its add-ons already installed and registered:
@@ -207,6 +224,10 @@ What happens then depends on whether the module predates the command:
207
224
  | `install` re-run over a module already in `dependencies`, or `reinstall` | Refused and **left alone**, settings included, because deleting a module you already had over a version mismatch is not a repair. Upgrade the SDK, or `marketplace remove` it. |
208
225
  | `init --marketplace` | Reported as a module that was not added and taken back off disk. The scaffold itself completes and works. |
209
226
 
227
+ A *different* installed module that is out of range does not stop the verb. `install`, `reinstall`
228
+ and `remove` skip it with a warning naming its range and the fix, and leave its settings and its
229
+ `routes.gen.ts` block exactly as they were. `export`, `deploy` and `preflight` still refuse it.
230
+
210
231
  The point of undoing the install is that the alternative is worse: a module whose hooks were
211
232
  built against a contract this SDK does not have registers and applies **nothing**, so
212
233
  `Installed` would be followed by a project where every command that loads modules refuses it.
@@ -163,6 +163,7 @@ const plugin: ToolchainPlugin = {
163
163
  answersFromConfig: (config) => ({ ... }),
164
164
  onBundle: async (ctx) => ({ ... }),
165
165
  onPreflight: async (ctx) => ({ ... }),
166
+ routesManifest: (ctx) => ({ imports: [...], source: "..." }),
166
167
  };
167
168
 
168
169
  export default plugin;
@@ -175,10 +176,11 @@ guessing which would run code the manifest did not describe.
175
176
  Every hook is optional. A module that only adds a `.gitattributes` line declares
176
177
  `contributes` alone.
177
178
 
178
- Five hooks, and deliberately no more. This contract was designed from one example, and a
179
- contract designed from one example generalizes badly, so it covers exactly what that first
180
- module needed and stops. The second toolchain module is the one that should widen it, with a
181
- real second set of requirements in hand.
179
+ Six hooks, and deliberately no more. The first five were designed from one example (a module
180
+ that renders the workspace to a committed tree) and cover exactly what it needed. The sixth,
181
+ `routesManifest`, was added when a second module, `@xano-sdk/zod`, brought a second real set
182
+ of requirements: writing into a file the SDK generates rather than a tree of its own. A hook
183
+ is added when a module needs it, not in anticipation.
182
184
 
183
185
  ## Questions
184
186
 
@@ -452,6 +454,78 @@ reason to blank.
452
454
  A project whose plugins declare no `onPreflight` never pays for the engine's rendering at all,
453
455
  so declaring the hook is what turns that fetch on.
454
456
 
457
+ ## `routesManifest`
458
+
459
+ ```ts
460
+ import type { ToolchainPlugin } from "@xano/sdk/plugin";
461
+
462
+ const plugin: ToolchainPlugin = {
463
+ kind: "toolchain",
464
+ routesManifest: (ctx) => ({
465
+ imports: [{ from: "zod", names: ["z"] }],
466
+ source: `export const ROUTE_SCHEMAS = ...;`,
467
+ }),
468
+ };
469
+ ```
470
+
471
+ Your module's section of the route manifest, `xano/routes.gen.ts`. It runs wherever that file
472
+ is written: `xanosdk routes ./xano/index.ts --emit xano/routes.gen.ts` (the scaffold's
473
+ `xano:routes`), `pull`, `generate`, and the refresh `marketplace install`, `reinstall` and
474
+ `remove` make, so your block lands with your module.
475
+
476
+ | `RoutesManifestContext` | What it carries |
477
+ |---|---|
478
+ | `inputs` | Every endpoint's, channel's and message's request inputs, under the manifest's final keys (`routes`, `channels`, `messages`), in a fixed order. |
479
+ | `config` | Your block from the project's `package.json` `"xanosdk"` object. |
480
+ | `sdkVersion` | The running `@xano/sdk` version. |
481
+
482
+ `inputs` is a validator-neutral description (type `RouteInputs` in `@xano/sdk/plugin`, not
483
+ the generated map of the same name): each input's name, type, `required`, `nullable`, list
484
+ bounds, enum values, methods, and children. A database link is one `dbLink` entry carrying the
485
+ linked table's expanded `columns`, to spread into the surrounding object; `columns` is
486
+ `undefined` when the payload does not carry that table, which is not "no columns". Walk this
487
+ rather than the payload: it is the same description the SDK renders its own `RouteInputs`,
488
+ `ChannelInputs` and `MessageInputs` types from, so a validator built from it cannot disagree
489
+ with them.
490
+
491
+ **Where the section lands.** The SDK composes the file: the merged imports of every module at
492
+ the top, then the core sections, then each module's `source` in a marked block, blocks ordered
493
+ by package name:
494
+
495
+ ```ts
496
+ // xanosdk:begin @xano-sdk/zod
497
+ // xanosdk:version 1.0.3 - generated; edits inside this block are overwritten
498
+ ...
499
+ // xanosdk:end @xano-sdk/zod
500
+ ```
501
+
502
+ Your source is in the same file as the core sections, so it names `RouteInputs`,
503
+ `ChannelInputs`, `MessageInputs` and `MessageName` directly, without importing them; all four
504
+ are always emitted, as `{}` when empty. Anything you export is exported from `routes.gen.ts`.
505
+ Your names share one scope with the core sections and every other module's, so a collision
506
+ fails the user's typecheck rather than being renamed. A blank `source` writes no block, and its
507
+ imports are dropped with it: that is how a config that turns the section off removes it.
508
+
509
+ **Imports are declared, never written.** The core sections import nothing, which is what keeps
510
+ the file free of the SDK runtime in a frontend bundle. Declare yours in `imports`; never put an
511
+ `import` line in `source`. Each `from` must be a bare package name: `@xano/sdk` and its
512
+ subpaths, a relative or absolute path, and a protocol (`node:`) are all refused, naming your
513
+ module. Each name must be a plain identifier, with no `as` rename. A package you import must
514
+ resolve from the user's project, so declare it in your `peerDependencies`:
515
+ `xanosdk marketplace install` adds each peer other than `@xano/sdk` that the project does not
516
+ already declare as a direct dependency, with your range, through the project's package manager.
517
+
518
+ **Synchronous and pure.** No filesystem, network, clock or randomness: the same context must
519
+ return the same section every time. Every writer of the file must produce the same bytes for
520
+ the same workspace and installed modules, or `routes --emit --strict` passes or fails depending
521
+ on which command last wrote it. A Promise, or any value that is not `{ imports?, source }`, is
522
+ refused, and `source` must not spell a block marker (`// xanosdk:begin`, `// xanosdk:end`).
523
+
524
+ **A throw is your module failing, not the manifest.** The core sections are still refreshed,
525
+ your previous block is kept exactly as it was, and a warning names your module. On
526
+ `routes --emit --strict` it is fatal instead, because a check that did not run must not read
527
+ as one that passed.
528
+
455
529
  ## `HookResult`: `failed` is not a throw
456
530
 
457
531
  ```ts
@@ -544,6 +618,8 @@ Things worth proving about your own module:
544
618
  - Your `onBundle` writes nothing when `ctx.frozen` is true.
545
619
  - Your `onBundle` handles `ctx.entry === undefined`.
546
620
  - Your hooks never read `payload.env` values, because they are blanked.
621
+ - `routesManifest` returns the same section for the same context, called twice, and what it
622
+ writes typechecks beside the core sections of a real `routes.gen.ts`.
547
623
 
548
624
  ## Publishing
549
625
 
@@ -238,5 +238,42 @@ const ws = new WebSocket(socketUrl("chat", XANO_HOST), token);
238
238
  ws.send(JSON.stringify({ action: "join", channel: channelPath("rooms/{room_id}", { room_id }) }));
239
239
  ```
240
240
 
241
+ **Request types come from the same file.** It exports four types-only maps, keyed exactly
242
+ like the runtime tables they sit beside, so a frontend types what it sends without importing a
243
+ def at all:
244
+
245
+ | Type | Keyed by | Holds |
246
+ |---|---|---|
247
+ | `RouteInputs` | the `ROUTES` key (`"POST listings"`, `"v1:GET vehicles"`) | the endpoint's inputs, path params included |
248
+ | `ChannelInputs` | the `CHANNELS` key (`"rooms/{room_id}"`) | the channel's path params |
249
+ | `MessageInputs` | `"<channel key> <message name>"` (`"rooms/{room_id} send"`) | the message's payload |
250
+ | `MessageName` | | every `MessageInputs` key |
251
+
252
+ ```ts
253
+ import { ROUTES, routePath, type RouteInputs } from "../xano/routes.gen";
254
+
255
+ type NewListing = RouteInputs["POST listings"];
256
+
257
+ fetch(BASE + routePath("POST listings"), {
258
+ method: ROUTES["POST listings"].verb,
259
+ headers: { "content-type": "application/json" },
260
+ body: JSON.stringify({ title, price } satisfies NewListing),
261
+ });
262
+ ```
263
+
264
+ Each type agrees with `InferInput<typeof def>` for the same endpoint — required and optional
265
+ keys, `null`, enums, nested objects and lists — so code that already imports a def can keep
266
+ using `InferInput`. The one difference is a database-link input (`input.dbLink(table)`): the
267
+ manifest types it as the linked table's columns, which is what the server accepts, where
268
+ `InferInput` shows an opaque marker under the link's name. Responses are not in the manifest;
269
+ type them with `InferResponse` on an `import type` of the def.
270
+
271
+ These are types, so they add nothing to a bundle. For runtime validation, install
272
+ `@xano-sdk/zod` (`npx xanosdk marketplace install zod`): it writes `ROUTE_SCHEMAS`,
273
+ `CHANNEL_SCHEMAS` and `MESSAGE_SCHEMAS` into the same file under the same keys
274
+ (`ROUTE_SCHEMAS["POST listings"].parse(body)`), each checked against its type when you
275
+ typecheck, so a schema cannot drift from the type it validates. The file then imports `zod`,
276
+ and still never `@xano/sdk`.
277
+
241
278
  Add `--strict` in CI to fail when the committed manifest is out of date. A hand-typed
242
279
  `ROUTES` table is the option that gives up both the bundle saving and the rename safety.
package/llms/client.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Consuming defs from a client
2
2
 
3
- > Read when a frontend imports a def (`getPath()`/`InferResponse`) or calls the deployed backend — what the import costs, `window.XANO_HOST`, local dev, file URLs, and a Node spot-check.
3
+ > Read when a frontend calls the deployed backend or imports a def — request types and zod schemas without the import, its cost, `window.XANO_HOST`, local dev, file URLs, a Node spot-check.
4
4
 
5
5
  Importing a def into a browser bundle or a Node script — for `getPath()`, `getUrl()`, `verb`, or `InferResponse` — runs its factory calls; these are the costs and the checks.
6
6
 
@@ -15,6 +15,16 @@ Importing a def into a browser bundle or a Node script — for `getPath()`, `get
15
15
  plain data importing NOTHING, still compile-checked: `routePath("GET blog/{slug}", { slug })`
16
16
  `channelPath("rooms/{room_id}", { room_id })`, `socketUrl("chat", baseUrl)` (tenant base
17
17
  URLs lifted to `wss://h/ws/<tenant>:<canonical>`). A rename is a type error, not a 404.
18
+ - **Request types without the def.** `routes.gen.ts` also exports types-only `RouteInputs`,
19
+ `ChannelInputs`, `MessageInputs` (and `MessageName`), keyed like `ROUTES`, `CHANNELS`, and
20
+ `"<channel key> <message name>"`: `type NewListing = RouteInputs["POST listings"]`. A
21
+ frontend types bodies, channel params and payloads from these, not `InferInput` on a def;
22
+ keep `InferInput` in code that already imports defs. They match `InferInput`, except a
23
+ `dbLink` input appears as the linked table's columns (what the server accepts). Responses
24
+ are not in the file: `InferResponse` on an `import type` of the def.
25
+ Runtime validation: `xanosdk marketplace install zod` adds `@xano-sdk/zod`, which writes
26
+ `ROUTE_SCHEMAS`/`CHANNEL_SCHEMAS`/`MESSAGE_SCHEMAS` into the file under the same keys, each
27
+ checked against its type at typecheck; the file then imports `zod`, never `@xano/sdk`.
18
28
  - **Verifying a def outside a bundler.** Inside a bundler (Vite/webpack) importing a
19
29
  query def to read `getPath()`/`verb` works directly. To spot-check from Node, run a REAL
20
30
  file with `tsx <file.ts>` **from inside the project root** — not `tsx -e "import …"`
package/llms/filters.md CHANGED
@@ -27,6 +27,10 @@ with `c.obj`/`c.array`. Any argument also takes a runtime value (`inp`, `ref`, a
27
27
  `withFilters` chain) — inside `obj()`/`expr()` an argument cannot carry its own filter
28
28
  chain, so compute it in a prior `set_var`. The arg types below name each argument's
29
29
  ENGINE type, not the JS type you may pass.
30
+ `fl.add`/`fl.sub`/`fl.mul` keep an INT when both operands are ints (`2 × 3` is `6`, not
31
+ `6.0`) and give a decimal only when either operand is one — the `decimal` return type
32
+ below covers both, so an int pipeline needs no `fl.to_int()`. `fl.div` is an int only
33
+ when it divides exactly.
30
34
  To add to a numeric column (counter, stock, balance), use `s.db.increment`
31
35
  (`llms/statements-data.md`) — one atomic UPDATE. A pipeline read-modify-write is NOT
32
36
  atomic (concurrent writers lose updates), and `col("clicks")` does NOT resolve to the
@@ -25,7 +25,7 @@ to survive a rename).
25
25
  - `getPath` percent-encodes each value (so `?`/`#`/spaces stay in their segment) and throws on what encoding cannot contain: a `/`, and a segment that becomes `.`/`..` as sent (a URL parser drops those before routing, addressing a different endpoint).
26
26
  - The keys are typed from the literal `name`, so a typo is a compile error.
27
27
  - `q.toSearchParams(input)` drops GET path params (free `query.toSearchParams` keeps them); lists send `k[]=a&k[]=b` (`k=a&k=b` binds only `b`).
28
- - Browser bundle cost, the `routes.gen.ts` alternative, and spot-checking a def from Node: `llms/client.md`.
28
+ - Browser bundle cost, the `routes.gen.ts` alternative (paths and request types), and spot-checking a def from Node: `llms/client.md`.
29
29
  - `apiGroup({ name, guid?, canonical?, description?, docs?, swagger?, apiGroupEnabled?, documentation?, cors?, middleware? })` — a query container; queries bind to it via their `apiGroup`. `canonical` holds only letters, digits, `_` and `-` (it is the `<canonical>` of `/api:<canonical>`); anything else THROWS at build.
30
30
  - `documentation?`: `{ require_token? }` — the gate on this group's hosted docs. `require_token: true` IS the declaration; the token lives in `xano/.secrets.json` under this group's guid, and a literal `token` FAILS the export. ⚠ ALWAYS emitted, present or not: an absent key is written as the engine default on import, so omitting the block CLEARS an existing gate (the opposite of the `workspaceConfig` rule). `swagger: true` publishes the docs; `require_token` gates them only alongside a non-empty token, so `swagger: true` with no gate makes the whole group readable by anyone with the URL — export warns once per build and `--strict` fails; `diagnostics: { allow: ["api-group.docs-public"] }` accepts it. A declared gate with NO token drops the block, so those bytes clear it: export FAILS under `swagger: true`, and with `swagger` off warns and completes.
31
31
  - `cors?`: `{ mode?, allowOrigins?: string[], allowHeaders?: string[], allowCredentials?, maxAge?, allowMethods?: { get?, post?, put?, patch?, delete?, head? } }`.
@@ -4,7 +4,7 @@
4
4
 
5
5
  Array blocks (an `if`/`transform` is applied per item):
6
6
 
7
- - `s.array.map({ source, as?, transform? })` — `transform` is either a per-item `Value` expression (each item maps to that value) or a **record of values** (each item maps to an object with those keys), or a list of `{ key, value }` pairs, for a key computed per item or two rows sharing one. Use `ref("$this")` for the item and `ref("$index")` for its position. These are THIS statement's own bindings, in a value expression — not the JavaScript lambda contract (see **Lambda bodies**), which binds a different set per surface and is written with `lam.fn`.
7
+ - `s.array.map({ source, as?, transform? })` — `transform` is either a per-item `Value` expression (each item maps to that value) or a **record of values** (each item maps to an object with those keys), or a list of `{ key, value }` pairs, for a key computed per item or two rows sharing one. Use `ref("$this")` for the item and `ref("$index")` for its position. A `transform` value, filter arguments included, can read `ref("$this.<path>")` and any outer stack variable or input. These are THIS statement's own bindings, in a value expression — not the JavaScript lambda contract (see **Lambda bodies**), which binds a different set per surface and is written with `lam.fn`.
8
8
  - `s.array.union({ source, with, as?, transform? })` — set-union two arrays. `with` is REQUIRED; omitted → `Unable to locate input: `.
9
9
 
10
10
  DB reads/writes (`table` is a def handle or name; `fieldName` defaults to the
@@ -58,7 +58,8 @@ primary key `id`):
58
58
  - Template placeholders are Twig over the request scope: `{{ $input.name }}` for an input, `{{ $var.name }}` for a stack variable. ⚠ A BARE `{{ name }}` renders as the empty string — HTTP 200, no error, a query that silently ran with a blank where the value belonged. A bound `?` arg carries a VALUE without the template at all.
59
59
  - ⚠ A table's PHYSICAL name is **not stable across deploys**. A deploy is a full replace, so every table is created afresh and the id in its name moves every time — the same unchanged project redeployed three times gave one table three different names. Never store, cache, hardcode or fixture one: resolve it from `information_schema` inside the same request that uses it.
60
60
  - `s.db.external.<engine>.direct_query({ sql, connectionString, responseType?, args?, parser?, as? })` — same shape against an EXTERNAL database; `<engine>` is `postgres`/`mysql`/`mssql`/`oracle`/`snowflake`. `connectionString` is a `Value` — reach for `env(...)`, not a literal — stored as `context.connection_string_flex`. A bare string stores the older `context.connection_string` instead (an env-var name unless it looks like a URL); each form round-trips as itself.
61
- - `s.db.transaction({ body, as? })` — run a `Statement[]` atomically. `as` binds whatever the block returned.
61
+ - `s.db.transaction({ body })` — run a `Statement[]` atomically. It returns nothing, so it takes no `as`: read what the body binds. An `s.return` in the body ends the WHOLE stack with that value, and the writes before it commit.
62
+ - The body shares the enclosing stack: a variable it binds (`as: "order"` on an `s.db.add`) is still bound AFTER the transaction.
62
63
  - `s.db.bulk.add({ table, items, allowIdField?, as? })` / `s.db.bulk.update` / `s.db.bulk.patch` — `items` is an array `Value`.
63
64
  - ⚠ `bulk.add` **drops `id` on every row unless `allowIdField: true`** (silently, next sequence value instead) — the opposite of `seed`, where `id` pins. Rows referenced by a foreign key need `allowIdField: true`; literal `items` carrying `id` without it throw. `bulk.update`/`patch` keep `id` (their match key).
64
65
  - ⚠ **`bulk.update` is a whole-row REPLACE: every column an item OMITS is zeroed** (`""`/`0`/`null`), HTTP 200, no error — `{ id: 7, status: "done" }` blanks the rest of row 7. **Use `s.db.bulk.patch`** for the partial write "update these rows" means. `export()` warns on a STATIC `items` missing columns (`--strict` fails); a `ref`/`inp` `items` is uninspectable.
package/llms/toolchain.md CHANGED
@@ -14,3 +14,15 @@ shipped defaults. `marketplace reinstall <pkg>` re-asks with the current setting
14
14
  defaults and re-enables a disabled one; `marketplace remove <pkg>` drops block, lines and
15
15
  dependency together — a plain `npm uninstall` leaves the block, and a package it names
16
16
  that is no longer installed fails every `--frozen-lock` run.
17
+
18
+ **A module's section of `xano/routes.gen.ts`.** A module with a `routesManifest` hook (types:
19
+ `@xano/sdk/plugin`) writes a block between `// xanosdk:begin <pkg>` and `// xanosdk:end <pkg>`
20
+ after the core sections, on every write of the file (`routes --emit`, `xano:routes`, `pull`,
21
+ `generate`, `marketplace install|reinstall|remove`). Edits inside the block are overwritten.
22
+ Install also adds the module's non-SDK peers (e.g. `zod`) as direct dependencies.
23
+ The hook is synchronous and pure: given
24
+ the request inputs under the manifest's keys and its config, it returns `{ imports?, source }`,
25
+ imports as bare package names (`@xano/sdk*`, relative and `node:` are refused). A module that
26
+ fails to load or throws leaves its previous block as it was, with a warning naming it, and the
27
+ core sections still refresh; under `routes --emit --strict` it is fatal. `@xano-sdk/zod`
28
+ (`xanosdk marketplace install zod`) is one: it adds `ROUTE_SCHEMAS` and its siblings.
package/llms-full.txt CHANGED
@@ -1,4 +1,4 @@
1
- # xanosdk v1.0.5
1
+ # xanosdk v1.0.6
2
2
 
3
3
  > TypeScript SDK that compiles a typed Xano workspace into the importable packageExport JSON bundle.
4
4
 
@@ -39,7 +39,7 @@ plain file read resolves them at the version you have.
39
39
 
40
40
  - [Object kinds](llms/object-kinds.md): Read when deciding WHAT to build — every authorable primitive, what each is, and which factory + register method builds it. Also when `register*` will not typecheck an array built by `.flatMap()`/`.concat()`.
41
41
  - [Core def shapes](llms/kinds-core.md): Read when authoring a function, query, api group, task, workflow test, middleware, tool, or addon — and for the `response` and `expr` shapes every one of them uses.
42
- - [Consuming defs from a client](llms/client.md): Read when a frontend imports a def (`getPath()`/`InferResponse`) or calls the deployed backend — what the import costs, `window.XANO_HOST`, local dev, file URLs, and a Node spot-check.
42
+ - [Consuming defs from a client](llms/client.md): Read when a frontend calls the deployed backend or imports a def — request types and zod schemas without the import, its cost, `window.XANO_HOST`, local dev, file URLs, a Node spot-check.
43
43
  - [Toolchain modules](llms/toolchain.md): Read when `package.json` has a `"xanosdk"` block or you run `xanosdk marketplace`.
44
44
  - [Error index](llms/errors.md): Read when a request, test, build, or pull fails with a message you did not write — the string, its cause, and where the fix is.
45
45
  - [Saved unit tests, assertions, and mocks](llms/tests.md): Read when authoring a `workflowTest()` stack, when a query/function/middleware carries `tests`, when a statement needs a `mock`, or when running a deployed environment's tests.
@@ -436,7 +436,7 @@ Non-obvious authoring rules:
436
436
  checked only by the `xanosdk export`/`deploy` CLI path. Only `deploy` ships seed rows.
437
437
  - Entry points: the `node:fs` writers (`writeBundle`/`writeArtifact`) and lock-file I/O
438
438
  import from `@xano/sdk/node`, NOT the browser-safe `@xano/sdk` entry (a frontend
439
- imports defs from it for `getPath()`/`InferInput`). `@xano/sdk/internal` is the
439
+ imports from it; request types come from `routes.gen.ts`). `@xano/sdk/internal` is the
440
440
  compiler machinery, never needed to author. READING a bundle back is `@xano/sdk/bundle`
441
441
  — a statement walker (`2.if.0` paths), a structural hash, `mvp:*` catalog, `tableRefOf`.
442
442
  - **Intra-workspace imports use `.js` specifiers** (`../tables/links.js`), not
@@ -554,7 +554,7 @@ to survive a rename).
554
554
  - `getPath` percent-encodes each value (so `?`/`#`/spaces stay in their segment) and throws on what encoding cannot contain: a `/`, and a segment that becomes `.`/`..` as sent (a URL parser drops those before routing, addressing a different endpoint).
555
555
  - The keys are typed from the literal `name`, so a typo is a compile error.
556
556
  - `q.toSearchParams(input)` drops GET path params (free `query.toSearchParams` keeps them); lists send `k[]=a&k[]=b` (`k=a&k=b` binds only `b`).
557
- - Browser bundle cost, the `routes.gen.ts` alternative, and spot-checking a def from Node: `llms/client.md`.
557
+ - Browser bundle cost, the `routes.gen.ts` alternative (paths and request types), and spot-checking a def from Node: `llms/client.md`.
558
558
  - `apiGroup({ name, guid?, canonical?, description?, docs?, swagger?, apiGroupEnabled?, documentation?, cors?, middleware? })` — a query container; queries bind to it via their `apiGroup`. `canonical` holds only letters, digits, `_` and `-` (it is the `<canonical>` of `/api:<canonical>`); anything else THROWS at build.
559
559
  - `documentation?`: `{ require_token? }` — the gate on this group's hosted docs. `require_token: true` IS the declaration; the token lives in `xano/.secrets.json` under this group's guid, and a literal `token` FAILS the export. ⚠ ALWAYS emitted, present or not: an absent key is written as the engine default on import, so omitting the block CLEARS an existing gate (the opposite of the `workspaceConfig` rule). `swagger: true` publishes the docs; `require_token` gates them only alongside a non-empty token, so `swagger: true` with no gate makes the whole group readable by anyone with the URL — export warns once per build and `--strict` fails; `diagnostics: { allow: ["api-group.docs-public"] }` accepts it. A declared gate with NO token drops the block, so those bytes clear it: export FAILS under `swagger: true`, and with `swagger` off warns and completes.
560
560
  - `cors?`: `{ mode?, allowOrigins?: string[], allowHeaders?: string[], allowCredentials?, maxAge?, allowMethods?: { get?, post?, put?, patch?, delete?, head? } }`.
@@ -630,7 +630,7 @@ surface — `s.conditional`/`s.while` `when` (incl. each `elif` branch), and
630
630
 
631
631
  # Consuming defs from a client
632
632
 
633
- > Read when a frontend imports a def (`getPath()`/`InferResponse`) or calls the deployed backend — what the import costs, `window.XANO_HOST`, local dev, file URLs, and a Node spot-check.
633
+ > Read when a frontend calls the deployed backend or imports a def — request types and zod schemas without the import, its cost, `window.XANO_HOST`, local dev, file URLs, a Node spot-check.
634
634
 
635
635
  Importing a def into a browser bundle or a Node script — for `getPath()`, `getUrl()`, `verb`, or `InferResponse` — runs its factory calls; these are the costs and the checks.
636
636
 
@@ -645,6 +645,16 @@ Importing a def into a browser bundle or a Node script — for `getPath()`, `get
645
645
  plain data importing NOTHING, still compile-checked: `routePath("GET blog/{slug}", { slug })`
646
646
  `channelPath("rooms/{room_id}", { room_id })`, `socketUrl("chat", baseUrl)` (tenant base
647
647
  URLs lifted to `wss://h/ws/<tenant>:<canonical>`). A rename is a type error, not a 404.
648
+ - **Request types without the def.** `routes.gen.ts` also exports types-only `RouteInputs`,
649
+ `ChannelInputs`, `MessageInputs` (and `MessageName`), keyed like `ROUTES`, `CHANNELS`, and
650
+ `"<channel key> <message name>"`: `type NewListing = RouteInputs["POST listings"]`. A
651
+ frontend types bodies, channel params and payloads from these, not `InferInput` on a def;
652
+ keep `InferInput` in code that already imports defs. They match `InferInput`, except a
653
+ `dbLink` input appears as the linked table's columns (what the server accepts). Responses
654
+ are not in the file: `InferResponse` on an `import type` of the def.
655
+ Runtime validation: `xanosdk marketplace install zod` adds `@xano-sdk/zod`, which writes
656
+ `ROUTE_SCHEMAS`/`CHANNEL_SCHEMAS`/`MESSAGE_SCHEMAS` into the file under the same keys, each
657
+ checked against its type at typecheck; the file then imports `zod`, never `@xano/sdk`.
648
658
  - **Verifying a def outside a bundler.** Inside a bundler (Vite/webpack) importing a
649
659
  query def to read `getPath()`/`verb` works directly. To spot-check from Node, run a REAL
650
660
  file with `tsx <file.ts>` **from inside the project root** — not `tsx -e "import …"`
@@ -708,6 +718,18 @@ defaults and re-enables a disabled one; `marketplace remove <pkg>` drops block,
708
718
  dependency together — a plain `npm uninstall` leaves the block, and a package it names
709
719
  that is no longer installed fails every `--frozen-lock` run.
710
720
 
721
+ **A module's section of `xano/routes.gen.ts`.** A module with a `routesManifest` hook (types:
722
+ `@xano/sdk/plugin`) writes a block between `// xanosdk:begin <pkg>` and `// xanosdk:end <pkg>`
723
+ after the core sections, on every write of the file (`routes --emit`, `xano:routes`, `pull`,
724
+ `generate`, `marketplace install|reinstall|remove`). Edits inside the block are overwritten.
725
+ Install also adds the module's non-SDK peers (e.g. `zod`) as direct dependencies.
726
+ The hook is synchronous and pure: given
727
+ the request inputs under the manifest's keys and its config, it returns `{ imports?, source }`,
728
+ imports as bare package names (`@xano/sdk*`, relative and `node:` are refused). A module that
729
+ fails to load or throws leaves its previous block as it was, with a warning naming it, and the
730
+ core sections still refresh; under `routes --emit --strict` it is fatal. `@xano-sdk/zod`
731
+ (`xanosdk marketplace install zod`) is one: it adds `ROUTE_SCHEMAS` and its siblings.
732
+
711
733
  # Error index
712
734
 
713
735
  > Read when a request, test, build, or pull fails with a message you did not write — the string, its cause, and where the fix is.
@@ -997,7 +1019,7 @@ off); a trigger's own failure reaches the error log only while it is on.
997
1019
 
998
1020
  Array blocks (an `if`/`transform` is applied per item):
999
1021
 
1000
- - `s.array.map({ source, as?, transform? })` — `transform` is either a per-item `Value` expression (each item maps to that value) or a **record of values** (each item maps to an object with those keys), or a list of `{ key, value }` pairs, for a key computed per item or two rows sharing one. Use `ref("$this")` for the item and `ref("$index")` for its position. These are THIS statement's own bindings, in a value expression — not the JavaScript lambda contract (see **Lambda bodies**), which binds a different set per surface and is written with `lam.fn`.
1022
+ - `s.array.map({ source, as?, transform? })` — `transform` is either a per-item `Value` expression (each item maps to that value) or a **record of values** (each item maps to an object with those keys), or a list of `{ key, value }` pairs, for a key computed per item or two rows sharing one. Use `ref("$this")` for the item and `ref("$index")` for its position. A `transform` value, filter arguments included, can read `ref("$this.<path>")` and any outer stack variable or input. These are THIS statement's own bindings, in a value expression — not the JavaScript lambda contract (see **Lambda bodies**), which binds a different set per surface and is written with `lam.fn`.
1001
1023
  - `s.array.union({ source, with, as?, transform? })` — set-union two arrays. `with` is REQUIRED; omitted → `Unable to locate input: `.
1002
1024
 
1003
1025
  DB reads/writes (`table` is a def handle or name; `fieldName` defaults to the
@@ -1051,7 +1073,8 @@ primary key `id`):
1051
1073
  - Template placeholders are Twig over the request scope: `{{ $input.name }}` for an input, `{{ $var.name }}` for a stack variable. ⚠ A BARE `{{ name }}` renders as the empty string — HTTP 200, no error, a query that silently ran with a blank where the value belonged. A bound `?` arg carries a VALUE without the template at all.
1052
1074
  - ⚠ A table's PHYSICAL name is **not stable across deploys**. A deploy is a full replace, so every table is created afresh and the id in its name moves every time — the same unchanged project redeployed three times gave one table three different names. Never store, cache, hardcode or fixture one: resolve it from `information_schema` inside the same request that uses it.
1053
1075
  - `s.db.external.<engine>.direct_query({ sql, connectionString, responseType?, args?, parser?, as? })` — same shape against an EXTERNAL database; `<engine>` is `postgres`/`mysql`/`mssql`/`oracle`/`snowflake`. `connectionString` is a `Value` — reach for `env(...)`, not a literal — stored as `context.connection_string_flex`. A bare string stores the older `context.connection_string` instead (an env-var name unless it looks like a URL); each form round-trips as itself.
1054
- - `s.db.transaction({ body, as? })` — run a `Statement[]` atomically. `as` binds whatever the block returned.
1076
+ - `s.db.transaction({ body })` — run a `Statement[]` atomically. It returns nothing, so it takes no `as`: read what the body binds. An `s.return` in the body ends the WHOLE stack with that value, and the writes before it commit.
1077
+ - The body shares the enclosing stack: a variable it binds (`as: "order"` on an `s.db.add`) is still bound AFTER the transaction.
1055
1078
  - `s.db.bulk.add({ table, items, allowIdField?, as? })` / `s.db.bulk.update` / `s.db.bulk.patch` — `items` is an array `Value`.
1056
1079
  - ⚠ `bulk.add` **drops `id` on every row unless `allowIdField: true`** (silently, next sequence value instead) — the opposite of `seed`, where `id` pins. Rows referenced by a foreign key need `allowIdField: true`; literal `items` carrying `id` without it throw. `bulk.update`/`patch` keep `id` (their match key).
1057
1080
  - ⚠ **`bulk.update` is a whole-row REPLACE: every column an item OMITS is zeroed** (`""`/`0`/`null`), HTTP 200, no error — `{ id: 7, status: "done" }` blanks the rest of row 7. **Use `s.db.bulk.patch`** for the partial write "update these rows" means. `export()` warns on a STATIC `items` missing columns (`--strict` fails); a `ref`/`inp` `items` is uninspectable.
@@ -1428,6 +1451,10 @@ with `c.obj`/`c.array`. Any argument also takes a runtime value (`inp`, `ref`, a
1428
1451
  `withFilters` chain) — inside `obj()`/`expr()` an argument cannot carry its own filter
1429
1452
  chain, so compute it in a prior `set_var`. The arg types below name each argument's
1430
1453
  ENGINE type, not the JS type you may pass.
1454
+ `fl.add`/`fl.sub`/`fl.mul` keep an INT when both operands are ints (`2 × 3` is `6`, not
1455
+ `6.0`) and give a decimal only when either operand is one — the `decimal` return type
1456
+ below covers both, so an int pipeline needs no `fl.to_int()`. `fl.div` is an int only
1457
+ when it divides exactly.
1431
1458
  To add to a numeric column (counter, stock, balance), use `s.db.increment`
1432
1459
  (`llms/statements-data.md`) — one atomic UPDATE. A pipeline read-modify-write is NOT
1433
1460
  atomic (concurrent writers lose updates), and `col("clicks")` does NOT resolve to the
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # xanosdk v1.0.5
1
+ # xanosdk v1.0.6
2
2
 
3
3
  > TypeScript SDK that compiles a typed Xano workspace into the importable packageExport JSON bundle.
4
4
 
@@ -39,7 +39,7 @@ plain file read resolves them at the version you have.
39
39
 
40
40
  - [Object kinds](llms/object-kinds.md): Read when deciding WHAT to build — every authorable primitive, what each is, and which factory + register method builds it. Also when `register*` will not typecheck an array built by `.flatMap()`/`.concat()`.
41
41
  - [Core def shapes](llms/kinds-core.md): Read when authoring a function, query, api group, task, workflow test, middleware, tool, or addon — and for the `response` and `expr` shapes every one of them uses.
42
- - [Consuming defs from a client](llms/client.md): Read when a frontend imports a def (`getPath()`/`InferResponse`) or calls the deployed backend — what the import costs, `window.XANO_HOST`, local dev, file URLs, and a Node spot-check.
42
+ - [Consuming defs from a client](llms/client.md): Read when a frontend calls the deployed backend or imports a def — request types and zod schemas without the import, its cost, `window.XANO_HOST`, local dev, file URLs, a Node spot-check.
43
43
  - [Toolchain modules](llms/toolchain.md): Read when `package.json` has a `"xanosdk"` block or you run `xanosdk marketplace`.
44
44
  - [Error index](llms/errors.md): Read when a request, test, build, or pull fails with a message you did not write — the string, its cause, and where the fix is.
45
45
  - [Saved unit tests, assertions, and mocks](llms/tests.md): Read when authoring a `workflowTest()` stack, when a query/function/middleware carries `tests`, when a statement needs a `mock`, or when running a deployed environment's tests.
@@ -436,7 +436,7 @@ Non-obvious authoring rules:
436
436
  checked only by the `xanosdk export`/`deploy` CLI path. Only `deploy` ships seed rows.
437
437
  - Entry points: the `node:fs` writers (`writeBundle`/`writeArtifact`) and lock-file I/O
438
438
  import from `@xano/sdk/node`, NOT the browser-safe `@xano/sdk` entry (a frontend
439
- imports defs from it for `getPath()`/`InferInput`). `@xano/sdk/internal` is the
439
+ imports from it; request types come from `routes.gen.ts`). `@xano/sdk/internal` is the
440
440
  compiler machinery, never needed to author. READING a bundle back is `@xano/sdk/bundle`
441
441
  — a statement walker (`2.if.0` paths), a structural hash, `mvp:*` catalog, `tableRefOf`.
442
442
  - **Intra-workspace imports use `.js` specifiers** (`../tables/links.js`), not
package/manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xanosdk",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "TypeScript SDK that compiles a typed Xano workspace into the importable packageExport JSON bundle.",
5
5
  "coverage": {
6
6
  "objectKinds": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xano/sdk",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Xano SDK — your Xano backend as TypeScript. `xanosdk deploy` ships your typed workspace (and an optional static frontend) to a live, auto-expiring ephemeral environment and prints its URL. init → deploy → URL.",
5
5
  "keywords": [
6
6
  "xanosdk",