@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,1038 @@
1
+ import {
2
+ impliedInputs
3
+ } from "./chunk-G554NZNI.js";
4
+
5
+ // src/validate/normalize.ts
6
+ var STRIP_KEYS = /* @__PURE__ */ new Set([
7
+ // server columns / persistence
8
+ "id",
9
+ "created_at",
10
+ "updated_at",
11
+ "deleted_at",
12
+ "guid",
13
+ "_draft",
14
+ // auto-generated xsids / runtime keys
15
+ "_xsid",
16
+ "@guid",
17
+ "@index",
18
+ "stack_id",
19
+ "index",
20
+ // deploy-target / market binding (deferred)
21
+ "workspace",
22
+ "branch",
23
+ "market_item",
24
+ // The CREATOR of a knowledge item (`{id: 0}` for anything an import created).
25
+ // Server-assigned provenance, in the same family as the already-stripped
26
+ // `workspace`/`branch` bindings: the SDK never authors it, and a workspace
27
+ // synced by two different people would otherwise diff on who touched it last.
28
+ // Verified to be a knowledge-only key — no encoder in this SDK emits `user`
29
+ // anywhere in a compiled payload.
30
+ "user",
31
+ // engine-stored source artifact (the raw XanoScript text), not authored data
32
+ "xanoscript",
33
+ // A workflow test's LAST RUN result — when it ran, how long it took, and the
34
+ // pass/fail of each statement. Instance state produced by executing the test,
35
+ // not workspace source, so the SDK neither authors nor emits it. A stored
36
+ // object always carries the key (`null` until the test has been run once), so
37
+ // without this the whole kind reads as a failed round trip.
38
+ "lastRun",
39
+ // storage-mode flag the golden table corpus predates (those fixtures were
40
+ // captured before `use_xdo` was serialized). The SDK always emits it; it
41
+ // doesn't change the authored schema, so drop it from both sides — same as
42
+ // the already-stripped `index`, whose gin entry `use_xdo` only gates.
43
+ "use_xdo",
44
+ // A dead key, dropped for the same reason as `iterator` (see
45
+ // {@link returnWithoutIterator}) and traced the same way.
46
+ //
47
+ // Xano's frontend writes `context: {dbo:{id}, allow_notfound: true}` from ONE
48
+ // place — the auth scaffold generator that builds a signup/login query. No
49
+ // engine class reads it: the `mvp` get-by class consults `dbo`, `output`, and
50
+ // its args and nothing else, and the older non-MVP class reads a differently
51
+ // named `allow_null`. So the member cannot change what a query does.
52
+ //
53
+ // It is deliberately NOT modelled — an authoring surface for a key the engine
54
+ // ignores is the mistake this file already refuses to make elsewhere. But the
55
+ // exclusion was only half-done: the encoder correctly declined to write it
56
+ // while the comparison still demanded it, so a correct decision read as a
57
+ // round-trip failure and sent every scaffolded auth query to `raw()`.
58
+ "allow_notfound"
59
+ ]);
60
+ function isEmptyObject(v) {
61
+ return v !== null && typeof v === "object" && !Array.isArray(v) && Object.keys(v).length === 0;
62
+ }
63
+ function isEmptyCustomize(v) {
64
+ return v === "" || isEmptyObject(v) || isEmptyArray(v);
65
+ }
66
+ function isSavedTest(value) {
67
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
68
+ const rec = value;
69
+ return typeof rec.name === "string" && Array.isArray(rec.expect);
70
+ }
71
+ function isEmptyArray(v) {
72
+ return Array.isArray(v) && v.length === 0;
73
+ }
74
+ function isNumber(v, n) {
75
+ return v === n || typeof v === "string" && v !== "" && Number(v) === n;
76
+ }
77
+ function deepEqual(a, b) {
78
+ if (a === b) return true;
79
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
80
+ const aArr = Array.isArray(a);
81
+ if (aArr !== Array.isArray(b)) return false;
82
+ if (aArr) {
83
+ const x2 = a;
84
+ const y2 = b;
85
+ return x2.length === y2.length && x2.every((v, i) => deepEqual(v, y2[i]));
86
+ }
87
+ const x = a;
88
+ const y = b;
89
+ const keys = Object.keys(x);
90
+ return keys.length === Object.keys(y).length && keys.every((k) => deepEqual(x[k], y[k]));
91
+ }
92
+ var TIMESTAMP_RE = /^(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}:\d{2})(?:\.\d+)?(Z|z|[+-]\d{2}:?\d{2})?$/;
93
+ function canonicalizeTimestamp(s) {
94
+ const m = TIMESTAMP_RE.exec(s);
95
+ if (!m) return void 0;
96
+ let tz = m[3] ?? "Z";
97
+ if (tz === "z") tz = "Z";
98
+ if (/^[+-]\d{4}$/.test(tz)) tz = `${tz.slice(0, 3)}:${tz.slice(3)}`;
99
+ const d = /* @__PURE__ */ new Date(`${m[1]}T${m[2]}${tz}`);
100
+ return Number.isNaN(d.getTime()) ? void 0 : d.toISOString();
101
+ }
102
+ var DEFAULT_CONTEXT_RETURN = {
103
+ list: {
104
+ sort: [],
105
+ paging: { page: 1, offset: 0, totals: false, enabled: false, metadata: true, per_page: 25 },
106
+ distinct: "auto"
107
+ },
108
+ type: "list",
109
+ single: { sort: [] },
110
+ stream: { sort: [], paging: { page: 1, enabled: false, per_page: 25 }, distinct: "auto" },
111
+ aggregate: {
112
+ eval: [],
113
+ sort: [],
114
+ group: [],
115
+ index: [],
116
+ paging: { page: 1, enabled: false, metadata: true, per_page: 25 }
117
+ }
118
+ };
119
+ var DEFAULT_RETURN_BLOCKS = {
120
+ list: DEFAULT_CONTEXT_RETURN.list,
121
+ single: DEFAULT_CONTEXT_RETURN.single,
122
+ stream: DEFAULT_CONTEXT_RETURN.stream,
123
+ aggregate: DEFAULT_CONTEXT_RETURN.aggregate
124
+ };
125
+ var MINIMAL_CONTEXT_RETURN = { type: "list" };
126
+ function hasNoListBounds(value) {
127
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
128
+ const entries = Object.entries(value);
129
+ if (entries.length === 0) return false;
130
+ return entries.every(
131
+ ([member, bound]) => (member === "min" || member === "max") && (bound === "" || typeof bound === "object" && bound !== null && isEmptyObject(bound))
132
+ );
133
+ }
134
+ var PAGING_INT_KEYS = /* @__PURE__ */ new Set(["page", "per_page", "offset"]);
135
+ var UNREADABLE_INPUT = /* @__PURE__ */ new Set(["mvp:create_image"]);
136
+ function hasUnreadableInput(name) {
137
+ return typeof name === "string" && UNREADABLE_INPUT.has(name);
138
+ }
139
+ var RETIRED_INPUT = {
140
+ "mvp:datadog_log": { ddtags: "tags" },
141
+ "mvp:datadog_metric": { ddtags: "tags" },
142
+ "mvp:amazon_opensearch_query": { hidden_cols: "included_fields" },
143
+ "mvp:elasticsearch_query": { hidden_cols: "included_fields" }
144
+ };
145
+ var NO_RETIRED_INPUTS = [];
146
+ function retiredInputs(name) {
147
+ const row = typeof name === "string" ? Object.hasOwn(RETIRED_INPUT, name) ? RETIRED_INPUT[name] : void 0 : void 0;
148
+ return row ? Object.keys(row) : NO_RETIRED_INPUTS;
149
+ }
150
+ function retiredInputSuccessor(name, input) {
151
+ const row = typeof name === "string" ? Object.hasOwn(RETIRED_INPUT, name) ? RETIRED_INPUT[name] : void 0 : void 0;
152
+ return row?.[input] ?? null;
153
+ }
154
+ var NAME_KEYED_INPUT = /* @__PURE__ */ new Set([
155
+ "mvp:create_auth",
156
+ "mvp:api_request",
157
+ "mvp:amazon_opensearch_document",
158
+ "mvp:elasticsearch_document"
159
+ ]);
160
+ var EMPTY_SEARCH = { expression: [] };
161
+ function isBlankGroupStatement(v) {
162
+ if (v === null || typeof v !== "object" || Array.isArray(v)) return false;
163
+ const node = v;
164
+ if (node.op !== "=") return false;
165
+ const blankSide = (side) => side !== null && typeof side === "object" && side.tag === "const" && side.operand === "";
166
+ return blankSide(node.left) && blankSide(node.right);
167
+ }
168
+ var RETURN_BLOCKS = ["single", "list", "stream", "aggregate"];
169
+ var RETURN_TYPES = /* @__PURE__ */ new Set([...RETURN_BLOCKS, "count", "exists"]);
170
+ function liveReturnSection(value) {
171
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
172
+ const section = value;
173
+ const type = section.type;
174
+ if (typeof type !== "string" || !RETURN_TYPES.has(type)) return void 0;
175
+ const dead = RETURN_BLOCKS.filter((b) => b !== type && b in section);
176
+ if (dead.length === 0) return void 0;
177
+ const live = {};
178
+ for (const [k, v] of Object.entries(section)) {
179
+ if (!RETURN_BLOCKS.includes(k) || k === type) live[k] = v;
180
+ }
181
+ return live;
182
+ }
183
+ function unboundAuthTable(value) {
184
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
185
+ const block = value;
186
+ if (block.dbo_id !== 0 || !("row_id" in block)) return void 0;
187
+ const rest = { ...block };
188
+ delete rest["dbo_id"];
189
+ return rest;
190
+ }
191
+ function returnWithoutIterator(value) {
192
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
193
+ const section = value;
194
+ if (typeof section.type !== "string" || !RETURN_TYPES.has(section.type)) return void 0;
195
+ let found = false;
196
+ const out = {};
197
+ for (const [k, v] of Object.entries(section)) {
198
+ if (RETURN_BLOCKS.includes(k) && v !== null && typeof v === "object" && !Array.isArray(v) && "iterator" in v) {
199
+ found = true;
200
+ const rest = { ...v };
201
+ delete rest.iterator;
202
+ out[k] = rest;
203
+ continue;
204
+ }
205
+ out[k] = v;
206
+ }
207
+ return found ? out : void 0;
208
+ }
209
+ var DEDICATED_RUNTIME_KEYS = ["cpu", "memory", "timeout", "max_retry"];
210
+ function liveAsyncRuntime(value) {
211
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
212
+ const block = value;
213
+ const mode = block.mode;
214
+ if (typeof mode !== "string") return void 0;
215
+ if (mode === "disabled") return {};
216
+ if (mode !== "async-shared") return void 0;
217
+ if (!DEDICATED_RUNTIME_KEYS.some((k) => k in block)) return void 0;
218
+ const live = {};
219
+ for (const [k, v] of Object.entries(block)) {
220
+ if (!DEDICATED_RUNTIME_KEYS.includes(k)) live[k] = v;
221
+ }
222
+ return live;
223
+ }
224
+ function isDeadResultItem(item, total) {
225
+ if (item === null || typeof item !== "object" || Array.isArray(item)) return false;
226
+ const entry = item;
227
+ if (entry.disabled !== void 0 && entry.disabled !== false) return true;
228
+ return entry.name === "" && total !== 1;
229
+ }
230
+ function isResultList(value) {
231
+ return Array.isArray(value) && value.length > 0 && value.every(
232
+ (e) => e !== null && typeof e === "object" && !Array.isArray(e) && "name" in e && "value" in e && "tag" in e && "filters" in e
233
+ );
234
+ }
235
+ function liveResultItems(value) {
236
+ if (!isResultList(value)) return void 0;
237
+ const live = value.filter((e) => !isDeadResultItem(e, value.length));
238
+ return live.length === value.length ? void 0 : live;
239
+ }
240
+ function isBlankAgentSettings(value) {
241
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
242
+ const settings = value;
243
+ if (settings.type !== "") return false;
244
+ if (settings.structuredOutputs === true) return false;
245
+ const schema = settings.structuredOutputsSchema;
246
+ if (Array.isArray(schema) && schema.length > 0) return false;
247
+ return true;
248
+ }
249
+ function configuredDeadReturnBlocks(value) {
250
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return [];
251
+ const section = value;
252
+ const type = section.type;
253
+ if (typeof type !== "string" || !RETURN_TYPES.has(type)) return [];
254
+ return RETURN_BLOCKS.filter((b) => b !== type && isConfiguredReturnBlock(section[b]));
255
+ }
256
+ function isConfiguredReturnBlock(block) {
257
+ if (block === null || typeof block !== "object" || Array.isArray(block)) return false;
258
+ const b = block;
259
+ for (const list of ["sort", "group", "eval", "index"]) {
260
+ if (Array.isArray(b[list]) && b[list].length > 0) return true;
261
+ }
262
+ const paging = b.paging;
263
+ return paging !== null && typeof paging === "object" && paging.enabled === true;
264
+ }
265
+ var DEFAULT_CONTEXT_EXTERNAL = {
266
+ tag: "input",
267
+ value: "",
268
+ permissions: { page: true, sort: true, search: true, per_page: false }
269
+ };
270
+ function bindsNoPagingFacet(value) {
271
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
272
+ const facets = Object.values(value);
273
+ if (facets.length === 0) return false;
274
+ return facets.every(
275
+ (facet) => facet !== null && typeof facet === "object" && !Array.isArray(facet) && facet.value === "" && (facet.filters ?? []).length === 0
276
+ );
277
+ }
278
+ var DEFAULT_CORS = {
279
+ mode: "default",
280
+ allowOrigins: [],
281
+ allowHeaders: [],
282
+ allowCredentials: false,
283
+ maxAge: 0,
284
+ allowMethods: { delete: false, get: false, head: false, patch: false, post: false, put: false }
285
+ };
286
+ var DEFAULT_DOCUMENTATION = { require_token: false, token: "" };
287
+ var DEFAULT_MIDDLEWARE = { pre: [], post: [], pre_customize: false, post_customize: false };
288
+ function isRawSqlContext(container) {
289
+ return container !== null && typeof container === "object" && typeof container.code === "string";
290
+ }
291
+ function withoutLeadingJoin(v) {
292
+ if (v === null || typeof v !== "object") return v;
293
+ const expression = v.expression;
294
+ if (!Array.isArray(expression)) return v;
295
+ const cleared = expression.map((entry, i) => {
296
+ if (entry === null || typeof entry !== "object") return entry;
297
+ const node = entry;
298
+ const group = "group" in node ? { group: withoutLeadingJoin(node.group) } : {};
299
+ if (i > 0) return { ...node, ...group };
300
+ const rest = Object.fromEntries(Object.entries(node).filter(([key]) => key !== "or"));
301
+ return { ...rest, ...group };
302
+ });
303
+ return { ...v, expression: cleared };
304
+ }
305
+ function isDefaultEnvelopeMember(key, v) {
306
+ switch (key) {
307
+ // An empty `mocks` arrives as `[]` from the engine and `{}` from the SDK — the
308
+ // empty-associative-collection artifact again. Both mean "no mocks".
309
+ case "mocks":
310
+ return isEmptyObject(v) || isEmptyArray(v);
311
+ // An UNSET runtime binding, in both stored spellings: the `null` the engine
312
+ // writes on one generation and the blank-member object it writes on another
313
+ // (`{id: "", mode: ""}` on 6 real `mvp:function` statements). A binding that
314
+ // names anything is preserved and still compares.
315
+ case "runtime":
316
+ return v === null || typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every((member) => member === "");
317
+ case "settings_registry":
318
+ return v === null || isEmptyArray(v);
319
+ case "addon":
320
+ return isEmptyArray(v);
321
+ case "disabled":
322
+ return v === false;
323
+ case "as":
324
+ case "description":
325
+ case "sql_name":
326
+ return v === "";
327
+ // The object-level members below are the same generational gap one level up
328
+ // — an object saved by an older engine generation omits them, while both the
329
+ // current engine and the SDK always write them at a fixed default. They were
330
+ // 1,716 of the 1,744 round-trip mismatches in a 187-workspace sweep, and
331
+ // each default is evidenced twice: the engine reads the absent key as this
332
+ // value, and real workspaces store present-at-default and absent side by
333
+ // side on one instance.
334
+ case "docs":
335
+ case "datasource":
336
+ case "view_alias":
337
+ return v === "";
338
+ // An MCP tool entry's optional metadata, and the agent provider-config
339
+ // members whose unset spelling is the empty string. Both store the empty
340
+ // form and the absent form side by side across the corpus.
341
+ case "tool_meta":
342
+ case "resource_uri":
343
+ case "alias":
344
+ case "baseURL":
345
+ case "safetySettings":
346
+ case "dynamicRetrievalConfig":
347
+ case "apiKey":
348
+ return v === "";
349
+ // `headers` is an empty STRING on an unset agent config and a string[] on an
350
+ // api_request statement — dropping only the string spelling leaves an empty
351
+ // header list comparing as the authored value it is.
352
+ case "headers":
353
+ return v === "";
354
+ // MCP metadata a newer engine fills on every tool and toolset, at the value
355
+ // an older one reads the absent key as: a tool's `icons`/`title`/
356
+ // `annotations`/`output_schema`, a toolset's `prompt`/`resource` lists. The
357
+ // SDK writes none of them, so a pulled tree re-exported without them and
358
+ // every MCP server and tool on a current instance failed its round trip.
359
+ // Array-only for `prompt` — an agent's own `prompt` is a string.
360
+ case "icons":
361
+ case "output_schema":
362
+ case "prompt":
363
+ case "resource":
364
+ return isEmptyArray(v);
365
+ case "title":
366
+ return v === "";
367
+ case "annotations":
368
+ return typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every((m) => m === null || isEmptyArray(m));
369
+ // A tool entry's kind. Absent means `tool`; a `resource` or `prompt` entry
370
+ // says so and still compares. Value-distinct from the other `type`
371
+ // discriminators (an expression node, a column type), none of which is `tool`.
372
+ case "type":
373
+ return v === "tool";
374
+ // Four stored spellings of "no thinking budget" across 16 real configs: the
375
+ // empty string, absent, and the block with its budget as either `0` or `""`.
376
+ case "thinkingConfig":
377
+ return v === "" || typeof v === "object" && v !== null && !Array.isArray(v) && v["includeThoughts"] === false && (v["thinkingBudget"] === 0 || v["thinkingBudget"] === "");
378
+ // A query with no declared response type. Type- and value-distinct from the
379
+ // raw-SQL `response_type`, whose values are `list`/`single`/`count` and
380
+ // whose own default (`list`) is spelled differently.
381
+ case "response_type":
382
+ return v === "standard";
383
+ // Empty list members. `tag` is the load-bearing one: it is also the
384
+ // discriminator every tagged value carries, so the rule is restricted to the
385
+ // ARRAY spelling — a `tag: "const:str"` is a string and never matches.
386
+ case "tag":
387
+ case "views":
388
+ case "result":
389
+ return isEmptyArray(v);
390
+ // Two API-group gates with opposite defaults, each the value the engine
391
+ // falls back to when the key is absent: a group serves unless disabled,
392
+ // documentation is off unless turned on.
393
+ case "api_group_enabled":
394
+ return v === true;
395
+ case "swagger":
396
+ return v === false;
397
+ case "documentation":
398
+ return deepEqual(normalize(v), normalize(DEFAULT_DOCUMENTATION));
399
+ // A CORS block is applied ONLY when its `mode` is `"custom"` — the engine
400
+ // reads an absent mode as `""`, which is not custom — so a block that does
401
+ // not say `custom` configures nothing.
402
+ //
403
+ // Two spellings therefore mean the same default. The current one says
404
+ // `mode: "default"`; an older one predates `mode` entirely and carries
405
+ // `enabled: false`, a key that request path never reads.
406
+ case "cors": {
407
+ if (typeof v !== "object" || v === null || Array.isArray(v)) return false;
408
+ const block = { ...v };
409
+ if (block["enabled"] === false) delete block["enabled"];
410
+ block["mode"] ??= "default";
411
+ return deepEqual(normalize(block), normalize(DEFAULT_CORS));
412
+ }
413
+ // Both stored spellings of "no middleware": the engine hands an empty
414
+ // associative map back as a JSON array, the same artifact already absorbed
415
+ // for `mocks`, `customize` and an empty `context`. A phase explicitly
416
+ // customized to run nothing still compares — that is not inheriting.
417
+ case "middleware":
418
+ return isEmptyArray(v) || deepEqual(normalize(v), normalize(DEFAULT_MIDDLEWARE));
419
+ // Two unrelated `offset`s, both at a default. An addon's is the response path
420
+ // its rows are spliced into, `""` when spliced at the root. A list context's
421
+ // paging offset is declared to default to 0. Neither carries information at
422
+ // its default; any other value is preserved.
423
+ case "offset":
424
+ return v === "" || isNumber(v, 0);
425
+ // Return-block paging members, each at its declared default. Type-distinct
426
+ // from their same-named neighbours in a permissions block (`page: true`,
427
+ // `per_page: false`), which are booleans and so untouched.
428
+ case "page":
429
+ return isNumber(v, 1);
430
+ case "per_page":
431
+ return isNumber(v, 25);
432
+ case "metadata":
433
+ return v === true;
434
+ case "totals":
435
+ return v === false;
436
+ case "distinct":
437
+ return v === "auto";
438
+ // `s.setheader`'s duplicate-handling mode. The engine declares it
439
+ // `duplicates?=replace` and reads it as `($data["duplicates"] ?? "replace")`,
440
+ // so an absent key IS "replace"; 3 real statements omit it against 8 that
441
+ // store it present-at-default. The key appears on no other statement.
442
+ case "duplicates":
443
+ return v === "replace";
444
+ // A return sub-block whose every member sat at a default. These are checked
445
+ // against their NORMALIZED form because the member rules above are what empty
446
+ // them — without this the block survives as `{}` and the whole return envelope
447
+ // never collapses, which is the only reason it matters.
448
+ //
449
+ // `list` also names a foreach's iterated value; a tagged value never
450
+ // normalizes to empty, so that one is untouched.
451
+ //
452
+ // `enabled:false` is the one member no rule above empties, deliberately — it
453
+ // is meaningful on a history block, so it cannot be dropped by name. It IS
454
+ // droppable here, where the key says the block is paging: 7 real db.query
455
+ // statements omit `paging` outright against 149 that store it present at
456
+ // `enabled:false`, and the two spellings mean the same thing.
457
+ //
458
+ // Evidenced twice before being trusted. Every engine consumer reads the flag
459
+ // as `["paging"]["enabled"] ?? false`, so an absent block IS a disabled one,
460
+ // and the serializer returns before writing anything when it is off — a
461
+ // disabled block emits no source at all. The siblings are provably inert
462
+ // meanwhile: every read of `page`/`per_page`/`offset`/`metadata` sits behind
463
+ // that same gate.
464
+ //
465
+ // Still narrow: this fires only once every OTHER member has normalized away.
466
+ // A disabled block that customizes something (`{enabled:false, per_page:50}`)
467
+ // keeps both and compares as itself.
468
+ case "paging": {
469
+ const normalized = normalize(v);
470
+ return isEmptyObject(normalized) || deepEqual(normalized, { enabled: false });
471
+ }
472
+ // The same four blocks, plus the residue the member rules above cannot reach.
473
+ //
474
+ // The engine writes ALL FOUR result-shape blocks on every query; the SDK writes
475
+ // only the one its `returnType` selects. Emptiness alone does not collapse a
476
+ // default sibling, because two of its members have no rule that empties them —
477
+ // the paging `enabled:false` gate and an aggregate's empty `group`/`index`
478
+ // lists. So one customized `per_page` left every default sibling mismatching,
479
+ // and a paged query could never verify.
480
+ //
481
+ // Deep-equality against each block's own frozen default is what reaches those
482
+ // members WITHOUT a global rule on their generic names — `enabled:false` is
483
+ // meaningful on a history block, and an empty `group` is a condition default
484
+ // elsewhere. A block with anything authored inside it still compares.
485
+ case "list":
486
+ if (hasNoListBounds(v)) return true;
487
+ // falls through to the result-shape block of the same name
488
+ case "single":
489
+ case "stream":
490
+ case "aggregate":
491
+ return isEmptyObject(normalize(v)) || deepEqual(normalize(v), normalize(Object.hasOwn(DEFAULT_RETURN_BLOCKS, key) ? DEFAULT_RETURN_BLOCKS[key] : void 0));
492
+ // Field-envelope members the engine fills with a fixed default on save. A
493
+ // field saved by an older engine generation omits them entirely, while both
494
+ // the current engine and the SDK always write them — the same lean-vs-full
495
+ // generational gap as the members above, and by far the most common one in
496
+ // the wild: nearly every field in a workspace that has not been re-saved
497
+ // lacks `is_settings_registry`. Without these the decoder cannot prove ANY
498
+ // authored form reproduces such a field, so every one of them degrades to a
499
+ // descriptor literal or `rawField()` — including foreign keys, which lose
500
+ // their `f.tableRef(table)` form and the table import with it.
501
+ case "is_settings_registry":
502
+ case "sensitive":
503
+ return v === false;
504
+ case "mode":
505
+ case "format":
506
+ return v === "";
507
+ // A field's `vector.size` is only authored on a `vector` column; on every
508
+ // other type the engine writes this exact default. Dropping it at the
509
+ // default is symmetric, so a real `vector` column of size 3 still compares
510
+ // equal, and any other size is preserved and still compared.
511
+ case "vector":
512
+ return deepEqual(v, { size: 3 });
513
+ // Agent `agent_settings.model`: the engine persists a top-level empty
514
+ // `model:""` (the real model lives under `configs.<provider>.model`); the SDK
515
+ // omits the empty top-level field. Drop it on both sides when empty.
516
+ case "model":
517
+ return v === "";
518
+ // Statement input-entry members: the lean parser form omits these; the full
519
+ // persisted form carries them. Drop at their defaults (a meaningful
520
+ // `ignore:true` on a system column, or non-empty `children`, is kept).
521
+ case "ignore":
522
+ case "expand":
523
+ return v === false;
524
+ // Expression right-operand flag: the engine schema marks it `?=false` and
525
+ // drops it at the default on save, so the persisted form (and the SDK) omit
526
+ // it; older parser-generation fixtures still carry `ignore_empty:false`.
527
+ case "ignore_empty":
528
+ return v === false;
529
+ case "children":
530
+ return isEmptyArray(v);
531
+ // The two stored generations of an external database connection sit in
532
+ // SEPARATE fields, and a statement that uses one leaves the other at its
533
+ // unset value rather than dropping it: the engine's optional-schema pass
534
+ // gives the bare `connection_string` the text default `""` and leaves the
535
+ // nested `connection_string_flex` as nothing at all. Neither unset spelling
536
+ // says anything about the connection, so both drop on both sides — which is
537
+ // what lets a statement stored in either generation prove against the one
538
+ // field it actually uses. A populated field of either
539
+ // generation is preserved and still compared.
540
+ case "connection_string":
541
+ return v === "";
542
+ case "connection_string_flex":
543
+ return v === null || v === "{}" || isEmptyObject(v);
544
+ // A value's filter chain: an empty `filters:[]` is identical to no filter
545
+ // chain. The engine always serializes it on a nested value (e.g. a
546
+ // `context`-nested `filename`); the SDK omits it there. Drop the empty form
547
+ // on both sides so the representational gap doesn't fail an otherwise-equal
548
+ // value. A non-empty chain is preserved and still compared.
549
+ case "filters":
550
+ return isEmptyArray(v);
551
+ // Statement/object input-entry array: the lean parser form omits an empty
552
+ // `input`; the full persisted form carries `input:[]`; and the engine writes
553
+ // `input:null` for a statement that takes no inputs at all. All three are the
554
+ // same "no inputs" state — the SDK emits the `[]` spelling, so without the
555
+ // null arm every input-less statement in a pulled workspace fails to prove
556
+ // and degrades to `raw()`. Drop all three on both sides; a populated `input`
557
+ // is preserved. Same two-spellings-of-empty shape as `settings_registry`.
558
+ case "input":
559
+ return v === null || isEmptyArray(v);
560
+ case "shared_workspace":
561
+ return v !== null && typeof v === "object" && v.is_shared === false;
562
+ // A trigger's `obj_id`: a table trigger's is the referenced table's GUID
563
+ // *string* (authored, derived by the SDK, kept and compared). A workspace /
564
+ // realtime / error trigger has no table, so the engine stores a *numeric*
565
+ // branch/workspace reference (`1`) while the SDK emits a `0` placeholder —
566
+ // deploy-target state, same rationale as the stripped `branch`. Drop the
567
+ // numeric form on both sides; the guid-string form is preserved.
568
+ case "obj_id":
569
+ return typeof v === "number";
570
+ // Toolset/query/function inherit-tier `history` block: when `inherit` is true
571
+ // nothing is customized (the limit/enabled members are the inherited
572
+ // defaults, not authored). The SDK omits it on a toolset; drop the inheriting
573
+ // form on both sides. A customized (`inherit:false`) history is preserved.
574
+ case "history":
575
+ return Array.isArray(v) || v !== null && typeof v === "object" && v.inherit === true;
576
+ // An MCP-server toolset persists `agent_settings:null` (only agents carry a
577
+ // real settings block); the SDK omits it. Drop the null form.
578
+ // `null`, and the engine's BLANK SCAFFOLD — an MCP toolset that configures no
579
+ // model still gets the whole block written, inert (see
580
+ // {@link isBlankAgentSettings}). The SDK spells both by omitting it.
581
+ case "agent_settings":
582
+ return v === null || isBlankAgentSettings(v);
583
+ // An agent's default `agent_settings.telemetry` (all providers off, empty
584
+ // keys): the SDK omits it. Drop when telemetry is disabled.
585
+ case "telemetry":
586
+ return v !== null && typeof v === "object" && v.enabled === false;
587
+ // A tool/query/function `test:[]` scaffold array — the SDK omits it on a tool;
588
+ // an empty test list is identical to none. Drop the empty form both sides.
589
+ case "test":
590
+ return isEmptyArray(v);
591
+ // A query's saved request/response sample at its empty spelling. The SDK
592
+ // writes `{}` whenever no sample is authored and the engine may store the
593
+ // key not at all, or with both halves null. All three mean "no sample".
594
+ // A POPULATED one is preserved and compared (and copied through opaquely —
595
+ // see the `example` branch in the recursion below).
596
+ case "example":
597
+ return v === null || isEmptyArray(v) || typeof v === "object" && Object.values(v).every((half) => half === null);
598
+ // A default `auth:false` (public / no auth table): the engine persists it on a
599
+ // tool where the SDK omits it. Drop the `false` form; `auth:true` and an
600
+ // auth-table id are preserved and still compared.
601
+ // `false` and `""` are both "no auth table"; a guid names one and compares —
602
+ // the round trip translates the compiled guid into the engine's re-minted
603
+ // one first (`./guid-remap.ts`), so naming the WRONG table still diffs.
604
+ case "auth":
605
+ return v === false || v === "";
606
+ // Default db-query `context` members the engine fills when an addon (or any
607
+ // db context) customizes nothing; the SDK omits them. Empty-collection /
608
+ // false members drop directly; the three structured members below match
609
+ // their exact engine default (a customized context is preserved).
610
+ case "bind":
611
+ case "eval":
612
+ case "sort":
613
+ return isEmptyArray(v);
614
+ case "future":
615
+ return v === false;
616
+ // Compare NORMALIZED against NORMALIZED default: normalize strips empty
617
+ // `sort`/`eval`/`index` members from the nested subtree, so the frozen
618
+ // default must pass through the same reduction to compare equal.
619
+ case "lock":
620
+ return deepEqual(normalize(v), normalize({ tag: "const:bool", value: "" }));
621
+ // A condition container that holds nothing, in either stored spelling: the
622
+ // `{expression: []}` the SDK writes and the empty associative-map form `[]`
623
+ // the engine hands back — the same artifact already absorbed for `mocks`,
624
+ // `customize` and an empty `context`. Both mean "no condition configured".
625
+ // A populated container is untouched and still compares node for node.
626
+ case "expr":
627
+ return isEmptyArray(v) || v !== null && typeof v === "object" && isEmptyArray(v.expression);
628
+ case "search":
629
+ return deepEqual(normalize(v), normalize({ expression: [] }));
630
+ // Two spellings of an all-defaults return block. The engine's declared shape
631
+ // defaults the result type to a list and leaves every sub-block optional, so
632
+ // a query that customizes nothing persists either the whole subtree (when the
633
+ // engine filled it on save) or nothing but the type — and the SDK omits it
634
+ // entirely. Accept both, and preserve any customized paging/sort/distinct.
635
+ case "return":
636
+ return deepEqual(normalize(v), normalize(DEFAULT_CONTEXT_RETURN)) || deepEqual(normalize(v), MINIMAL_CONTEXT_RETURN);
637
+ // A condition entry's nested group. The engine declares it optional with no
638
+ // default, so an entry that nests nothing omits the key while the SDK
639
+ // materializes an empty search. Same state; drop the empty form on both
640
+ // sides. A group that actually nests expressions is preserved and compared.
641
+ case "group":
642
+ return deepEqual(normalize(v), EMPTY_SEARCH);
643
+ // A condition entry's or-flag, declared to default false: the persisted form
644
+ // omits it at the default where the SDK writes it.
645
+ case "or":
646
+ return v === false;
647
+ // Generated-asset visibility, declared to default public wherever it appears.
648
+ case "access":
649
+ return v === "public";
650
+ // A precondition's error class, declared to default to the standard error.
651
+ case "error_type":
652
+ return v === "standard";
653
+ case "external":
654
+ return deepEqual(normalize(v), normalize(DEFAULT_CONTEXT_EXTERNAL));
655
+ case "simpleExternal":
656
+ return bindsNoPagingFacet(v);
657
+ default:
658
+ return false;
659
+ }
660
+ }
661
+ function isEmptyOutput(v) {
662
+ if (v === null) return true;
663
+ if (typeof v !== "object" || Array.isArray(v)) return false;
664
+ const o = v;
665
+ const noItems = o.items === void 0 || Array.isArray(o.items) && o.items.length === 0;
666
+ const noFilters = o.filters === void 0 || Array.isArray(o.filters) && o.filters.length === 0;
667
+ return noItems && noFilters && o.customize !== true;
668
+ }
669
+ function historyWithDefaultLimit(v) {
670
+ if (v === null || typeof v !== "object" || Array.isArray(v)) return void 0;
671
+ const block = v;
672
+ if (block.inherit !== false) return void 0;
673
+ const enabledKey = Object.keys(block).find((key) => key === "enabled" || key.endsWith("_enabled"));
674
+ if (enabledKey === void 0) return void 0;
675
+ const limitKey = enabledKey === "enabled" ? "limit" : `${enabledKey.slice(0, -"_enabled".length)}_limit`;
676
+ if (Object.hasOwn(block, limitKey)) return void 0;
677
+ return { ...block, [limitKey]: ENGINE_HISTORY_LIMIT };
678
+ }
679
+ function withoutDefaultMcpHistoryPairs(v) {
680
+ if (v === null || typeof v !== "object" || Array.isArray(v)) return void 0;
681
+ const block = v;
682
+ if (Object.hasOwn(block, "inherit")) return void 0;
683
+ const drop = ["prompt", "resource"].filter(
684
+ (type) => block[`${type}_enabled`] === true && block[`${type}_limit`] === ENGINE_HISTORY_LIMIT
685
+ );
686
+ if (drop.length === 0) return void 0;
687
+ const out = { ...block };
688
+ for (const type of drop) {
689
+ delete out[`${type}_enabled`];
690
+ delete out[`${type}_limit`];
691
+ }
692
+ return out;
693
+ }
694
+ var ENGINE_HISTORY_LIMIT = 100;
695
+ var LOCAL_DBO_REF = /^dbo=\d+$/;
696
+ function clearLocalDboRefs(value, cleared) {
697
+ if (Array.isArray(value)) {
698
+ return value.map((item) => clearLocalDboRefs(item, cleared));
699
+ }
700
+ if (value === null || typeof value !== "object") return value;
701
+ const next = Object.fromEntries(
702
+ Object.entries(value).map(([key, member]) => [
703
+ key,
704
+ clearLocalDboRefs(member, cleared)
705
+ ])
706
+ );
707
+ if (next.name === "@" && Array.isArray(next.arg)) {
708
+ const target = next.arg[0];
709
+ if (typeof target === "string" && LOCAL_DBO_REF.test(target)) {
710
+ cleared?.add(target);
711
+ return { ...next, arg: ["dbo=", ...next.arg.slice(1)] };
712
+ }
713
+ }
714
+ return next;
715
+ }
716
+ var EMPTY_CONTEXT_FILL = /* @__PURE__ */ new Map([
717
+ // Its name rides the envelope `as`, so the context is the value alone.
718
+ ["mvp:set_var", { tag: "const", named: false }],
719
+ // Standalone classes, each declaring its own default tag.
720
+ ["mvp:sleep", { tag: "const:int", named: false }],
721
+ ["mvp:die", { tag: "input", named: false }],
722
+ ["mvp:setheader", { tag: "input", named: false }],
723
+ // `array_pop`/`array_shift` carry NO `tag`, because they take no operand:
724
+ // popping or shifting reads nothing, their specs route no spread field, and
725
+ // the encoder writes `name` alone. The fill must be exactly what the encoder
726
+ // writes — filling a value they cannot author invents members the comparison
727
+ // then demands forever, which is what shipped once when they were given the
728
+ // full `UpdateVarBase` treatment below.
729
+ //
730
+ // A name-only fill is a different claim from that one, and it is evidenced
731
+ // twice on the engine, both times on the SCALAR `name`:
732
+ // • the statement's own XanoScript schema declares `name?='': context.name`
733
+ // — the default for an absent name IS the empty string; and
734
+ // • the shared base class declares `name` as a plain `text` member and runs
735
+ // it through the same optional-schema pass that licenses every entry here.
736
+ //
737
+ // That second point is exactly where the loops failed (see
738
+ // {@link LOOP_EMPTY_ITERAND}): that pass materializes a SCALAR member but
739
+ // defaults a NESTED object to the literal string `"{}"`. `name` is a scalar,
740
+ // `list`/`cnt` are not, and the shape is what decides. The engine's own
741
+ // statement-transform corpus stores `{"context":{}}` for `mvp:array_shift`.
742
+ ["mvp:array_pop", { named: true }],
743
+ ["mvp:array_shift", { named: true }],
744
+ // The `UpdateVarBase` family: `{name, value, tag, filters}`, `tag` overridden
745
+ // per subclass by `getDefaultTag()`. `test/codegen/spec-inverse` asserts every
746
+ // entry's members against the spec catalog so the two cannot drift.
747
+ ["mvp:update_var", { tag: "const", named: true }],
748
+ ["mvp:array_merge", { tag: "const:array", named: true }],
749
+ ["mvp:array_push", { tag: "const", named: true }],
750
+ ["mvp:array_unshift", { tag: "const", named: true }],
751
+ ["mvp:bitwise_and", { tag: "const:int", named: true }],
752
+ ["mvp:bitwise_or", { tag: "const:int", named: true }],
753
+ ["mvp:bitwise_xor", { tag: "const:int", named: true }],
754
+ ["mvp:math_add", { tag: "const:decimal", named: true }],
755
+ ["mvp:math_sub", { tag: "const:decimal", named: true }],
756
+ ["mvp:math_mul", { tag: "const:decimal", named: true }],
757
+ ["mvp:math_div", { tag: "const:decimal", named: true }],
758
+ ["mvp:math_mod", { tag: "const:int", named: true }],
759
+ ["mvp:text_append", { tag: "const", named: true }],
760
+ ["mvp:text_prepend", { tag: "const", named: true }],
761
+ ["mvp:text_trim", { tag: "const", named: true }],
762
+ ["mvp:text_ltrim", { tag: "const", named: true }],
763
+ ["mvp:text_rtrim", { tag: "const", named: true }],
764
+ ["mvp:text_starts_with", { tag: "const", named: true }],
765
+ ["mvp:text_istarts_with", { tag: "const", named: true }],
766
+ ["mvp:text_ends_with", { tag: "const", named: true }],
767
+ ["mvp:text_iends_with", { tag: "const", named: true }],
768
+ ["mvp:text_contains", { tag: "const", named: true }],
769
+ ["mvp:text_icontains", { tag: "const", named: true }],
770
+ // The file-resource family and `debug_log`: the context IS the value, like
771
+ // `set_var`, but the file resources declare a sibling SCALAR (`access`) that
772
+ // the same optional pass materializes alongside it — so the fill carries it.
773
+ // The nested `filename` is NOT filled: a nested object defaults to the literal
774
+ // string `"{}"` and materializes nothing.
775
+ //
776
+ // `extra` is exactly where the `array_pop` note above applies. `create_attachment`
777
+ // ALSO declares `include_meta?=false`, and filling it failed the round trip —
778
+ // the SDK's spec models no such field, so the encoder never writes it and the
779
+ // fill demanded a member the recovered record could not produce. The fill has
780
+ // to equal what the ENCODER writes, not everything the engine would supply.
781
+ // (A workspace that stores a real `include_meta` still degrades to `raw()`,
782
+ // which is the correct handling for an unmodelled member.)
783
+ //
784
+ // Read off each statement class's own schema, and the default tag is NOT
785
+ // uniform across them — the file resources declare `tag?=input` while
786
+ // `debug_log` declares `tag?=const`, the same split `die`/`setheader` have.
787
+ ["mvp:create_image", { tag: "input", named: false, extra: { access: "public" } }],
788
+ ["mvp:create_audio", { tag: "input", named: false, extra: { access: "public" } }],
789
+ ["mvp:create_attachment", { tag: "input", named: false, extra: { access: "public" } }],
790
+ ["mvp:debug_log", { tag: "const", named: false }]
791
+ ]);
792
+ var LOOP_EMPTY_ITERAND = /* @__PURE__ */ new Map([
793
+ ["mvp:foreach", { member: "list", value: "[]", tag: "const:array" }],
794
+ ["mvp:for", { member: "cnt", value: "0", tag: "const:int" }]
795
+ ]);
796
+ function blankValue(tag) {
797
+ return { value: "", tag, filters: [] };
798
+ }
799
+ function liveSwitchContext(stored) {
800
+ if (stored === null || typeof stored !== "object") return void 0;
801
+ const { name, context } = stored;
802
+ if (name !== "mvp:switch") return void 0;
803
+ if (context === null || typeof context !== "object" || Array.isArray(context)) return void 0;
804
+ const block = context;
805
+ const subject = block.value;
806
+ const nested = subject !== null && typeof subject === "object" && !Array.isArray(subject) && typeof subject.tag === "string";
807
+ if (!nested) return void 0;
808
+ const strays = ["tag", "filters"].filter((key) => key in block);
809
+ if (strays.length === 0) return void 0;
810
+ return Object.fromEntries(Object.entries(block).filter(([k]) => !strays.includes(k)));
811
+ }
812
+ function liveArrayMapContext(stored) {
813
+ if (stored === null || typeof stored !== "object") return void 0;
814
+ const { name, context } = stored;
815
+ if (name !== "mvp:array_map") return void 0;
816
+ if (context === null || typeof context !== "object" || Array.isArray(context)) return void 0;
817
+ const block = context;
818
+ const dead = (block.output_type ?? "value") === "object" ? "transform_value" : "transform_object";
819
+ if (!(dead in block)) return void 0;
820
+ return Object.fromEntries(Object.entries(block).filter(([k]) => k !== dead));
821
+ }
822
+ function filledContext(stored) {
823
+ if (stored === null || typeof stored !== "object") return null;
824
+ const { name, context } = stored;
825
+ if (typeof name !== "string") return null;
826
+ const whole = EMPTY_CONTEXT_FILL.get(name);
827
+ if (whole) {
828
+ const empty = context === null || Array.isArray(context) && context.length === 0 || typeof context === "object" && Object.keys(context).length === 0;
829
+ if (!empty) return null;
830
+ if (whole.tag === void 0) return { name: "" };
831
+ return {
832
+ ...whole.named ? { name: "" } : {},
833
+ ...blankValue(whole.tag),
834
+ ...whole.extra ?? {}
835
+ };
836
+ }
837
+ const loop = LOOP_EMPTY_ITERAND.get(name);
838
+ if (loop) {
839
+ if (context === null || typeof context !== "object" || Array.isArray(context)) return null;
840
+ const block = context;
841
+ if (block[loop.member] !== void 0) return null;
842
+ return { ...block, [loop.member]: { value: loop.value, tag: loop.tag, filters: [] } };
843
+ }
844
+ return null;
845
+ }
846
+ var INERT_TRIGGER_META_GROUPS = {
847
+ database: {
848
+ datasource: [],
849
+ search: { expression: [] },
850
+ action: { delete: false, insert: false, truncate: false, update: false }
851
+ },
852
+ toolset: { action: { connection: false } },
853
+ workspace: { action: { branch_live: false, branch_merge: false, branch_new: false } },
854
+ workspace_realtime_channel: { action: { message: false, join: false } },
855
+ realtime_server: { action: { connect: false, disconnect: false } },
856
+ channel: { action: { join: false, leave: false, deliver: false } }
857
+ };
858
+ function withoutInertTriggerMetaGroups(value) {
859
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
860
+ const entries = Object.entries(value);
861
+ if (entries.length === 0) return void 0;
862
+ if (!entries.every(([k]) => Object.hasOwn(INERT_TRIGGER_META_GROUPS, k))) return void 0;
863
+ const kept = entries.filter(([k, v]) => !deepEqual(v, Object.hasOwn(INERT_TRIGGER_META_GROUPS, k) ? INERT_TRIGGER_META_GROUPS[k] : void 0));
864
+ return kept.length === entries.length ? void 0 : Object.fromEntries(kept);
865
+ }
866
+ var canonicalToolsetPrimitives;
867
+ function toolsetPrimitive(name) {
868
+ canonicalToolsetPrimitives ??= new Map(
869
+ impliedInputs("toolset", "mcp").filter((i) => i.name === "prompts" || i.name === "resources" || i.name === "auth").map((i) => [i.name, normalize(i)])
870
+ );
871
+ return typeof name === "string" ? canonicalToolsetPrimitives.get(name) : void 0;
872
+ }
873
+ function withoutToolsetPrimitiveInputs(value) {
874
+ if (!Array.isArray(value)) return value;
875
+ return value.filter((i) => {
876
+ const canonical = toolsetPrimitive(i?.name);
877
+ return canonical === void 0 || !deepEqual(normalize(i), canonical);
878
+ });
879
+ }
880
+ function normalize(value) {
881
+ if (Array.isArray(value)) {
882
+ return value.map((v) => normalize(v));
883
+ }
884
+ if (value !== null && typeof value === "object") {
885
+ const out = /* @__PURE__ */ Object.create(null);
886
+ const blankObj = value.tag === "const:obj" && "value" in value && (value.value === "" || value.value === null);
887
+ const isTable = "schema" in value && !("context" in value);
888
+ const sortsInput = NAME_KEYED_INPUT.has(value.name);
889
+ const dropsInput = UNREADABLE_INPUT.has(value.name);
890
+ const retired = retiredInputs(value.name);
891
+ const contextFill = filledContext(value);
892
+ const arrayMapContext = liveArrayMapContext(value);
893
+ const switchContext = liveSwitchContext(value);
894
+ const isGroupNode = value.type === "group";
895
+ const isMiddlewareBlock = "pre_customize" in value || "post_customize" in value;
896
+ const isDescriptor = "type" in value && "required" in value;
897
+ const requiredEntry = value.required === true;
898
+ for (const [k, stored] of Object.entries(value)) {
899
+ const v = k === "expr" ? withoutLeadingJoin(stored) : k === "result" ? liveResultItems(stored) ?? stored : k === "return" ? (() => {
900
+ const live = liveReturnSection(stored) ?? stored;
901
+ return returnWithoutIterator(live) ?? live;
902
+ })() : k === "runtime" ? liveAsyncRuntime(stored) ?? stored : stored;
903
+ if (k === "token" && isSavedTest(value)) continue;
904
+ if (k === "id" && isSavedTest(value)) {
905
+ out[k] = v;
906
+ continue;
907
+ }
908
+ if (STRIP_KEYS.has(k)) continue;
909
+ if (isTable && k === "as") continue;
910
+ if (isGroupNode && k === "statement") continue;
911
+ if (isMiddlewareBlock && (k === "pre" || k === "post") && value[`${k}_customize`] !== true) {
912
+ continue;
913
+ }
914
+ if (k === "arg" && isEmptyArray(v) && isRawSqlContext(value)) continue;
915
+ if (isDefaultEnvelopeMember(k, v)) continue;
916
+ if (isDescriptor && k === "default") {
917
+ if (requiredEntry || v === null || v === "") {
918
+ out[k] = null;
919
+ continue;
920
+ }
921
+ }
922
+ if (k === "output" && isEmptyOutput(v)) continue;
923
+ if (k === "history") {
924
+ const trimmed = withoutDefaultMcpHistoryPairs(v);
925
+ if (trimmed !== void 0) {
926
+ out[k] = normalize(trimmed);
927
+ continue;
928
+ }
929
+ const filled = historyWithDefaultLimit(v);
930
+ if (filled !== void 0) {
931
+ out[k] = normalize(filled);
932
+ continue;
933
+ }
934
+ }
935
+ if (k === "meta") {
936
+ const reduced = withoutInertTriggerMetaGroups(v);
937
+ if (reduced !== void 0) {
938
+ out[k] = normalize(reduced);
939
+ continue;
940
+ }
941
+ }
942
+ if (k === "input" && value.obj_type === "toolset" && "meta" in value) {
943
+ out[k] = normalize(withoutToolsetPrimitiveInputs(v));
944
+ continue;
945
+ }
946
+ if (k === "customize" && isEmptyCustomize(v)) {
947
+ out[k] = {};
948
+ continue;
949
+ }
950
+ if (k === "customize") {
951
+ out[k] = normalize(clearLocalDboRefs(v));
952
+ continue;
953
+ }
954
+ if (k === "example") {
955
+ out[k] = Object.fromEntries(
956
+ Object.entries(v).filter(([, half]) => half !== null)
957
+ );
958
+ continue;
959
+ }
960
+ if (dropsInput && k === "input") continue;
961
+ if (k === "input" && Array.isArray(v) && retired.length > 0) {
962
+ out[k] = v.filter((entry) => !retired.includes(String(entry?.name ?? ""))).map((entry) => normalize(entry));
963
+ continue;
964
+ }
965
+ if (sortsInput && k === "input" && Array.isArray(v)) {
966
+ out[k] = [...v].sort(
967
+ (a, b) => String(a?.name ?? "").localeCompare(
968
+ String(b?.name ?? "")
969
+ )
970
+ ).map((entry) => normalize(entry));
971
+ continue;
972
+ }
973
+ if (k === "auth") {
974
+ const unbound = unboundAuthTable(v);
975
+ if (unbound) {
976
+ out[k] = normalize(unbound);
977
+ continue;
978
+ }
979
+ }
980
+ if (k === "context" && arrayMapContext) {
981
+ out[k] = normalize(arrayMapContext);
982
+ continue;
983
+ }
984
+ if (k === "context" && switchContext) {
985
+ out[k] = normalize(switchContext);
986
+ continue;
987
+ }
988
+ if (k === "context" && contextFill) {
989
+ out[k] = normalize(contextFill);
990
+ continue;
991
+ }
992
+ if (k === "context" && (isEmptyArray(v) || v === null)) {
993
+ out[k] = {};
994
+ continue;
995
+ }
996
+ if (k === "arg" && Array.isArray(v)) {
997
+ out[k] = v.map((e) => typeof e === "number" ? String(e) : normalize(e));
998
+ continue;
999
+ }
1000
+ if (PAGING_INT_KEYS.has(k) && typeof v === "string" && /^-?\d+$/.test(v)) {
1001
+ out[k] = Number(v);
1002
+ continue;
1003
+ }
1004
+ if (k === "value" && blankObj) {
1005
+ out[k] = "";
1006
+ continue;
1007
+ }
1008
+ out[k] = (k === "value" || k === "operand" || k === "temperature") && (typeof v === "number" || typeof v === "boolean") ? String(v) : normalize(v);
1009
+ }
1010
+ return out;
1011
+ }
1012
+ if (typeof value === "string") {
1013
+ const ts = canonicalizeTimestamp(value);
1014
+ if (ts !== void 0) return ts;
1015
+ }
1016
+ return value;
1017
+ }
1018
+
1019
+ export {
1020
+ isEmptyCustomize,
1021
+ deepEqual,
1022
+ hasNoListBounds,
1023
+ hasUnreadableInput,
1024
+ retiredInputs,
1025
+ retiredInputSuccessor,
1026
+ isBlankGroupStatement,
1027
+ isDeadResultItem,
1028
+ isBlankAgentSettings,
1029
+ configuredDeadReturnBlocks,
1030
+ isDefaultEnvelopeMember,
1031
+ isEmptyOutput,
1032
+ ENGINE_HISTORY_LIMIT,
1033
+ clearLocalDboRefs,
1034
+ liveArrayMapContext,
1035
+ filledContext,
1036
+ normalize
1037
+ };
1038
+ //# sourceMappingURL=chunk-L5JYN3NM.js.map